Untitled
unknown
javascript
a year ago
22 kB
8
Indexable
import { Box, Button, Card, CardContent, Divider, Paper, Stack, Step, StepLabel, Stepper, Typography, } from '@mui/material'; // utils import { enqueueSnackbar } from 'notistack'; import { useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useBoolean } from 'src/hooks/use-boolean'; import { getUserBank, getUserFinance } from 'src/redux/slices/user'; // import { useLocales } from 'src/locales'; import { lang } from 'src/locales/multiLang'; // @component import { Cancel, CheckCircle, HourglassEmpty } from '@mui/icons-material'; import { Timeline, TimelineConnector, TimelineContent, TimelineDot, TimelineItem, TimelineSeparator, } from '@mui/lab'; import axios from 'axios'; import Iconify from 'src/components/iconify'; import LoadingSpinner from 'src/components/loading-screen/loading-spinner'; import axiosInstance, { API_ENDPOINTS } from 'src/utils/axios'; import { fWords } from 'src/utils/format-string'; import { fDateTime } from 'src/utils/format-time'; import useCBToken from 'src/utils/useCBToken'; import BusinessInformation from './finance-profile-request/BusinessInformation'; import UploadCNIC from './finance-profile-request/UploadCNIC'; import TrustBox from './trust-box'; import { CREDITBOOK_URL } from 'src/config-global'; export default function AdvanceKYC() { // const { t } = useLocales(); const creditBookToken = useCBToken(); const dispatch = useDispatch(); const { auth: { userData, userAttachments }, user: { documents, userFinance }, } = useSelector((state) => state); // get kyc const [kycStatus, setKycStatus] = useState(fWords('not_applied')); const [kycStatusesList, setKycStatusesList] = useState([]); const handleRequestKYC = async () => { loading.onTrue(); if (userFinance.lendingPartner === 'CreditBook') { await handleCreditBookKYC(); } else { loading.onFalse(); enqueueSnackbar('KYC Patner isnot assigned yet', { variant: 'error' }); } }; // handle credit-book kyc const handleCreditBookKYC = async () => { await dispatch(getUserBank()); // ------------------ const tempData = [ { resourceURL: `${userAttachments.url}${userAttachments.token}`, name: 'tetsing', }, ]; // Define the data to be sent in the POST request const partnerCnic = documents .filter((doc) => doc.docType === 'Partner CNIC') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const partnershipDeed = documents .filter((doc) => doc.docType === 'Partnership Deed') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const incorporationCertificate = documents .filter((doc) => doc.docType === 'Incorporation Certificate') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const authorityLetter = documents .filter((doc) => doc.docType === 'Authority Letter') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const directorsResolution = documents .filter((doc) => doc.docType === "Director's Resolution") .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const memorandumArticlesAssociation = documents .filter((doc) => doc.docType === 'Memorandum Articles Association') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const boardMemberCnic = documents .filter((doc) => doc.docType === 'Board Member CNIC') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const pocCnic = documents .filter((doc) => doc.docType === 'POC CNIC') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const beneficialOwnerCnic = documents .filter((doc) => doc.docType === 'Beneficial Owner CNIC') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const cnicFront = documents .filter((doc) => doc.docType === 'CNIC_FRONT') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const cnicBack = documents .filter((doc) => doc.docType === 'CNIC_BACK') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const proprietorshipDeclaration = documents .filter((doc) => doc.docType === 'Proprietorship Declaration') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const ntnCertificate = documents .filter((doc) => doc.docType === 'ntn Certificate') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const bankStatement = documents .filter((doc) => doc.docType === 'Bank Statement (6 Months)') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const pastPurchaseOrders = documents .filter((doc) => doc.docType === 'Past Purchase Orders') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const pastInvoices = documents .filter((doc) => doc.docType === 'Past Invoices') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const otherFiles = documents .filter((doc) => doc.docType === 'Other Files') .map((item) => ({ resourceURL: `${userAttachments.url}${item.path}${userAttachments.token}`, name: item.title, })); const postData = { partnerCnic: partnerCnic.length > 0 ? partnerCnic : tempData, partnershipDeed: partnershipDeed.length > 0 ? partnershipDeed : tempData, incorporationCertificate: incorporationCertificate.length > 0 ? incorporationCertificate : tempData, authorityLetter: authorityLetter.length > 0 ? authorityLetter : tempData, directorsResolution: directorsResolution.length > 0 ? directorsResolution : tempData, memorandumArticlesAssociation: memorandumArticlesAssociation.length > 0 ? memorandumArticlesAssociation : tempData, boardMemberCnic: boardMemberCnic.length > 0 ? boardMemberCnic : tempData, pocCnic: pocCnic.length > 0 ? pocCnic : tempData, beneficialOwnerCnic: beneficialOwnerCnic.length > 0 ? beneficialOwnerCnic : tempData, cnicFront: cnicFront.length > 0 ? cnicFront : tempData, cnicBack: cnicBack.length > 0 ? cnicBack : tempData, proprietorshipDeclaration: proprietorshipDeclaration.length > 0 ? proprietorshipDeclaration : tempData, ntnCertificate: ntnCertificate.length > 0 ? ntnCertificate : tempData, bankStatement: bankStatement.length > 0 ? bankStatement : tempData, pastPurchaseOrders: pastPurchaseOrders.length > 0 ? pastPurchaseOrders : tempData, pastInvoices: pastInvoices.length > 0 ? pastInvoices : tempData, otherFiles: otherFiles.length > 0 ? otherFiles : tempData, email: userData.email, fullName: userData.name, contactNumber: userData.mobileNumber, businessName: userFinance.businessName, // businessType: 'partnership', businessType: userFinance.businessType.toLowerCase(), businessAddress: userFinance.businessAddress, ntn: userFinance.ntn, }; let response = ''; try { if (kycStatus.toLowerCase() === 'need more info') { response = await axios.patch( `${CREDITBOOK_URL}/api/v1/external-lending/sme/users`, postData, { headers: { accept: 'application/json', Authorization: `Bearer ${creditBookToken}`, 'Content-Type': 'application/json', }, } ); } else { response = await axios.post( `${CREDITBOOK_URL}/api/v1/external-lending/sme/users`, postData, { headers: { accept: 'application/json', Authorization: `Bearer ${creditBookToken}`, 'Content-Type': 'application/json', }, } ); } // save all RAW responce on DB await axiosInstance.post(`${API_ENDPOINTS.finance.add_LP_Raw_Responce}`, { lendingPartner: 'CreditBook', vendorId: userData.userId, ...response.data, }); await axiosInstance.post(`${API_ENDPOINTS.finance.partner_webhook}`, { lendingPartner: 'CreditBook', email: userData.email, event_data: { status: 'pending', reason: 'Update by User', comment: '', user_id: response?.data?.user?.id, }, }); loading.onFalse(); setActiveStep(1); debugger; setKycStatus(fWords('pending')); setKycStatusesList(response?.data?.kyb?.statuses); enqueueSnackbar('Request submitted successfully!'); } catch (error) { loading.onFalse(); enqueueSnackbar(error.response.data.message.toString(), { variant: 'error' }); } }; const getKYCReport = async () => { try { const response = await axiosInstance.post( `${API_ENDPOINTS.finance.get_kyc_logs} `, { userId: userData.userId, } ); // console.log('🚀 ~ getKYCReport ~ response:', response); // setKycStatus(userFinance?.advanceKyc[0]?.event_data?.status || 'Pending'); setKycStatus(fWords(userFinance?.advanceKyc[0]?.event_data?.status || 'not_applied')); setKycStatusesList(response); if (userFinance?.advanceKyc[0]?.event_data?.status) { setActiveStep(1); } if (userFinance?.advanceKyc[0]?.event_data?.contract_url) { setActiveStep(2); } if (userFinance.contractUrlSigned) { setActiveStep(3); } } catch (error) { console.log('🚀 ~ getKYCReport ~ error:', error); } // try { // const response = await axios.get( // `https://stage.creditbookapi.com/api/v1/external-lending/sme/users?email=${encodeURIComponent( // userData.email // )}`, // { // headers: { // accept: 'application/json', // Authorization: `Bearer ${creditBookToken}`, // }, // } // ); // setKycStatus(camelToSentenceCase(response?.data?.kyb?.status)); // setKycStatusesList(response?.data?.kyb?.statuses); // if (response?.data?.kyb?.status) { // setActiveStep(1); // } // } catch (error) { // console.log('🚀 ~ getKYCReport ~ error:', error); // } }; // ----------------------------------------------- const getDetails = async () => { loading.onTrue(); try { await dispatch(getUserBank()); } catch (error) { console.log('🚀 ~ getDetails ~ error:', error); } try { await dispatch(getUserFinance(userData?.userId)); } catch (error) { loading.onFalse(); } loading.onFalse(); }; useEffect(() => { getDetails(); }, []); // ------------ useEffect(() => { if (userFinance?.advanceKyc) { getKYCReport(); } }, [userFinance?.advanceKyc]); // const [activeStep, setActiveStep] = useState(0); const completed = useBoolean(); const loading = useBoolean(); const submitting = useBoolean(); const [userInfo, setUserInfo] = useState({ cnicFrontImage: '', cnicBackImage: '', fullName: '', fatherName: '', DateOfBirth: '', homeAddress: '', cnicNumber: '', frontRecognition: false, backRecognition: false, }); const steps = [ t(`${lang.financing}.review`), kycStatus, t(`${lang.financing}.econtrcat`), t(`${lang.financing}.complete`), ]; // * useEffect(() => { if (userFinance?.applied || userFinance?.cnicFrontImage) { completed.onTrue(); } }, [userFinance?.applied]); // action is passing to components const action = <Box display="flex" justifyContent="flex-end" sx={{ p: 1.5 }}></Box>; const buttonContent = () => { if ( kycStatus.toLowerCase() === 'pending' || kycStatus.toLowerCase() === 'approved' || kycStatus.toLowerCase() === 'rejected' ) { return <TimelineComponent statuses={kycStatusesList} />; } if (kycStatus.toLowerCase() === 'need more info') { return ( <Button color="primary" variant="contained" onClick={handleRequestKYC} startIcon={<Iconify icon="formkit:submit" />} > Re-Submit Request </Button> ); } return ( <Button color="primary" variant="contained" onClick={handleRequestKYC} startIcon={<Iconify icon="formkit:submit" />} > Submit Request </Button> ); }; function reviewInfo(step) { switch (step) { case 0: return { type: 'UploadCNIC', component: ( <UploadCNIC userInfo={userInfo} userFinance={userFinance} setUserInfo={setUserInfo} completed={completed} /> ), }; case 1: return { type: 'BusinessInformation', component: ( <BusinessInformation action={action} kycStatus={kycStatus} completed={completed} userFinance={userFinance} submitting={submitting} /> ), }; case 2: return { type: 'request', component: <Box sx={{ p: 4, textAlign: 'center' }}>{buttonContent()}</Box>, }; default: return { type: 'Unknown', component: 'Unknown step', }; } } function signContract(step) { switch (step) { case 2: return { type: 'Signed', component: ( <Card sx={{ p: 4, }} > <CardContent> <Typography variant="h5" component="div"> Contract Information </Typography> <Typography variant="body2" color="text.secondary" sx={{ mt: 4, }} > URL: {userFinance?.advanceKyc[0]?.event_data?.contract_url} </Typography> <Button sx={{ mt: 4, }} variant="contained" color="primary" href={userFinance?.advanceKyc[0]?.event_data?.contract_url} onClick={async () => { await axiosInstance.post( `${API_ENDPOINTS.finance.signContract} `, { _id: userData.userId, } ); }} target="_blank" > Sign Contract </Button> </CardContent> </Card> ), }; case 3: return { type: 'request', component: ( <Box sx={{ p: 4, textAlign: 'center' }}> {Array.from({ length: 3 }).map((_, index) => ( <Paper key={index} elevation={3} sx={{ p: 3, my: 3, minHeight: 120, // bgcolor: (theme) => alpha(theme.palette.grey[500]), }} > <Typography sx={{ my: 1 }}>{reviewInfo(index).component}</Typography> </Paper> ))} </Box> ), }; default: return { type: 'Unknown', component: 'Unknown step', }; } } return ( <div> {loading.value && <LoadingSpinner />} <Stack sx={{ my: 2 }}> <Stepper activeStep={activeStep} alternativeLabel> {steps.map((label, index) => { return ( <Step key={label}> <StepLabel>{index === 0 ? 'Review Information' : label}</StepLabel> </Step> ); })} </Stepper> <Divider sx={{ my: 2 }} /> </Stack> <Stack sx={{ my: 2 }}> {kycStatus.toLowerCase() === 'need more info' && ( <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', p: 2, border: 1, borderRadius: 1, borderColor: 'grey.500', textAlign: 'center', fontSize: 14, mb: 3, }} > <span style={{ fontWeight: 'bolder' }}> Correction Required Remarks:</span> Please Upload your Patner CNIC </Box> )} {/* */} <TrustBox /> </Stack> <Stack sx={{ my: 2 }}> {activeStep === steps.length ? ( <Paper elevation={3} sx={{ p: 3, my: 3, minHeight: 150, // bgcolor: (theme) => alpha(theme.palette.grey[500], 0.12), display: 'flex', alignItems: 'center', // Vertical alignment justifyContent: 'center', // Horizontal alignment }} > <Typography sx={{ my: 1 }}>{t(`${lang.financing}.profileSubmitted`)}</Typography> </Paper> ) : ( <> {activeStep === 2 ? signContract(activeStep).component : Array.from({ length: 3 }).map((_, index) => ( <Paper key={index} elevation={3} sx={{ p: 3, my: 3, minHeight: 120, // bgcolor: (theme) => alpha(theme.palette.grey[500]), }} > <Typography sx={{ my: 1 }}>{reviewInfo(index).component}</Typography> </Paper> ))} {/* <Box sx={{ display: 'flex' }}> <Button variant="outlined" color="inherit" disabled={activeStep === 0} onClick={async () => { setActiveStep((active) => active - 1); }} sx={{ mr: 1 }} > {t(`${lang.financing}.back`)} </Button> <Box sx={{ flexGrow: 1 }} /> </Box> */} </> )} </Stack> </div> ); } const TimelineComponent = ({ statuses }) => { return ( <> <Typography variant="h5" color="primary"> Request Tracking </Typography> <Timeline position="alternate"> {statuses .toReversed() .map((status, index) => ( <TimelineItem key={index}> <TimelineSeparator> <TimelineDot color={ (status.status === 'approved' && 'success') || (status.status === 'pending' && 'warning') || (status.status === 'rejected' && 'error') || 'info' } > {(status.status === 'approved' && <CheckCircle />) || (status.status === 'pending' && <HourglassEmpty />) || (status.status === 'rejected' && <Cancel />) || <HourglassEmpty />} </TimelineDot> {index < statuses.length - 1 && <TimelineConnector />} </TimelineSeparator> <TimelineContent> <Typography variant="h6" color="textPrimary"> {fWords(status?.status || 'pending')} </Typography> <Typography color="textSecondary"> {status?.Date ? fDateTime(status.Date) : fDateTime(status.timestamp)} </Typography> {/* <Typography color="textSecondary">{status.updated_by}</Typography> */} {status?.requestBodyObj?.event_data?.reason && ( <Typography color="textSecondary"> Reason: {status?.requestBodyObj?.event_data?.reason || ''} </Typography> )} </TimelineContent> </TimelineItem> ))} </Timeline> </> ); };
Editor is loading...
Leave a Comment