1447 lines
78 KiB
JavaScript
1447 lines
78 KiB
JavaScript
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 { DeleteFilled, NotificationOutlined } 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,
|
|
// 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,
|
|
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 (
|
|
<TableHead>
|
|
<TableRow>
|
|
{/* <TableCell padding="checkbox">
|
|
<Checkbox
|
|
color="primary"
|
|
indeterminate={numSelected > 0 && numSelected < rowCount}
|
|
checked={rowCount > 0 && numSelected === rowCount}
|
|
onChange={onSelectAllClick}
|
|
inputProps={{
|
|
'aria-label': 'select all desserts',
|
|
}}
|
|
/>
|
|
</TableCell> */}
|
|
{headCells.map((headCell) => (
|
|
<TableCell
|
|
key={headCell.id}
|
|
align={headCell.numeric ? 'right' : 'left'}
|
|
padding={headCell.disablePadding ? 'none' : 'normal'}
|
|
sortDirection={orderBy === headCell.id ? order : false}
|
|
>
|
|
<TableSortLabel
|
|
active={orderBy === headCell.id}
|
|
direction={orderBy === headCell.id ? order : 'asc'}
|
|
onClick={createSortHandler(headCell.id)}
|
|
>
|
|
{headCell.label}
|
|
{orderBy === headCell.id ? (
|
|
<Box component="span" sx={visuallyHidden}>
|
|
{order === 'desc' ? 'sorted descending' : 'sorted ascending'}
|
|
</Box>
|
|
) : null}
|
|
</TableSortLabel>
|
|
</TableCell>
|
|
))}
|
|
</TableRow>
|
|
</TableHead>
|
|
);
|
|
}
|
|
|
|
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 handleClickAway = () => {
|
|
setOpen('');
|
|
};
|
|
// 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'))
|
|
}
|
|
setLoading(false)
|
|
|
|
}).catch((err) => {
|
|
console.log(err)
|
|
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 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 (
|
|
<Dialog
|
|
open={open}
|
|
onClose={() => handleClose(false)}
|
|
maxWidth="xs"
|
|
|
|
>
|
|
<DialogContent sx={{ mt: 2, my: 1 }}>
|
|
<Stack alignItems="center" spacing={3.5}>
|
|
<Avatar color="error" sx={{ width: 72, height: 72, fontSize: '1.75rem' }}>
|
|
<DeleteFilled />
|
|
</Avatar>
|
|
{/* <Grid >
|
|
<Chip label={orderid.slice(4)} variant="combined" color='warning' size='small' />
|
|
</Grid> */}
|
|
<Stack spacing={2}>
|
|
<Typography variant="h4" align="center">
|
|
Are you sure you want to Remove this Client?
|
|
</Typography>
|
|
|
|
{/* <Typography variant="h4" align="center">
|
|
Please type in the order number to confirm.
|
|
</Typography> */}
|
|
{/* <TextField
|
|
type='text'
|
|
onChange={(e) => {
|
|
console.log(e.target.value)
|
|
setDeletepassword(e.target.value)
|
|
}}
|
|
error={deletepassword !== orderid.slice(4)}
|
|
value={deletepassword}
|
|
/> */}
|
|
|
|
</Stack>
|
|
|
|
<Stack direction="row" spacing={2} sx={{ width: 1 }}>
|
|
<Button fullWidth color="error" variant="contained" onClick={() => {
|
|
// if (deletepassword === orderid.slice(4)) {
|
|
// cancelorder();
|
|
removeclient()
|
|
handleClose(true);
|
|
// }
|
|
|
|
}} autoFocus>
|
|
Yes, Remove
|
|
</Button>
|
|
<Button fullWidth onClick={() => {
|
|
handleClose(false)
|
|
setCurrentcustomerid('')
|
|
}} color="secondary" variant="outlined">
|
|
No
|
|
</Button>
|
|
|
|
</Stack>
|
|
</Stack>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
<>
|
|
{loading && <Loader />}
|
|
<AlertCustomerDelete open={open} handleClose={handleClose} />
|
|
|
|
{/* <Dialog
|
|
open={open} onClose={() => setOpen(false)}
|
|
scroll={'paper'}
|
|
TransitionComponent={PopupTransition}>
|
|
|
|
<DialogTitle>
|
|
<Stack direction={'row'} justifyContent={'space-between'}>
|
|
<Stack direction={{ sm: 'row', xs: 'column' }} spacing={2} alignItems={'center'}>
|
|
<Typography variant='h3'>Staff Details</Typography>
|
|
|
|
</Stack>
|
|
|
|
</Stack>
|
|
|
|
</DialogTitle>
|
|
<DialogContent dividers={true}>
|
|
|
|
|
|
{(loading1) ?
|
|
<>
|
|
|
|
|
|
<Stack alignItems={'center'}>
|
|
<CircularProgress />
|
|
</Stack>
|
|
|
|
</>
|
|
|
|
:
|
|
|
|
<>
|
|
<MainCard sx={{ height: '100%' }}>
|
|
|
|
<Grid container spacing={2}>
|
|
<Grid item xs={12} md={(stafflog[0]) ? 6 : 12}>
|
|
<MainCard sx={{ height: '100%' }}>
|
|
<Stack direction='row' spacing={2.5} alignItems="center" justifyContent={'center'}>
|
|
<Avatar alt="Avatar 1" size="xl" >
|
|
</Avatar>
|
|
<Stack spacing={0.5} alignItems="center">
|
|
<Typography variant="h5">
|
|
{`${currentshiftobj.staffname}`}
|
|
</Typography>
|
|
<Typography color="secondary">
|
|
{currentshiftobj.productname}
|
|
</Typography>
|
|
</Stack>
|
|
</Stack>
|
|
</MainCard>
|
|
</Grid>
|
|
|
|
{(stafflog[0]) &&
|
|
<>
|
|
<Grid item xs={12} md={6}>
|
|
<MainCard sx={{ height: '100%' }}>
|
|
<Stack sx={{ height: '100%' }}
|
|
alignItems={'center'}
|
|
justifyContent={'center'}
|
|
>
|
|
<List component="nav" aria-label="main mailbox folders" sx={{ py: 0 }}>
|
|
|
|
|
|
<ListItem>
|
|
<ListItemIcon>
|
|
<LocalPhoneOutlinedIcon />
|
|
</ListItemIcon>
|
|
<Typography variant='body1' align="left" sx={{ ml: 1 }}>
|
|
|
|
|
|
+1
|
|
|
|
</Typography>
|
|
<Typography sx={{ ml: 1 }}>{stafflog[0].contactno}</Typography>
|
|
</ListItem>
|
|
|
|
|
|
|
|
<ListItem>
|
|
<ListItemIcon>
|
|
<AccessTimeOutlinedIcon />
|
|
</ListItemIcon>
|
|
<Typography>Hours Worked: </Typography>
|
|
<Typography align='right' variant='h5' sx={{ ml: 1 }}>
|
|
{' '}
|
|
{stafflog[0].hoursworked} Hrs</Typography>
|
|
|
|
</ListItem>
|
|
|
|
|
|
</List>
|
|
</Stack>
|
|
</MainCard>
|
|
</Grid>
|
|
</>
|
|
}
|
|
{(stafflog[0]) &&
|
|
<>
|
|
<Grid item xs={12}>
|
|
<Divider />
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<Stack direction="row" justifyContent="space-around" alignItems="center">
|
|
<Stack spacing={0.5} alignItems="center">
|
|
<Typography variant="h5">Clock In:</Typography>
|
|
<Chip label={dayjs(stafflog[0].clockin)
|
|
.format('MM/DD/YYYY')} color="primary" variant="light" size="small" />
|
|
<Chip label={dayjs(stafflog[0].clockin)
|
|
.format('hh:mm A')} color="info" variant="light" size="small" />
|
|
|
|
</Stack>
|
|
<Divider orientation="vertical" flexItem />
|
|
<Stack spacing={0.5} alignItems="center">
|
|
<Typography variant="h5">Clock Out:</Typography>
|
|
<Chip label={(stafflog[0].clockout) ? dayjs(stafflog[0].clockout)
|
|
.format('MM/DD/YYYY') : ''} color="primary" variant="light" size="small" />
|
|
<Chip label={(stafflog[0].clockout) ? dayjs(stafflog[0].clockout)
|
|
.format('hh:mm A') : ''} color="info" variant="light" size="small" />
|
|
</Stack>
|
|
|
|
</Stack>
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<Divider />
|
|
</Grid>
|
|
</>
|
|
}
|
|
|
|
<Grid item xs={12}>
|
|
<MainCard title='Shift Details'>
|
|
<Grid container>
|
|
<Grid item xs={12}>
|
|
<List component="nav" aria-label="main mailbox folders" sx={{ py: 0 }}>
|
|
<ListItem>
|
|
|
|
<ListItemIcon>
|
|
<PlaceOutlinedIcon />
|
|
</ListItemIcon>
|
|
<Typography sx={{ ml: 1 }} align="right">{currentshiftobj.locationaddress}</Typography>
|
|
|
|
|
|
</ListItem>
|
|
</List>
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<Divider />
|
|
</Grid>
|
|
<Grid item xs={12} sx={{ mt: 1 }}>
|
|
<Stack direction="row" justifyContent="space-around" alignItems="center">
|
|
<Stack spacing={0.5} alignItems="center">
|
|
<Typography variant="h5">Start Time</Typography>
|
|
<Stack direction="column">
|
|
<Typography variant="body2">{dayjs(currentshiftobj.Starttime)
|
|
.utc()
|
|
.format('MM/DD/YYYY')}</Typography>
|
|
<Typography variant="caption">{dayjs(currentshiftobj.Starttime)
|
|
.utc()
|
|
.format('hh:mm A')}</Typography>
|
|
</Stack>
|
|
|
|
</Stack>
|
|
<Divider orientation="vertical" flexItem />
|
|
<Stack spacing={0.5} alignItems="center">
|
|
<Typography variant="h5">End Time</Typography>
|
|
<Stack direction="column">
|
|
<Typography variant="body2">{dayjs(currentshiftobj.Endtime)
|
|
.utc()
|
|
.format('MM/DD/YYYY')}</Typography>
|
|
<Typography variant="caption">{dayjs(currentshiftobj.Endtime)
|
|
.utc()
|
|
.format('hh:mm A')}</Typography>
|
|
</Stack>
|
|
</Stack>
|
|
|
|
</Stack>
|
|
</Grid>
|
|
</Grid>
|
|
</MainCard>
|
|
</Grid>
|
|
|
|
|
|
|
|
</Grid>
|
|
</MainCard>
|
|
|
|
</>
|
|
}
|
|
</DialogContent>
|
|
|
|
|
|
</Dialog > */}
|
|
<Box sx={{
|
|
width: '100%',
|
|
}}>
|
|
|
|
<TableContainer sx={{ width: '100%', borderBottom: 1, borderColor: 'divider' }}>
|
|
<Table
|
|
sx={{ minWidth: 750 }}
|
|
aria-labelledby="tableTitle"
|
|
size={'medium'}
|
|
>
|
|
<EnhancedTableHead
|
|
numSelected={selected.length}
|
|
order={order}
|
|
orderBy={orderBy}
|
|
onSelectAllClick={handleSelectAllClick}
|
|
onRequestSort={handleRequestSort}
|
|
rowCount={rows.length}
|
|
|
|
/>
|
|
|
|
{(loading) &&
|
|
<>
|
|
<TableBody>
|
|
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((item) => (
|
|
<TableRow key={item}>
|
|
|
|
<TableCell>
|
|
<Skeleton animation="wave" />
|
|
|
|
</TableCell>
|
|
<TableCell>
|
|
<Skeleton animation="wave" />
|
|
<Skeleton animation="wave" />
|
|
|
|
</TableCell>
|
|
<TableCell>
|
|
<Skeleton animation="wave" />
|
|
</TableCell>
|
|
<TableCell>
|
|
<Skeleton animation="wave" />
|
|
</TableCell>
|
|
<TableCell>
|
|
<Skeleton animation="wave" />
|
|
|
|
</TableCell>
|
|
<TableCell>
|
|
<Skeleton animation="wave" />
|
|
|
|
</TableCell>
|
|
|
|
</TableRow>
|
|
|
|
))}
|
|
</TableBody>
|
|
</>
|
|
}
|
|
|
|
|
|
|
|
<TableBody>
|
|
{((visibleRows.length == 0) && !loading) &&
|
|
|
|
<>
|
|
<TableCell colSpan={6}>
|
|
<Stack width={'100%'} direction={'row'} justifyContent={'center'}>
|
|
<Empty />
|
|
</Stack>
|
|
</TableCell>
|
|
{/* <div>empty</div> */}
|
|
</>
|
|
|
|
}
|
|
{visibleRows.map((row, index) => {
|
|
const isItemSelected = isSelected(row.sno);
|
|
const labelId = `enhanced-table-checkbox-${index}`;
|
|
|
|
return (
|
|
<>
|
|
<TableRow
|
|
hover
|
|
onClick={(event) => handleClick(event, row.sno)}
|
|
role="checkbox"
|
|
aria-checked={isItemSelected}
|
|
tabIndex={-1}
|
|
key={row.sno}
|
|
sx={{ cursor: 'pointer' }}
|
|
>
|
|
|
|
<TableCell
|
|
component="th"
|
|
id={labelId}
|
|
scope="row"
|
|
padding="none"
|
|
>
|
|
{/* <Stack direction={'row'} alignItems={'center'} spacing={2}> */}
|
|
{row.sno}
|
|
{/* <Tooltip title='Expand'>
|
|
<IconButton style={{ color: theme.palette.primary.main }}
|
|
aria-label="expand row"
|
|
|
|
onClick={() => {
|
|
if(!expandopen){
|
|
fetchstafflist(row.orderheaderid)
|
|
}
|
|
setExpandopen((expandopen === row.sno) ? '' : row.sno)
|
|
|
|
}}>
|
|
{(expandopen === row.sno) ?
|
|
<KeyboardArrowUp />
|
|
:
|
|
<KeyboardArrowDown />
|
|
|
|
}
|
|
</IconButton>
|
|
</Tooltip> */}
|
|
{/* </Stack> */}
|
|
</TableCell>
|
|
<TableCell align="left" sx={{ paddingLeft: '0px !important' }} >
|
|
|
|
|
|
<Stack direction="row" alignItems="center" spacing={1} justifyContent="flex-start">
|
|
<Avatar
|
|
alt=""
|
|
size="sm"
|
|
// src={row.profileimage}
|
|
sx={{
|
|
width: '25px',
|
|
height: '25px'
|
|
}}
|
|
>
|
|
|
|
</Avatar>
|
|
<Stack direction="column">
|
|
<Typography variant="caption">{`${row.firstname} ${row.lastname}`}</Typography>
|
|
<Typography variant="caption" color="textSecondary">
|
|
|
|
{/* {row.identification}*/}
|
|
{row.contactno}
|
|
</Typography>
|
|
</Stack>
|
|
</Stack>
|
|
</TableCell>
|
|
{/* <TableCell align="left" >
|
|
<Stack direction='column'>
|
|
<Typography variant='caption'>
|
|
{row.contactno}
|
|
</Typography>
|
|
|
|
</Stack>
|
|
|
|
</TableCell> */}
|
|
<TableCell align="left">
|
|
<Stack direction='column'>
|
|
<Typography variant="caption" > {row.address}</Typography>
|
|
{/* <Tooltip title={row.locationaddress}>
|
|
<Typography variant="caption" color="textSecondary"
|
|
> {`${row.locationaddress.slice(0, 25)}${(row.locationaddress.length > 25)?'...':''}`}</Typography>
|
|
</Tooltip> */}
|
|
</Stack>
|
|
</TableCell>
|
|
<TableCell>
|
|
{row.landmark}
|
|
</TableCell>
|
|
{/* <TableCell>
|
|
<Stack direction="column">
|
|
<Typography variant="body2">{dayjs(row.Endtime)
|
|
// .utc()
|
|
.format('MM/DD/YYYY')}</Typography>
|
|
<Typography variant="caption">{dayjs(row.Endtime)
|
|
// .utc()
|
|
.format('hh:mm A')}</Typography>
|
|
</Stack>
|
|
</TableCell> */}
|
|
{/* <TableCell align="left">
|
|
<Stack direction="column">
|
|
<Typography variant="caption">
|
|
{row.staffname}
|
|
</Typography>
|
|
<Grid>
|
|
<Chip label={row.productname} color="info" variant="light" size="small" />
|
|
</Grid>
|
|
</Stack>
|
|
</TableCell> */}
|
|
<TableCell align="left">
|
|
{row.city}
|
|
|
|
</TableCell>
|
|
<TableCell>
|
|
{/* <Tooltip title='Expand'>
|
|
<IconButton style={{ color: theme.palette.primary.main }}
|
|
aria-label="expand row"
|
|
|
|
onClick={() => {
|
|
fetchstafflist(row.orderheaderid)
|
|
setExpandopen((expandopen === row.sno) ? '' : row.sno)
|
|
|
|
}}>
|
|
{(expandopen === row.sno) ?
|
|
<KeyboardArrowUp />
|
|
:
|
|
<KeyboardArrowDown />
|
|
|
|
}
|
|
</IconButton>
|
|
</Tooltip> */}
|
|
{/* </TableCell> */}
|
|
|
|
{/* <TableCell>
|
|
<Stack direction='row'>
|
|
|
|
{(row.orderstatus === 'pending'
|
|
) &&
|
|
<Tooltip title='cancel'>
|
|
<IconButton onClick={() => {
|
|
|
|
|
|
}}>
|
|
<DeleteTwoTone twoToneColor={theme.palette.error.main} />
|
|
</IconButton>
|
|
</Tooltip>
|
|
}
|
|
|
|
<Tooltip title='View'>
|
|
<IconButton onClick={() => {
|
|
|
|
setCurrentshiftobj({ ...row })
|
|
console.log(row)
|
|
setStafflog([])
|
|
fetchstafflog(row.Userid, row.shiftid)
|
|
setOpen(true)
|
|
|
|
}}>
|
|
<EyeTwoTone twoToneColor={theme.palette.primary.main} />
|
|
</IconButton>
|
|
</Tooltip>
|
|
</Stack>*/}
|
|
<Tooltip title='Delete'>
|
|
<IconButton onClick={() => {
|
|
setOpen(true)
|
|
setCurrentcustomerid(row.customerid)
|
|
}}>
|
|
<DeleteTwoTone twoToneColor={theme.palette.error.main} />
|
|
</IconButton>
|
|
</Tooltip>
|
|
</TableCell>
|
|
|
|
</TableRow>
|
|
<TableRow >
|
|
<TableCell style={{ paddingBottom: 0, paddingTop: 0, paddingLeft: 0, paddingRight: 0 }} colSpan={9} sx={{ width: '100%' }}>
|
|
<Collapse in={(expandopen === row.sno)} timeout="auto" unmountOnExit >
|
|
<Grid container sx={{ width: '100%' }}>
|
|
<Grid item sx={{ width: '100%', m: 1 }}>
|
|
<MainCard title='Staffs'>
|
|
|
|
{/* <TableContainer>
|
|
<Table sx={{ p: 2 }}>
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>Contact Name</TableCell>
|
|
<TableCell>Contact No</TableCell>
|
|
|
|
</TableRow>
|
|
</TableHead>
|
|
|
|
<TableBody>
|
|
{(row.ordercontacts.map((val) => {
|
|
return <>
|
|
<TableRow>
|
|
<TableCell>{val.contactname}</TableCell>
|
|
<TableCell>{val.contactno}</TableCell>
|
|
</TableRow>
|
|
</>
|
|
}))
|
|
|
|
}
|
|
|
|
</TableBody>
|
|
</Table>
|
|
|
|
</TableContainer> */}
|
|
|
|
{(loading1) ?
|
|
<>
|
|
|
|
|
|
<Stack alignItems={'center'}>
|
|
<CircularProgress />
|
|
</Stack>
|
|
|
|
</>
|
|
|
|
:
|
|
|
|
<TableContainer>
|
|
<Table>
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>#</TableCell>
|
|
<TableCell>Staff</TableCell>
|
|
<TableCell>Start Time</TableCell>
|
|
<TableCell>End Time</TableCell>
|
|
{/* <TableCell>Pay Rate</TableCell> */}
|
|
|
|
{/* <TableCell>Category</TableCell> */}
|
|
<TableCell align='center'>Clockin</TableCell>
|
|
<TableCell align='center'>Clockout</TableCell>
|
|
<TableCell>Actual Hrs</TableCell>
|
|
|
|
<TableCell>Hrs Worked</TableCell>
|
|
|
|
<TableCell>OT</TableCell>
|
|
|
|
<TableCell>Deficit</TableCell>
|
|
|
|
{/* <TableCell>Experience</TableCell> */}
|
|
|
|
{/* <TableCell>Level</TableCell> */}
|
|
{/* <TableCell>City</TableCell> */}
|
|
<TableCell>Status</TableCell>
|
|
<TableCell>Action</TableCell>
|
|
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{/* {row.ordeprocessInfo.map((val, i) => { */}
|
|
{staffdetaillist.map((val, i) => {
|
|
|
|
return <Fragment key={i}>
|
|
|
|
|
|
<TableRow sx={{
|
|
// backgroundColor: (staffarr.find((res) => res.userid == val.userid)) ? '#f5f5f5' : '', ':hover': {
|
|
// backgroundColor: (staffarr.find((res) => res.userid == val.userid)) ? '#f5f5f5 !important' : ''
|
|
// }
|
|
}}>
|
|
<TableCell component="th"
|
|
scope="row" padding="none">
|
|
{i + 1}
|
|
</TableCell>
|
|
|
|
<TableCell align="left">
|
|
<Stack direction="column">
|
|
<Typography variant="caption">
|
|
{val.staffname}
|
|
</Typography>
|
|
<Grid>
|
|
<Chip label={val.productname} color="info" variant="light" size="small" />
|
|
</Grid>
|
|
</Stack>
|
|
</TableCell>
|
|
<TableCell>
|
|
<Stack direction="column">
|
|
<Typography variant="body2">{dayjs(val.starttime)
|
|
// .utc()
|
|
.format('MM/DD/YYYY')}</Typography>
|
|
<Typography variant="caption">{dayjs(val.starttime)
|
|
// .utc()
|
|
.format('hh:mm A')}</Typography>
|
|
</Stack>
|
|
</TableCell>
|
|
<TableCell>
|
|
<Stack direction="column">
|
|
<Typography variant="body2">{dayjs(val.endtime)
|
|
// .utc()
|
|
.format('MM/DD/YYYY')}</Typography>
|
|
<Typography variant="caption">{dayjs(val.endtime)
|
|
// .utc()
|
|
.format('hh:mm A')}</Typography>
|
|
</Stack>
|
|
</TableCell>
|
|
{/* <TableCell>{val.rolecost}</TableCell> */}
|
|
|
|
|
|
|
|
<TableCell>
|
|
<Stack spacing={0.5}
|
|
alignItems="center"
|
|
>
|
|
<Chip label={(val.clockin) ? dayjs(val.clockin).format('MM/DD/YYYY') : ''} color="primary" variant="light" size="small" />
|
|
<Chip label={(val.clockin) ? dayjs(val.clockin).format('hh:mm A') : ''} color="info" variant="light" size="small" />
|
|
|
|
</Stack>
|
|
</TableCell>
|
|
<TableCell>
|
|
<Stack spacing={0.5}
|
|
alignItems="center"
|
|
>
|
|
<Chip label={(val.clockout) ? dayjs(val.clockout).format('MM/DD/YYYY') : ''} color="primary" variant="light" size="small" />
|
|
<Chip label={(val.clockout) ? dayjs(val.clockout).format('hh:mm A') : ''} color="info" variant="light" size="small" />
|
|
|
|
</Stack>
|
|
</TableCell>
|
|
<TableCell>{val.workhours}</TableCell>
|
|
<TableCell>
|
|
{val.hoursworked}
|
|
</TableCell>
|
|
<TableCell>{val.overtime}</TableCell>
|
|
<TableCell>{val.shorttime}</TableCell>
|
|
|
|
|
|
|
|
<TableCell align="left">
|
|
<Stack direction="row">
|
|
|
|
{(val.orderstatus === 'pending') &&
|
|
|
|
<Chip label="Pending" color="error" size="small" />
|
|
}
|
|
{(val.orderstatus === 'cancelled') &&
|
|
|
|
|
|
<Chip label="Cancelled" color="secondary" size="small" />
|
|
}
|
|
{(val.orderstatus === 'completed') &&
|
|
|
|
<Chip label="Completed" color="primary" size="small" />
|
|
}
|
|
{(val.orderstatus === 'processing') &&
|
|
<Chip label="Processing" color="primary" size="small" />
|
|
}
|
|
{(val.orderstatus === 'assigned') &&
|
|
<Chip label="Assigned" color="warning" size="small" />
|
|
}
|
|
{(val.orderstatus === 'confirmed') &&
|
|
<Chip label="Confirmed" color="success" size="small" />
|
|
}
|
|
|
|
{(val.orderstatus === 'active') &&
|
|
<Chip label="Active" color="info" size="small" />
|
|
}
|
|
{(val.orderstatus === 'closed') &&
|
|
<Chip label="Closed" color="info" size="small" />
|
|
}
|
|
</Stack>
|
|
|
|
</TableCell>
|
|
<TableCell>
|
|
|
|
|
|
<Stack direction='row'>
|
|
{((val.verified == 0) && (val.orderstatus === 'completed')) &&
|
|
<>
|
|
|
|
|
|
<IconButton
|
|
// onClick={(e) => handleClick1(e, row.sno)}
|
|
onClick={(e) => {
|
|
setOpen(i + 1)
|
|
setAnchorEl(e.currentTarget);
|
|
}}
|
|
aria-describedby={`aria-${row.sno}`}
|
|
>
|
|
<MoreOutlined />
|
|
</IconButton>
|
|
|
|
<Popper id={`aria-${row.sno}`} open={(open == (i + 1))}
|
|
anchorEl={anchorEl}
|
|
placement='bottom-end'
|
|
sx={{
|
|
zIndex: 5000,
|
|
p: 0
|
|
}}
|
|
>
|
|
|
|
<Box sx={{ backgroundColor: '#fff', px: 2, py: 1, cursor: 'pointer', boxShadow: theme.customShadows.z1 }}
|
|
onClick={() => {
|
|
|
|
// setApproveid(true)
|
|
// setDisableid(false)
|
|
|
|
// setExpandopen('')
|
|
// setRolestab(0)
|
|
staffearningsverify(val.staffearningsid)
|
|
// fetchclientbyid(row.tenantid, row.sno);
|
|
// fetchclientpricing(row.tenantid)
|
|
// setEditexpandopen(row.sno)
|
|
|
|
handleClickAway()
|
|
}}
|
|
>
|
|
<ClickAwayListener onClickAway={handleClickAway}>
|
|
|
|
<Typography>Verify</Typography>
|
|
|
|
</ClickAwayListener>
|
|
</Box>
|
|
|
|
|
|
</Popper>
|
|
</>
|
|
}
|
|
|
|
{(val.verified == 1) &&
|
|
|
|
<>
|
|
<Tooltip title='Verified' >
|
|
<IconButton
|
|
>
|
|
|
|
<CheckCircleOutlined
|
|
style={{ color: '#4caf50' }}
|
|
|
|
/>
|
|
</IconButton>
|
|
</Tooltip>
|
|
|
|
</>
|
|
|
|
}
|
|
</Stack>
|
|
|
|
</TableCell>
|
|
</TableRow>
|
|
</Fragment>
|
|
|
|
})
|
|
}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
}
|
|
</MainCard>
|
|
</Grid></Grid>
|
|
</Collapse>
|
|
</TableCell>
|
|
</TableRow>
|
|
</>
|
|
);
|
|
})}
|
|
{emptyRows > 0 && (
|
|
<TableRow
|
|
style={{
|
|
height: (53) * emptyRows,
|
|
}}
|
|
>
|
|
<TableCell colSpan={9} />
|
|
</TableRow>
|
|
)}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
<TablePagination
|
|
rowsPerPageOptions={[10, 25, 50, 100]}
|
|
component="div"
|
|
count={rows.length}
|
|
rowsPerPage={rowsPerPage}
|
|
page={page}
|
|
onPageChange={handleChangePage}
|
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
|
/>
|
|
|
|
</Box>
|
|
|
|
</>
|
|
);
|
|
}
|
|
|
|
|
|
|
|
return <>
|
|
<Grid container rowSpacing={2} columnSpacing={2.75}>
|
|
<Grid
|
|
item
|
|
xs={12}
|
|
>
|
|
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
|
<Typography variant="h3">Clients</Typography>
|
|
</Stack>
|
|
</Grid>
|
|
|
|
<Grid item xs={12}>
|
|
<Box sx={{ overflow: 'auto', border: 1, borderColor: 'grey.200', borderRadius: 2, backgroundColor: '#fff', minHeight: 400 }}>
|
|
<Stack
|
|
alignItems='center'
|
|
justifyContent='flex-end'
|
|
direction='row'
|
|
|
|
sx={{
|
|
p: 2,
|
|
width: '100%',
|
|
|
|
}}>
|
|
<FormControl sx={{
|
|
width: 250,
|
|
}}>
|
|
<OutlinedInput
|
|
size="small"
|
|
id="header-search5"
|
|
startAdornment={
|
|
<InputAdornment position="start"
|
|
sx={{ mr: -0.5 }}
|
|
|
|
>
|
|
<SearchOutlined />
|
|
</InputAdornment>
|
|
}
|
|
aria-describedby="header-search-text"
|
|
inputProps={{
|
|
'aria-label': 'weight'
|
|
}}
|
|
placeholder="Search"
|
|
value={searchword}
|
|
onChange={(e) => {
|
|
|
|
setSearchword(e.target.value)
|
|
}}
|
|
autoComplete='off'
|
|
/>
|
|
</FormControl>
|
|
</Stack>
|
|
|
|
<EnhancedTable />
|
|
</Box>
|
|
</Grid>
|
|
</Grid>
|
|
</>
|
|
}
|
|
|
|
export default Client; |