Files
aso/frontend/client-portal/src/sections/claim-submit/DialogClaimSubmitMember.tsx
2023-10-09 17:25:16 +07:00

307 lines
9.4 KiB
TypeScript

// @mui
import { styled } from '@mui/material/styles';
import {
Typography,
LinearProgress,
linearProgressClasses,
Stack,
TextField,
InputAdornment,
Card,
Grid,
IconButton,
FormControlLabel,
Checkbox,
} from '@mui/material';
import { Search as SearchIcon } from '@mui/icons-material';
// components
import MuiDialog from '../../components/MuiDialog';
import Iconify from '../../components/Iconify';
import HistoryRoundedIcon from '@mui/icons-material/HistoryRounded';
// React
import { ReactElement, useContext, useEffect, useState } from 'react';
import DialogRequestLog from './DialogRequestLog';
import axios from '../../utils/axios';
import { useSearchParams, useNavigate, Link } from 'react-router-dom';
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
import { fSplit } from '../../utils/formatNumber';
import { LoadingButton } from '@mui/lab';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from '../../store';
import { claimSubmitAction, claimSubmitType } from '../../store/claimSubmit';
// ----------------------------------------------------------------------
type DataContentType = {
id: number;
fullName: string;
memberId: string;
limit: {
current: number;
total: number;
percentage: number;
};
avatar?: {
url?: string;
title?: string;
};
};
type MuiDialogProps = {
title?: {
name?: string;
icon?: string;
};
openDialog: boolean;
setOpenDialog: Function;
content?: ReactElement;
// data?: DataContent[];
};
// ----------------------------------------------------------------------
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
height: 10,
borderRadius: 6,
[`&.${linearProgressClasses.colorPrimary}`]: {
backgroundColor: '#D1F1F1',
},
[`& .${linearProgressClasses.bar}`]: {
borderRadius: 6,
backgroundColor: '#54D62C',
},
}));
// ----------------------------------------------------------------------
export default function DialogClaimSubmitMember({
title,
openDialog,
setOpenDialog,
}: MuiDialogProps) {
const { corporateValue } = useContext(UserCurrentCorporateContext);
/* ---------------------------------- data ---------------------------------- */
const [data, setData] = useState([]);
const dispatch = useDispatch();
const selectedData = useSelector((state: RootState) => state.claims.data);
const [dataMemberClaim, setDataMemberClaim] = useState<DataContentType>({
id: 0,
fullName: '',
memberId: '',
limit: {
current: 0,
total: 0,
percentage: 0,
},
});
const navigate = useNavigate();
/* -------------------------------------------------------------------------- */
/* --------------------------------- Search --------------------------------- */
const [searchText, setSearchText] = useState('');
const [appliedParams, setAppliedParams] = useState({});
const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (searchText === '') {
setAppliedParams({});
} else {
setAppliedParams({ search: searchText });
}
await new Promise((resolve) => setTimeout(resolve, 500));
};
/* -------------------------------------------------------------------------- */
/* ------------------------------ Icon On Click ----------------------------- */
const clickHandler = ({ id, fullName, memberId, limit, avatar }: DataContentType) => {
setDataMemberClaim({
id: id,
fullName: fullName,
memberId: memberId,
limit: {
current: limit.current,
total: limit.total,
percentage: limit.percentage,
},
avatar: {
url: avatar && avatar.url,
title: avatar && avatar.title,
},
});
};
const handleCheck = (data: DataContentType, isChecked: boolean) => {
if (isChecked) {
dispatch(claimSubmitAction.patch([...selectedData, data]));
} else {
let temp = selectedData.filter((row) => row.memberId !== data.memberId);
dispatch(claimSubmitAction.patch(temp));
}
};
/* -------------------------------------------------------------------------- */
useEffect(() => {
(async () => {
if (openDialog === true) {
const response = await axios.get(`${corporateValue}/members`, {
params: { ...appliedParams, type: 'claim-submit' },
});
setData(response.data.data);
}
})();
}, [corporateValue, openDialog, appliedParams]);
useEffect(() => {
dispatch(claimSubmitAction.dispatch());
}, [dispatch]);
const getContent = () => (
<Stack>
<Stack marginTop={2} spacing={1}>
{data.map((row: DataContentType, key) => (
<Card
key={key}
sx={{ paddingY: 1, paddingX: 2 }}
// onClick={() =>
// clickHandler({
// id: row.id,
// fullName: row.fullName,
// memberId: row.memberId,
// limit: {
// current: row.limit.current,
// total: row.limit.total,
// percentage: row.limit.percentage,
// },
// })
// }
>
<Stack direction="row" alignItems="center">
<Grid item xs={1} lg={1} xl={1}>
<form>
<FormControlLabel
value="end"
control={<Checkbox onChange={(e) => handleCheck(row, e.target.checked)} />}
label=""
labelPlacement="end"
sx={{ marginLeft: '20px' }}
/>
</form>
</Grid>
<div
style={{
position: 'relative',
flex: 'none',
height: 'fit-content',
margin: '15px',
}}
>
<img
width={52}
height={52}
src="/images/user-profile.png"
alt="user-profile"
style={{ borderRadius: '50%' }}
/>
</div>
<Grid item xs={7} lg={7} xl={7}>
<Typography variant="subtitle1">{row.fullName}</Typography>
<Typography color="#637381" variant="body2" sx={{ fontWeight: 500 }}>
{row.memberId}
</Typography>
</Grid>
<Grid item xs={3} lg={3} xl={3}>
<BorderLinearProgress
variant="determinate"
value={row.limit && row.limit.percentage}
// color='success'
sx={{ mb: 1 }}
/>
<Stack direction={'row'}>
<Grid item xs={3}>
<Typography variant="overline" sx={{ textAlign: 'left' }}>
LIMIT
</Typography>
</Grid>
<Grid item xs={7} sx={{ display: 'flex', justifyContent: 'flex-end' }}>
<Stack direction={'row'}>
<Typography variant="overline">
{fSplit(row.limit && row.limit.current)}
</Typography>
<Typography variant="overline">
/ {fSplit(row.limit && row.limit.total)}
</Typography>
</Stack>
</Grid>
</Stack>
</Grid>
<Grid
item
xs={2}
lg={2}
xl={2}
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}
>
<IconButton>
<Iconify icon="ic:history" />
</IconButton>
<IconButton
disabled={selectedData.length > 0}
sx={{ marginLeft: '10px' }}
onClick={() => {
dispatch(claimSubmitAction.patch([row]));
navigate(`/claim-request/${row.id}`);
}}
>
<Iconify icon="ic:round-chevron-right" />
</IconButton>
</Grid>
</Stack>
</Card>
))}
</Stack>
</Stack>
);
return (
<Grid container>
<Grid item xs={12} paddingX="10px" paddingY="20px">
<form onSubmit={handleSearchSubmit}>
<TextField
id="search-input"
variant="outlined"
fullWidth
onChange={(event) => setSearchText(event?.target.value)}
value={searchText}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
placeholder="Search Name or Member ID... "
sx={{ marginTop: 2 }}
/>
</form>
{getContent()}
</Grid>
<Grid item xs={12}>
<LoadingButton
variant="contained"
// sx={{ marginTop: 2, p: 2, margin: '10px', color: '#212B36', backgroundColor: '#DFE3E8' }}
sx={{ marginTop: 2, p: 2, margin: '10px' }}
fullWidth
disabled={selectedData.length === 0}
onClick={() => navigate('/claim-request/bulk')}
>
Claim Submit Selected
</LoadingButton>
</Grid>
</Grid>
);
}