overall updates
This commit is contained in:
596
src/pages/nearle/locations/ResponsiveLocationDrawer.js
Normal file
596
src/pages/nearle/locations/ResponsiveLocationDrawer.js
Normal file
@@ -0,0 +1,596 @@
|
||||
import React, { useState, useEffect, Fragment, useRef } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Drawer,
|
||||
IconButton,
|
||||
Toolbar,
|
||||
Typography,
|
||||
AppBar,
|
||||
useMediaQuery,
|
||||
Divider,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemText,
|
||||
useTheme,
|
||||
ListItemAvatar,
|
||||
Avatar,
|
||||
Tooltip,
|
||||
TableCell,
|
||||
Chip,
|
||||
Stack,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableHead,
|
||||
Table,
|
||||
TableContainer,
|
||||
Tabs,
|
||||
Tab,
|
||||
CircularProgress
|
||||
} from '@mui/material';
|
||||
import MenuIcon from '@mui/icons-material/Menu';
|
||||
import SearchBar from 'components/nearle_components/SearchBar';
|
||||
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
|
||||
import { fetchOrders1, gettenantlocations } from '../api/api';
|
||||
import Loader from 'components/Loader';
|
||||
import CircularLoader from 'components/nearle_components/CircularLoader';
|
||||
import { Empty, Skeleton } from 'antd';
|
||||
import MainCard from 'components/MainCard';
|
||||
import AccessTimeIcon from '@mui/icons-material/AccessTime';
|
||||
import LocalShippingOutlinedIcon from '@mui/icons-material/LocalShippingOutlined';
|
||||
import { CancelOutlined, CheckCircleOutline } from '@mui/icons-material';
|
||||
import axios from 'axios';
|
||||
import dayjs from 'dayjs';
|
||||
var utc = require('dayjs/plugin/utc');
|
||||
dayjs.extend(utc);
|
||||
|
||||
const drawerWidth = 300;
|
||||
|
||||
const ResponsiveLocationDrawer = () => {
|
||||
const loadMoreRef = useRef();
|
||||
const containerRef = useRef();
|
||||
const theme = useTheme();
|
||||
const tenantid = localStorage.getItem('tenantid');
|
||||
const isDesktop = useMediaQuery('(min-width:900px)');
|
||||
const [open, setOpen] = useState(false);
|
||||
const [selectedLocation, setSelectedLocation] = useState(null);
|
||||
const [currentStatus, setCurrentStatus] = useState('created');
|
||||
const [tabvalue, setTabvalue] = useState(0);
|
||||
const [createdLenght, setCreatedLenght] = useState();
|
||||
const [pendingLenght, setPendingLenght] = useState();
|
||||
const [deliveredlenght, setDeliveredlenght] = useState();
|
||||
const [cancelledLenght, setCancelledLenght] = useState();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [page, setPage] = React.useState(0);
|
||||
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||
const [pageCount, setPageCount] = React.useState(0);
|
||||
const [startdate, setStartdate] = useState(dayjs().format('YYYY-MM-DD'));
|
||||
const [enddate, setEnddate] = useState(dayjs().format('YYYY-MM-DD'));
|
||||
const [searchLocation, setSearchLocation] = useState('');
|
||||
const [debouncedSearchLocation, setDebouncedSearchLocation] = useState('');
|
||||
|
||||
const [searchword, setSearchword] = useState('');
|
||||
const [debouncedSearchword, setDebouncedSearchword] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => {
|
||||
setDebouncedSearchLocation(searchLocation);
|
||||
}, 400);
|
||||
|
||||
return () => clearTimeout(handler);
|
||||
}, [searchLocation]);
|
||||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => {
|
||||
setDebouncedSearchword(searchword);
|
||||
}, 400);
|
||||
|
||||
return () => clearTimeout(handler);
|
||||
}, [searchword]);
|
||||
|
||||
const statusMap = [
|
||||
{
|
||||
label: 'Created',
|
||||
value: 'created',
|
||||
count: createdLenght,
|
||||
icon: <AccessTimeIcon color="primary" fontSize="small" />
|
||||
},
|
||||
{
|
||||
label: 'Pending',
|
||||
value: 'pending',
|
||||
count: pendingLenght,
|
||||
icon: <LocalShippingOutlinedIcon color="primary" fontSize="small" />
|
||||
},
|
||||
{
|
||||
label: 'Delivered',
|
||||
value: 'delivered',
|
||||
count: deliveredlenght,
|
||||
icon: <CheckCircleOutline color="primary" fontSize="small" />
|
||||
},
|
||||
{
|
||||
label: 'Cancelled',
|
||||
value: 'cancelled',
|
||||
count: cancelledLenght,
|
||||
icon: <CancelOutlined color="primary" fontSize="small" />
|
||||
}
|
||||
];
|
||||
|
||||
const handleChangetab = (e, i) => {
|
||||
setSearchword('');
|
||||
setRowsPerPage(10);
|
||||
setTabvalue(i);
|
||||
setCurrentStatus(statusMap[i].value);
|
||||
setPage(0);
|
||||
};
|
||||
|
||||
const {
|
||||
data: locations,
|
||||
isLoading: locationIsLoading,
|
||||
isError: locationIsError,
|
||||
error: locationError
|
||||
} = useQuery({
|
||||
queryKey: ['locations', debouncedSearchLocation],
|
||||
queryFn: gettenantlocations
|
||||
});
|
||||
useEffect(() => {
|
||||
if (!searchLocation) locations?.length > 0 ? setSelectedLocation(locations[0]) : null;
|
||||
}, [locations]);
|
||||
|
||||
const {
|
||||
data: ordersData,
|
||||
fetchNextPage,
|
||||
hasNextPage,
|
||||
isFetchingNextPage,
|
||||
isLoading,
|
||||
error
|
||||
} = useInfiniteQuery({
|
||||
queryKey: [
|
||||
'orders',
|
||||
tenantid,
|
||||
selectedLocation?.locationid ?? null, // stable
|
||||
currentStatus,
|
||||
startdate,
|
||||
enddate,
|
||||
debouncedSearchLocation,
|
||||
rowsPerPage
|
||||
],
|
||||
queryFn: fetchOrders1,
|
||||
getNextPageParam: (lastPage) => lastPage.nextPage
|
||||
});
|
||||
|
||||
const rows = ordersData?.pages?.flatMap((page) => page.details) || [];
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasNextPage) return;
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (entries[0].isIntersecting) {
|
||||
fetchNextPage();
|
||||
}
|
||||
},
|
||||
{
|
||||
root: document.querySelector('.MuiTableContainer-root'), // 👈 or explicitly TableContainer
|
||||
rootMargin: '0px',
|
||||
threshold: 1.0
|
||||
}
|
||||
);
|
||||
if (loadMoreRef.current) observer.observe(loadMoreRef.current);
|
||||
return () => {
|
||||
if (loadMoreRef.current) observer.unobserve(loadMoreRef.current);
|
||||
};
|
||||
}, [hasNextPage, fetchNextPage]);
|
||||
|
||||
const handleScroll = (event) => {
|
||||
const { scrollTop, scrollHeight, clientHeight } = event.currentTarget;
|
||||
if (scrollTop + clientHeight >= scrollHeight - 50) {
|
||||
if (hasNextPage && !isFetchingNextPage) {
|
||||
fetchNextPage();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const fetchorderscount = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await axios
|
||||
.get(
|
||||
`${process.env.REACT_APP_URL}/orders/getordersummary/?tenantid=${tenantid}&locationid=${selectedLocation?.locationid}&fromdate=${startdate}&todate=${enddate}`
|
||||
)
|
||||
.then((res) => {
|
||||
console.log('fetchorderscount', res.data.details);
|
||||
setCreatedLenght(res.data.details.created);
|
||||
setPendingLenght(res.data.details.pending);
|
||||
setDeliveredlenght(res.data.details.delivered);
|
||||
setCancelledLenght(res.data.details.cancelled);
|
||||
tabvalue === 0 && setPageCount(res.data.details.created);
|
||||
tabvalue === 1 && setPageCount(res.data.details.pending);
|
||||
tabvalue === 2 && setPageCount(res.data.details.delivered);
|
||||
tabvalue === 3 && setPageCount(res.data.details.cancelled);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
setLoading(false);
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
fetchorderscount();
|
||||
}, [currentStatus, selectedLocation, startdate, enddate]);
|
||||
|
||||
useEffect(() => {
|
||||
setOpen(isDesktop);
|
||||
}, [isDesktop]);
|
||||
const toggleDrawer = () => setOpen(!open);
|
||||
|
||||
const errMessage = locationIsError ? `${locationError.message}` : null;
|
||||
|
||||
useEffect(() => {
|
||||
errMessage && console.log(errMessage);
|
||||
}, [errMessage]);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{locationIsLoading && (
|
||||
<>
|
||||
<Loader /> <CircularLoader />
|
||||
</>
|
||||
)}
|
||||
|
||||
<Box sx={{ display: 'flex', width: '100%', height: '100%', position: 'relative' }}>
|
||||
{/* ---------------- LOCAL DRAWER ---------------- */}
|
||||
|
||||
<Drawer
|
||||
variant={isDesktop ? 'persistent' : 'temporary'}
|
||||
open={open}
|
||||
onClose={() => !isDesktop && toggleDrawer()}
|
||||
ModalProps={{ keepMounted: true }}
|
||||
sx={{
|
||||
'& .MuiDrawer-paper': {
|
||||
width: drawerWidth,
|
||||
boxSizing: 'border-box',
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
height: '100%',
|
||||
overflowY: 'auto',
|
||||
transition: 'transform 0.35s ease-in-out',
|
||||
zIndex: 10,
|
||||
|
||||
/* vertical scrollbar */
|
||||
'&::-webkit-scrollbar:vertical': {
|
||||
width: '7px',
|
||||
opacity: 0,
|
||||
transition: 'opacity 0.3s'
|
||||
},
|
||||
|
||||
/* horizontal scrollbar */
|
||||
'&::-webkit-scrollbar:horizontal': {
|
||||
height: '6px', // thinner horizontal bar
|
||||
opacity: 0,
|
||||
transition: 'opacity 0.3s'
|
||||
},
|
||||
|
||||
/* show scrollbar when hovering drawer */
|
||||
'&:hover::-webkit-scrollbar': {
|
||||
opacity: 1
|
||||
},
|
||||
|
||||
/* thumb styling */
|
||||
'&::-webkit-scrollbar-thumb': {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
borderRadius: '8px'
|
||||
},
|
||||
'&::-webkit-scrollbar-thumb:hover': {
|
||||
backgroundColor: theme.palette.primary.dark
|
||||
},
|
||||
|
||||
/* track styling */
|
||||
'&::-webkit-scrollbar-track': {
|
||||
backgroundColor: theme.palette.primary.lighter
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Box sx={{ position: 'sticky', top: 0, zIndex: 11, border: 'none' }}>
|
||||
<SearchBar
|
||||
value={searchLocation}
|
||||
placeholder="Search Location"
|
||||
onChange={(e) => setSearchLocation(e.target.value)}
|
||||
sx={{
|
||||
width: 'auto',
|
||||
height: 60,
|
||||
bgcolor: theme.palette.primary.lighter,
|
||||
|
||||
'& .MuiOutlinedInput-notchedOutline': {
|
||||
border: 'none',
|
||||
borderBottom: '1px solid ',
|
||||
borderColor: theme.palette.secondary.light
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
<List sx={{ mt: -1 }}>
|
||||
{locations?.map((row, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<ListItem
|
||||
sx={{
|
||||
cursor: 'pointer',
|
||||
bgcolor: row.locationid == selectedLocation?.locationid ? theme.palette.secondary[200] : 'none',
|
||||
'&:hover': {
|
||||
bgcolor: theme.palette.secondary.lighter
|
||||
}
|
||||
}}
|
||||
onClick={() => {
|
||||
setSelectedLocation(row);
|
||||
}}
|
||||
>
|
||||
<ListItemAvatar>
|
||||
<Avatar
|
||||
sx={{
|
||||
bgcolor: 'primary.main', // background color
|
||||
color: 'white' // text color
|
||||
}}
|
||||
>
|
||||
{row.locationname[0].toUpperCase()}
|
||||
</Avatar>{' '}
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={row.locationname} secondary={row.suburb} />
|
||||
</ListItem>
|
||||
<Divider />
|
||||
</React.Fragment>
|
||||
))}
|
||||
</List>
|
||||
</Drawer>
|
||||
{/* -------------- LOCAL PAGE APPBAR -------------- */}
|
||||
<AppBar
|
||||
elevation={0}
|
||||
position="absolute"
|
||||
sx={{
|
||||
top: 0,
|
||||
left: open && isDesktop ? `${drawerWidth}px` : 0,
|
||||
width: open && isDesktop ? `calc(100% - ${drawerWidth}px)` : '100%',
|
||||
transition: 'left 0.3s ease, width 0.3s ease',
|
||||
zIndex: 1100, // BELOW drawer, ABOVE content
|
||||
backgroundColor: theme.palette.primary.lighter
|
||||
}}
|
||||
>
|
||||
<Toolbar>
|
||||
<Stack
|
||||
sx={{ width: '100%' }}
|
||||
display={'flex'}
|
||||
flexDirection={'row'}
|
||||
alignItems={'center'}
|
||||
justifyContent={'space-between'}
|
||||
flexWrap={'wrap'}
|
||||
>
|
||||
<Stack display={'flex'} flexDirection={'row'} alignItems={'center'}>
|
||||
<IconButton color="primary" onClick={toggleDrawer} sx={{ mr: 1 }}>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
|
||||
<Typography variant="h5" color={'primary'} sx={{ whiteSpace: 'nowrap', ml: 2 }}>
|
||||
{selectedLocation?.locationname}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack flexGrow={1} sx={{ mx: { xs: 0, custom600: 3 } }}>
|
||||
<SearchBar
|
||||
value={searchword}
|
||||
placeholder={'Search Order Details'}
|
||||
onChange={(e) => setSearchword(e.target.value)}
|
||||
sx={{
|
||||
width: 'auto',
|
||||
height: 40,
|
||||
bgcolor: theme.palette.primary.lighter,
|
||||
'& .MuiOutlinedInput-notchedOutline': {
|
||||
border: 'none',
|
||||
borderBottom: '1px solid ',
|
||||
borderColor: theme.palette.secondary.light
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
{/* ---------------- PAGE SCROLLABLE CONTENT ---------------- */}
|
||||
<Box
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
overflow: 'auto',
|
||||
pt: '64px', // Height of AppBar
|
||||
pl: isDesktop && open ? `${drawerWidth}px` : 0,
|
||||
transition: 'padding-left 0.3s ease',
|
||||
mt: -1
|
||||
}}
|
||||
>
|
||||
<Stack
|
||||
display={'flex'}
|
||||
flexDirection={'row'}
|
||||
justifyContent={'space-between'}
|
||||
alignItems={'center'}
|
||||
flexWrap={'wrap-reverse'}
|
||||
gap={2}
|
||||
sx={{
|
||||
border: '1px solid ',
|
||||
borderBottom: 0,
|
||||
borderColor: 'bg.main',
|
||||
p: 1.5
|
||||
}}
|
||||
>
|
||||
{/* Tabs Wrapper */}
|
||||
|
||||
<Tabs value={tabvalue} onChange={handleChangetab} variant="scrollable" scrollButtons="auto" allowScrollButtonsMobile>
|
||||
{statusMap.map((item, index) => (
|
||||
<Tab
|
||||
key={index}
|
||||
label={
|
||||
<Stack direction="row" alignItems="center" spacing={1}>
|
||||
{item.icon}
|
||||
<span>{item.label}</span>
|
||||
<Chip label={item.count} color="primary" variant="light" size="small" />
|
||||
</Stack>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</Tabs>
|
||||
</Stack>
|
||||
<MainCard
|
||||
content={false}
|
||||
sx={{
|
||||
overflow: 'hidden',
|
||||
height: 'calc(100vh - 200px)', // adjust as needed
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}}
|
||||
>
|
||||
<Fragment>
|
||||
{/* Scrollable table container */}
|
||||
<TableContainer
|
||||
onScroll={handleScroll}
|
||||
ref={containerRef}
|
||||
sx={{
|
||||
width: '100%',
|
||||
flex: 1,
|
||||
overflow: 'auto',
|
||||
borderBottom: 1,
|
||||
maxHeight: 'calc(100vh - 225px)',
|
||||
borderColor: 'divider',
|
||||
'&::-webkit-scrollbar': { width: '12px' },
|
||||
'&::-webkit-scrollbar-thumb': {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
borderRadius: '8px'
|
||||
},
|
||||
'&::-webkit-scrollbar-thumb:hover': {
|
||||
backgroundColor: theme.palette.primary.dark
|
||||
},
|
||||
'&::-webkit-scrollbar-track': {
|
||||
backgroundColor: theme.palette.primary.lighter
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Table stickyHeader>
|
||||
{/* HEADER */}
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell sx={{ backgroundColor: theme.palette.secondary.light, position: 'sticky !important' }}>S.No</TableCell>
|
||||
<TableCell sx={{ backgroundColor: theme.palette.secondary.light, position: 'sticky !important' }}>Orders</TableCell>
|
||||
<TableCell sx={{ backgroundColor: theme.palette.secondary.light, position: 'sticky !important' }}>Pickup</TableCell>
|
||||
<TableCell sx={{ backgroundColor: theme.palette.secondary.light, position: 'sticky !important' }}>Drop</TableCell>
|
||||
<TableCell sx={{ backgroundColor: theme.palette.secondary.light, position: 'sticky !important' }}>Notes</TableCell>
|
||||
<TableCell sx={{ backgroundColor: theme.palette.secondary.light, position: 'sticky !important' }}>Status</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
|
||||
{/* BODY */}
|
||||
<TableBody>
|
||||
{/* LOADING STATE */}
|
||||
{loading &&
|
||||
[...Array(10)].map((_, index) => (
|
||||
<TableRow key={index}>
|
||||
{[...Array(6)].map((__, i) => (
|
||||
<TableCell key={i}>
|
||||
<Skeleton animation="wave" />
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
|
||||
{/* EMPTY STATE */}
|
||||
{!loading && rows?.length === 0 && (
|
||||
<TableRow>
|
||||
<TableCell colSpan={6} sx={{ minWidth: '100%', height: 500 }} align="center">
|
||||
<Empty description={'No Orders'} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
|
||||
{/* DATA ROWS */}
|
||||
{!loading &&
|
||||
rows?.map((row, index) => (
|
||||
<TableRow key={index} sx={{ cursor: 'pointer' }}>
|
||||
<TableCell>{page * rowsPerPage + index + 1}</TableCell>
|
||||
|
||||
{/* Order Info */}
|
||||
<TableCell>
|
||||
<Typography variant="body2" noWrap>
|
||||
{row.orderid}
|
||||
</Typography>
|
||||
<Typography variant="caption" noWrap>
|
||||
{dayjs(row.deliverydate).utc().format('DD/MM/YYYY')}
|
||||
</Typography>
|
||||
<Typography variant="caption" noWrap>
|
||||
{dayjs(row.deliverydate).utc().format('hh:mm A')}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
|
||||
{/* Pickup */}
|
||||
<TableCell>
|
||||
<Stack direction="row" spacing={1}>
|
||||
<Avatar sx={{ width: 25, height: 25 }} />
|
||||
<Stack>
|
||||
<Typography variant="caption">{row.pickupcustomer}</Typography>
|
||||
<Typography variant="caption">{row.pickupcontactno}</Typography>
|
||||
<Tooltip title={row.pickupaddress}>
|
||||
<Typography variant="caption">{row.pickupsuburb || row.pickupaddress.slice(0, 20)}</Typography>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</TableCell>
|
||||
|
||||
{/* Drop */}
|
||||
<TableCell>
|
||||
<Stack direction="row" spacing={1}>
|
||||
<Avatar sx={{ width: 25, height: 25 }} />
|
||||
<Stack>
|
||||
<Typography variant="caption">{row.deliverycustomer}</Typography>
|
||||
<Typography variant="caption">{row.deliverycontactno}</Typography>
|
||||
<Tooltip title={row.deliveryaddress}>
|
||||
<Typography variant="caption">{row.deliverysuburb || row.deliveryaddress.slice(0, 20)}</Typography>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</TableCell>
|
||||
|
||||
{/* Notes */}
|
||||
<TableCell>{row.ordernotes}</TableCell>
|
||||
|
||||
{/* Status */}
|
||||
<TableCell>
|
||||
<Stack direction="row" spacing={1}>
|
||||
{row.orderstatus === 'pending' && <Chip label="Pending" color="warning" size="small" />}
|
||||
{row.orderstatus === 'confirmed' && <Chip label="Confirmed" color="success" size="small" />}
|
||||
{row.orderstatus === 'cancelled' && <Chip label="Cancelled" color="error" size="small" />}
|
||||
{row.orderstatus === 'delivered' && <Chip label="Completed" color="primary" size="small" />}
|
||||
{row.orderstatus === 'processing' && <Chip label="Processing" color="primary" size="small" />}
|
||||
{row.orderstatus === 'ready' && <Chip label="Accepted" color="info" size="small" />}
|
||||
{row.orderstatus === 'active' && <Chip label="Picked" color="info" size="small" />}
|
||||
{row.orderstatus === 'closed' && <Chip label="Closed" color="info" size="small" />}
|
||||
{row.orderstatus === 'created' && <Chip label="Created" color="secondary" size="small" />}
|
||||
</Stack>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
{rows?.length != 0 && (
|
||||
<TableRow>
|
||||
<TableCell colSpan={6} rowSpan={3}>
|
||||
<div ref={loadMoreRef} style={{ height: 40, textAlign: 'center' }}>
|
||||
{isFetchingNextPage ? <CircularProgress /> : hasNextPage ? <CircularProgress /> : 'No More Orders'}
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Fragment>
|
||||
</MainCard>
|
||||
</Box>
|
||||
</Box>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResponsiveLocationDrawer;
|
||||
Reference in New Issue
Block a user