2027 lines
94 KiB
JavaScript
2027 lines
94 KiB
JavaScript
import {
|
|
Grid,
|
|
Stack,
|
|
Typography,
|
|
Box,
|
|
Tabs,
|
|
Tab,
|
|
Chip,
|
|
Table,
|
|
TableCell,
|
|
TableBody,
|
|
TableHead,
|
|
Avatar,
|
|
TableRow,
|
|
IconButton,
|
|
Collapse,
|
|
Divider,
|
|
List,
|
|
ListItem,
|
|
ListItemIcon,
|
|
TextField,
|
|
Button,
|
|
InputAdornment,
|
|
FormControl,
|
|
OutlinedInput,
|
|
Dialog,
|
|
DialogContent,
|
|
Skeleton,
|
|
CircularProgress,
|
|
DialogTitle,
|
|
FormLabel,
|
|
DialogActions,
|
|
useMediaQuery,
|
|
useTheme
|
|
} from '@mui/material';
|
|
import { MobileCard, MobileCardList, MobileField, MobileFieldGrid } from 'components/nearle_components/MobileCard';
|
|
|
|
import { Autocomplete as Autocomplete1 } from '@mui/material';
|
|
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons';
|
|
import { SearchOutlined } from '@ant-design/icons';
|
|
import { PopupTransition } from 'components/@extended/Transitions';
|
|
import { enqueueSnackbar } from 'notistack';
|
|
import dayjs from 'dayjs';
|
|
import { PhoneOutlined, MailOutlined } from '@ant-design/icons';
|
|
|
|
import MainCard from 'components/MainCard';
|
|
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import axios from 'axios';
|
|
import Loader from 'components/Loader';
|
|
import Transitions from 'components/@extended/Transitions';
|
|
import Autocomplete from 'react-google-autocomplete';
|
|
|
|
import * as React from 'react';
|
|
|
|
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 Geocode from 'react-geocode';
|
|
|
|
const Requests = () => {
|
|
// let dispatch = useDispatch();
|
|
|
|
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]);
|
|
}
|
|
|
|
const headCells = [
|
|
{
|
|
id: 'sno',
|
|
disablePadding: true,
|
|
label: '#'
|
|
},
|
|
{
|
|
id: 'tenantname',
|
|
numeric: false,
|
|
disablePadding: false,
|
|
label: 'REQUESTOR'
|
|
},
|
|
{
|
|
id: 'contact',
|
|
numeric: false,
|
|
disablePadding: false,
|
|
label: 'BANK'
|
|
},
|
|
{
|
|
id: 'address3',
|
|
disablePadding: false,
|
|
label: 'IFSC'
|
|
},
|
|
{
|
|
id: 'address',
|
|
disablePadding: false,
|
|
label: 'REF NO'
|
|
},
|
|
{
|
|
id: 'amount',
|
|
disablePadding: false,
|
|
label: 'AMOUNT'
|
|
},
|
|
{
|
|
id: 'city',
|
|
disablePadding: false,
|
|
label: 'REASON'
|
|
}
|
|
// {
|
|
// id: 'action',
|
|
// disablePadding: false,
|
|
// label: 'ACTION',
|
|
// }
|
|
];
|
|
|
|
function EnhancedTableHead(props) {
|
|
const { order, orderBy, onRequestSort } = props;
|
|
const createSortHandler = (property) => (event) => {
|
|
onRequestSort(event, property);
|
|
};
|
|
|
|
return (
|
|
<TableHead>
|
|
<TableRow>
|
|
{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 theme = useTheme();
|
|
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
|
const [order, setOrder] = React.useState('asc');
|
|
const [orderBy, setOrderBy] = React.useState('calories');
|
|
const [selected, setSelected] = React.useState([]);
|
|
const [page, setPage] = React.useState(0);
|
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
|
|
|
const [clientname, setClientname] = useState('');
|
|
const [emailaddress, setEmailaddress] = useState('');
|
|
const [mobilenumber, setMobilenumber] = useState('');
|
|
const [regno, setRegno] = useState('');
|
|
const [address, setAddress] = useState('');
|
|
const [city, setCity] = useState('');
|
|
const [zipcode, setZipcode] = useState('');
|
|
const [contactname, setContactname] = useState('');
|
|
const [state1, setState1] = useState('');
|
|
const [suburb, setSuburb] = useState('');
|
|
const [currenttenantid] = useState('');
|
|
const [latlong, setLatlong] = useState({});
|
|
Geocode.setApiKey(process.env.REACT_APP_GOOGLE_MAPS_API_KEY);
|
|
// const [alertmessage, setAlertmessage] = useState('');
|
|
// const [toast, setToast] = useState(false);
|
|
const [rolesarr, setRolesarr] = useState([]);
|
|
const [roleslist] = useState([]);
|
|
const [rolestab, setRolestab] = useState(0);
|
|
|
|
const [approveid] = useState(false);
|
|
const [disableid] = useState(false);
|
|
const [loading1] = useState(false);
|
|
|
|
const [refno, setRefno] = useState('');
|
|
const [requestor, setRequestor] = useState('');
|
|
const [bankname, setBankname] = useState('');
|
|
|
|
useEffect(() => {
|
|
setRolesarr([
|
|
{
|
|
sno: 1,
|
|
role: '',
|
|
cost: '',
|
|
serviceid: 0,
|
|
tenantid: 0,
|
|
categoryid: 0,
|
|
subcategoryid: 0,
|
|
servicecode: '',
|
|
servicename: '',
|
|
unitid: 0,
|
|
unitname: '',
|
|
serviceamount: '',
|
|
discountid: 0,
|
|
taxpercent: 0,
|
|
taxamount: 0,
|
|
servicevalue: 0,
|
|
categoryname: ''
|
|
}
|
|
]);
|
|
console.log(rolesarr);
|
|
// fetchroleslist();
|
|
}, []);
|
|
|
|
// useEffect(() => {
|
|
|
|
// if (alertmessage && toast) {
|
|
// dispatch(
|
|
// openSnackbar({
|
|
// open: true,
|
|
// message: alertmessage,
|
|
// variant: 'alert',
|
|
// anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
// alert: {
|
|
// color: 'error',
|
|
|
|
// }
|
|
// })
|
|
// )
|
|
// }
|
|
// }, [toast])
|
|
const opentoast = (message) => {
|
|
enqueueSnackbar(message, {
|
|
variant: 'error',
|
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
autoHideDuration: 2000
|
|
});
|
|
console.log(alertmessage);
|
|
};
|
|
|
|
// const opentoast = () => {
|
|
// setToast(true)
|
|
|
|
// setTimeout(() => {
|
|
// setToast(false)
|
|
// }, 2000);
|
|
|
|
// }
|
|
|
|
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]);
|
|
|
|
useEffect(() => {
|
|
console.log('rolesarr');
|
|
console.log(rolesarr);
|
|
}, [rolesarr]);
|
|
|
|
|
|
|
|
const addarr = () => {
|
|
let arr = rolesarr;
|
|
if (arr[arr.length - 1].role && arr[arr.length - 1].cost) {
|
|
arr.push({
|
|
sno: arr.length + 1,
|
|
cost: '',
|
|
role: '',
|
|
serviceid: 0,
|
|
tenantid: 0,
|
|
categoryid: 0,
|
|
subcategoryid: 0,
|
|
servicecode: '',
|
|
servicename: '',
|
|
unitid: 0,
|
|
unitname: '',
|
|
serviceamount: '',
|
|
discountid: 0,
|
|
taxpercent: 0,
|
|
taxamount: 0,
|
|
servicevalue: 0,
|
|
categoryname: ''
|
|
});
|
|
setRolesarr([...arr]);
|
|
} else {
|
|
// setAlertmessage('Fill all Previous Details');
|
|
opentoast('Fill all Previous Details');
|
|
}
|
|
};
|
|
const deletearr = async (sno, val1) => {
|
|
console.log(val1);
|
|
let arr = rolesarr;
|
|
|
|
if (val1.serviceid !== 0 && rolesarr.length > 1) {
|
|
console.log([
|
|
{
|
|
serviceid: val1.serviceid,
|
|
tenantid: val1.tenantid,
|
|
categoryid: val1.categoryid,
|
|
subcategoryid: val1.subcategoryid,
|
|
servicecode: val1.servicecode,
|
|
servicename: val1.servicename,
|
|
unitid: val1.unitid,
|
|
unitname: val1.unitname,
|
|
serviceamount: val1.servicevalue
|
|
}
|
|
]);
|
|
try {
|
|
await axios
|
|
.delete(`${process.env.REACT_APP_URL2}/tenants/delete/services`, {
|
|
data: [
|
|
{
|
|
serviceid: val1.serviceid,
|
|
tenantid: val1.tenantid,
|
|
categoryid: val1.categoryid,
|
|
subcategoryid: val1.subcategoryid,
|
|
servicecode: val1.servicecode,
|
|
servicename: val1.servicename,
|
|
unitid: val1.unitid,
|
|
unitname: val1.unitname,
|
|
serviceamount: val1.servicevalue
|
|
}
|
|
]
|
|
})
|
|
.then((res) => {
|
|
console.log('res');
|
|
console.log(res);
|
|
if (res.data.message === 'Deleted successful') {
|
|
enqueueSnackbar('Client pricing Deleted', {
|
|
variant: 'success',
|
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
autoHideDuration: 2000
|
|
});
|
|
arr.splice(sno - 1, 1);
|
|
arr.map((val, i) => {
|
|
val.sno = i + 1;
|
|
});
|
|
console.log(arr);
|
|
setRolesarr([...arr]);
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
setLoading(false);
|
|
});
|
|
} catch (err) {
|
|
console.log(err);
|
|
setLoading(false);
|
|
}
|
|
} else if (rolesarr.length > 1) {
|
|
arr.splice(sno - 1, 1);
|
|
arr.map((val, i) => {
|
|
val.sno = i + 1;
|
|
});
|
|
console.log(arr);
|
|
setRolesarr([...arr]);
|
|
} else if (rolesarr.length === 1) {
|
|
setRolesarr([
|
|
{
|
|
sno: 1,
|
|
role: '',
|
|
cost: '',
|
|
serviceid: val1.serviceid,
|
|
tenantid: 0,
|
|
categoryid: 0,
|
|
subcategoryid: 0,
|
|
servicecode: '',
|
|
servicename: '',
|
|
unitid: 0,
|
|
unitname: '',
|
|
serviceamount: '',
|
|
discountid: 0,
|
|
taxpercent: 0,
|
|
taxamount: 0,
|
|
servicevalue: 0,
|
|
categoryname: ''
|
|
}
|
|
]);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const clientupdate = async () => {
|
|
if (!clientname) {
|
|
// setAlertmessage('Fill Business name');
|
|
opentoast('Fill Business name');
|
|
} else if (!regno) {
|
|
// setAlertmessage('Fill Business No.');
|
|
opentoast('Fill Business No.');
|
|
} else if (!emailaddress) {
|
|
// setAlertmessage('Fill Email address');
|
|
opentoast('Fill Email address');
|
|
} else if (!mobilenumber) {
|
|
// setAlertmessage('Fill Mobile number');
|
|
opentoast('Fill Mobile number');
|
|
} else if (!contactname) {
|
|
// setAlertmessage('Fill Contact name');
|
|
opentoast('Fill Contact name');
|
|
} else if (!address) {
|
|
// setAlertmessage('Fill Address');
|
|
opentoast('Fill Address');
|
|
} else if (!city) {
|
|
// setAlertmessage('Fill City name');
|
|
opentoast('Fill City name');
|
|
} else if (!zipcode) {
|
|
// setAlertmessage('Fill Zip code');
|
|
opentoast('Fill Zip code');
|
|
} else if (!latlong.lat || !latlong.lng) {
|
|
setAlertmessage('Fill correct address');
|
|
opentoast('Fill correct address');
|
|
} else if ((approveid || disableid) && !(rolesarr[0].role && rolesarr[0].cost)) {
|
|
opentoast('Fill client pricing');
|
|
} else {
|
|
let obj = {
|
|
tenantid: currenttenantid,
|
|
registrationno: regno,
|
|
tenantname: clientname,
|
|
primaryemail: emailaddress,
|
|
primarycontact: contactname,
|
|
contactno: mobilenumber,
|
|
address: address,
|
|
suburb: suburb,
|
|
city: city,
|
|
state: state1,
|
|
postcode: zipcode,
|
|
latitude: latlong.lat.toString(),
|
|
longitude: latlong.lng.toString(),
|
|
approved: (approveid && tabvalue === 1) || (!approveid && tabvalue === 0 && !disableid) ? 1 : 0
|
|
};
|
|
console.log(obj);
|
|
|
|
try {
|
|
setLoading(true);
|
|
await axios
|
|
.put(`${process.env.REACT_APP_URL2}/tenants/update`, obj)
|
|
.then((res) => {
|
|
console.log('res:', res);
|
|
if (res.data.message === 'Update successful') {
|
|
// dispatch(
|
|
// openSnackbar({
|
|
// open: true,
|
|
// message: 'Client Detail Updated Successfully',
|
|
// variant: 'alert',
|
|
// anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
// alert: {
|
|
// color: 'success'
|
|
// }
|
|
// })
|
|
// )
|
|
enqueueSnackbar('Client Details Updated Successfully', {
|
|
variant: 'success',
|
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
autoHideDuration: 3000
|
|
});
|
|
setLoading(true);
|
|
|
|
setTimeout(() => {
|
|
clientdetailspending();
|
|
clientdetailsapproved();
|
|
setTabvalue(0);
|
|
setLoading(false);
|
|
}, 2000);
|
|
}
|
|
setLoading(false);
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
setLoading(false);
|
|
});
|
|
} catch (err) {
|
|
console.log(err);
|
|
setLoading(false);
|
|
}
|
|
}
|
|
};
|
|
|
|
const rolepricesubmit = async () => {
|
|
console.log('submit');
|
|
let arr = [];
|
|
let objcheck = false;
|
|
rolesarr.map((val) => {
|
|
if (!val.role || !val.cost) {
|
|
objcheck = true;
|
|
}
|
|
arr.push({
|
|
serviceid: val.serviceid,
|
|
tenantid: currenttenantid,
|
|
categoryid: val.categoryid,
|
|
subcategoryid: val.subcategoryid,
|
|
servicecode: val.servicecode,
|
|
servicename: val.servicename,
|
|
unitid: val.unitid,
|
|
unitname: val.unitname,
|
|
serviceamount: parseFloat(val.serviceamount),
|
|
categoryname: val.categoryname,
|
|
subcategoryname: val.servicename
|
|
// discountid: val.discountid,
|
|
// taxpercent: val.taxpercent,
|
|
// taxamount: val.taxamount,
|
|
// servicevalue: parseFloat(val.servicevalue),
|
|
});
|
|
});
|
|
console.log(arr);
|
|
if (!objcheck) {
|
|
try {
|
|
setLoading(true);
|
|
// await axios.post(`${process.env.REACT_APP_URL2}/tenants/createservice`, arr)tenants/update/services
|
|
await axios
|
|
.put(`${process.env.REACT_APP_URL2}/tenants/update/services`, arr)
|
|
.then((res) => {
|
|
console.log('res:', res);
|
|
if (res.data.message === 'Update successful') {
|
|
enqueueSnackbar('Service Updated Successfully', {
|
|
variant: 'success',
|
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
autoHideDuration: 2000
|
|
});
|
|
}
|
|
setLoading(false);
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
setLoading(false);
|
|
});
|
|
} catch (err) {
|
|
console.log(err);
|
|
setLoading(false);
|
|
}
|
|
} else {
|
|
enqueueSnackbar('Fill all Details', {
|
|
variant: 'error',
|
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
autoHideDuration: 2000
|
|
});
|
|
}
|
|
};
|
|
|
|
const createrequest = () => {
|
|
if (!refno) {
|
|
// setAlertmessage('Fill Business name');
|
|
opentoast('Fill Reference No');
|
|
} else if (!requestor) {
|
|
// setAlertmessage('Fill Business No.');
|
|
opentoast('Fill Requestor');
|
|
} else if (!bankname) {
|
|
// setAlertmessage('Fill Email address');
|
|
opentoast('Fill Bank Name');
|
|
} else if (!amount) {
|
|
// setAlertmessage('Fill Mobile number');
|
|
opentoast('Fill Amount');
|
|
} else if (!accountno) {
|
|
// setAlertmessage('Fill Contact name');
|
|
opentoast('Fill Account No');
|
|
} else if (!ifsc) {
|
|
// setAlertmessage('Fill Address');
|
|
opentoast('Fill IFSC');
|
|
} else if (!reason) {
|
|
// setAlertmessage('Fill City name');
|
|
opentoast('Fill Reason');
|
|
} else {
|
|
let obj = {
|
|
requestid: 0,
|
|
requestdate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
|
referenceno: refno,
|
|
Apptypeid: 22,
|
|
requesttype: 'staffexpenses',
|
|
reason: reason,
|
|
requestor: requestor,
|
|
amount: amount,
|
|
Accountno: accountno,
|
|
bankname: bankname,
|
|
ifsccode: ifsc
|
|
};
|
|
|
|
console.log(obj);
|
|
}
|
|
};
|
|
|
|
// const rolepriceupdate = async () => {
|
|
// console.log('submit')
|
|
// let arr = [];
|
|
// let objcheck = false;
|
|
// rolesarr.map((val) => {
|
|
// if (!val.role || !val.cost) {
|
|
// objcheck = true;
|
|
// }
|
|
// arr.push({
|
|
// serviceid: 0,
|
|
// tenantid: currenttenantid,
|
|
// categoryid: val.categoryid,
|
|
// subcategoryid: val.subcategoryid,
|
|
// servicecode: val.servicecode,
|
|
// servicename: val.servicename,
|
|
// unitid: val.unitid,
|
|
// unitname: val.unitname,
|
|
// serviceamount: parseFloat(val.serviceamount),
|
|
// discountid: val.discountid,
|
|
// taxpercent: val.taxpercent,
|
|
// taxamount: val.taxamount,
|
|
// servicevalue: parseFloat(val.servicevalue),
|
|
|
|
// })
|
|
// })
|
|
// console.log(arr)
|
|
// if (!objcheck) {
|
|
// try {
|
|
// setLoading(true)
|
|
// // await axios.post(`${process.env.REACT_APP_URL2}/clients/createservice`, arr)
|
|
// await axios.post(`${process.env.REACT_APP_URL2}/tenants/createservice`, arr)
|
|
|
|
// // await axios.post(`${process.env.REACT_APP_URL2}/clients/createservice`, arr)
|
|
// .then((res) => {
|
|
// console.log('res:', res);
|
|
// if (res.data.message === "Successful") {
|
|
|
|
// enqueueSnackbar('Service created Successfully', { variant: 'success',anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
// autoHideDuration: 3000 })
|
|
// }
|
|
// setLoading(false)
|
|
// }).catch((err) => {
|
|
// console.log(err)
|
|
// setLoading(false)
|
|
// })
|
|
|
|
// } catch (err) {
|
|
// console.log(err);
|
|
// setLoading(false)
|
|
// }
|
|
// } else {
|
|
|
|
// enqueueSnackbar('Fill all Details', { variant: 'error',anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
// autoHideDuration: 2000 })
|
|
// }
|
|
// }
|
|
|
|
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]
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<Dialog
|
|
// maxWidth={false}
|
|
fullWidth={true}
|
|
open={dialogopen}
|
|
onClose={dialogclose}
|
|
scroll={'paper'}
|
|
fullScreen={isMobile}
|
|
maxWidth="sm"
|
|
TransitionComponent={PopupTransition}
|
|
PaperProps={{ sx: { borderRadius: { xs: 0, sm: 3 } } }}
|
|
>
|
|
<DialogTitle>Create Request</DialogTitle>
|
|
|
|
<DialogContent dividers={true}>
|
|
<MainCard sx={{ height: '100%' }}>
|
|
<Grid
|
|
container
|
|
spacing={2.5}
|
|
// sx={{ pl: { xs: 0, sm: 5, md: 6, lg: 10, xl: 12 }, p: 2 }}
|
|
>
|
|
{/* <Grid item xs={12} sm={5} md={4} lg={4} xl={3}> */}
|
|
{/* <MainCard title={<Box sx={{ p: 1 }}>Client</Box>} sx={{ height: '100%' }}>
|
|
|
|
<Grid container spacing={3}> */}
|
|
<Grid item xs={12} sm={6}>
|
|
{/* <Stack spacing={2} alignItems="center" sx={{ width: '100%' }}> */}
|
|
<FormLabel>Reference No</FormLabel>
|
|
<TextField
|
|
type="number"
|
|
// label='Reference No'
|
|
fullWidth
|
|
sx={{ width: '100%' }}
|
|
value={refno}
|
|
onChange={(e) => {
|
|
setRefno(e.target.value);
|
|
console.log(e);
|
|
}}
|
|
/>
|
|
</Grid>
|
|
<Grid item xs={12} sm={6}>
|
|
<FormLabel>Requestor</FormLabel>
|
|
<TextField
|
|
value={requestor}
|
|
onChange={(e) => setRequestor(e.target.value)}
|
|
// label='Business No.'
|
|
fullWidth
|
|
sx={{ width: '100%' }}
|
|
/>
|
|
{/* </Stack> */}
|
|
</Grid>
|
|
|
|
<Grid item xs={12} sm={6}>
|
|
{/* <List component="nav" aria-label="main mailbox folders" sx={{ py: 0 }}>
|
|
<Stack direction={'column'} spacing={2} sx={{ width: '100%' }}> */}
|
|
|
|
<FormLabel>Bank Name</FormLabel>
|
|
|
|
<TextField
|
|
// type='email'
|
|
value={bankname}
|
|
sx={{ width: '100%' }}
|
|
onChange={(e) => setBankname(e.target.value)}
|
|
// label='Email'
|
|
/>
|
|
</Grid>
|
|
<Grid item xs={12} sm={6}>
|
|
<FormLabel>Amount</FormLabel>
|
|
|
|
<TextField
|
|
type="number"
|
|
value={amount}
|
|
// placeholder='Mobile Number'
|
|
// InputProps={{
|
|
// startAdornment: <InputAdornment position="start">+1</InputAdornment>,
|
|
// }}
|
|
sx={{ width: '100%' }}
|
|
onChange={(e) => setAmount(e.target.value)}
|
|
/>
|
|
{/* </Stack>
|
|
</List> */}
|
|
</Grid>
|
|
{/* </Grid>
|
|
</MainCard>
|
|
</Grid> */}
|
|
<Grid item xs={12} sm={6}>
|
|
{/* <Stack spacing={2} alignItems="center" sx={{ width: '100%' }}> */}
|
|
<FormLabel>Account No</FormLabel>
|
|
|
|
<TextField
|
|
type="number"
|
|
// label='Business name'
|
|
fullWidth
|
|
sx={{ width: '100%' }}
|
|
value={accountno}
|
|
onChange={(e) => {
|
|
setAccountno(e.target.value);
|
|
console.log(e);
|
|
}}
|
|
/>
|
|
</Grid>
|
|
<Grid item xs={12} sm={6}>
|
|
<FormLabel>IFSC Code</FormLabel>
|
|
|
|
<TextField
|
|
value={ifsc}
|
|
onChange={(e) => setIfsc(e.target.value)}
|
|
// label='Business No.'
|
|
fullWidth
|
|
sx={{ width: '100%' }}
|
|
/>
|
|
{/* </Stack> */}
|
|
</Grid>
|
|
<Grid item xs={12} sm={6}>
|
|
<FormLabel>Reason</FormLabel>
|
|
|
|
<TextField
|
|
value={reason}
|
|
onChange={(e) => setReason(e.target.value)}
|
|
// label='Business No.'
|
|
fullWidth
|
|
sx={{ width: '100%' }}
|
|
/>
|
|
{/* </Stack> */}
|
|
</Grid>
|
|
</Grid>
|
|
</MainCard>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Grid container>
|
|
<Grid item xs={12}>
|
|
<Stack direction={'row'} justifyContent={'flex-end'} spacing={2} sx={{ p: 2 }}>
|
|
<Button
|
|
variant="contained"
|
|
onClick={() => {
|
|
createrequest();
|
|
}}
|
|
>
|
|
Update
|
|
</Button>
|
|
<Button
|
|
variant="contained"
|
|
onClick={() => {
|
|
dialogclose();
|
|
}}
|
|
color="error"
|
|
>
|
|
Close
|
|
</Button>
|
|
</Stack>
|
|
</Grid>
|
|
</Grid>
|
|
</DialogActions>
|
|
</Dialog>
|
|
<Box
|
|
sx={{
|
|
width: '100%'
|
|
}}
|
|
>
|
|
{isMobile && (
|
|
<MobileCardList scroll>
|
|
{loading &&
|
|
[0, 1, 2, 3, 4].map((item) => (
|
|
<MobileCard key={item} accent="#662582">
|
|
<Stack direction="row" alignItems="center" spacing={1}>
|
|
<Skeleton variant="circular" width={32} height={32} />
|
|
<Stack sx={{ flex: 1 }}>
|
|
<Skeleton animation="wave" width="60%" />
|
|
<Skeleton animation="wave" width="40%" />
|
|
</Stack>
|
|
</Stack>
|
|
<MobileFieldGrid>
|
|
<MobileField label="Amount" value={<Skeleton animation="wave" width={50} />} />
|
|
<MobileField label="Ref No" value={<Skeleton animation="wave" width={50} />} />
|
|
</MobileFieldGrid>
|
|
</MobileCard>
|
|
))}
|
|
|
|
{!loading &&
|
|
visibleRows.map((row, index) => {
|
|
const isItemSelected = isSelected(row.sno);
|
|
return (
|
|
<MobileCard
|
|
key={row.sno}
|
|
accent="#662582"
|
|
selected={isItemSelected}
|
|
onClick={(event) => handleClick(event, row.sno)}
|
|
header={
|
|
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={1}>
|
|
<Stack direction="row" alignItems="center" spacing={1} sx={{ minWidth: 0 }}>
|
|
<Avatar sx={{ width: 32, height: 32, bgcolor: '#66258218', color: '#662582', fontSize: 13 }}>
|
|
{row.requestor ? String(row.requestor).charAt(0).toUpperCase() : '#'}
|
|
</Avatar>
|
|
<Stack sx={{ minWidth: 0 }}>
|
|
<Typography sx={{ fontSize: 14, fontWeight: 700, color: '#0f172a' }} noWrap>
|
|
{row.requestor || '—'}
|
|
</Typography>
|
|
<Typography sx={{ fontSize: 11, color: '#94a3b8' }} noWrap>
|
|
#{row.sno}
|
|
</Typography>
|
|
</Stack>
|
|
</Stack>
|
|
{row.amount != null && (
|
|
<Chip label={row.amount} size="small" sx={{ bgcolor: '#66258218', color: '#662582', fontWeight: 700 }} />
|
|
)}
|
|
</Stack>
|
|
}
|
|
>
|
|
<MobileFieldGrid>
|
|
<MobileField label="Bank" value={row.bankname} />
|
|
<MobileField label="Account No" value={row.accountno} />
|
|
<MobileField label="IFSC" value={row.ifsccode} />
|
|
<MobileField label="Ref No" value={row.referenceno} />
|
|
<MobileField label="Reason" value={row.reason} full />
|
|
</MobileFieldGrid>
|
|
</MobileCard>
|
|
);
|
|
})}
|
|
|
|
{!loading && visibleRows.length === 0 && (
|
|
<Stack alignItems="center" spacing={1.5} sx={{ py: 6 }}>
|
|
<Avatar sx={{ width: 64, height: 64, bgcolor: '#f1f5f9', color: '#94a3b8' }} />
|
|
<Typography sx={{ fontSize: 15, fontWeight: 700, color: '#0f172a' }}>No requests to show</Typography>
|
|
<Typography sx={{ fontSize: 13, color: '#94a3b8' }}>Requests will appear here once available.</Typography>
|
|
</Stack>
|
|
)}
|
|
</MobileCardList>
|
|
)}
|
|
|
|
<TableContainer sx={{ width: '100%', borderBottom: 1, borderColor: 'divider', display: isMobile ? 'none' : 'block' }}>
|
|
<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>
|
|
<Stack direction={'row'} spacing={1}>
|
|
<Skeleton variant="circular" width={40} height={40} />
|
|
<Stack direction={'column'}>
|
|
<Skeleton animation="wave" width={100} />
|
|
<Skeleton animation="wave" width={100} />
|
|
</Stack>
|
|
</Stack>
|
|
</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.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}
|
|
// selected={isItemSelected}
|
|
sx={{ cursor: 'pointer' }}
|
|
>
|
|
{/* <TableCell padding="checkbox">
|
|
<Checkbox
|
|
color="primary"
|
|
checked={isItemSelected}
|
|
inputProps={{
|
|
'aria-labelledby': labelId,
|
|
}}
|
|
/>
|
|
</TableCell> */}
|
|
<TableCell component="th" id={labelId} scope="row" padding="none">
|
|
{row.sno}
|
|
</TableCell>
|
|
|
|
<TableCell align="left" sx={{ paddingLeft: '0px !important' }}>
|
|
<Stack direction="row" alignItems="center" spacing={1} justifyContent="flex-start">
|
|
<Avatar
|
|
alt=""
|
|
size="sm"
|
|
sx={{
|
|
width: '25px',
|
|
height: '25px'
|
|
}}
|
|
></Avatar>
|
|
<Stack direction="column">
|
|
<Typography variant="caption">{row.requestor}</Typography>
|
|
{/* <Typography variant='caption' color="textSecondary">
|
|
{row.primaryemail}
|
|
</Typography> */}
|
|
</Stack>
|
|
</Stack>
|
|
</TableCell>
|
|
<TableCell align="left">
|
|
<Typography variant="caption"> {row.accountno}</Typography>
|
|
<Typography variant="h6"> {row.bankname}</Typography>
|
|
</TableCell>
|
|
<TableCell>{row.ifsccode}</TableCell>
|
|
<TableCell align="left">
|
|
{/* <Tooltip title={row.address}>
|
|
<Typography variant="caption" color="textSecondary">
|
|
{row.address.slice(0, 15)}...
|
|
</Typography>
|
|
</Tooltip> */}
|
|
{row.referenceno}
|
|
</TableCell>
|
|
<TableCell>{row.amount}</TableCell>
|
|
<TableCell>{row.reason}</TableCell>
|
|
{/*
|
|
<TableCell >
|
|
{row.reason}
|
|
|
|
</TableCell> */}
|
|
</TableRow>
|
|
|
|
<TableRow>
|
|
<TableCell
|
|
style={{ paddingBottom: 0, paddingTop: 0, paddingLeft: 0, paddingRight: 0 }}
|
|
colSpan={8}
|
|
sx={{ width: '100%' }}
|
|
>
|
|
<Collapse in={expandopen === row.sno} timeout="auto" unmountOnExit>
|
|
<Transitions type="slide" direction="down" in={true}>
|
|
<MainCard sx={{ height: '100%' }}>
|
|
{loading1 ? (
|
|
<>
|
|
<MainCard>
|
|
{/* <TableRow>
|
|
<Typography>Loading...</Typography>
|
|
</TableRow> */}
|
|
<Stack alignItems={'center'}>
|
|
<CircularProgress />
|
|
</Stack>
|
|
</MainCard>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Tabs value={rolestab} onChange={(e, i) => setRolestab(i)}>
|
|
<Tab label="client Details" />
|
|
<Tab label="Client Pricing" />
|
|
</Tabs>
|
|
{rolestab === 0 && (
|
|
<>
|
|
<Grid container spacing={2.5} sx={{ pl: { xs: 0, sm: 5, md: 6, lg: 10, xl: 12 }, p: 2 }}>
|
|
<Grid item xs={12} sm={5} md={4} lg={4} xl={3}>
|
|
<MainCard sx={{ height: '100%' }}>
|
|
<Grid container spacing={3}>
|
|
<Grid item xs={12}>
|
|
<Stack spacing={2.5} alignItems="center">
|
|
<Avatar alt="Avatar 1" size="xl" />
|
|
<Stack spacing={0.5} alignItems="center">
|
|
<Typography variant="h5">{clientname}</Typography>
|
|
<Typography color="secondary">{regno}</Typography>
|
|
</Stack>
|
|
</Stack>
|
|
</Grid>
|
|
{/* <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">All orders</Typography>
|
|
<Chip label={4} color="primary" variant="light" size="small" />
|
|
</Stack>
|
|
<Divider orientation="vertical" flexItem />
|
|
<Stack spacing={0.5} alignItems="center">
|
|
<Typography variant="h5">Covered orders</Typography>
|
|
<Chip label={2} color="success" variant="light" size="small" />
|
|
</Stack>
|
|
</Stack>
|
|
</Grid> */}
|
|
<Grid item xs={12}>
|
|
<Divider />
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<List component="nav" aria-label="main mailbox folders" sx={{ py: 0 }}>
|
|
<ListItem>
|
|
<ListItemIcon>
|
|
<MailOutlined />
|
|
</ListItemIcon>
|
|
{/* <ListItemSecondaryAction> */}
|
|
<Typography align="right">{emailaddress}</Typography>
|
|
{/* </ListItemSecondaryAction> */}
|
|
</ListItem>
|
|
<ListItem>
|
|
<ListItemIcon>
|
|
<PhoneOutlined />
|
|
</ListItemIcon>
|
|
{/* <ListItemSecondaryAction> */}
|
|
<Typography align="left">
|
|
{/* <PatternFormat displayType="text" */}
|
|
+1 {mobilenumber}
|
|
</Typography>
|
|
{/* </ListItemSecondaryAction> */}
|
|
</ListItem>
|
|
{/* <ListItem>
|
|
<ListItemIcon>
|
|
<EnvironmentOutlined />
|
|
</ListItemIcon>
|
|
<ListItemSecondaryAction>
|
|
<Typography align="right">city</Typography>
|
|
</ListItemSecondaryAction>
|
|
|
|
{/* </ListItem> */}
|
|
</List>
|
|
</Grid>
|
|
</Grid>
|
|
</MainCard>
|
|
</Grid>
|
|
<Grid item xs={12} sm={7} md={8} lg={8} xl={9}>
|
|
{/* <Stack spacing={2.5}> */}
|
|
<MainCard title={<Box sx={{ p: 1 }}>Contact Details</Box>} sx={{ height: '100%' }}>
|
|
<List sx={{ py: 0 }}>
|
|
<ListItem
|
|
// divider={!matchDownMD}
|
|
>
|
|
<Grid container spacing={3}>
|
|
<Grid item xs={12} md={6}>
|
|
<Stack spacing={0.5}>
|
|
<Typography color="secondary"> Contact Name</Typography>
|
|
<Typography>{contactname}</Typography>
|
|
</Stack>
|
|
</Grid>
|
|
<Grid item xs={12} md={6}>
|
|
{/* <Stack spacing={0.5}>
|
|
<Typography color="secondary">Contact number</Typography>
|
|
<Typography>
|
|
{mobilenumber}
|
|
</Typography>
|
|
</Stack> */}
|
|
</Grid>
|
|
</Grid>
|
|
</ListItem>
|
|
|
|
<ListItem>
|
|
<Stack spacing={0.5}>
|
|
<Typography color="secondary">Address</Typography>
|
|
<Typography>{address}</Typography>
|
|
</Stack>
|
|
</ListItem>
|
|
<ListItem
|
|
// divider={!matchDownMD}
|
|
>
|
|
<Grid container spacing={3}>
|
|
<Grid item xs={12} md={6}>
|
|
<Stack spacing={0.5}>
|
|
<Typography color="secondary">City</Typography>
|
|
<Typography>{city}</Typography>
|
|
</Stack>
|
|
</Grid>
|
|
<Grid item xs={12} md={6}>
|
|
<Stack spacing={0.5}>
|
|
<Typography color="secondary">Zip Code</Typography>
|
|
<Typography>
|
|
{/* <PatternFormat displayType="text" format="### ###" mask="_" defaultValue={zipcode} /> */}
|
|
{zipcode}
|
|
</Typography>
|
|
</Stack>
|
|
</Grid>
|
|
</Grid>
|
|
</ListItem>
|
|
</List>
|
|
</MainCard>
|
|
|
|
{/* </Stack> */}
|
|
</Grid>
|
|
</Grid>
|
|
</>
|
|
)}
|
|
{rolestab === 1 && (
|
|
<>
|
|
<Grid container sx={{ p: 1 }}>
|
|
<Grid item xs={12}>
|
|
<MainCard sx={{ height: '100%', p: 1 }}>
|
|
{/* <MainCard sx={{ height: '100%' }}> */}
|
|
{rolesarr[0].role ? (
|
|
<>
|
|
<TableContainer sx={{ width: '100%', borderBottom: 1, borderColor: 'divider' }}>
|
|
<Table sx={{ width: '100%' }}>
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>#</TableCell>
|
|
<TableCell sx={{ width: '30%' }}>Category</TableCell>
|
|
|
|
<TableCell sx={{ width: '30%' }}>Skill</TableCell>
|
|
|
|
<TableCell sx={{ width: '30%' }}>Cost/Hr</TableCell>
|
|
|
|
{/* <TableCell sx={{ width: '10px' }}></TableCell> */}
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{rolesarr.map((val1) => {
|
|
return (
|
|
<>
|
|
<TableRow>
|
|
<TableCell>{val1.sno}</TableCell>
|
|
<TableCell>{val1.categoryname}</TableCell>
|
|
<TableCell>{val1.role}</TableCell>
|
|
<TableCell>{val1.cost}</TableCell>
|
|
</TableRow>
|
|
</>
|
|
);
|
|
})}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Typography>No Data found</Typography>
|
|
</>
|
|
)}
|
|
{/* <Grid item xs={12}>
|
|
<Button
|
|
color="primary"
|
|
endIcon={<PlusOutlined />}
|
|
|
|
onClick={() => addarr()}
|
|
|
|
sx={{ m: 2 }}
|
|
variant="dashed" size="extraSmall"
|
|
>
|
|
ADD SKILL
|
|
</Button>
|
|
</Grid> */}
|
|
{/* <Grid item xs={12}>
|
|
<Grid container justifyContent={'flex-end'}>
|
|
<Grid item>
|
|
|
|
<Button
|
|
variant='contained'
|
|
size='small'
|
|
onClick={rolepricesubmit}
|
|
>
|
|
SUBMIT
|
|
</Button>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
</Grid> */}
|
|
{/* </MainCard> */}
|
|
</MainCard>
|
|
</Grid>
|
|
</Grid>
|
|
</>
|
|
)}
|
|
</>
|
|
)}
|
|
</MainCard>
|
|
</Transitions>
|
|
</Collapse>
|
|
|
|
{/* edit page collapse */}
|
|
|
|
<Collapse in={editexpandopen === row.sno} timeout="auto" unmountOnExit>
|
|
<Transitions type="slide" direction="down" in={true}>
|
|
{loading1 ? (
|
|
<>
|
|
<MainCard>
|
|
{/* <TableRow>
|
|
<Typography>Loading...</Typography>
|
|
</TableRow> */}
|
|
<Stack alignItems={'center'}>
|
|
<CircularProgress />
|
|
</Stack>
|
|
</MainCard>
|
|
</>
|
|
) : (
|
|
<>
|
|
<MainCard sx={{ height: '100%' }}>
|
|
<Tabs value={rolestab} onChange={(e, i) => setRolestab(i)}>
|
|
<Tab label="client Details" />
|
|
<Tab label="Client Pricing" />
|
|
</Tabs>
|
|
{rolestab === 0 && (
|
|
<>
|
|
<MainCard sx={{ height: '100%' }}>
|
|
<Grid
|
|
container
|
|
spacing={2.5}
|
|
// sx={{ pl: { xs: 0, sm: 5, md: 6, lg: 10, xl: 12 }, p: 2 }}
|
|
>
|
|
<Grid item xs={12} sm={5} md={4} lg={4} xl={3}>
|
|
<MainCard title={<Box sx={{ p: 1 }}>Client</Box>} sx={{ height: '100%' }}>
|
|
<Grid container spacing={3}>
|
|
<Grid item xs={12}>
|
|
{/* <Stack spacing={2.5} alignItems="center" sx={{width:'100%'}}> */}
|
|
{/* <Avatar alt="Avatar 1" size="xl" /> */}
|
|
<Stack spacing={2} alignItems="center" sx={{ width: '100%' }}>
|
|
{/* <Typography variant="h5">Client name</Typography> */}
|
|
<TextField
|
|
type="text"
|
|
label="Business name"
|
|
fullWidth
|
|
sx={{ width: '100%' }}
|
|
value={clientname}
|
|
onChange={(e) => setClientname(e.target.value)}
|
|
/>
|
|
|
|
<TextField
|
|
type="number"
|
|
value={regno}
|
|
onChange={(e) => setRegno(e.target.value)}
|
|
label="Business No."
|
|
// placeholder='Registration Number'
|
|
fullWidth
|
|
sx={{ width: '100%' }}
|
|
/>
|
|
</Stack>
|
|
{/* </Stack> */}
|
|
</Grid>
|
|
|
|
<Grid item xs={12}>
|
|
<List component="nav" aria-label="main mailbox folders" sx={{ py: 0 }}>
|
|
<Stack direction={'column'} spacing={2} sx={{ width: '100%' }}>
|
|
<TextField
|
|
type="email"
|
|
value={emailaddress}
|
|
// startAdornment={<MailOutlined />}
|
|
sx={{ width: '100%' }}
|
|
onChange={(e) => setEmailaddress(e.target.value)}
|
|
label="Email"
|
|
/>
|
|
|
|
<TextField
|
|
type="number"
|
|
value={mobilenumber}
|
|
placeholder="Mobile Number"
|
|
InputProps={{
|
|
startAdornment: <InputAdornment position="start">+1</InputAdornment>
|
|
}}
|
|
sx={{ width: '100%' }}
|
|
onChange={(e) => setMobilenumber(e.target.value)}
|
|
/>
|
|
{/* </Typography> */}
|
|
{/* </ListItemSecondaryAction> */}
|
|
{/* </ListItem> */}
|
|
</Stack>
|
|
</List>
|
|
</Grid>
|
|
</Grid>
|
|
</MainCard>
|
|
</Grid>
|
|
<Grid item xs={12} sm={7} md={8} lg={8} xl={9}>
|
|
{/* <Stack spacing={2.5}> */}
|
|
<MainCard title={<Box sx={{ p: 1 }}>Contact Details</Box>} sx={{ height: '100%' }}>
|
|
{/* <List sx={{ py: 0 }}>
|
|
<ListItem
|
|
// divider={!matchDownMD}
|
|
> */}
|
|
<Grid container spacing={3}>
|
|
<Grid item xs={12}>
|
|
<Stack spacing={0.5}>
|
|
{/* <Typography color="secondary"> Contact Name</Typography> */}
|
|
<TextField
|
|
type="text"
|
|
value={contactname}
|
|
onChange={(e) => setContactname(e.target.value)}
|
|
label="Contact Name"
|
|
/>
|
|
{/* <Typography>name</Typography> */}
|
|
</Stack>
|
|
</Grid>
|
|
|
|
{/* </Grid> */}
|
|
{/* </ListItem>
|
|
<ListItem> */}
|
|
{/* <Grid container spacing={3}> */}
|
|
<Grid item xs={12}>
|
|
<Stack spacing={0.5}>
|
|
{/* <Typography color="secondary">Address</Typography> */}
|
|
{/* {((row.sno === 1)) && */}
|
|
|
|
<>
|
|
{/* <TextField
|
|
id={`address22${row.sno}`}
|
|
label='Address'
|
|
type='text'
|
|
value={address}
|
|
onChange={(e) => setAddress(e.target.value)}
|
|
inputRef={materialRef}
|
|
|
|
|
|
/> */}
|
|
</>
|
|
|
|
{/* } */}
|
|
|
|
<Autocomplete
|
|
className="automap"
|
|
apiKey={process.env.REACT_APP_GOOGLE_MAPS_API_KEY}
|
|
style={{
|
|
width: '100%',
|
|
height: '40px',
|
|
borderRadius: '5px',
|
|
border: '1px solid #e0e0e0',
|
|
textIndent: '10px',
|
|
outline: 'none'
|
|
// ':hover': {
|
|
// border: '1px solid #00b0ff !important',
|
|
// backgroundColor:'blue'
|
|
// }
|
|
}}
|
|
onPlaceSelected={(place) => {
|
|
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 || '');
|
|
setState1(state || '');
|
|
setZipcode(zipcode1 || '');
|
|
setSuburb(suburb1 || '');
|
|
}}
|
|
options={{
|
|
types: ['address' || 'geocode']
|
|
}}
|
|
placeholder="Address"
|
|
value={address}
|
|
onChange={(e) => setAddress(e.target.value)}
|
|
/>
|
|
</Stack>
|
|
</Grid>
|
|
{/* </Grid> */}
|
|
{/* </ListItem>
|
|
<ListItem
|
|
// divider={!matchDownMD}
|
|
> */}
|
|
{/* <Grid container spacing={3}> */}
|
|
<Grid item xs={12} md={6}>
|
|
<Stack spacing={0.5}>
|
|
{/* <Typography color="secondary">City</Typography> */}
|
|
{/* <Typography>City</Typography> */}
|
|
<TextField
|
|
label="City"
|
|
type="text"
|
|
value={city}
|
|
onChange={(e) => setCity(e.target.value)}
|
|
/>
|
|
{/* <Typography>{'data.address'}</Typography> */}
|
|
</Stack>
|
|
</Grid>
|
|
<Grid item xs={12} md={6}>
|
|
<Stack spacing={0.5}>
|
|
{/* <Typography color="secondary">Zip Code</Typography> */}
|
|
{/* <Typography>
|
|
<PatternFormat displayType="text" format="### ###" mask="_" defaultValue={666666} />
|
|
</Typography> */}
|
|
<TextField
|
|
label="Zip Code"
|
|
// type="number"
|
|
value={zipcode}
|
|
onChange={(e) => setZipcode(e.target.value)}
|
|
/>
|
|
</Stack>
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<Stack direction={'row'} justifyContent={'flex-end'}>
|
|
<Button
|
|
variant="contained"
|
|
onClick={() => {
|
|
clientupdate();
|
|
if (approveid) {
|
|
rolepricesubmit();
|
|
}
|
|
}}
|
|
>
|
|
Update {approveid ? '& Approve' : ''}
|
|
{disableid ? '& Disable' : ''}
|
|
</Button>
|
|
</Stack>
|
|
</Grid>
|
|
</Grid>
|
|
{/* </ListItem>
|
|
|
|
</List> */}
|
|
</MainCard>
|
|
|
|
{/* </Stack> */}
|
|
</Grid>
|
|
</Grid>
|
|
</MainCard>
|
|
</>
|
|
)}
|
|
{rolestab === 1 && (
|
|
<>
|
|
<Grid
|
|
container
|
|
// sx={{ pl: { xs: 0, sm: 5, md: 6, lg: 10, xl: 12 }, p: 2 }}
|
|
>
|
|
<Grid item xs={12}>
|
|
<MainCard sx={{ height: '100%', p: 1 }}>
|
|
<MainCard sx={{ height: '100%' }}>
|
|
<TableContainer sx={{ width: '100%', borderBottom: 1, borderColor: 'divider' }}>
|
|
<Table sx={{ width: '100%' }}>
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>#</TableCell>
|
|
<TableCell>Category</TableCell>
|
|
|
|
<TableCell sx={{ width: '40%' }}>Skill</TableCell>
|
|
|
|
<TableCell sx={{ width: '40%' }}>Cost/Hr</TableCell>
|
|
|
|
<TableCell sx={{ width: '10px' }}></TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{rolesarr.map((val1) => {
|
|
return (
|
|
<>
|
|
<TableRow>
|
|
<TableCell>{val1.sno}</TableCell>
|
|
{/* <TableCell>{val1.sno}</TableCell> */}
|
|
<TableCell>{val1.categoryname}</TableCell>
|
|
|
|
<TableCell>
|
|
<Autocomplete1
|
|
// margin="normal"
|
|
fullWidth
|
|
id="venuetype33"
|
|
variant="outlined"
|
|
error={true}
|
|
freeSolo
|
|
options={roleslist.sort(
|
|
(a, b) => -b.categoryname.localeCompare(a.categoryname)
|
|
)}
|
|
groupBy={(option) => option.categoryname}
|
|
getOptionLabel={(option) => option.subcategoryname}
|
|
isOptionEqualToValue={(option, value) =>
|
|
option.subcategoryid === value.subcategoryid
|
|
}
|
|
onChange={(e, val) => {
|
|
if (val) {
|
|
console.log('eval', e);
|
|
// console.log(skillsarr)
|
|
// let res = rolesarr.find((val2) => val2.role === val.servicename);
|
|
let res = rolesarr.find(
|
|
(val2) => val2.subcategoryid === val.subcategoryid
|
|
);
|
|
|
|
console.log(val);
|
|
if (!res) {
|
|
let arr = rolesarr;
|
|
arr[val1.sno - 1].role = val.subcategoryname;
|
|
arr[val1.sno - 1].categoryname = val.categoryname;
|
|
|
|
// arr[val1.sno - 1].Staffroleid = 0;
|
|
|
|
arr[val1.sno - 1].categoryid = val.categoryid;
|
|
arr[val1.sno - 1].subcategoryid = val.subcategoryid;
|
|
// arr[val1.sno - 1].servicename = val.servicename;
|
|
arr[val1.sno - 1].servicename = val.subcategoryname;
|
|
// arr[val1.sno - 1].servicecode = val.servicecode;
|
|
|
|
// arr[val1.sno - 1].unitid = val.serviceunit;
|
|
arr[val1.sno - 1].unitid = val.unitid;
|
|
// arr[val1.sno - 1].serviceid = val.serviceid;
|
|
|
|
// arr[val1.sno - 1].unitname = val.serviceunitname;
|
|
arr[val1.sno - 1].unitname = val.unitname;
|
|
|
|
// setSkillsarr([...arr]);
|
|
setRolesarr([...arr]);
|
|
} else {
|
|
// setAlertmessage('select different skill')
|
|
opentoast('select different skill');
|
|
}
|
|
}
|
|
console.log(val);
|
|
}}
|
|
renderInput={(params) => (
|
|
<TextField
|
|
{...params}
|
|
placeholder="Choose a Skill"
|
|
defaultValue={val1.role}
|
|
variant="outlined"
|
|
sx={{
|
|
input: {
|
|
'&::placeholder': {
|
|
opacity: 0.9
|
|
}
|
|
}
|
|
}}
|
|
/>
|
|
)}
|
|
// renderGroup={(params) => (
|
|
// <li key={params.key}>
|
|
|
|
// <h5>{params.group}</h5>
|
|
// <p>{params.children}</p>
|
|
|
|
// </li>
|
|
// )}
|
|
// options={roleslist}
|
|
value={{
|
|
categoryid: val1.categoryid,
|
|
categoryname: '',
|
|
cost: val1.serviceamount,
|
|
label: val1.servicename,
|
|
status: 0,
|
|
subcategoryid: val1.subcategoryid,
|
|
subcategoryname: val1.servicename,
|
|
unitid: val1.unitid,
|
|
unitname: val1.unitname
|
|
}}
|
|
// textContent={val1.servicename}
|
|
|
|
disabled={loading ? true : false}
|
|
/>
|
|
</TableCell>
|
|
|
|
<TableCell>
|
|
<TextField
|
|
type="number"
|
|
// sx={{ width: '150px' }}
|
|
onChange={(e) => {
|
|
let arr = rolesarr;
|
|
if (e.target.value < 1000) {
|
|
arr[val1.sno - 1].cost = e.target.value;
|
|
arr[val1.sno - 1].servicevalue = e.target.value;
|
|
arr[val1.sno - 1].serviceamount = e.target.value;
|
|
|
|
setRolesarr([...arr]);
|
|
}
|
|
|
|
// forceUpdate()
|
|
console.log(e.target.value);
|
|
}}
|
|
value={val1.cost}
|
|
autoComplete="off"
|
|
fullWidth
|
|
/>
|
|
</TableCell>
|
|
|
|
<TableCell>
|
|
<IconButton onClick={() => deletearr(val1.sno, val1)} color="error">
|
|
<DeleteOutlined />
|
|
</IconButton>
|
|
</TableCell>
|
|
</TableRow>
|
|
</>
|
|
);
|
|
})}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
<Grid item xs={12}>
|
|
<Button
|
|
color="primary"
|
|
endIcon={<PlusOutlined />}
|
|
onClick={() => addarr()}
|
|
sx={{ m: 2 }}
|
|
variant="dashed"
|
|
size="extraSmall"
|
|
>
|
|
ADD SKILL
|
|
</Button>
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<Grid container justifyContent={'flex-end'}>
|
|
<Grid item>
|
|
{/* <Stack direction={'row'} justifyContent={'flex-end'}> */}
|
|
<Button variant="contained" size="small" onClick={rolepricesubmit}>
|
|
Update
|
|
</Button>
|
|
</Grid>
|
|
</Grid>
|
|
{/* </Stack> */}
|
|
</Grid>
|
|
</MainCard>
|
|
</MainCard>
|
|
</Grid>
|
|
</Grid>
|
|
</>
|
|
)}
|
|
</MainCard>
|
|
</>
|
|
)}
|
|
</Transitions>
|
|
</Collapse>
|
|
</TableCell>
|
|
</TableRow>
|
|
</>
|
|
);
|
|
})}
|
|
{emptyRows > 0 && (
|
|
<TableRow
|
|
style={{
|
|
height: 53 * emptyRows
|
|
}}
|
|
>
|
|
<TableCell colSpan={6} />
|
|
</TableRow>
|
|
)}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
<TablePagination
|
|
rowsPerPageOptions={[10, 25, 50, 100]}
|
|
component="div"
|
|
count={rows.length}
|
|
rowsPerPage={rowsPerPage}
|
|
page={page}
|
|
onPageChange={handleChangePage}
|
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
|
/>
|
|
{/* </Paper> */}
|
|
{/* <FormControlLabel
|
|
control={<Switch checked={dense} onChange={handleChangeDense} />}
|
|
label="Dense padding"
|
|
/> */}
|
|
{/* <AlertCustomerDelete title={'uuuu'} open={open} handleClose={handleClose} /> */}
|
|
</Box>
|
|
</>
|
|
);
|
|
}
|
|
|
|
const outerTheme = useTheme();
|
|
const isMobile = useMediaQuery(outerTheme.breakpoints.down('md'));
|
|
const [tabvalue, setTabvalue] = useState(0);
|
|
const [rows, setRows] = useState([]);
|
|
const [clientapproved, setClientApproved] = useState([]);
|
|
const [clientpending, setClientPending] = useState([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [searchword, setSearchword] = useState('');
|
|
const [dialogopen, setDialogopen] = useState(false);
|
|
|
|
// const [expandopen, setExpandopen] = React.useState('');
|
|
|
|
// const setinitial = (val)=>{
|
|
// if(val){
|
|
|
|
// console.log(val);
|
|
// setClientname(val.tenantname)
|
|
// }else{
|
|
// setClientname('')
|
|
// }
|
|
// console.log(clientname)
|
|
|
|
// }
|
|
|
|
useEffect(() => {
|
|
if (localStorage.getItem('partnerid')) {
|
|
clientdetailspending(localStorage.getItem('partnerid'));
|
|
clientdetailsapproved(localStorage.getItem('partnerid'));
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
// if (searchword) {
|
|
// if (tabvalue === 0) {
|
|
// let arr = clientapproved.filter((val) => {
|
|
// return (val.tenantname.toLowerCase().includes(searchword.toLowerCase())
|
|
// || val.primarycontact.toLowerCase().includes(searchword.toLowerCase())
|
|
// || val.primaryemail.toLowerCase().includes(searchword.toLowerCase())
|
|
// || val.city.toString().toLowerCase().includes(searchword.toLowerCase())
|
|
// )
|
|
// })
|
|
// console.log(arr)
|
|
// setRows([...arr])
|
|
// }
|
|
// if (tabvalue === 1) {
|
|
// let arr = clientpending.filter((val) => {
|
|
// return (val.tenantname.toLowerCase().includes(searchword.toLowerCase())
|
|
// || val.primarycontact.toLowerCase().includes(searchword.toLowerCase())
|
|
// || val.primaryemail.toLowerCase().includes(searchword.toLowerCase())
|
|
// || val.city.toString().toLowerCase().includes(searchword.toLowerCase())
|
|
// )
|
|
// })
|
|
// console.log(arr)
|
|
// setRows([...arr])
|
|
// }
|
|
// }
|
|
}, [searchword, tabvalue]);
|
|
|
|
const handleChangetab = (e, i) => {
|
|
setTabvalue(i);
|
|
if (i === 1) setRows(clientapproved);
|
|
if (i === 0) setRows(clientpending);
|
|
};
|
|
|
|
const clientdetailsapproved = async (tid) => {
|
|
setLoading(true);
|
|
try {
|
|
await axios
|
|
.get(`${process.env.REACT_APP_URL}/payments/requests/getpaymentrequest/?partnerid=${tid}&status=1`)
|
|
|
|
.then((res) => {
|
|
if (res.data.message === 'Successful') {
|
|
let arr = [];
|
|
res.data.details.map((val, i) => {
|
|
arr = [...arr, { ...val, sno: i + 1 }];
|
|
});
|
|
// setArr(arr)
|
|
setClientApproved(arr);
|
|
console.log(res.data.details);
|
|
setLoading(false);
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
setLoading(false);
|
|
});
|
|
} catch (err) {
|
|
console.log(err);
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const clientdetailspending = async (tid) => {
|
|
setLoading(true);
|
|
try {
|
|
await axios
|
|
.get(`${process.env.REACT_APP_URL}/payments/requests/getpaymentrequest/?partnerid=${tid}&status=0`)
|
|
|
|
.then((res) => {
|
|
if (res.data.message === 'Success') {
|
|
let arr = [];
|
|
res.data.details.map((val, i) => {
|
|
arr = [...arr, { ...val, sno: i + 1 }];
|
|
});
|
|
// setArr(arr)
|
|
setClientPending(arr);
|
|
setRows(arr);
|
|
console.log(res.data.details);
|
|
setLoading(false);
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
setLoading(false);
|
|
});
|
|
} catch (err) {
|
|
console.log(err);
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const dialogclose = () => {
|
|
setDialogopen(false);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
{loading && <Loader />}
|
|
|
|
<Grid container rowSpacing={2} columnSpacing={2.75}>
|
|
<Grid
|
|
item
|
|
xs={12}
|
|
// sx={{ mb: -2.25 }}
|
|
>
|
|
<Stack
|
|
direction={{ xs: 'column', sm: 'row' }}
|
|
justifyContent="space-between"
|
|
alignItems={{ xs: 'stretch', sm: 'center' }}
|
|
spacing={{ xs: 1.5, sm: 0 }}
|
|
>
|
|
<Typography variant="h3">Payment Requests</Typography>
|
|
<Button
|
|
variant="contained"
|
|
fullWidth={isMobile}
|
|
onClick={() => {
|
|
// setDialogopen(true)
|
|
}}
|
|
>
|
|
Create Request
|
|
</Button>
|
|
</Stack>
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<Box sx={{ overflow: 'auto', border: 1, borderColor: 'grey.200', borderRadius: 2, backgroundColor: '#fff', minHeight: 400 }}>
|
|
{/* <Box
|
|
sx={{
|
|
p: 1,
|
|
width: '100%'
|
|
}}
|
|
> */}
|
|
|
|
<Stack
|
|
alignItems="center"
|
|
justifyContent="space-between"
|
|
direction="row"
|
|
sx={{
|
|
// borderBottom: 1, borderColor: 'divider',
|
|
p: 2,
|
|
// m:2,
|
|
width: '100%',
|
|
flexWrap: 'wrap',
|
|
gap: 1
|
|
}}
|
|
>
|
|
<Tabs value={tabvalue} onChange={handleChangetab} variant="scrollable" scrollButtons="auto">
|
|
<Tab
|
|
label="Pending"
|
|
icon={<Chip label={clientpending.length} color="primary" variant="light" size="small" />}
|
|
iconPosition="end"
|
|
/>
|
|
<Tab
|
|
label="Paid"
|
|
iconPosition="end"
|
|
// icon={<ListIcon />}
|
|
icon={<Chip label={clientapproved.length} color="primary" variant="light" size="small" />}
|
|
/>
|
|
</Tabs>
|
|
|
|
<FormControl sx={{ width: { xs: '100%', md: 250 } }}>
|
|
<OutlinedInput
|
|
size="small"
|
|
id="header-search"
|
|
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>
|
|
{/* </Box> */}
|
|
<EnhancedTable />
|
|
</Box>
|
|
</Grid>
|
|
</Grid>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Requests;
|