Change Permission & WIP Dashboard Client Portal
This commit is contained in:
0
frontend/client-portal/src/sections/auth/AuthFirebaseSocial.tsx
Executable file → Normal file
0
frontend/client-portal/src/sections/auth/AuthFirebaseSocial.tsx
Executable file → Normal file
0
frontend/client-portal/src/sections/auth/login/LoginEmailForm.tsx
Executable file → Normal file
0
frontend/client-portal/src/sections/auth/login/LoginEmailForm.tsx
Executable file → Normal file
0
frontend/client-portal/src/sections/auth/login/LoginPhoneForm.tsx
Executable file → Normal file
0
frontend/client-portal/src/sections/auth/login/LoginPhoneForm.tsx
Executable file → Normal file
0
frontend/client-portal/src/sections/auth/login/VerifyCodeForm.tsx
Executable file → Normal file
0
frontend/client-portal/src/sections/auth/login/VerifyCodeForm.tsx
Executable file → Normal file
0
frontend/client-portal/src/sections/auth/login/index.ts
Executable file → Normal file
0
frontend/client-portal/src/sections/auth/login/index.ts
Executable file → Normal file
@@ -20,6 +20,21 @@ import DialogClaimSubmitMember from './DialogClaimSubmitMember';
|
||||
|
||||
/* ---------------------------------- types --------------------------------- */
|
||||
|
||||
type DataMember = {
|
||||
id: number;
|
||||
fullName: string;
|
||||
memberId: string;
|
||||
limit: {
|
||||
current: number;
|
||||
total: number;
|
||||
percentage: number;
|
||||
};
|
||||
avatar?: {
|
||||
url?: string;
|
||||
title?: string;
|
||||
};
|
||||
};
|
||||
|
||||
type CardPolicyProps = {
|
||||
data: {
|
||||
limit: {
|
||||
@@ -33,15 +48,19 @@ type CardPolicyProps = {
|
||||
percentage: number;
|
||||
};
|
||||
};
|
||||
// topUpLimit: {
|
||||
// companyName: string;
|
||||
// policyNumber: number;
|
||||
// totalMembers: number;
|
||||
// totalCases: number;
|
||||
// totalPersen: number;
|
||||
// myLimit: number;
|
||||
// totalLimit: number;
|
||||
// };
|
||||
topUpLimit: {
|
||||
companyName: string;
|
||||
policyNumber: number;
|
||||
totalMembers: number;
|
||||
totalCases: number;
|
||||
totalPersen: number;
|
||||
myLimit: {
|
||||
balance: number;
|
||||
total: number;
|
||||
percentage: number;
|
||||
};
|
||||
maxTopUp: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -76,7 +95,9 @@ export default function CardPolicy(props: CardPolicyProps) {
|
||||
const [dialogTitle, setDialogTitle] = useState('');
|
||||
const [isDialog, setIsDialog] = useState('');
|
||||
|
||||
const { limit } = props.data;
|
||||
const { limit, topUpLimit } = props.data;
|
||||
|
||||
console.log(limit);
|
||||
|
||||
const clickHandler = (isDialog: string) => {
|
||||
switch (isDialog) {
|
||||
@@ -163,19 +184,21 @@ export default function CardPolicy(props: CardPolicyProps) {
|
||||
</Stack>
|
||||
</>
|
||||
|
||||
{isDialog === 'submitClaim' && (
|
||||
{/* {isDialog === 'submitClaim' && (
|
||||
<DialogClaimSubmitMember
|
||||
openDialog={openDialog}
|
||||
setOpenDialog={setOpenDialog}
|
||||
title={{ name: dialogTitle }}
|
||||
data={members}
|
||||
/>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
{isDialog === 'topUpLimit' && (
|
||||
<DialogTopUpLimit
|
||||
openDialog={openDialog}
|
||||
setOpenDialog={setOpenDialog}
|
||||
title={{ name: dialogTitle, icon: 'heroicons-solid:cash' }}
|
||||
data={topUpLimit}
|
||||
/>
|
||||
)}
|
||||
</RootBalanceStyle>
|
||||
|
||||
@@ -15,10 +15,8 @@ import { Search as SearchIcon } from '@mui/icons-material';
|
||||
import MuiDialog from '../../components/MuiDialog';
|
||||
import Iconify from '../../components/Iconify';
|
||||
// React
|
||||
import { ReactElement, useContext, useEffect, useRef, useState } from 'react';
|
||||
import { ReactElement, useState } from 'react';
|
||||
import DialogClaimSubmitMemberSubmission from './DialogClaimSubmitMemberSubmission';
|
||||
import axios from '../../utils/axios';
|
||||
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@@ -45,7 +43,7 @@ type MuiDialogProps = {
|
||||
openDialog: boolean;
|
||||
setOpenDialog: Function;
|
||||
content?: ReactElement;
|
||||
// data?: DataContent[];
|
||||
data?: DataContentType[];
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -68,11 +66,9 @@ export default function DialogClaimSubmitMember({
|
||||
title,
|
||||
openDialog,
|
||||
setOpenDialog,
|
||||
data,
|
||||
}: MuiDialogProps) {
|
||||
const { corporateValue } = useContext(UserCurrentCorporateContext);
|
||||
|
||||
/* ---------------------------------- data ---------------------------------- */
|
||||
const [data, setData] = useState([]);
|
||||
const [dataMemberClaim, setDataMemberClaim] = useState<DataContentType>({
|
||||
id: 0,
|
||||
fullName: '',
|
||||
@@ -87,15 +83,10 @@ export default function DialogClaimSubmitMember({
|
||||
|
||||
/* --------------------------------- 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));
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@@ -127,18 +118,6 @@ export default function DialogClaimSubmitMember({
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (openDialog === true) {
|
||||
const response = await axios.get(`${corporateValue}/members`, {
|
||||
params: { ...appliedParams, claimMember: true },
|
||||
});
|
||||
|
||||
setData(response.data.data);
|
||||
}
|
||||
})();
|
||||
}, [corporateValue, openDialog, appliedParams]);
|
||||
|
||||
const getContent = () => (
|
||||
<Stack>
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center" paddingY={1}>
|
||||
@@ -167,56 +146,57 @@ export default function DialogClaimSubmitMember({
|
||||
/>
|
||||
</form>
|
||||
<Stack marginTop={2} spacing={1}>
|
||||
{data.map((row: DataContentType, key) => (
|
||||
<Card key={key} sx={{ paddingY: 1, paddingX: 2 }}>
|
||||
<Stack direction="row" alignItems="center" spacing={2}>
|
||||
<img
|
||||
width={40}
|
||||
height={40}
|
||||
src={row.avatar ? row.avatar.url : '/images/member.png'}
|
||||
alt={row.avatar ? row.avatar.url : 'user-profile'}
|
||||
style={{ borderRadius: '50%' }}
|
||||
/>
|
||||
<Stack sx={{ flex: '45%' }}>
|
||||
<Typography variant="subtitle1">{row.fullName}</Typography>
|
||||
<Typography color="#637381" variant="body2" sx={{ fontWeight: 500 }}>
|
||||
Member ID : {row.memberId}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack spacing={1} paddingY={1}>
|
||||
<Typography color="#0A0A0A" variant="caption">
|
||||
Total Limit
|
||||
</Typography>
|
||||
<BorderLinearProgress
|
||||
variant="determinate"
|
||||
value={row.limit && row.limit.percentage}
|
||||
{data &&
|
||||
data.map((row: DataContentType, key) => (
|
||||
<Card key={key} sx={{ paddingY: 1, paddingX: 2 }}>
|
||||
<Stack direction="row" alignItems="center" spacing={2}>
|
||||
<img
|
||||
width={40}
|
||||
height={40}
|
||||
src={row.avatar ? row.avatar.url : '/images/member.png'}
|
||||
alt={row.avatar ? row.avatar.url : 'user-profile'}
|
||||
style={{ borderRadius: '50%' }}
|
||||
/>
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
||||
{row.limit && row.limit.current} /{' '}
|
||||
<Typography variant="body2" color="#757575" component="span">
|
||||
{row.limit && row.limit.total}
|
||||
<Stack sx={{ flex: '45%' }}>
|
||||
<Typography variant="subtitle1">{row.fullName}</Typography>
|
||||
<Typography color="#637381" variant="body2" sx={{ fontWeight: 500 }}>
|
||||
Member ID : {row.memberId}
|
||||
</Typography>
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack spacing={1} paddingY={1}>
|
||||
<Typography color="#0A0A0A" variant="caption">
|
||||
Total Limit
|
||||
</Typography>
|
||||
<BorderLinearProgress
|
||||
variant="determinate"
|
||||
value={row.limit && row.limit.percentage}
|
||||
/>
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 500 }}>
|
||||
{row.limit && row.limit.current} /{' '}
|
||||
<Typography variant="body2" color="#757575" component="span">
|
||||
{row.limit && row.limit.total}
|
||||
</Typography>
|
||||
</Typography>
|
||||
</Stack>
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
clickHandler({
|
||||
id: row.id,
|
||||
fullName: row.fullName,
|
||||
memberId: row.memberId,
|
||||
limit: {
|
||||
current: row.limit.current,
|
||||
total: row.limit.total,
|
||||
percentage: row.limit.percentage,
|
||||
},
|
||||
})
|
||||
}
|
||||
>
|
||||
<Iconify icon="ic:round-chevron-right" />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
clickHandler({
|
||||
id: row.id,
|
||||
fullName: row.fullName,
|
||||
memberId: row.memberId,
|
||||
limit: {
|
||||
current: row.limit.current,
|
||||
total: row.limit.total,
|
||||
percentage: row.limit.percentage,
|
||||
},
|
||||
})
|
||||
}
|
||||
>
|
||||
<Iconify icon="ic:round-chevron-right" />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
</Card>
|
||||
))}
|
||||
</Card>
|
||||
))}
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -20,6 +20,7 @@ import * as Yup from 'yup';
|
||||
// form
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import axios from '../../utils/axios';
|
||||
|
||||
/* ---------------------------------- types --------------------------------- */
|
||||
type MuiDialogProps = {
|
||||
@@ -30,15 +31,21 @@ type MuiDialogProps = {
|
||||
openDialog: boolean;
|
||||
setOpenDialog: Function;
|
||||
content?: ReactElement;
|
||||
data?: {
|
||||
companyName: string;
|
||||
policyNumber: number;
|
||||
totalMembers: number;
|
||||
totalCases: number;
|
||||
totalPersen: number;
|
||||
myLimit: number;
|
||||
totalLimit: number;
|
||||
data?: DataProps;
|
||||
};
|
||||
|
||||
type DataProps = {
|
||||
companyName: string;
|
||||
policyNumber: number;
|
||||
totalMembers: number;
|
||||
totalCases: number;
|
||||
totalPersen: number;
|
||||
myLimit: {
|
||||
balance: number;
|
||||
total: number;
|
||||
percentage: number;
|
||||
};
|
||||
maxTopUp: number;
|
||||
};
|
||||
|
||||
type FormValuesProps = {
|
||||
@@ -46,16 +53,6 @@ type FormValuesProps = {
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
// const testData = {
|
||||
// companyName: 'PT. Aman Mineral',
|
||||
// policyNumber: 12345678,
|
||||
// totalMembers: 50,
|
||||
// totalCases: 100,
|
||||
// totalPersen: 75,
|
||||
// myLimit: 375000000,
|
||||
// totalLimit: 500000000,
|
||||
// };
|
||||
|
||||
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
|
||||
height: 10,
|
||||
borderRadius: 6,
|
||||
@@ -76,14 +73,15 @@ export default function DialogTopUpLimit({
|
||||
setOpenDialog,
|
||||
data,
|
||||
}: MuiDialogProps) {
|
||||
const [isDisabledCheckbox, setIsDisabledCheckbox] = useState(false);
|
||||
const [isDisabledInput, setIsDisabledInput] = useState(false);
|
||||
const [isDisabledButton, setIsDisabledButton] = useState(true);
|
||||
const [isCheckboxChecked, setIsCheckboxChecked] = useState(false);
|
||||
|
||||
const TopUpSchema = Yup.object().shape({
|
||||
topup: Yup.number(),
|
||||
/*
|
||||
// @ts-ignore */
|
||||
// .test('limit', 'Maximum Top Up Rp. 5.000.000', (val) => (val > 5000000 ? false : true)),
|
||||
topup: Yup.number().max(
|
||||
data?.maxTopUp,
|
||||
`Maximum top-up amount is ${fCurrency(data?.maxTopUp)}`
|
||||
),
|
||||
});
|
||||
|
||||
const defaultValues = {
|
||||
@@ -100,29 +98,52 @@ export default function DialogTopUpLimit({
|
||||
setValue,
|
||||
reset,
|
||||
handleSubmit,
|
||||
formState: { isSubmitting },
|
||||
formState: { errors, isSubmitting },
|
||||
} = methods;
|
||||
|
||||
useEffect(() => {
|
||||
if (openDialog === false) {
|
||||
setIsDisabledInput(false);
|
||||
setIsDisabledButton(true);
|
||||
setIsCheckboxChecked(false);
|
||||
|
||||
reset();
|
||||
}
|
||||
}, [openDialog, reset]);
|
||||
|
||||
const onSubmit = async (data: FormValuesProps) => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
|
||||
setIsDisabledInput(false);
|
||||
setIsDisabledButton(true);
|
||||
setIsCheckboxChecked(false);
|
||||
|
||||
// await axios.post('');
|
||||
|
||||
reset();
|
||||
};
|
||||
|
||||
const onCheckHandler = (data: FormValuesProps) => {
|
||||
setIsDisabledCheckbox(!isDisabledCheckbox);
|
||||
setIsDisabledButton(false);
|
||||
const onCheckHandler = (value: string) => {
|
||||
setIsDisabledInput(!isDisabledInput);
|
||||
value === '0' || value === '' ? setIsDisabledButton(true) : setIsDisabledButton(false);
|
||||
setIsCheckboxChecked(!isCheckboxChecked);
|
||||
// @ts-ignore
|
||||
setValue('topup', testData.totalLimit - testData.myLimit);
|
||||
setValue('topup', data.maxTopUp);
|
||||
};
|
||||
|
||||
const onTopupHandler = (value: string) => {
|
||||
value === '0' || value === '' ? setIsDisabledButton(true) : setIsDisabledButton(false);
|
||||
setValue('topup', value);
|
||||
console.log(!!errors);
|
||||
|
||||
let newValue;
|
||||
|
||||
if (value.startsWith('0')) {
|
||||
newValue = '0';
|
||||
} else {
|
||||
newValue = value;
|
||||
}
|
||||
|
||||
newValue === '0' || newValue === '' ? setIsDisabledButton(true) : setIsDisabledButton(false);
|
||||
setValue('topup', newValue);
|
||||
};
|
||||
|
||||
const getContent = () => (
|
||||
@@ -157,16 +178,16 @@ export default function DialogTopUpLimit({
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||
<Stack>
|
||||
<Typography variant="body2">Company Pooled Fund</Typography>
|
||||
<Typography variant="body2">{fCurrency(data ? data.myLimit : 0)}</Typography>
|
||||
<Typography variant="body2">{fCurrency(data ? data.myLimit.balance : 0)}</Typography>
|
||||
<Typography variant="caption" color="#919EAB">
|
||||
/ {data ? data.totalLimit : 0}
|
||||
/ {data ? data.myLimit.total : 0}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<Typography variant="h5">{data ? data.totalPersen : 0}%</Typography>
|
||||
<Typography variant="h5">{data ? data.myLimit.percentage : 0}%</Typography>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<BorderLinearProgress variant="determinate" value={data ? data.totalPersen : 0} />
|
||||
<BorderLinearProgress variant="determinate" value={data ? data.myLimit.percentage : 0} />
|
||||
</Stack>
|
||||
<Stack spacing={2}>
|
||||
<Typography variant="subtitle1" marginTop={3}>
|
||||
@@ -177,14 +198,21 @@ export default function DialogTopUpLimit({
|
||||
name="topup"
|
||||
label="Top Up"
|
||||
type="number"
|
||||
disabled={isDisabledCheckbox}
|
||||
disabled={isDisabledInput}
|
||||
onChange={(e) => onTopupHandler(e.target.value)}
|
||||
error={!!errors.topup}
|
||||
helperText={errors.topup?.message}
|
||||
/>
|
||||
<FormControlLabel
|
||||
name="checkboxTopUp"
|
||||
sx={{ typography: 'caption' }}
|
||||
control={<Checkbox />}
|
||||
label={'Max ' + fCurrency((data ? data.totalLimit : 0) - (data ? data.myLimit : 0))}
|
||||
onChange={handleSubmit(onCheckHandler)}
|
||||
control={
|
||||
<Checkbox
|
||||
checked={isCheckboxChecked}
|
||||
onChange={(e) => onCheckHandler(e.target.value)}
|
||||
/>
|
||||
}
|
||||
label={'Max ' + fCurrency(data ? data.maxTopUp : 0)}
|
||||
/>
|
||||
|
||||
<LoadingButton
|
||||
|
||||
Reference in New Issue
Block a user