diff options
Diffstat (limited to 'client/src')
15 files changed, 272 insertions, 174 deletions
diff --git a/client/src/components/BackButton/BackButton.jsx b/client/src/components/BackButton/BackButton.jsx index c02681b..ff99eb6 100644 --- a/client/src/components/BackButton/BackButton.jsx +++ b/client/src/components/BackButton/BackButton.jsx @@ -12,7 +12,7 @@ const BackButton = ({ onClick, onChange }) => { > <img className={styles.submit__image} - src={`${process.env.PUBLIC_URL}/assets/images/next_icon.svg`} + src={`${process.env.PUBLIC_URL}/assets/images/back.svg`} alt="" /> </button> diff --git a/client/src/components/Card/CardAgreement.module.css b/client/src/components/Card/CardAgreement.module.css index ed36cba..c9bdae8 100644 --- a/client/src/components/Card/CardAgreement.module.css +++ b/client/src/components/Card/CardAgreement.module.css @@ -1,8 +1,8 @@ @import '../../styles/GlobalVariables.css'; .card { - height: 400px; - width: 900px; + height: 300px; + width: 600px; display: flex; flex-direction: column; justify-content: center; @@ -10,6 +10,7 @@ border: 3px solid var(--color-black); border-radius: 10px; margin: 30px; + padding: 20px; transition: 0.2s all; cursor: pointer; color: var(--color-black); @@ -27,4 +28,4 @@ .card__image { padding-bottom: 32px; -}
\ No newline at end of file +} diff --git a/client/src/components/LanguageSelect/locales/en/translation.json b/client/src/components/LanguageSelect/locales/en/translation.json index 8603116..254b3db 100644 --- a/client/src/components/LanguageSelect/locales/en/translation.json +++ b/client/src/components/LanguageSelect/locales/en/translation.json @@ -55,6 +55,7 @@ "PLEASE_VERIFY_YOUR_IDENTITY": "Please verify your identity by receiving the OTP on your registered mobile number xxxxxxxx15", "SEND_OTP": "Send OTP", "RESEND": "Resend", + "VERIFY_OTP": "Verify OTP", "PLEASE_SELECT_YOUR_RESIDENCY": "Please select your residency", "PLEASE_ENTER_YOUR_NAME": "Please enter your name", "PLEASE_ENTER_VALID_NAME": "Please enter valid name", diff --git a/client/src/components/LanguageSelect/locales/hi/translation.json b/client/src/components/LanguageSelect/locales/hi/translation.json index 3c9db8a..a5ce358 100644 --- a/client/src/components/LanguageSelect/locales/hi/translation.json +++ b/client/src/components/LanguageSelect/locales/hi/translation.json @@ -55,6 +55,7 @@ "PLEASE_VERIFY_YOUR_IDENTITY": "कृपया अपने पंजीकृत मोबाइल नंबर xxxxxxxx15 पर ओटीपी प्राप्त करके अपनी पहचान सत्यापित करें", "SEND_OTP": "ओटीपी भेजें", "RESEND": "फिर से भेजें", + "VERIFY_OTP": "ओटीपी की पुष्टि करें", "PLEASE_SELECT_YOUR_RESIDENCY": "कृपया अपना निवास चुनें", "PLEASE_ENTER_VALID_EMAIL": "कृपया मान्य ईमेल दर्ज करें", "PLEASE_SELECT_YOUR_COUNTRY": "कृपया अपना देश चुनें", diff --git a/client/src/components/SubmitButton/SubmitButton.jsx b/client/src/components/SubmitButton/SubmitButton.jsx index bcf3543..ed796d9 100644 --- a/client/src/components/SubmitButton/SubmitButton.jsx +++ b/client/src/components/SubmitButton/SubmitButton.jsx @@ -1,10 +1,16 @@ import React from 'react' import styles from './SubmitButton.module.css' -const SubmitButton = ({ onClick, onChange }) => { +const SubmitButton = ({ onClick, onChange, disabled }) => { return ( <> - <button onClick={onClick} className={styles.submit} type="submit" onChange={onChange}> + <button + onClick={onClick} + className={styles.submit} + type="submit" + onChange={onChange} + disabled={disabled} + > <img className={styles.submit__image} src={`${process.env.PUBLIC_URL}/assets/images/next_icon.svg`} diff --git a/client/src/constants/userData.js b/client/src/constants/userData.js new file mode 100644 index 0000000..f929e39 --- /dev/null +++ b/client/src/constants/userData.js @@ -0,0 +1,25 @@ +export const initialUserData = { + indianResident: '', + name: '', + gender: '', + dob: '', + mobile: '', + email: '', + address: { + houseNo: '', + street: '', + locality: '', + landmark: '', + village: '', + district: '', + state: '', + postOffice: '', + pincode: '' + }, + photo: '', + documents: { + POI: '', + POA: '', + DOB: '' + } +} diff --git a/client/src/context/User.js b/client/src/context/User.js index a3a883e..881d302 100644 --- a/client/src/context/User.js +++ b/client/src/context/User.js @@ -1,59 +1,12 @@ import React, { createContext, useState, useContext } from 'react' +import { initialUserData } from '../constants/userData' export const UserContext = createContext() export const Context = ({ children }) => { const [aadhaarNumber, setAadhaarNumber] = useState(null) - const [userData, setUserData] = useState({ - indianResident: '', - name: '', - gender: '', - dob: new Date().toISOString().slice(0, 10), - mobile: '', - email: '', - address: { - houseNo: '', - street: '', - locality: '', - landmark: '', - village: '', - district: {}, - state: {}, - postOffice: '', - pincode: '' - }, - photo: '', - documents: { - POI: '', - POA: '', - DOB: '' - } - }) - const [oriUserData, setOriUserData] = useState({ - indianResident: '', - name: '', - gender: '', - dob: new Date().toISOString().slice(0, 10), - mobile: '', - email: '', - address: { - houseNo: '', - street: '', - locality: '', - landmark: '', - village: '', - district: {}, - state: {}, - postOffice: '', - pincode: '' - }, - photo: '', - documents: { - POI: '', - POA: '', - DOB: '' - } - }) + const [userData, setUserData] = useState(initialUserData) + const [oriUserData, setOriUserData] = useState(initialUserData) const initialUser = { aadhaarNumber, diff --git a/client/src/pages/Enrollment/Agreement/Agreement.jsx b/client/src/pages/Enrollment/Agreement/Agreement.jsx index d5690f3..cf74d46 100644 --- a/client/src/pages/Enrollment/Agreement/Agreement.jsx +++ b/client/src/pages/Enrollment/Agreement/Agreement.jsx @@ -3,71 +3,103 @@ import Header from '../../../components/Header/Header' import CardAgreement from '../../../components/Card/CardAgreement' import styles from './Agreement.module.css' import Input from '../../../components/Input/Input' -import { Grid, Button } from '@mui/material' +import { Button, Typography } from '@mui/material' import { useTranslation } from 'react-i18next' import { sendOTP } from '../../../services/apiservice' import { userContext } from '../../../context/User' import { useMutation } from 'react-query' +import { ToastContainer, toast } from 'react-toastify' +import 'react-toastify/dist/ReactToastify.css' -const Agreement = () => { +const Agreement = ({ unverified, setUnverified }) => { const { t } = useTranslation() - const [otp, setOtp] = useState(0) + const [otp, setOtp] = useState() + const [disabled, setDisabled] = useState(false) + const [finalDisable, setFinalDisable] = useState(false) + const [show, setShow] = useState(false) const { userData } = userContext() console.log(userData) const { data, mutate } = useMutation(() => sendOTP({ mobile: `+91${userData?.mobile}` }) ) + console.log('Disabled: ', disabled, 'Final Disable: ', finalDisable) + const verifyOTP = () => { if (data?.data?.otpCode === Number(otp)) { - console.log('Verified', data?.data?.otpCode, otp) + console.log('Disabled: ', disabled, 'Final Disable: ', finalDisable) + setFinalDisable(true) + setDisabled(true) + setShow(false) + setUnverified(false) + toast.success(t('OTP_VERIFIED!')) } else { - console.log(typeof otp) - console.log(typeof data?.data?.otpCode) - console.log('Incorrect OTP', data?.data?.otpCode, otp) + toast.error(t('INCORRECT_OTP!')) } } + const sendResendOTP = () => { + setTimeout(() => { + if (finalDisable === false) { + console.log('Disabled: ', disabled, 'Final Disable: ', finalDisable) + setDisabled(false) + } + }, 30000) + } + return ( <> + <ToastContainer + autoClose={1000} + hideProgressBar={true} + theme={'colored'} + /> <Header subheading={t('ENROLLMENT')} /> <div className={styles.card__container}> <CardAgreement image={`${process.env.PUBLIC_URL}/assets/images/agreement.svg`} /> </div> - <Input - type="number" - id="otp" - value={otp} - label={t('PLEASE_VERIFY_YOUR_IDENTITY')} - onChange={(e) => setOtp(e.target.value)} - placeholder="XXXXXX" - /> - <Grid container columnSpacing={10} justifyContent="center"> - <Grid item> - <Button - color="primary" - size="large" - type="submit" - variant="contained" - onClick={() => mutate()} - > - {t('SEND_OTP')} - </Button> - </Grid> - <Grid item> - <Button - color="primary" - size="large" - type="submit" - variant="contained" - onClick={() => verifyOTP()} - > - {t('VERIFY_OTP')} - </Button> - </Grid> - </Grid> + <div className={styles.card__elements}> + <Typography>{t('PLEASE_VERIFY_YOUR_IDENTITY')}</Typography> + <Button + color="primary" + size="large" + type="submit" + variant="contained" + disabled={disabled} + onClick={() => { + mutate() + setDisabled(true) + setShow(true) + sendResendOTP() + }} + > + {show ? t('RESEND') : t('SEND_OTP')} + </Button> + {show && ( + <> + <Input + type="number" + id="otp" + value={otp} + onChange={(e) => setOtp(e.target.value)} + placeholder="XXXXXX" + /> + <Button + color="primary" + size="large" + type="submit" + variant="contained" + onClick={() => { + verifyOTP() + }} + > + {t('VERIFY_OTP')} + </Button> + </> + )} + </div> </> ) } diff --git a/client/src/pages/Enrollment/Agreement/Agreement.module.css b/client/src/pages/Enrollment/Agreement/Agreement.module.css index c618a4d..2580d47 100644 --- a/client/src/pages/Enrollment/Agreement/Agreement.module.css +++ b/client/src/pages/Enrollment/Agreement/Agreement.module.css @@ -1,4 +1,11 @@ .card__container { - display: flex; - justify-content: center; - }
\ No newline at end of file + display: flex; + justify-content: center; +} + +.card__elements { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} diff --git a/client/src/pages/Enrollment/DocumentScanner/DocumentScanner.jsx b/client/src/pages/Enrollment/DocumentScanner/DocumentScanner.jsx index f65051e..20ea7d2 100644 --- a/client/src/pages/Enrollment/DocumentScanner/DocumentScanner.jsx +++ b/client/src/pages/Enrollment/DocumentScanner/DocumentScanner.jsx @@ -15,6 +15,8 @@ import { import SubmitButton from '../../../components/SubmitButton/SubmitButton' import { useTranslation } from 'react-i18next' import { userContext } from '../../../context/User' +import { toast } from 'react-toastify' +import { useStyles } from './styles' const DocumentScanner = () => { const { t } = useTranslation() @@ -27,10 +29,9 @@ const DocumentScanner = () => { const [documents, setDocuments] = useState({ POI: '', POA: '', DOB: '' }) const [activeStep, setActiveStep] = React.useState(0) - // eslint-disable-next-line no-unused-vars - const [doccu, setDoccu] = useState({ POI: '', POA: '', DOB: '' }) + const [doccu] = useState({ POI: '', POA: '', DOB: '' }) - console.log(documents) + const classes = useStyles() const webcamRef = React.useRef(null) @@ -49,7 +50,15 @@ const DocumentScanner = () => { if (activeStep === steps.length - 1) { setUserData({ ...userData, documents: documents }) } - setActiveStep((prevActiveStep) => prevActiveStep + 1) + if ( + !userData.documents.POI || + !userData.documents.POA || + !userData.documents.DOB + ) { + toast.error(t('SCAN_YOUR_DOCUMENT')) + } else { + setActiveStep((prevActiveStep) => prevActiveStep + 1) + } } const handleBack = () => { @@ -78,7 +87,7 @@ const DocumentScanner = () => { )} </div> <Grid container columnSpacing={10} justifyContent="center"> - <Grid item> + <Grid item sx={{}}> <Button color="primary" size="large" @@ -129,53 +138,60 @@ const DocumentScanner = () => { <> <Header subheading={t('ENROLLMENT')} /> <SubmitButton /> - <Box sx={{ width: '100%' }}> - <Stepper activeStep={activeStep}> - {steps.map((label, index) => { - const stepProps = {} - const labelProps = {} - return ( - <Step key={label} {...stepProps}> - <StepLabel {...labelProps}>{label}</StepLabel> - </Step> - ) - })} - </Stepper> - {activeStep === steps.length ? ( - <React.Fragment> - <Typography sx={{ mt: 2, mb: 1 }}> - {t('ALL_STEPS_COMPLETED')} - </Typography> - <Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}> - <Box sx={{ flex: '1 1 auto' }} /> - </Box> - </React.Fragment> - ) : ( - <React.Fragment> - {activeStep === 0 ? ( - <WebcamComponent doc="POI" /> - ) : activeStep === 1 ? ( - <WebcamComponent doc="POA" /> - ) : ( - activeStep === 2 && <WebcamComponent doc="DOB" /> - )} - <Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}> - <Button - color="inherit" - disabled={activeStep === 0} - onClick={handleBack} - sx={{ mr: 1 }} - > - {t('BACK')} - </Button> - <Box sx={{ flex: '1 1 auto' }} /> - <Button onClick={handleNext}> - {activeStep === steps.length - 1 ? t('FINISH') : t('NEXT')} - </Button> - </Box> - </React.Fragment> - )} - </Box> + <div className={styles.stepper__container}> + <Box sx={{ width: '60%', fontSize: '100px !important' }}> + <Stepper activeStep={activeStep}> + {steps.map((label, index) => { + const stepProps = {} + const labelProps = {} + return ( + <Step key={label} {...stepProps}> + <StepLabel + {...labelProps} + classes={{ label: classes.stepLabel }} + > + {label} + </StepLabel> + </Step> + ) + })} + </Stepper> + {activeStep === steps.length ? ( + <React.Fragment> + <Typography sx={{ mt: 2, mb: 1 }}> + {t('ALL_STEPS_COMPLETED')} + </Typography> + <Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}> + <Box sx={{ flex: '1 1 auto' }} /> + </Box> + </React.Fragment> + ) : ( + <React.Fragment> + {activeStep === 0 ? ( + <WebcamComponent doc="POI" /> + ) : activeStep === 1 ? ( + <WebcamComponent doc="POA" /> + ) : ( + activeStep === 2 && <WebcamComponent doc="DOB" /> + )} + <Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}> + <Button + color="inherit" + disabled={activeStep === 0} + onClick={handleBack} + sx={{ mr: 1 }} + > + {t('BACK')} + </Button> + <Box sx={{ flex: '1 1 auto' }} /> + <Button onClick={handleNext}> + {activeStep === steps.length - 1 ? t('FINISH') : t('NEXT')} + </Button> + </Box> + </React.Fragment> + )} + </Box> + </div> </> ) } diff --git a/client/src/pages/Enrollment/DocumentScanner/DocumentScanner.module.css b/client/src/pages/Enrollment/DocumentScanner/DocumentScanner.module.css index ec59f61..58baaa8 100644 --- a/client/src/pages/Enrollment/DocumentScanner/DocumentScanner.module.css +++ b/client/src/pages/Enrollment/DocumentScanner/DocumentScanner.module.css @@ -1,5 +1,10 @@ .card__container { - display: flex; - justify-content: center; - } -
\ No newline at end of file + display: flex; + justify-content: center; + margin: 20px; +} + +.stepper__container { + display: flex; + justify-content: center; +} diff --git a/client/src/pages/Enrollment/DocumentScanner/styles.js b/client/src/pages/Enrollment/DocumentScanner/styles.js new file mode 100644 index 0000000..0b7e915 --- /dev/null +++ b/client/src/pages/Enrollment/DocumentScanner/styles.js @@ -0,0 +1,7 @@ +import { makeStyles } from '@mui/styles' + +export const useStyles = makeStyles({ + stepLabel: { + fontSize: '20px' + } +}) diff --git a/client/src/pages/Enrollment/Enrollment.jsx b/client/src/pages/Enrollment/Enrollment.jsx index 59211f9..f180667 100644 --- a/client/src/pages/Enrollment/Enrollment.jsx +++ b/client/src/pages/Enrollment/Enrollment.jsx @@ -23,12 +23,15 @@ import { ToastContainer, toast } from 'react-toastify' import 'react-toastify/dist/ReactToastify.css' import { userContext } from '../../context/User' import { useNavigate } from 'react-router-dom' +import BackButton from '../../components/BackButton/BackButton' +import { initialUserData } from '../../constants/userData' const Enrollment = () => { const { t } = useTranslation() const [page, setPage] = useState(0) const { userData, setUserData } = userContext() const navigate = useNavigate() + const [unverified, setUnverified] = useState(true) const { mutate } = useMutation((payload) => createUser(payload)) @@ -42,6 +45,8 @@ const Enrollment = () => { toast.error(t('PLEASE_ENTER_VALID_NAME')) } else if (userData.gender === '') { toast.error(t('PLEASE_SELECT_YOUR_GENDER')) + } else if (userData.dob === '') { + toast.error(t('PLEASE_SELECT_YOUR_DOB')) } else { setPage(page + 1) } @@ -82,13 +87,17 @@ const Enrollment = () => { setPage(page + 1) } } else if (page === 3) { - setPage(page + 1) + if (!userData.photo) { + toast.error(t('PLEASE_CAPTURE_PHOTOGRAPH')) + } else { + setPage(page + 1) + } } else if (page === 4) { - if (userData.documents.POI === '') { + if (!userData.documents.POI) { toast.error(t('PLEASE_TAKE_THE_PICTURE_OF_THE_PROOF_OF_IDENTITY')) - } else if (userData.documents.POA === '') { + } else if (!userData.documents.POA) { toast.error(t('PLEASE_TAKE_THE_PICTURE_OF_THE_PROOF_OF_ADDRESS')) - } else if (userData.documents.DOB === '') { + } else if (!userData.documents.DOB) { toast.error(t('PLEASE_TAKE_THE_PICTURE_OF_THE_PROOF_OF_DATE_OF_BIRTH')) } else { setPage(page + 1) @@ -118,7 +127,7 @@ const Enrollment = () => { }, { onSuccess: () => { - setUserData(null) + setUserData(initialUserData) navigate('/') } } @@ -145,7 +154,9 @@ const Enrollment = () => { case 6: return <Fingerprint /> case 7: - return <Agreement /> + return ( + <Agreement unverified={unverified} setUnverified={setUnverified} /> + ) case 8: return <FinalSlip /> default: @@ -156,25 +167,39 @@ const Enrollment = () => { const conditionalButton = () => { switch (page) { case 0: - return <SubmitButton onClick={handleSubmit}>Next</SubmitButton> + return ( + <> + <SubmitButton onClick={handleSubmit} /> + <BackButton + onClick={() => { + setUserData(initialUserData) + navigate('/') + }} + /> + </> + ) case 1: - return <SubmitButton onClick={handleSubmit}>Next</SubmitButton> case 2: - return <SubmitButton onClick={handleSubmit}>Next</SubmitButton> case 3: - return <SubmitButton onClick={handleSubmit}>Next</SubmitButton> case 4: - return <SubmitButton onClick={handleSubmit}>Next</SubmitButton> case 5: - return <SubmitButton onClick={handleSubmit}>Next</SubmitButton> case 6: - return <SubmitButton onClick={handleSubmit}>Next</SubmitButton> + return ( + <> + <SubmitButton onClick={handleSubmit} /> + <BackButton onClick={() => setPage(page - 1)} /> + </> + ) case 7: - return <SubmitButton onClick={handleSubmit}>Submit</SubmitButton> + return ( + <> + <SubmitButton onClick={handleSubmit} disabled={unverified} /> + <BackButton onClick={() => setPage(page - 1)} /> + </> + ) case 8: - return <SubmitButton onClick={handleSubmit}>Exit</SubmitButton> default: - return <SubmitButton onClick={handleSubmit}>Next</SubmitButton> + return <SubmitButton onClick={handleSubmit} /> } } return ( diff --git a/client/src/pages/Enrollment/FormOne/FormOne.jsx b/client/src/pages/Enrollment/FormOne/FormOne.jsx index 2754660..f601921 100644 --- a/client/src/pages/Enrollment/FormOne/FormOne.jsx +++ b/client/src/pages/Enrollment/FormOne/FormOne.jsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' import { useTranslation } from 'react-i18next' import Header from '../../../components/Header/Header' import Input from '../../../components/Input/Input' @@ -10,6 +10,26 @@ const FormOne = () => { const { t } = useTranslation() const { userData, setUserData } = userContext() + useEffect(() => { + switch (userData.gender) { + case 'Male': + document.getElementById('male').checked = 'checked' + break + case 'Female': + document.getElementById('female').checked = 'checked' + break + case 'Other': + document.getElementById('other').checked = 'checked' + break + } + + if (userData.indianResident === true) { + document.getElementById('indian').checked = 'checked' + } else if (userData.indianResident === false) { + document.getElementById('non-resident-indian').checked = 'checked' + } + }, [userData.gender]) + return ( <> <Header subheading={t('ENROLLMENT')} /> @@ -34,7 +54,7 @@ const FormOne = () => { <span className={styles.formone__resident}> <input type="radio" - id="indian" + id="non-resident-indian" name="resident" value={userData.indianResident} onChange={() => { @@ -91,7 +111,7 @@ const FormOne = () => { image={`${process.env.PUBLIC_URL}/assets/images/female.svg`} /> <LabelCard - id="trans" + id="other" name="gender" value={userData.gender} title={t('OTHER')} diff --git a/client/src/pages/Update/FormOne/FormOne.jsx b/client/src/pages/Update/FormOne/FormOne.jsx index 9c38d64..e0b1ca0 100644 --- a/client/src/pages/Update/FormOne/FormOne.jsx +++ b/client/src/pages/Update/FormOne/FormOne.jsx @@ -18,7 +18,6 @@ const FormOne = () => { } useEffect(() => { - console.log(userData.gender) document.getElementById(`${userData.gender}`).checked = 'checked' }, [userData.gender]) |