diff --git a/package-lock.json b/package-lock.json index b2690c0..d29146e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@mui/x-date-pickers": "^6.18.2", "@reduxjs/toolkit": "^1.9.5", "@svgr/webpack": "^7.0.0", + "@tanstack/react-query": "^5.22.2", "antd": "^5.11.5", "autosuggest-highlight": "^3.3.4", "axios": "^1.3.5", @@ -40,7 +41,10 @@ "prop-types": "^15.8.1", "react": "^18.2.0", "react-app-rewired": "^2.2.1", + "react-csv": "^2.2.2", "react-device-detect": "^2.2.3", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.2.0", "react-geocode": "^0.2.3", "react-google-autocomplete": "^2.7.3", @@ -51,6 +55,7 @@ "react-router-dom": "^6.10.0", "react-scripts": "^5.0.1", "react-timer-hook": "^3.0.5", + "react-virtuoso": "^4.7.0", "react18-input-otp": "^1.1.3", "redux": "^4.2.1", "simplebar": "^6.2.5", @@ -4086,6 +4091,21 @@ "react-dom": ">=16.9.0" } }, + "node_modules/@react-dnd/asap": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz", + "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==" + }, + "node_modules/@react-dnd/invariant": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz", + "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==" + }, + "node_modules/@react-dnd/shallowequal": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz", + "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" + }, "node_modules/@reduxjs/toolkit": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz", @@ -4715,6 +4735,30 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@tanstack/query-core": { + "version": "5.22.2", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.22.2.tgz", + "integrity": "sha512-z3PwKFUFACMUqe1eyesCIKg3Jv1mysSrYfrEW5ww5DCDUD4zlpTKBvUDaEjsfZzL3ULrFLDM9yVUxI/fega1Qg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.22.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.22.2.tgz", + "integrity": "sha512-TaxJDRzJ8/NWRT4lY2jguKCrNI6MRN+67dELzPjNUlvqzTxGANlMp68l7aC7hG8Bd1uHNxHl7ihv7MT50i/43A==", + "dependencies": { + "@tanstack/query-core": "5.22.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -7889,6 +7933,16 @@ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, + "node_modules/dnd-core": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz", + "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==", + "dependencies": { + "@react-dnd/asap": "^5.0.1", + "@react-dnd/invariant": "^4.0.1", + "redux": "^4.2.0" + } + }, "node_modules/dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -16563,6 +16617,11 @@ "semver": "bin/semver" } }, + "node_modules/react-csv": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-csv/-/react-csv-2.2.2.tgz", + "integrity": "sha512-RG5hOcZKZFigIGE8LxIEV/OgS1vigFQT4EkaHeKgyuCbUAu9Nbd/1RYq++bJcJJ9VOqO/n9TZRADsXNDR4VEpw==" + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -16746,6 +16805,43 @@ "react-dom": ">= 0.14.0" } }, + "node_modules/react-dnd": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz", + "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==", + "dependencies": { + "@react-dnd/invariant": "^4.0.1", + "@react-dnd/shallowequal": "^4.0.1", + "dnd-core": "^16.0.1", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2" + }, + "peerDependencies": { + "@types/hoist-non-react-statics": ">= 3.3.1", + "@types/node": ">= 12", + "@types/react": ">= 16", + "react": ">= 16.14" + }, + "peerDependenciesMeta": { + "@types/hoist-non-react-statics": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-dnd-html5-backend": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz", + "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==", + "dependencies": { + "dnd-core": "^16.0.1" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -17448,6 +17544,18 @@ "react-dom": ">=16.6.0" } }, + "node_modules/react-virtuoso": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.7.0.tgz", + "integrity": "sha512-cpgvI1rSOETGDMhqVAVDuH+XHbWO1uIGKv5I6l4CyC71xWYUeGrE5n7sgTZklROB4+Vbv85pcgfWloTlY48HGQ==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16 || >=17 || >= 18", + "react-dom": ">=16 || >=17 || >= 18" + } + }, "node_modules/react18-input-otp": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/react18-input-otp/-/react18-input-otp-1.1.3.tgz", @@ -23024,6 +23132,21 @@ "rc-util": "^5.38.0" } }, + "@react-dnd/asap": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz", + "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==" + }, + "@react-dnd/invariant": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz", + "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==" + }, + "@react-dnd/shallowequal": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz", + "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" + }, "@reduxjs/toolkit": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz", @@ -23421,6 +23544,19 @@ "@svgr/plugin-svgo": "^7.0.0" } }, + "@tanstack/query-core": { + "version": "5.22.2", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.22.2.tgz", + "integrity": "sha512-z3PwKFUFACMUqe1eyesCIKg3Jv1mysSrYfrEW5ww5DCDUD4zlpTKBvUDaEjsfZzL3ULrFLDM9yVUxI/fega1Qg==" + }, + "@tanstack/react-query": { + "version": "5.22.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.22.2.tgz", + "integrity": "sha512-TaxJDRzJ8/NWRT4lY2jguKCrNI6MRN+67dELzPjNUlvqzTxGANlMp68l7aC7hG8Bd1uHNxHl7ihv7MT50i/43A==", + "requires": { + "@tanstack/query-core": "5.22.2" + } + }, "@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -25864,6 +26000,16 @@ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, + "dnd-core": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz", + "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==", + "requires": { + "@react-dnd/asap": "^5.0.1", + "@react-dnd/invariant": "^4.0.1", + "redux": "^4.2.0" + } + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -31916,6 +32062,11 @@ } } }, + "react-csv": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-csv/-/react-csv-2.2.2.tgz", + "integrity": "sha512-RG5hOcZKZFigIGE8LxIEV/OgS1vigFQT4EkaHeKgyuCbUAu9Nbd/1RYq++bJcJJ9VOqO/n9TZRADsXNDR4VEpw==" + }, "react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -32043,6 +32194,26 @@ "ua-parser-js": "^1.0.33" } }, + "react-dnd": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz", + "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==", + "requires": { + "@react-dnd/invariant": "^4.0.1", + "@react-dnd/shallowequal": "^4.0.1", + "dnd-core": "^16.0.1", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2" + } + }, + "react-dnd-html5-backend": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz", + "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==", + "requires": { + "dnd-core": "^16.0.1" + } + }, "react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -32518,6 +32689,12 @@ "prop-types": "^15.6.2" } }, + "react-virtuoso": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.7.0.tgz", + "integrity": "sha512-cpgvI1rSOETGDMhqVAVDuH+XHbWO1uIGKv5I6l4CyC71xWYUeGrE5n7sgTZklROB4+Vbv85pcgfWloTlY48HGQ==", + "requires": {} + }, "react18-input-otp": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/react18-input-otp/-/react18-input-otp-1.1.3.tgz", diff --git a/package.json b/package.json index 633fa47..5aa9a9a 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@mui/x-date-pickers": "^6.18.2", "@reduxjs/toolkit": "^1.9.5", "@svgr/webpack": "^7.0.0", + "@tanstack/react-query": "^5.22.2", "antd": "^5.11.5", "autosuggest-highlight": "^3.3.4", "axios": "^1.3.5", @@ -35,7 +36,10 @@ "prop-types": "^15.8.1", "react": "^18.2.0", "react-app-rewired": "^2.2.1", + "react-csv": "^2.2.2", "react-device-detect": "^2.2.3", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.2.0", "react-geocode": "^0.2.3", "react-google-autocomplete": "^2.7.3", @@ -46,6 +50,7 @@ "react-router-dom": "^6.10.0", "react-scripts": "^5.0.1", "react-timer-hook": "^3.0.5", + "react-virtuoso": "^4.7.0", "react18-input-otp": "^1.1.3", "redux": "^4.2.1", "simplebar": "^6.2.5", diff --git a/src/components/third-party/ReactTable.js b/src/components/third-party/ReactTable.js new file mode 100644 index 0000000..7a3a656 --- /dev/null +++ b/src/components/third-party/ReactTable.js @@ -0,0 +1,577 @@ +import PropTypes from 'prop-types'; +import React, { forwardRef, useEffect, useRef, useState } from 'react'; + +// material-ui +import { styled, useTheme } from '@mui/material/styles'; +import { + Box, + Checkbox, + Chip, + FormControl, + Grid, + ListItemText, + MenuItem, + OutlinedInput, + Pagination, + Select, + Stack, + TableCell, + TableRow, + TextField, + Tooltip, + Typography +} from '@mui/material'; + +// project-import +import { ThemeMode } from 'config'; + +// third-party +import { CSVLink } from 'react-csv'; +import { getEmptyImage } from 'react-dnd-html5-backend'; +import { useDrop, useDrag, useDragLayer } from 'react-dnd'; + +// assets +import { CaretUpOutlined, CaretDownOutlined, DragOutlined, CheckOutlined, DownloadOutlined } from '@ant-design/icons'; + +// ==============================|| HEADER HEADER ||============================== // + +export const HeaderSort = ({ column, sort }) => { + const theme = useTheme(); + return ( + + {column.render('Header')} + {!column.disableSortBy && ( + + + + + )} + + ); +}; + +HeaderSort.propTypes = { + column: PropTypes.any, + sort: PropTypes.bool +}; + +// ==============================|| TABLE PAGINATION ||============================== // + +export const TablePagination = ({ gotoPage, rows, setPageSize, pageSize, pageIndex }) => { + const [open, setOpen] = useState(false); + + const handleClose = () => { + setOpen(false); + }; + + const handleOpen = () => { + setOpen(true); + }; + + const handleChangePagination = (event, value) => { + gotoPage(value - 1); + }; + + const handleChange = (event) => { + setPageSize(+event.target.value); + }; + + return ( + + + + + + Row per page + + + + + + + Go to + + { + const page = e.target.value ? Number(e.target.value) : 0; + gotoPage(page - 1); + }} + sx={{ '& .MuiOutlinedInput-input': { py: 0.75, px: 1.25, width: 36 } }} + /> + + + + + + + ); +}; + +TablePagination.propTypes = { + gotoPage: PropTypes.func, + setPageSize: PropTypes.func, + pageIndex: PropTypes.number, + pageSize: PropTypes.number, + rows: PropTypes.array +}; + +// ==============================|| SELECTION - PREVIEW ||============================== // + +export const IndeterminateCheckbox = forwardRef(({ indeterminate, ...rest }, ref) => { + const defaultRef = useRef(); + const resolvedRef = ref || defaultRef; + + return ; +}); + +IndeterminateCheckbox.propTypes = { + indeterminate: PropTypes.bool +}; + +export const TableRowSelection = ({ selected }) => ( + <> + {selected > 0 && ( + + )} + +); + +TableRowSelection.propTypes = { + selected: PropTypes.number +}; + +// ==============================|| DRAG & DROP - DRAGGABLE HEADR ||============================== // + +export const DraggableHeader = ({ children, column, index, reorder }) => { + const theme = useTheme(); + const ref = useRef(); + const { id, Header } = column; + + const DND_ITEM_TYPE = 'column'; + + const [{ isOverCurrent }, drop] = useDrop({ + accept: DND_ITEM_TYPE, + drop: (item) => { + reorder(item, index); + }, + collect: (monitor) => ({ + isOver: monitor.isOver(), + isOverCurrent: monitor.isOver({ shallow: true }) + }) + }); + + const [{ isDragging }, drag, preview] = useDrag({ + type: DND_ITEM_TYPE, + item: () => ({ + id, + index, + header: Header + }), + collect: (monitor) => ({ + isDragging: monitor.isDragging() + }) + }); + + useEffect(() => { + preview(getEmptyImage(), { captureDraggingState: true }); + }, [preview]); + + drag(drop(ref)); + + let borderColor = theme.palette.text.primary; + if (isOverCurrent) { + borderColor = theme.palette.primary.main; + } + + return ( + + {children} + + ); +}; + +DraggableHeader.propTypes = { + column: PropTypes.any, + sort: PropTypes.bool, + reorder: PropTypes.func, + index: PropTypes.number, + children: PropTypes.node +}; + +// ==============================|| DRAG & DROP - DRAG PREVIEW ||============================== // + +const DragHeader = styled('div')(({ theme, x, y }) => ({ + color: theme.palette.text.secondary, + position: 'fixed', + pointerEvents: 'none', + left: 12, + top: 24, + transform: `translate(${x}px, ${y}px)`, + opacity: 0.6 +})); + +export const DragPreview = () => { + const theme = useTheme(); + const { isDragging, item, currentOffset } = useDragLayer((monitor) => ({ + item: monitor.getItem(), + itemType: monitor.getItemType(), + initialOffset: monitor.getInitialSourceClientOffset(), + currentOffset: monitor.getSourceClientOffset(), + isDragging: monitor.isDragging() + })); + + const { x, y } = currentOffset || {}; + + return isDragging ? ( + + {item.header && ( + + + {item.header} + + )} + + ) : null; +}; + +// ==============================|| DRAG & DROP - DRAGGABLE ROW ||============================== // + +export const DraggableRow = ({ index, moveRow, children }) => { + const DND_ITEM_TYPE = 'row'; + + const dropRef = useRef(null); + const dragRef = useRef(null); + + const [, drop] = useDrop({ + accept: DND_ITEM_TYPE, + hover(item, monitor) { + if (!dropRef.current) { + return; + } + const dragIndex = item.index; + const hoverIndex = index; + if (dragIndex === hoverIndex) { + return; + } + + const hoverBoundingRect = dropRef.current.getBoundingClientRect(); + const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; + const clientOffset = monitor.getClientOffset(); + const hoverClientY = clientOffset.y - hoverBoundingRect.top; + if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) { + return; + } + if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { + return; + } + + moveRow(dragIndex, hoverIndex); + item.index = hoverIndex; + } + }); + + const [{ isDragging }, drag, preview] = useDrag({ + type: DND_ITEM_TYPE, + item: { index }, + collect: (monitor) => ({ + isDragging: monitor.isDragging() + }) + }); + + const opacity = isDragging ? 0 : 1; + + preview(drop(dropRef)); + drag(dragRef); + + return ( + + + + + {children} + + ); +}; + +DraggableRow.propTypes = { + moveRow: PropTypes.func, + index: PropTypes.number, + children: PropTypes.node +}; + +// ==============================|| COLUMN HIDING - SELECT ||============================== // + +const ITEM_HEIGHT = 48; +const ITEM_PADDING_TOP = 8; +const MenuProps = { + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 200 + } + } +}; + +export const HidingSelect = ({ hiddenColumns, setHiddenColumns, allColumns }) => { + const handleChange = (event) => { + const { + target: { value } + } = event; + + setHiddenColumns(typeof value === 'string' ? value.split(',') : value); + }; + + const theme = useTheme(); + let visible = allColumns.filter((c) => !hiddenColumns.includes(c.id)).length; + + return ( + + + + ); +}; + +HidingSelect.propTypes = { + setHiddenColumns: PropTypes.func, + hiddenColumns: PropTypes.array, + allColumns: PropTypes.array +}; + +// ==============================|| COLUMN SORTING - SELECT ||============================== // + +export const SortingSelect = ({ sortBy, setSortBy, allColumns }) => { + const [sort, setSort] = useState(sortBy); + + const handleChange = (event) => { + const { + target: { value } + } = event; + setSort(value); + setSortBy([{ id: value, desc: false }]); + }; + + return ( + + + + ); +}; + +SortingSelect.propTypes = { + setSortBy: PropTypes.func, + sortBy: PropTypes.string, + allColumns: PropTypes.array +}; + +// ==============================|| CSV EXPORT ||============================== // + +export const CSVExport = ({ data, filename, headers }) => { + return ( + + + + + + ); +}; + +CSVExport.propTypes = { + data: PropTypes.array, + headers: PropTypes.any, + filename: PropTypes.string +}; +// ==============================|| EMPTY TABLE - NO DATA ||============================== // + +const StyledGridOverlay = styled(Stack)(({ theme }) => ({ + height: '400px', + '& .ant-empty-img-1': { + fill: theme.palette.mode === ThemeMode.DARK ? theme.palette.secondary[200] : theme.palette.secondary[400] + }, + '& .ant-empty-img-2': { + fill: theme.palette.secondary.light + }, + '& .ant-empty-img-3': { + fill: theme.palette.mode === ThemeMode.DARK ? theme.palette.secondary.A200 : theme.palette.secondary[200] + }, + '& .ant-empty-img-4': { + fill: theme.palette.mode === ThemeMode.DARK ? theme.palette.secondary.A300 : theme.palette.secondary.A100 + }, + '& .ant-empty-img-5': { + fillOpacity: theme.palette.mode === ThemeMode.DARK ? '0.09' : '0.95', + fill: theme.palette.mode === ThemeMode.DARK ? theme.palette.secondary.darker : theme.palette.secondary.light + } +})); + +export const EmptyTable = ({ msg, colSpan }) => { + return ( + + + + + + + + + + + + + + + + + + + + {msg} + + + + + ); +}; + +EmptyTable.propTypes = { + msg: PropTypes.string, + colSpan: PropTypes.number +}; diff --git a/src/config.js b/src/config.js index cab3cf7..fbfd0eb 100644 --- a/src/config.js +++ b/src/config.js @@ -4,7 +4,8 @@ export const twitterColor = '#1DA1F2'; export const facebookColor = '#3b5998'; export const linkedInColor = '#0e76a8'; -export const APP_DEFAULT_PATH = '/sample-page'; +// export const APP_DEFAULT_PATH = '/sample-page'; +export const APP_DEFAULT_PATH = '/orders'; export const HORIZONTAL_MAX_ITEM = 6; export const DRAWER_WIDTH = 260; diff --git a/src/index.js b/src/index.js index 877e503..5acfc60 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,8 @@ import 'simplebar/dist/simplebar.css'; import 'assets/third-party/apex-chart.css'; import 'assets/third-party/react-table.css'; +import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query'; + // project import import App from './App'; import { store } from 'store'; @@ -19,6 +21,7 @@ import reportWebVitals from './reportWebVitals'; const container = document.getElementById('root'); const root = createRoot(container); +const queryClient = new QueryClient(); // const root = ReactDOM.createRoot(document.getElementById('root')); @@ -27,9 +30,11 @@ const root = createRoot(container); root.render( {/* */} - - - + + + + + {/* */} ); diff --git a/src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavCollapse.js b/src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavCollapse.js index 07fb6e9..82a1ad6 100644 --- a/src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavCollapse.js +++ b/src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavCollapse.js @@ -45,7 +45,8 @@ const PopperStyled = styled(Popper)(({ theme }) => ({ left: -5, width: 10, height: 10, - backgroundColor: theme.palette.background.paper, + // backgroundColor: theme.palette.background.paper, + backgroundColor: theme.palette.primary.main, transform: 'translateY(-50%) rotate(45deg)', zIndex: 120, borderLeft: `1px solid ${theme.palette.grey.A800}`, @@ -210,11 +211,14 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s const isSelected = selected === menu.id; const borderIcon = level === 1 ? : false; const Icon = menu.icon; - const menuIcon = menu.icon ? : borderIcon; - const textColor = theme.palette.mode === ThemeMode.DARK ? 'grey.400' : 'text.primary'; - const iconSelectedColor = theme.palette.mode === ThemeMode.DARK && drawerOpen ? theme.palette.text.primary : theme.palette.primary.main; + const menuIcon = menu.icon ? : borderIcon; + // const textColor = theme.palette.mode === ThemeMode.DARK ? 'grey.400' : 'text.primary'; + // const iconSelectedColor = theme.palette.mode === ThemeMode.DARK && drawerOpen ? theme.palette.text.primary : theme.palette.primary.main; const popperId = miniMenuOpened ? `collapse-pop-${menu.id}` : undefined; const FlexBox = { display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }; + const textColor = 'white'; + const iconSelectedColor = 'white'; + // const isSelected = true; return ( <> @@ -228,9 +232,11 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s sx={{ pl: drawerOpen ? `${level * 28}px` : 1.5, py: !drawerOpen && level === 1 ? 1.25 : 1, + ...(drawerOpen && { '&:hover': { - bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter' + // bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter' + bgcolor: '#7b1fa2' }, '&.Mui-selected': { bgcolor: 'transparent', @@ -241,6 +247,7 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s ...(!drawerOpen && { '&:hover': { bgcolor: 'transparent' + // bgcolor:'#7b1fa2' }, '&.Mui-selected': { '&:hover': { @@ -256,7 +263,11 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s onClick={handlerIconLink} sx={{ minWidth: 28, - color: selected === menu.id ? 'primary.main' : textColor, + // color: selected === menu.id ? 'primary.main' : textColor, + // color: selected === menu.id ? textColor : textColor, + + // bgcolor:'white', + // color:'white', ...(!drawerOpen && { borderRadius: 1.5, width: 36, @@ -264,14 +275,20 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s alignItems: 'center', justifyContent: 'center', '&:hover': { - bgcolor: theme.palette.mode === ThemeMode.DARK ? 'secondary.light' : 'secondary.lighter' + // bgcolor: theme.palette.mode === ThemeMode.DARK ? 'secondary.light' : 'secondary.lighter' + bgcolor: '#7b1fa2', + color: 'white' } }), ...(!drawerOpen && selected === menu.id && { - bgcolor: theme.palette.mode === ThemeMode.DARK ? 'primary.900' : 'primary.lighter', + // bgcolor: theme.palette.mode === ThemeMode.DARK ? 'primary.900' : 'primary.lighter', + // bgcolor:'white', + bgcolor: '#7b1fa2', '&:hover': { - bgcolor: theme.palette.mode === ThemeMode.DARK ? 'primary.darker' : 'primary.lighter' + // bgcolor: theme.palette.mode === ThemeMode.DARK ? 'primary.darker' : 'primary.lighter' + bgcolor: '#7b1fa2' + // color:'white' } }) }} @@ -282,7 +299,12 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s {(drawerOpen || (!drawerOpen && level !== 1)) && ( + {menu.title} } @@ -297,9 +319,22 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s )} {(drawerOpen || (!drawerOpen && level !== 1)) && (miniMenuOpened || open ? ( - + ) : ( - + ))} {!drawerOpen && ( @@ -329,7 +364,8 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s mt: 1.5, boxShadow: theme.customShadows.z1, backgroundImage: 'none', - border: `1px solid ${theme.palette.divider}` + // border: `1px solid ${theme.palette.divider}`, + background: theme.palette.primary.main }} > @@ -373,7 +409,14 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s > {menuIcon && ( - + {menuIcon} )} @@ -386,7 +429,12 @@ const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, s )} + {menu.title} } diff --git a/src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavItem.js b/src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavItem.js index 292eb6d..6d6e2f5 100644 --- a/src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavItem.js +++ b/src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavItem.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import { forwardRef, useEffect,useState } from 'react'; +import { forwardRef, useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; @@ -20,14 +20,12 @@ import { activeItem, openDrawer } from 'store/reducers/menu'; const NavItem = ({ item, level }) => { const theme = useTheme(); const dispatch = useDispatch(); - const { menuOrientation } = useConfig(); const { drawerOpen, openItem } = useSelector((state) => state.menu); - const [ishover,setIshover]=useState('') + const [ishover, setIshover] = useState(''); const downLG = useMediaQuery(theme.breakpoints.down('lg')); - let itemTarget = '_self'; if (item.target) { itemTarget = '_blank'; @@ -41,8 +39,11 @@ const NavItem = ({ item, level }) => { const Icon = item.icon; const isSelected = openItem.findIndex((id) => id === item.id) > -1; - const itemIcon = item.icon ? : false; + const itemIcon = item.icon ? ( + + ) : ( + false + ); // const { pathname } = useLocation(); const pathname = document.location.pathname; @@ -77,11 +78,11 @@ const NavItem = ({ item, level }) => { {...listItemProps} disabled={item.disabled} selected={isSelected} - onMouseEnter={(e,val)=>{ - console.log(e) + onMouseEnter={(e, val) => { + console.log(e); }} - onMouseLeave={()=>{ -setIshover('') + onMouseLeave={() => { + setIshover(''); }} sx={{ zIndex: 1201, @@ -90,7 +91,7 @@ setIshover('') ...(drawerOpen && { '&:hover': { // bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter' - bgcolor:'#7b1fa2' + bgcolor: '#7b1fa2' }, '&.Mui-selected': { bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter', @@ -103,17 +104,18 @@ setIshover('') } }), ...(!drawerOpen && { + bgcolor: '#662582', '&:hover': { - bgcolor: 'transparent', + // bgcolor: 'transparent', // bgcolor:'#7b1fa2' - - + bgcolor: '#662582' }, '&.Mui-selected': { '&:hover': { bgcolor: 'transparent' }, bgcolor: 'transparent' + // bgcolor:'#7b1fa2' } }) }} @@ -126,20 +128,20 @@ setIshover('') sx={{ minWidth: 28, '&:hover': { - color:isSelected ? '#fff':iconSelectedColor , + color: isSelected ? '#fff' : iconSelectedColor }, color: isSelected ? iconSelectedColor : textColor, - + ...(!drawerOpen && { borderRadius: 1.5, width: 36, height: 36, alignItems: 'center', justifyContent: 'center', + '&:hover': { // bgcolor: theme.palette.mode === ThemeMode.DARK ? 'secondary.light' : 'secondary.lighter' - bgcolor:'#7b1fa2' - + bgcolor: '#7b1fa2' } }), ...(!drawerOpen && @@ -157,7 +159,17 @@ setIshover('') {(drawerOpen || (!drawerOpen && level !== 1)) && ( + {item.title} } diff --git a/src/layout/MainLayout/index.js b/src/layout/MainLayout/index.js index 8c0bf2c..29efa7a 100644 --- a/src/layout/MainLayout/index.js +++ b/src/layout/MainLayout/index.js @@ -44,7 +44,8 @@ const MainLayout = () => { , type: 'item', url: '/customers', icon: icons.UserOutlined }, + { + id: 'Reports', + title: , + type: 'collapse', + icon: AiOutlineBarChart, + children: [ + { + id: 'OrdersDetails', + title: , + type: 'item', + url: 'reports/ordersdetails', + icon: icons.UserOutlined + } + ] + } + // { // id: 'account', // title: , diff --git a/src/pages/nearle/api/api.js b/src/pages/nearle/api/api.js new file mode 100644 index 0000000..7bc9698 --- /dev/null +++ b/src/pages/nearle/api/api.js @@ -0,0 +1,176 @@ +import axios from 'axios'; +const tenid = localStorage.getItem('tenantid'); + +// ==============================|| fetchOrderSummary (orders)||============================== // +export const fetchOrderSummary = async () => { + const response = await axios.get(`${process.env.REACT_APP_URL}/orders/getordersummary`); + console.log('fetchOrderSummary', response.data.details); + return response.data.details; +}; + +// ==============================|| fetchLocationSummary (orders)||============================== // +export const fetchLocationSummary = async () => { + const response = await axios.get(`${process.env.REACT_APP_URL}/orders/getlocationsummary`); + console.log('fetchLocationSummary', response.data.details); + + return response.data.details; +}; + +// ==============================|| fetchOrderInsight (orders)||============================== // +export const fetchOrderInsight = async () => { + const response = await axios.get(`${process.env.REACT_APP_URL}/orders/getorderinsight`); + console.log('fetchOrderInsight', response.data.details); + + return response.data.details; +}; +// ==============================|| fetchDeliverySummary (delivery)||============================== // +export const fetchDeliverySummary = async () => { + const response = await axios.get(`${process.env.REACT_APP_URL}/deliveries/deliverysummary`); + console.log('fetchDeliverySummary', response.data.details); + return response.data.details; +}; + +// ==============================|| fetchDeliveryInsight (delivery)||============================== // +export const fetchDeliveryInsight = async () => { + const response = await axios.get(`${process.env.REACT_APP_URL}/deliveries/getdeliveryinsight`); + console.log('fetchDeliveryInsight', response.data.details); + + return response.data.details; +}; +// ==============================|| fetchDeliveryLocationSummary (delivery)||============================== // +export const fetchDeliveryLocationSummary = async () => { + const response = await axios.get(`${process.env.REACT_APP_URL}/deliveries/getlocationsummary`); + console.log('fetchDeliveryLocationSummary', response.data.details); + + return response.data.details; +}; + +// ==============================|| fetchAllTenants (clients)||============================== // + +export const fetchAllTenants = async ({ queryKey }) => { + const [size, status, pageno, search, rough] = queryKey; + + let url = ''; + if (search) { + // url = `https://jupiter.nearle.app/live/api/v1/tenants/search/?keyword=${search}`; + url = `${process.env.REACT_APP_URL}/tenants/search/?keyword=${search}`; + } else { + // url = `https://jupiter.nearle.app/live/api/v1/tenants/getalltenants?pageno=${pageno}&pagesize=${size}`; + url = `${process.env.REACT_APP_URL}/tenants/getalltenants?pageno=${pageno}&pagesize=${size}`; + } + const response = await axios.get(url); + + // tenants/search/?keyword=${search} + console.log('fetchAllTenants', response.data.details); + + return response.data.details; +}; +// ==============================|| fetchCustomersList (customers)||============================== // +export const fetchCustomersList = async ({ queryKey }) => { + const [pages] = queryKey; + const response = await axios.get(`${process.env.REACT_APP_URL}/customers/getallcustomers/?pageno=${pages}&pagesize=10`); + console.log('fetchCustomersList', response.data.details); + return response.data.details; +}; +// ==============================|| fetchCustomersListBySearch (customers)||============================== // +export const fetchCustomersListBySearch = async ({ queryKey }) => { + const [search] = queryKey; + const response = await axios.get(search.lenght > 3 && `${process.env.REACT_APP_URL}/customers/search/?keyword=${search}`); + console.log('fetchCustomersListBySearch', response.data.details); + return response.data.details; +}; +// ==============================|| fetchOrdersSummary (orders summary)||============================== // +export const fetchOrdersSummary = async ({ queryKey }) => { + console.log('queryKey for fetchOrdersSummary', queryKey); + const [id, startdate, enddate] = queryKey; + const response = await axios.get( + id == -1 + ? `${process.env.REACT_APP_URL}/deliveries/getreportsummary/?&fromdate=${startdate}&todate=${enddate}` + : `${process.env.REACT_APP_URL}/deliveries/getreportsummary/?partnerid=${id}&fromdate=${startdate}&todate=${enddate}` + ); + console.log('fetchOrdersSummary', response.data.details); + + return response.data.details; +}; +// ==============================|| fetchLocations (orders summary))||============================== // + +export const fetchLocations = async ({ queryKey }) => { + const response = await axios.get(`${process.env.REACT_APP_URL}/partners/getpartners`); + const updatedLocations = [ + ...response.data.details, + { partnername: 'All', partnerid: -1 } // Add your new object here + ]; + console.log('fetchLocations', updatedLocations); + + return updatedLocations; +}; +// ==============================|| fetchAppLocations (report summary))||============================== // + +export const fetchAppLocations = async ({ queryKey }) => { + const response = await axios.get(`${process.env.REACT_APP_URL}/partners/getpartners`); + const updatedLocations = [ + ...response.data.details, + { partnername: 'All', applocationid: -1 } // Add your new object here + ]; + console.log('fetchAppLocations', updatedLocations); + + return updatedLocations; +}; + +// ==============================|| fetchRidersSummary (riders summary)||============================== // + +export const fetchRidersSummary = async ({ queryKey }) => { + console.log('queryKey for fetchRidersSummary', queryKey); + const [id, startdate, enddate] = queryKey; + const response = await axios.get( + id == -1 + ? `${process.env.REACT_APP_URL}/deliveries/getridersummary/?&fromdate=${startdate}&todate=${enddate}` + : `${process.env.REACT_APP_URL}/deliveries/getridersummary/?applocationid=${id}&fromdate=${startdate}&todate=${enddate}` + ); + console.log('fetchRidersSummary', response.data.details); + + return response.data.details; +}; + +// ==============================|| fetchorderdetails (orders detail)||============================== // +export const fetchorderdetails = async ({ queryKey }) => { + console.log('queryKey of fetchorderdetails', queryKey); + const [tabValue, appId, startdate, enddate] = queryKey; + let status = tabValue === 0 ? 'delivered' : tabValue === 1 ? 'pending' : 'cancelled'; + const response = await axios.get( + // appId == -1 + // ? `https://jupiter.nearle.app/live/api/v1/orders/getorders/?fromdate=${startdate}&todate=${enddate}` + // : `https://jupiter.nearle.app/live/api/v1/orders/getorders/?fromdate=${startdate}&todate=${enddate}&applocationid=${appId}` + `https://jupiter.nearle.app/live/api/v1/deliveries/getdeliveries/?tenantid=${tenid}&fromdate=${startdate}&todate=${enddate}` + ); + console.log('fetchorderdetails', response.data.details); + + return response.data.details; +}; +// ==============================|| fetchCount (orders detail)||============================== // +export const fetchCount = async ({ queryKey }) => { + console.log('queryKey of fetchCount', queryKey); + const [startdate, enddate] = queryKey; + const response = await axios.get(`https://jupiter.nearle.app/live/api/v1/orders/getorders/?fromdate=${startdate}&todate=${enddate}`); + const calculateOrderCounts = () => { + let deliveredCount = 0; + let pendingCount = 0; + let cancelledCount = 0; + + response.data.details.forEach((order) => { + const status = order.orderstatus; + if (status === 'delivered') { + deliveredCount++; + } else if (status === 'pending') { + pendingCount++; + } else if (status === 'cancelled') { + cancelledCount++; + } + }); + + return { deliveredCount, pendingCount, cancelledCount }; + }; + console.log('fetchCount', calculateOrderCounts()); + + return calculateOrderCounts(); +}; diff --git a/src/pages/nearle/clients/client.js b/src/pages/nearle/clients/client.js deleted file mode 100644 index 23db33d..0000000 --- a/src/pages/nearle/clients/client.js +++ /dev/null @@ -1,1655 +0,0 @@ -import * as React from 'react'; -// import AlertCustomerDelete from 'sections/apps/customer/AlertCustomerDelete'; -// import { useNavigate } from 'react-router'; -import Loader from 'components/Loader' -// import AddCustomer from 'sections/apps/customer/AddCustomer'; -import { useState, Fragment } from 'react'; -// import PlaceOutlinedIcon from '@mui/icons-material/PlaceOutlined'; -// import EmailOutlinedIcon from '@mui/icons-material/EmailOutlined'; -// import LocalPhoneOutlinedIcon from '@mui/icons-material/LocalPhoneOutlined'; -// import AccessTimeOutlinedIcon from '@mui/icons-material/AccessTimeOutlined'; -// import CustomerCard from 'sections/apps/customer/CustomerCard'; -// import CustomerCardPage from 'pages/apps/customer/card'; -import { usePlacesWidget } from "react-google-autocomplete"; -import Autocomplete from "react-google-autocomplete"; -import { Autocomplete as Autocomplete1 } from '@mui/material'; -import Geocode from "react-geocode"; - - -import { - DeleteFilled, - NotificationOutlined, - // EditTwoTone, -} from '@ant-design/icons'; -import { Empty } from 'antd'; - -import { - Avatar, - // AvatarGroup, - Button, - Box, - // Button, - Grid, - Skeleton, - - Stack, - // TextField, - Chip, - // TableSortLabel, - Typography, - // Divider, - Table, TableCell, - TableBody, - TableHead, - IconButton, - Collapse, - // Tabs, - // Tab, - Dialog, - // DialogActions, - DialogTitle, - DialogContent, - CircularProgress, - // TableSortLabel, - TableRow, - Tooltip, - List, - ListItem, - ListItemIcon, - FormControl, - OutlinedInput, - InputAdornment, - Popper, - ClickAwayListener, - InputLabel, - TextField, - Select, - MenuItem, - // Tooltip, - // Badge, - // Avatar -} from '@mui/material'; -// import { PopupTransition } from 'components/@extended/Transitions'; -import { SearchOutlined } from '@ant-design/icons'; - -import { enqueueSnackbar } from 'notistack'; -var utc = require('dayjs/plugin/utc') - -// import { useEffect, useState } from 'react'; -import axios from 'axios'; -import { useTheme } from '@mui/material/styles'; - -// import ListIcon from '@mui/icons-material/List'; -// import CheckIcon from '@mui/icons-material/Check'; -// import CloseIcon from '@mui/icons-material/Close'; -// import TwoWheelerIcon from '@mui/icons-material/TwoWheeler'; -import { - // CloseOutlined, - // // PlusOutlined, - // ContactsOutlined, - // EyeTwoTone, - // MailOutlined, - // PhoneOutlined, - // // EditTwoTone, - DeleteTwoTone, - EditTwoTone, - CheckCircleOutlined, - MoreOutlined - -} from '@ant-design/icons'; -import dayjs from 'dayjs'; -dayjs.extend(utc) -import { KeyboardArrowUp, KeyboardArrowDown } from '@mui/icons-material' - - -import PropTypes from 'prop-types'; -import TableContainer from '@mui/material/TableContainer'; -import TablePagination from '@mui/material/TablePagination'; -import TableSortLabel from '@mui/material/TableSortLabel'; -import { visuallyHidden } from '@mui/utils'; -import { useEffect } from 'react'; -import MainCard from 'components/MainCard'; - - - - -const Client = () => { - let theme = useTheme(); - const [rows, setRows] = useState([]); - const [loading, setLoading] = useState(false); - - const [searchword, setSearchword] = useState(''); - const [stafflist, setStafflist] = useState([]); - - - - useEffect(() => { - if (localStorage.getItem('tenantid')) { - fetchtable(localStorage.getItem('tenantid')) - - } - }, []) - - - useEffect(() => { - if (searchword) { - let arr = stafflist.filter((val) => { - - return (val.firstname.toLowerCase().includes(searchword.toLowerCase()) - // || val.locationaddress.toLowerCase().includes(searchword.toLowerCase()) - || val.contactno.toLowerCase().includes(searchword.toLowerCase()) - // || val.productname.toString().toLowerCase().includes(searchword.toLowerCase()) - || val.address.toString().toLowerCase().includes(searchword.toLowerCase()) - // || val.staffname.toString().toLowerCase().includes(searchword.toLowerCase()) - - ) - }) - console.log(arr) - setRows([...arr]) - } else { - setRows([...stafflist]) - } - }, [searchword]) - - const fetchtable = async (tid) => { - setLoading(true) - try { - // await axios.get(`${process.env.REACT_APP_URL2}/orders/getordershiftsbystatus`) - await axios.get(`${process.env.REACT_APP_URL}/customers/getbytid/?tenantid=${tid}`) - - .then((res) => { - if (res.data.message === "Success") { - let arr = [] - res.data.details.map((val, i) => { - arr = [...arr, { ...val, sno: i + 1 }]; - }) - // setArr(arr) - setRows([...arr]) - setStafflist([...arr]) - console.log(res.data.Details) - console.log(arr) - setLoading(false) - } - - }).catch((err) => { - console.log(err) - setLoading(false) - enqueueSnackbar(err.message, { - variant: 'error', anchorOrigin: { vertical: 'top', horizontal: 'right' }, - autoHideDuration: 2000 - }) - }) - - } catch (err) { - console.log(err); - setLoading(false) - - } - } - - - - - - function descendingComparator(a, b, orderBy) { - if (b[orderBy] < a[orderBy]) { - return -1; - } - if (b[orderBy] > a[orderBy]) { - return 1; - } - return 0; - } - - function getComparator(order, orderBy) { - return order === 'desc' - ? (a, b) => descendingComparator(a, b, orderBy) - : (a, b) => -descendingComparator(a, b, orderBy); - } - - // Since 2020 all major browsers ensure sort stability with Array.prototype.sort(). - // stableSort() brings sort stability to non-modern browsers (notably IE11). If you - // only support modern browsers you can replace stableSort(exampleArray, exampleComparator) - // with exampleArray.slice().sort(exampleComparator) - function stableSort(array, comparator) { - const stabilizedThis = array.map((el, index) => [el, index]); - stabilizedThis.sort((a, b) => { - const order = comparator(a[0], b[0]); - if (order !== 0) { - return order; - } - return a[1] - b[1]; - }); - return stabilizedThis.map((el) => el[0]); - } - - - - - - const headCells = [ - { - id: 'sno', - disablePadding: true, - label: '#', - - }, - { - id: 'tenantname', - numeric: false, - disablePadding: false, - label: 'CLIENT', - }, - // { - // id: 'orderid', - // numeric: false, - // disablePadding: false, - // label: 'CONTACT', - // }, - { - id: 'eventname', - disablePadding: false, - label: 'ADDRESS', - }, - { - id: 'starttime1', - disablePadding: false, - label: 'LANDMARK', - }, - { - id: 'starttime', - disablePadding: false, - label: 'CITY', - }, - // { - // id: 'endtime', - // disablePadding: false, - // label: 'END TIME', - // }, - // { - // id: 'staff', - // numeric: false, - // disablePadding: false, - // label: 'STAFF', - // }, - - // { - // id: 'orderstatus', - // disablePadding: false, - // label: 'STATUS', - // }, - // { - // id: 'orderstatus', - // disablePadding: false, - // label: 'Details', - // } - { - id: 'orderstatus1', - disablePadding: false, - label: 'ACTION', - } - ]; - - - function EnhancedTableHead(props) { - const { - // onSelectAllClick, - order, orderBy, - // numSelected, rowCount, - onRequestSort } = - props; - const createSortHandler = (property) => (event) => { - onRequestSort(event, property); - }; - - return ( - - - {/* - 0 && numSelected < rowCount} - checked={rowCount > 0 && numSelected === rowCount} - onChange={onSelectAllClick} - inputProps={{ - 'aria-label': 'select all desserts', - }} - /> - */} - {headCells.map((headCell) => ( - - - {headCell.label} - {orderBy === headCell.id ? ( - - {order === 'desc' ? 'sorted descending' : 'sorted ascending'} - - ) : null} - - - ))} - - - ); - } - - EnhancedTableHead.propTypes = { - numSelected: PropTypes.number.isRequired, - onRequestSort: PropTypes.func.isRequired, - onSelectAllClick: PropTypes.func.isRequired, - order: PropTypes.oneOf(['asc', 'desc']).isRequired, - orderBy: PropTypes.string.isRequired, - rowCount: PropTypes.number.isRequired, - }; - - - - function EnhancedTable() { - const [order, setOrder] = React.useState('asc'); - const [orderBy, setOrderBy] = React.useState('calories'); - const [selected, setSelected] = React.useState([]); - const [page, setPage] = React.useState(0); - // const [dense, setDense] = React.useState(false); - const [rowsPerPage, setRowsPerPage] = React.useState(10); - const [expandopen, setExpandopen] = useState(''); - const [open, setOpen] = useState(''); - // const [stafflog, setStafflog] = useState([]); - // const [loading1, setLoading1] = useState(false); - // const [currentshiftobj, setCurrentshiftobj] = useState({}); - const [loading1, setLoading1] = useState(false); - const [staffdetaillist, setStaffdetaillist] = useState([]); - const [anchorEl, setAnchorEl] = React.useState(null); - const [currentcustomerid, setCurrentcustomerid] = useState(''); - - const [businessname, setBusinessname] = useState(''); - const [businessno, setBusinessno] = useState(''); - // const [role, setRole] = useState(''); - const [mobilenumber, setMobilenumber] = useState('') - const [emailaddress, setEmailaddress] = useState('') - const [city, setCity] = useState('') - const [zipcode, setZipcode] = useState(''); - const [address, setAddress] = useState(''); - const [state, setState] = useState(''); - const [suburb, setSuburb] = useState(''); - const [latlong, setLatlong] = useState({}); - const [profiledetails, setProfiledetails] = useState({}); - const [primarycontact, setPrimarycontact] = useState('') - const [firstname, setFirstname] = useState(''); - const [doorno, setDoorno] = useState(''); - const [landmark, setLandmark] = useState(''); - const [tenantinfo, setTenantinfo] = useState({}); - Geocode.setApiKey(process.env.REACT_APP_GOOGLE_MAPS_API_KEY); - - const handleClickAway = () => { - setOpen(''); - }; - useEffect(()=>{ - const fetchtenantinfo = async (tid) => { - // setLoading(true) - await axios.get(`${process.env.REACT_APP_URL}/tenants/gettenantinfo/?tenantid=${tid}`) - .then((res) => { - console.log(res) - if (res.data.status) { - setTenantinfo(res.data.details); - } - // setLoading(false) - }).catch((err) => { - console.log(err) - // setLoading(false) - }) - } - if(localStorage.getItem('tenantid')){ - fetchtenantinfo(localStorage.getItem('tenantid')) - } - },[]) - - useEffect(() => { - try { - Geocode.fromAddress(address).then( - (response) => { - if (response.status == 'OK') { - - - const { lat, lng } = response.results[0].geometry.location; - setLatlong({ - lat, lng - }) - console.log(response); - - - } - - }, (error) => { - console.log(error) - } - ); - - } catch (err) { - console.log(err) - - } - - }, [address]) - - const { ref: materialRef } = usePlacesWidget({ - apiKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY, - onPlaceSelected: (place) => { - - console.log(place) - - setAddress(place.formatted_address) - let city1, zipcode1, state1, suburb1; - for (let i = 0; i < place.address_components.length; i++) { - for (let j = 0; j < place.address_components[i].types.length; j++) { - switch (place.address_components[i].types[j]) { - case "locality": - city1 = place.address_components[i].long_name; - break; - case "administrative_area_level_1": - state1 = place.address_components[i].long_name; - break; - case "postal_code": - zipcode1 = place.address_components[i].long_name; - break; - case "sublocality": - suburb1 = place.address_components[i].long_name; - break; - } - } - } - setCity(city1 || '') - setState(state1 || ''); - setZipcode(zipcode1 || ''); - setSuburb(suburb1 || '') - - // setAddress(place.formatted_address) - }, - // inputAutocompleteValue: "country", - options: { - // componentRestrictions: 'us', - // types: ["establishment"] - types: ['address' || 'geocode'] - }, - }); - // const fetchstafflog = async (uid, sid) => { - // setLoading1(true) - // try { - // await axios.get(`${process.env.REACT_APP_URL2}/staffs/get/stafflogbytid/?userid=${uid}&shiftid=${sid}`) - // .then((res) => { - // if (res.data.message === "Success") { - - // console.log(res.data.details) - // setStafflog(res.data.details); - // setLoading1(false) - // } - - // }).catch((err) => { - // console.log(err) - // setLoading1(false) - // }) - - // } catch (err) { - // console.log(err); - // setLoading1(false) - - // } - // } - const removeclient = async () => { - setLoading(true) - try { - await axios.delete(`${process.env.REACT_APP_URL}/customers/delete/?customerid=${currentcustomerid}`) - - .then((res) => { - if (res.data.status) { - enqueueSnackbar("Deleted Successfully", { - variant: 'success', anchorOrigin: { vertical: 'top', horizontal: 'right' }, - autoHideDuration: 2000 - }) - setCurrentcustomerid('') - fetchtable(localStorage.getItem('tenantid')) - }else{ - enqueueSnackbar(res.data.message, { - variant: 'error', anchorOrigin: { vertical: 'top', horizontal: 'right' }, - autoHideDuration: 2000 - }) - } - setLoading(false) - - }).catch((err) => { - console.log(err) - enqueueSnackbar(err.message, { - variant: 'error', anchorOrigin: { vertical: 'top', horizontal: 'right' }, - autoHideDuration: 2000 - }) - setLoading(false) - - }) - - } catch (err) { - console.log(err); - setLoading(false) - - } - } - - const fetchstafflist = async (oid) => { - setLoading1(true) - try { - // await axios.get(`${process.env.REACT_APP_URL2}/orders/getorderprocessbyid?orderheaderid=${oid}`) - await axios.get(`${process.env.REACT_APP_URL2}/client/orders/getorderprocessbyid?orderheaderid=${oid}`) - - .then((res) => { - console.log(res) - if (res.data.message === "Successful") { - - let arr = [] - res.data.details.map((val, i) => { - arr = [...arr, { ...val, sno: i + 1 }]; - }) - // setRows([...arr]) - setStaffdetaillist([...arr]) - // console.log(res.data.Details) - // console.log(arr) - // setLoading(false) - } - setLoading1(false) - - }).catch((err) => { - console.log(err) - setLoading1(false) - }) - - } catch (err) { - console.log(err); - setLoading1(false) - - } - } - - - const staffearningsverify = async (sid) => { - setLoading(true) - try { - // await axios.get(`${process.env.REACT_APP_URL2}/orders/getorderprocessbystatus`) - await axios.put(`${process.env.REACT_APP_URL2}/staffs/earnings/update`, - { - "staffearningsid": sid, - "verified": 1 - }) - // await axios.get(`${process.env.REACT_APP_URL2}/staffs/earnings/?fromdate=2023-09-07&todate=2023-09-09`) - - - .then((res) => { - console.log(res) - if (res.data.status) { - // let arr = [] - // res.data.Details.map((val, i) => { - // arr = [...arr, { ...val, sno: i + 1 }]; - // }) - // // setArr(arr) - // setRows(arr) - // console.log(res.data.Details) - // console.log(arr) - // setLoading(false) - enqueueSnackbar("Updated Successfully", { - variant: 'success', anchorOrigin: { vertical: 'top', horizontal: 'right' }, - autoHideDuration: 2000 - }) - // setTimeout(() => { - - if (localStorage.getItem('appuserid')) { - fetchtable(localStorage.getItem('appuserid')) - - } - - // }, 2000) - } - - }).catch((err) => { - console.log(err) - setLoading(false) - }) - - } catch (err) { - console.log(err); - setLoading(false) - - } - } - - const updateclient = async (sid) => { - console.log({ - "customerid": 1364, - "configid": 1, - "firstname": firstname, - "applocationid":tenantinfo.applolcationid, - "profileimage": "", - "dialcode": "+91", - "contactno": mobilenumber, - "devicetype": "", - "deviceid": "", - // "customertoken": "123", - "address":address, - "suburb": suburb, - "city": city, - "state": state, - "postcode": zipcode, - "landmark": landmark, - "doorno": doorno, - "latitude": latlong.lat.toString(), - "longitude": latlong.lng.toString(), - "tenantid": parseInt(localStorage.getItem('tenantid')), - //email,regno,tenantname - }) - setLoading(true) - try { - // await axios.get(`${process.env.REACT_APP_URL2}/orders/getorderprocessbystatus`) - await axios.put(`${process.env.REACT_APP_URL}/staffs/earnings/update12`, - { - "customerid": 1364, - "configid": 1, - "firstname": firstname, - "applocationid":tenantinfo.applolcationid, - "profileimage": "", - "dialcode": "+91", - "contactno": mobilenumber, - "devicetype": "", - "deviceid": "", - // "customertoken": "123", - "address":address, - "suburb": suburb, - "city": city, - "state": state, - "postcode": zipcode, - "landmark": landmark, - "doorno": doorno, - "latitude": latlong.lat.toString(), - "longitude": latlong.lng.toString(), - "tenantid": parseInt(localStorage.getItem('tenantid')), - //email,regno,tenantname - } - ) - - - .then((res) => { - console.log(res) - if (res.data.status) { - // let arr = [] - // res.data.Details.map((val, i) => { - // arr = [...arr, { ...val, sno: i + 1 }]; - // }) - // // setArr(arr) - // setRows(arr) - // console.log(res.data.Details) - // console.log(arr) - // setLoading(false) - enqueueSnackbar("Updated Successfully", { - variant: 'success', anchorOrigin: { vertical: 'top', horizontal: 'right' }, - autoHideDuration: 2000 - }) - // setTimeout(() => { - - // if (localStorage.getItem('appuserid')) { - // fetchtable(localStorage.getItem('appuserid')) - - // } - - // }, 2000) - } - - }).catch((err) => { - console.log(err) - setLoading(false) - }) - - } catch (err) { - console.log(err); - setLoading(false) - - } - } - - - const handleRequestSort = (event, property) => { - const isAsc = orderBy === property && order === 'asc'; - setOrder(isAsc ? 'desc' : 'asc'); - setOrderBy(property); - }; - - const handleSelectAllClick = (event) => { - if (event.target.checked) { - const newSelected = rows.map((n) => n.name); - setSelected(newSelected); - return; - } - setSelected([]); - }; - - const handleClick = (event, name) => { - const selectedIndex = selected.indexOf(name); - let newSelected = []; - - if (selectedIndex === -1) { - newSelected = newSelected.concat(selected, name); - } else if (selectedIndex === 0) { - newSelected = newSelected.concat(selected.slice(1)); - } else if (selectedIndex === selected.length - 1) { - newSelected = newSelected.concat(selected.slice(0, -1)); - } else if (selectedIndex > 0) { - newSelected = newSelected.concat( - selected.slice(0, selectedIndex), - selected.slice(selectedIndex + 1), - ); - } - - setSelected(newSelected); - }; - - const handleChangePage = (event, newPage) => { - setPage(newPage); - }; - - const handleChangeRowsPerPage = (event) => { - setRowsPerPage(parseInt(event.target.value, 10)); - setPage(0); - }; - - // const handleChangeDense = (event) => { - // setDense(event.target.checked); - // }; - - const isSelected = (name) => selected.indexOf(name) !== -1; - - // Avoid a layout jump when reaching the last page with empty rows. - const emptyRows = - page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; - - const visibleRows = React.useMemo( - () => - stableSort(rows, getComparator(order, orderBy)).slice( - page * rowsPerPage, - page * rowsPerPage + rowsPerPage, - ), - [order, orderBy, page, rowsPerPage], - ); - - const handleClose = () => { - setOpen(false); - }; - - function AlertCustomerDelete({ - // title, - open, handleClose }) { - // const [deletepassword, setDeletepassword] = useState(''); - - return ( - handleClose(false)} - maxWidth="xs" - - > - - - - - - {/* - - */} - - - Are you sure you want to Remove this Client? - - - {/* - Please type in the order number to confirm. - */} - {/* { - console.log(e.target.value) - setDeletepassword(e.target.value) - }} - error={deletepassword !== orderid.slice(4)} - value={deletepassword} - /> */} - - - - - - - - - - - - ); - } - - - - - - return ( - <> - {loading && } - - - {/* setOpen(false)} - scroll={'paper'} - TransitionComponent={PopupTransition}> - - - - - Staff Details - - - - - - - - - - {(loading1) ? - <> - - - - - - - - - : - - <> - - - - - - - - - - - {`${currentshiftobj.staffname}`} - - - {currentshiftobj.productname} - - - - - - - {(stafflog[0]) && - <> - - - - - - - - - - - - - - +1 - - - {stafflog[0].contactno} - - - - - - - - - Hours Worked: - - {' '} - {stafflog[0].hoursworked} Hrs - - - - - - - - - - } - {(stafflog[0]) && - <> - - - - - - - Clock In: - - - - - - - Clock Out: - - - - - - - - - - - } - - - - - - - - - - - - {currentshiftobj.locationaddress} - - - - - - - - - - - - Start Time - - {dayjs(currentshiftobj.Starttime) - .utc() - .format('MM/DD/YYYY')} - {dayjs(currentshiftobj.Starttime) - .utc() - .format('hh:mm A')} - - - - - - End Time - - {dayjs(currentshiftobj.Endtime) - .utc() - .format('MM/DD/YYYY')} - {dayjs(currentshiftobj.Endtime) - .utc() - .format('hh:mm A')} - - - - - - - - - - - - - - - - } - - - - */} - - - - - - - {(loading) && - <> - - {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((item) => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ))} - - - } - - - - - {((visibleRows.length == 0) && !loading) && - - <> - - - - - - {/*
empty
*/} - - - } - {visibleRows.map((row, index) => { - const isItemSelected = isSelected(row.sno); - const labelId = `enhanced-table-checkbox-${index}`; - - return ( - <> - handleClick(event, row.sno)} - role="checkbox" - aria-checked={isItemSelected} - tabIndex={-1} - key={row.sno} - sx={{ cursor: 'pointer' }} - > - - - {/* */} - {row.sno} - {/* - { - if(!expandopen){ - fetchstafflist(row.orderheaderid) - } - setExpandopen((expandopen === row.sno) ? '' : row.sno) - - }}> - {(expandopen === row.sno) ? - - : - - - } - - */} - {/* */} - - - - - - - - - - {`${row.firstname} ${row.lastname}`} - - - {/* {row.identification}*/} - {row.contactno} - - - - - {/* - - - {row.contactno} - - - - - */} - - - {row.address} - {/* - {`${row.locationaddress.slice(0, 25)}${(row.locationaddress.length > 25)?'...':''}`} - */} - - - - {row.landmark} - - {/* - - {dayjs(row.Endtime) - // .utc() - .format('MM/DD/YYYY')} - {dayjs(row.Endtime) - // .utc() - .format('hh:mm A')} - - */} - {/* - - - {row.staffname} - - - - - - */} - - {row.city} - - - - {/* - { - fetchstafflist(row.orderheaderid) - setExpandopen((expandopen === row.sno) ? '' : row.sno) - - }}> - {(expandopen === row.sno) ? - - : - - - } - - */} - {/* */} - - {/* - - - {(row.orderstatus === 'pending' - ) && - - { - - - }}> - - - - } - - - { - - setCurrentshiftobj({ ...row }) - console.log(row) - setStafflog([]) - fetchstafflog(row.Userid, row.shiftid) - setOpen(true) - - }}> - - - - */} - - { - setOpen(true) - setCurrentcustomerid(row.customerid) - }}> - - - - {(false) && - - - { - setFirstname(row.firstname); - setAddress(row.address) - setMobilenumber(row.contactno) - // setEmailaddress(row.) - setSuburb(row.suburb) - setCity(row.city) - setState(row.state) - setZipcode(row.postcode) - setDoorno(row.doorno) - setLandmark(row.landmark) - setExpandopen((expandopen === row.sno) ? '' : row.sno) - }}> - - - } - - - - - - - - - - - {/* - - Business Name - setBusinessname(e.target.value)} - value={businessname} - autoComplete='off' - /> - - - - - Registration No - setBusinessno(e.target.value)} - value={businessno} - autoComplete='off' - - /> - - */} - - - Admin Name - setFirstname(e.target.value)} - value={firstname} - autoComplete='off' - - /> - - - - - - - Phone Number - - - { }} - onChange={(e) => { - if (e.target.value.toString().length <= 10) { - setMobilenumber(e.target.value) - } - }} - value={mobilenumber} - autoComplete='off' - // disabled - sx={{ cursor: 'not-allowed' }} - /> - - - - - - Email Address - setEmailaddress(e.target.value)} - value={emailaddress} - autoComplete='off' - - /> - - - - - - - Address - { - setAddress(place.formatted_address) - let city1, state, zipcode1, suburb1; - for (let i = 0; i < place.address_components.length; i++) { - for (let j = 0; j < place.address_components[i].types.length; j++) { - switch (place.address_components[i].types[j]) { - case "locality": - city1 = place.address_components[i].long_name; - break; - case "administrative_area_level_1": - state = place.address_components[i].long_name; - break; - case "postal_code": - zipcode1 = place.address_components[i].long_name; - break; - case "sublocality": - suburb1 = place.address_components[i].long_name; - break; - } - } - } - setCity(city1 || '') - setState(state || ''); - setZipcode(zipcode1 || ''); - setSuburb(suburb1 || '') - }} - options={{ - - types: ['address' || 'geocode'] - - }} - placeholder='Address' - value={address} - onChange={(e) => setAddress(e.target.value)} - - /> - - - - - - Suburb - setSuburb(e.target.value)} - value={suburb} - autoComplete='off' - - /> - - - - - City - setCity(e.target.value)} - value={city} - autoComplete='off' - - /> - - - - - - State - setState(e.target.value)} - value={state} - autoComplete='off' - - /> - - - - - Post Code - setZipcode(e.target.value)} - value={zipcode} - autoComplete='off' - - /> - - - - - - Door No - setDoorno(e.target.value)} - value={doorno} - autoComplete='off' - - /> - - - - - Landmark - setLandmark(e.target.value)} - value={landmark} - autoComplete='off' - - /> - - - - - - - - - - - - - - - ); - })} - {emptyRows > 0 && ( - - - - )} -
-
-
- - -
- - - ); - } - - - - return <> - - - - Clients - - - - - - - - - - - } - aria-describedby="header-search-text" - inputProps={{ - 'aria-label': 'weight' - }} - placeholder="Search" - value={searchword} - onChange={(e) => { - - setSearchword(e.target.value) - }} - autoComplete='off' - /> - - - - - - - - -} - -export default Client; \ No newline at end of file diff --git a/src/pages/nearle/reports/ordersDetails.js b/src/pages/nearle/reports/ordersDetails.js new file mode 100644 index 0000000..77a3c15 --- /dev/null +++ b/src/pages/nearle/reports/ordersDetails.js @@ -0,0 +1,1007 @@ +import PropTypes from 'prop-types'; +import { React, useState, useEffect, useRef, forwardRef } from 'react'; +import TitleCard from 'pages/nearle/titleCard'; +import axios from 'axios'; +import { useQuery } from '@tanstack/react-query'; +import { Empty } from 'antd'; +import ClearIcon from '@mui/icons-material/Clear'; +import { TableVirtuoso } from 'react-virtuoso'; +import { useTheme } from '@mui/material/styles'; + +// material-ui +import { + Box, + Checkbox, + Divider, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TablePagination, + TableSortLabel, + TableRow, + Grid, + Dialog, + DialogTitle, + Typography, + DialogContent, + Stack, + Button, + IconButton, + Tooltip, + Chip, + Avatar, + Autocomplete, + Tab, + Tabs, + Paper, + FormControl, + OutlinedInput, + InputAdornment, + Badge, + TextField +} from '@mui/material'; +import { SearchOutlined, MoreOutlined } from '@ant-design/icons'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import dayjs from 'dayjs'; +var utc = require('dayjs/plugin/utc'); +dayjs.extend(utc); +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { DateRangePicker } from 'mui-daterange-picker'; +import { + addDays, + addMonths, + addWeeks, + // addYears, + endOfMonth, + endOfWeek, + // endOfYear, + startOfMonth, + startOfWeek + // startOfYear, +} from 'date-fns'; +import { visuallyHidden } from '@mui/utils'; +import { FilterList } from '@mui/icons-material'; + +// project imports +import { fetchorderdetails, fetchCount, fetchAppLocations } from '../api/api'; +import MainCard from 'components/MainCard'; +import { CSVExport, TableRowSelection } from 'components/third-party/ReactTable'; +import Loader from 'components/Loader'; + +function descendingComparator(a, b, orderBy) { + if (b[orderBy] < a[orderBy]) { + return -1; + } + if (b[orderBy] > a[orderBy]) { + return 1; + } + return 0; +} + +function getComparator(order, orderBy) { + return order === 'desc' ? (a, b) => descendingComparator(a, b, orderBy) : (a, b) => -descendingComparator(a, b, orderBy); +} + +function stableSort(array, comparator) { + const stabilizedThis = array.map((el, index) => [el, index]); + stabilizedThis.sort((a, b) => { + const order = comparator(a[0], b[0]); + if (order !== 0) return order; + return a[1] - b[1]; + }); + return stabilizedThis.map((el) => el[0]); +} +function formatNumberToRupees(value) { + return new Intl.NumberFormat('en-IN', { + style: 'currency', + currency: 'INR', + minimumFractionDigits: 2 + }).format(value); +} +const headCells = [ + { + id: 'sno', + disablePadding: false, + label: '#' + }, + { + id: 'tenantname', + disablePadding: false, + label: 'Client' + }, + + { + id: 'Pickup loco', + disablePadding: false, + label: 'Pickup' + }, + { + id: 'Delivery loco', + disablePadding: false, + label: 'Drop' + }, + { + id: 'order status', + disablePadding: false, + label: 'status' + }, + { + id: 'assigned', + disablePadding: false, + label: 'assigned' + }, + { + id: 'Accepted', + disablePadding: false, + label: 'Accepted' + }, + { + id: 'arrived', + disablePadding: false, + label: 'arrived' + }, + { + id: 'picked', + disablePadding: false, + label: 'picked' + }, + { + id: 'Delivered', + disablePadding: false, + label: 'Delivered' + }, + { + id: 'cancelled', + disablePadding: false, + label: 'cancelled' + }, + { + id: ' notes', + disablePadding: false, + label: 'NOTES' + }, + // { + // id: "rider", + // disablePadding: false, + // label: "rider", + // }, + { + id: 'kms', + disablePadding: false, + label: 'KMS' + }, + { + id: 'charges', + disablePadding: false, + label: 'Charges', + numeric: true + } +]; + +// ==============================|| MUI TABLE - ENHANCED ||============================== // +const tabContent = ['Delivered', 'Pending', 'Cancelled']; +export default function ordersDetails() { + const textFieldRef = useRef(null); + const [order, setOrder] = useState('asc'); + const [orderBy, setOrderBy] = useState('calories'); + const [selected, setSelected] = useState([]); + const [page, setPage] = useState(0); + const [dense] = useState(false); + const [rowsPerPage, setRowsPerPage] = useState(20); + const [selectedValue, setSelectedValue] = useState([]); + const [locaName, setLocoName] = useState('All'); + const [startdate, setStartdate] = useState(dayjs().format('YYYY-MM-DD')); + const [enddate, setEnddate] = useState(dayjs().format('YYYY-MM-DD')); + const [open, setOpen] = useState(false); + const [dateselect, setDateselect] = useState('select'); + const [tabstatus1, setTabstatus1] = useState('Today'); + const [datestatus, setDatestatus] = useState('Today'); + const [totalCharge, settotalCharge] = useState(0); + const [totalAmount, settotalAmount] = useState(0); + const [appId, setAppId] = useState(-1); + const [value, setValue] = useState(0); + const [tabvalue, setTabvalue] = useState(0); + const [tabstatus, setTabstatus] = useState('Delivered'); + const [deliCount, setDeliCount] = useState(0); + const [pendCount, setPendCount] = useState(0); + const [cancelCount, setCancelCount] = useState(0); + const [searchword, setSearchword] = useState(''); + const [count, setCount] = useState(0); + const theme = useTheme(); + + // ==============================|| textFieldRef (cmd+k)||============================== // + useEffect(() => { + const handleKeyPress = (event) => { + if (event.key === 'k' && (event.metaKey || event.ctrlKey)) { + event.preventDefault(); + + textFieldRef.current.focus(); + } + if (event.key === 'Escape' && document.activeElement === textFieldRef.current) { + // Remove focus from the TextField + textFieldRef.current.blur(); + } + }; + + document.addEventListener('keydown', handleKeyPress); + + return () => { + document.removeEventListener('keydown', handleKeyPress); + }; + }, []); + + const handleChangetab = (e, i) => { + setTabvalue(i); + if (i === 0) setTabstatus('Delivered'); + + if (i === 1) setTabstatus('Pending'); + if (i === 2) setTabstatus('Cancelled'); + console.log(i); + }; + + // ==============================|| fetchorderdetails (orders)||============================== // + + const { + isLoading: isLoadingOrderDetails, + isError: isErrorOrderDetails, //true or false + data: rows, + error: orderDetailsError + } = useQuery({ + queryKey: [tabvalue, appId, startdate, enddate], + queryFn: fetchorderdetails + }); + + // ==============================|| calculate||============================== // + const calculate = () => { + let calculatedTotalCharge = 0; + let calculatedTotalAmount = 0; + rows && + rows.forEach((row) => { + calculatedTotalCharge += row.deliverycharges; + }); + settotalCharge(calculatedTotalCharge); + rows && + rows.forEach((row) => { + calculatedTotalAmount += row.deliveryamt; + }); + console.log('calculatedTotalAmount', calculatedTotalAmount); + settotalAmount(calculatedTotalAmount); + }; + useEffect(() => { + calculate(); + rows && setRowsPerPage(rows.length + 1); + rows && setCount(rows.length); + }, [rows]); + // ==============================|| fetchOrdersCount (orders)||============================== // + + const { + isLoading: isLoadingOrderCount, + isError: isErrorOrderCount, //true or false + data: countData, + error: orderCountError + } = useQuery({ + queryKey: [startdate, enddate], + queryFn: fetchCount + }); + useEffect(() => { + if (countData) { + setDeliCount(countData.deliveredCount); + setPendCount(countData.pendingCount); + setCancelCount(countData.cancelledCount); + } + }, [fetchCount, startdate, enddate]); + // ==============================|| fetchAppLocations ||============================== // + + const { + isLoading: isLoadingLocations, + isError: isErrorLocations, //true or false + data: locations, + error: locationsError + } = useQuery({ + queryKey: [appId], + queryFn: fetchAppLocations + }); + if (isLoadingOrderDetails || isLoadingLocations || isLoadingOrderCount) return ; + if (isErrorOrderDetails) return 'An error has occurred:(isErrorOrderDetails) ' + orderDetailsError.message; + if (isErrorOrderCount) return 'An error has occurred:(isErrorOrderCount) ' + orderCountError.message; + if (isErrorLocations) return 'An error has occurred:(isErrorlocations) ' + locationsError.message; + + const handleRequestSort = (event, property) => { + const isAsc = orderBy === property && order === 'asc'; + setOrder(isAsc ? 'desc' : 'asc'); + setOrderBy(property); + }; + const filteredOrders = rows.filter((row) => + row.orderstatus == '' + ? row.orderstatus.toLowerCase().includes(searchword.toLowerCase()) + : row.orderstatus.toLowerCase().includes(searchword.toLowerCase()) || + row.ordernotes.toLowerCase().includes(searchword.toLowerCase()) || + row.tenantname.toLowerCase().includes(searchword.toLowerCase()) || + row.orderid.toLowerCase().includes(searchword.toLowerCase()) || + row.pickupcustomer.toLowerCase().includes(searchword.toLowerCase()) || + row.pickupcontactno.toLowerCase().includes(searchword.toLowerCase()) || + row.pickuplocation.toLowerCase().includes(searchword.toLowerCase()) || + row.deliverycustomer.toLowerCase().includes(searchword.toLowerCase()) || + row.deliverycontactno.toLowerCase().includes(searchword.toLowerCase()) || + row.deliverylocation.toLowerCase().includes(searchword.toLowerCase()) || + row.ridername.toLowerCase().includes(searchword.toLowerCase()) + ); + const handleSelectAllClick = (event) => { + if (event.target.checked) { + const newSelectedId = rows.map((n) => n.name); + setSelected(newSelectedId); + return; + } + setSelected([]); + }; + + const handleClick = (event, name) => { + const selectedIndex = selected.indexOf(name); + let newSelected = []; + + if (selectedIndex === -1) { + newSelected = newSelected.concat(selected, name); + } else if (selectedIndex === 0) { + newSelected = newSelected.concat(selected.slice(1)); + } else if (selectedIndex === selected.length - 1) { + newSelected = newSelected.concat(selected.slice(0, -1)); + } else if (selectedIndex > 0) { + newSelected = newSelected.concat(selected.slice(0, selectedIndex), selected.slice(selectedIndex + 1)); + } + const selectedRowData = rows.filter((row) => newSelected.includes(row.name.toString())); + setSelectedValue(selectedRowData); + setSelected(newSelected); + }; + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(parseInt(event?.target.value, 10)); + setPage(0); + }; + + const isSelected = (name) => selected.indexOf(name) !== -1; + + // Avoid a layout jump when reaching the last page with empty rows. + const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; + + function formatDate(dateString) { + const date = dayjs(dateString); + const formattedDate = date.format('DD/MM/YYYY '); + return formattedDate; + } + function formatTime(dateString) { + const date = dayjs(dateString); + const formattedDate = date.format(' hh:mm A'); + return formattedDate; + } + return ( + <> + + + + + + {' '} + + {startdate && enddate && ( + + {`Orders-${datestatus}`} + + + {dayjs(startdate).format('DD/MM/YYYY')} - {dayjs(enddate).format('DD/MM/YYYY')} + + } + variant="combined" + color="warning" + size="small" + /> + + )} + {(!startdate || !enddate) && ( + <> + + + {/* ALL} variant="combined" color='warning' size='small' /> */} + + + )} + + + + {' '} +
+ + { + setSearchword(e.target.value); + }} + autoComplete="off" + startAdornment={ + + + + } + endAdornment={ + { + setSearchword(''); + // setPages(1); + // fetchCustomersList(1); + }} + > + + + } + /> + + + + setOpen(true)} + > + + + +
+
+
+ {/* + + + + } + iconPosition="end" + /> + + } + iconPosition="end" + /> + + + } + iconPosition="end" + /> + + + + + + + } + aria-describedby="header-search-text" + inputProps={{ + "aria-label": "weight", + }} + placeholder="Search" + value={searchword} + onChange={(e) => { + setSearchword(e.target.value); + }} + autoComplete="off" + /> + + + */} +
+ + + + + + {headCells.map((column) => ( + + {column.label} + + ))} + + + + {filteredOrders.length == 0 && ( + <> + + + + + + + )} + {stableSort(filteredOrders, getComparator(order, orderBy)) + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row, index) => { + if (typeof row === 'number') return null; + const isItemSelected = isSelected(row.name); + const labelId = `enhanced-table-checkbox-${index}`; + console.log('rows.length', rows.length); + return ( + filteredOrders.length !== 0 && ( + + // handleClick(event, row.name) + // } + role="checkbox" + aria-checked={isItemSelected} + tabIndex={-1} + key={row.name} + selected={isItemSelected} + > + {/* + + */} + {index + 1} + + + {row.tenantname} + + {row.orderid} + + + {dayjs(row.orderdate).utc().format('DD/MM/YYYY')} + + + {dayjs(row.orderdate).utc().format('hh:mm A')} + + + + + + {row.pickupcustomer} + + {row.pickupcontactno} + + + + {row.pickupsuburb || row.pickuplocation || row.Pickupaddress.slice(0, 20)} + + + + + + + + + {row.deliverycustomer} + + {row.deliverycontactno} + + + + {/* {row.Pickupaddress.slice(0, 20)} */} + {row.deliverysuburb || row.deliverylocation || row.deliveryaddress.slice(0, 20)} + + + + + + + {row.orderstatus == '' ? ( + + {row.orderstatus === 'created' && } + {row.orderstatus === 'pending' && } + {row.orderstatus === 'accepted' && ( + + )} + {row.orderstatus === 'arrived' && ( + + )} + {row.orderstatus === 'picked' && } + {row.orderstatus === 'delivered' && } + + {row.orderstatus === 'cancelled' && } + + ) : ( + + {row.orderstatus === 'created' && } + {row.orderstatus === 'pending' && } + {row.orderstatus === 'accepted' && ( + + )} + {row.orderstatus === 'arrived' && ( + + )} + {row.orderstatus === 'picked' && } + {row.orderstatus === 'delivered' && } + + {row.orderstatus === 'cancelled' && } + + )} + + + + {row.ridername} + + + {/* {dayjs(row.pending).format('DD/MM/YYYY')} */} + {row.assigntime === '' ? '' : formatDate(row.assigntime)} + + + {row.assigntime === '' ? '' : formatTime(row.assigntime)} + + + + {' '} + + {row.starttime === '' ? '' : formatDate(row.starttime)} + + + {row.starttime === '' ? '' : formatTime(row.starttime)} + + + + {' '} + + {row.arrivaltime === '' ? '' : formatDate(row.arrivaltime)} + + + {row.arrivaltime === '' ? '' : formatTime(row.arrivaltime)} + + + + {' '} + + {row.pickuptime === '' ? '' : formatDate(row.pickuptime)} + + + {row.pickuptime === '' ? '' : formatTime(row.pickuptime)} + + + + {' '} + + {row.deliverytime === '' ? '' : formatDate(row.deliverytime)} + + + {row.deliverytime === '' ? '' : formatTime(row.deliverytime)} + + + + {' '} + + {row.canceltime === '' ? '' : formatDate(row.canceltime)} + + + {row.canceltime === '' ? '' : formatTime(row.canceltime)} + + + + + {row.ordernotes} + + + + + + + + + + + + + + + + + + + + + + + + ) + ); + })} + +
+
+ + {/* table pagination */} + {/* */} +
+ +
+ Total Charges : + + + + {/* + {formatNumberToRupees(total)} + */} +
+
+ Total Amount : + + + +
+
+ + + Select Filter Options + + + setOpen(!open)} + id="daterange1" + onChange={(range) => { + if (range.label === 'All') { + setDateselect('all'); + setStartdate(''); + setEnddate(''); + + setOpen(false); + } else { + setDateselect('select'); + setStartdate(dayjs(range.startDate).format('YYYY-MM-DD')); + setEnddate(dayjs(range.endDate).format('YYYY-MM-DD')); + if (range.label) { + setDatestatus(range.label); + } else { + setDatestatus(''); + } + } + console.log(range); + }} + definedRanges={[ + { + label: 'Today', + startDate: new Date(), + endDate: new Date() + }, + { + label: 'Yesterday', + startDate: addDays(new Date(), -1), + endDate: addDays(new Date(), -1) + }, + { + label: 'Tomorrow', + startDate: addDays(new Date(), +1), + endDate: addDays(new Date(), +1) + }, + { + label: 'This Week', + startDate: startOfWeek(new Date()), + endDate: endOfWeek(new Date()) + }, + { + label: 'Last Week', + startDate: startOfWeek(addWeeks(new Date(), -1)), + endDate: endOfWeek(addWeeks(new Date(), -1)) + }, + { + label: 'Last 7 Days', + startDate: addWeeks(new Date(), -1), + endDate: new Date() + }, + { + label: 'This Month', + startDate: startOfMonth(new Date()), + endDate: endOfMonth(new Date()) + }, + { + label: 'Last Month', + startDate: startOfMonth(addMonths(new Date(), -1)), + endDate: endOfMonth(addMonths(new Date(), -1)) + }, + { + label: 'All', + startDate: new Date(), + endDate: addDays(new Date(), -1) + } + ]} + /> + + + + + + + ); +} diff --git a/src/pages/nearle/titleCard.js b/src/pages/nearle/titleCard.js new file mode 100644 index 0000000..8538e72 --- /dev/null +++ b/src/pages/nearle/titleCard.js @@ -0,0 +1,48 @@ +import React from 'react'; +import { useTheme } from '@mui/material/styles'; + +import { + Avatar, + Chip, + Grid, + Link, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Typography, + CardContent, + Skeleton, + Stack, + CardActions, + Button, + List +} from '@mui/material'; +const TitleCard = ({ title }) => { + const theme = useTheme(); + return ( + + + + + {title} + + + + + ); +}; + +export default TitleCard; diff --git a/src/routes/MainRoutes.js b/src/routes/MainRoutes.js index 3766556..80d2c46 100644 --- a/src/routes/MainRoutes.js +++ b/src/routes/MainRoutes.js @@ -17,7 +17,6 @@ const SamplePage = Loadable(lazy(() => import('pages/extra-pages/sample-page'))) const Login = Loadable(lazy(() => import('pages/nearle/login'))); const Dashboard = Loadable(lazy(() => import('pages/nearle/dashboard'))); -const Client = Loadable(lazy(() => import('pages/nearle/clients/client'))); const Client1 = Loadable(lazy(() => import('pages/nearle/clients/clients1'))); const Orders = Loadable(lazy(() => import('pages/nearle/orders/orders'))); @@ -30,7 +29,7 @@ const Createclient = Loadable(lazy(() => import('pages/nearle/clients/createclie const Createorder1 = Loadable(lazy(() => import('pages/nearle/orders/createorder1'))); - +const OrdersDetails = Loadable(lazy(() => import('pages/nearle/reports/ordersDetails'))); // ==============================|| MAIN ROUTING ||============================== // @@ -41,7 +40,7 @@ const MainRoutes = { path: '/', element: ( // - + // ), children: [ @@ -85,13 +84,16 @@ const MainRoutes = { path: 'customers/create', element: }, - + { + path: 'reports/ordersdetails', + element: + } ] }, - + { - path:'/login', - element: + path: '/login', + element: }, { path: '/maintenance', diff --git a/yarn.lock b/yarn.lock index aa42bdf..e4d9339 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2054,6 +2054,21 @@ rc-resize-observer "^1.3.1" rc-util "^5.38.0" +"@react-dnd/asap@^5.0.1": + version "5.0.2" + resolved "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz" + integrity sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A== + +"@react-dnd/invariant@^4.0.1": + version "4.0.2" + resolved "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz" + integrity sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw== + +"@react-dnd/shallowequal@^4.0.1": + version "4.0.2" + resolved "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz" + integrity sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA== + "@reduxjs/toolkit@^1.9.5": version "1.9.5" resolved "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz" @@ -2348,6 +2363,18 @@ "@svgr/plugin-jsx" "^7.0.0" "@svgr/plugin-svgo" "^7.0.0" +"@tanstack/query-core@5.22.2": + version "5.22.2" + resolved "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.22.2.tgz" + integrity sha512-z3PwKFUFACMUqe1eyesCIKg3Jv1mysSrYfrEW5ww5DCDUD4zlpTKBvUDaEjsfZzL3ULrFLDM9yVUxI/fega1Qg== + +"@tanstack/react-query@^5.22.2": + version "5.22.2" + resolved "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.22.2.tgz" + integrity sha512-TaxJDRzJ8/NWRT4lY2jguKCrNI6MRN+67dELzPjNUlvqzTxGANlMp68l7aC7hG8Bd1uHNxHl7ihv7MT50i/43A== + dependencies: + "@tanstack/query-core" "5.22.2" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" @@ -2478,7 +2505,7 @@ dependencies: "@types/node" "*" -"@types/hoist-non-react-statics@^3.3.1": +"@types/hoist-non-react-statics@^3.3.1", "@types/hoist-non-react-statics@>= 3.3.1": version "3.3.1" resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== @@ -2544,7 +2571,7 @@ resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz" integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== -"@types/node@*": +"@types/node@*", "@types/node@>= 12": version "17.0.31" resolved "https://registry.npmjs.org/@types/node/-/node-17.0.31.tgz" integrity sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q== @@ -2586,7 +2613,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^16.8 || ^17.0 || ^18.0", "@types/react@^17.0.0 || ^18.0.0", "@types/react@16 || 17 || 18": +"@types/react@*", "@types/react@^16.8 || ^17.0 || ^18.0", "@types/react@^17.0.0 || ^18.0.0", "@types/react@>= 16", "@types/react@16 || 17 || 18": version "17.0.45" resolved "https://registry.npmjs.org/@types/react/-/react-17.0.45.tgz" integrity sha512-YfhQ22Lah2e3CHPsb93tRwIGNiSwkuz1/blk4e6QrWS0jQzCSNbGLtOEYhPg02W0yGTTmpajp7dCTbBAMN3qsg== @@ -4655,6 +4682,15 @@ dlv@^1.1.3: resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== +dnd-core@^16.0.1: + version "16.0.1" + resolved "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz" + integrity sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng== + dependencies: + "@react-dnd/asap" "^5.0.1" + "@react-dnd/invariant" "^4.0.1" + redux "^4.2.0" + dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz" @@ -9063,6 +9099,11 @@ react-app-rewired@^2.2.1: dependencies: semver "^5.6.0" +react-csv@^2.2.2: + version "2.2.2" + resolved "https://registry.npmjs.org/react-csv/-/react-csv-2.2.2.tgz" + integrity sha512-RG5hOcZKZFigIGE8LxIEV/OgS1vigFQT4EkaHeKgyuCbUAu9Nbd/1RYq++bJcJJ9VOqO/n9TZRADsXNDR4VEpw== + react-dev-utils@^12.0.1: version "12.0.1" resolved "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz" @@ -9100,7 +9141,25 @@ react-device-detect@^2.2.3: dependencies: ua-parser-js "^1.0.33" -react-dom@*, "react-dom@^16.8 || ^17.0 || ^18.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.0 || ^18.0.0", react-dom@^17.0.2, react-dom@^18.0.0, react-dom@^18.2.0, "react-dom@>= 0.14.0", react-dom@>=16.0.0, react-dom@>=16.11.0, react-dom@>=16.6.0, react-dom@>=16.8, react-dom@>=16.8.0, react-dom@>=16.9.0, "react-dom@16.2.0 - 18": +react-dnd-html5-backend@^16.0.1: + version "16.0.1" + resolved "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz" + integrity sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw== + dependencies: + dnd-core "^16.0.1" + +react-dnd@^16.0.1: + version "16.0.1" + resolved "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz" + integrity sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q== + dependencies: + "@react-dnd/invariant" "^4.0.1" + "@react-dnd/shallowequal" "^4.0.1" + dnd-core "^16.0.1" + fast-deep-equal "^3.1.3" + hoist-non-react-statics "^3.3.2" + +react-dom@*, "react-dom@^16.8 || ^17.0 || ^18.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.0 || ^18.0.0", react-dom@^17.0.2, react-dom@^18.0.0, react-dom@^18.2.0, "react-dom@>= 0.14.0", "react-dom@>=16 || >=17 || >= 18", react-dom@>=16.0.0, react-dom@>=16.11.0, react-dom@>=16.6.0, react-dom@>=16.8, react-dom@>=16.8.0, react-dom@>=16.9.0, "react-dom@16.2.0 - 18": version "18.2.0" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== @@ -9281,7 +9340,12 @@ react-transition-group@^4.4.5: loose-envify "^1.4.0" prop-types "^15.6.2" -react@*, "react@^16.6.0 || 17 || 18", "react@^16.8 || ^17.0 || ^18.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.9.0 || ^17.0.0 || ^18", "react@^17.0.0 || ^18.0.0", react@^17.0.2, react@^18.0.0, react@^18.2.0, "react@>= 0.14.0", "react@>= 16", react@>=16.0.0, react@>=16.11.0, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=16.9.0, "react@16.2.0 - 18": +react-virtuoso@^4.7.0: + version "4.7.0" + resolved "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.7.0.tgz" + integrity sha512-cpgvI1rSOETGDMhqVAVDuH+XHbWO1uIGKv5I6l4CyC71xWYUeGrE5n7sgTZklROB4+Vbv85pcgfWloTlY48HGQ== + +react@*, "react@^16.6.0 || 17 || 18", "react@^16.8 || ^17.0 || ^18.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.9.0 || ^17.0.0 || ^18", "react@^17.0.0 || ^18.0.0", react@^17.0.2, react@^18.0.0, react@^18.2.0, "react@>= 0.14.0", "react@>= 16", "react@>= 16.14", "react@>=16 || >=17 || >= 18", react@>=16.0.0, react@>=16.11.0, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=16.9.0, "react@16.2.0 - 18": version "18.2.0" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== @@ -9359,7 +9423,7 @@ redux-thunk@^2.4.2: resolved "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz" integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q== -redux@^4, redux@^4.2.1: +redux@^4, redux@^4.2.0, redux@^4.2.1: version "4.2.1" resolved "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz" integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==