diff options
author | Rohan Raj Gupta <[email protected]> | 2022-08-12 12:57:43 +0530 |
---|---|---|
committer | GitHub <[email protected]> | 2022-08-12 12:57:43 +0530 |
commit | 6d821dc4aa7f6235d2d619dfd8b2954c241f0439 (patch) | |
tree | ca8811c7d708bbb7f3266b9bc1045ee70219f996 /client/src | |
parent | 53795fe3153f514e0eda6a01f6e55eeb50c94d46 (diff) | |
parent | 87a343644592e9b425e7fa0805988ad8e7ee8778 (diff) |
Merge pull request #3 from Blaster4385/develop
Refactor code, add country api, switch to multi-step form
Diffstat (limited to 'client/src')
-rw-r--r-- | client/src/App.js | 179 | ||||
-rw-r--r-- | client/src/components/Card/Card.jsx | 4 | ||||
-rw-r--r-- | client/src/components/Input/Input.jsx | 7 | ||||
-rw-r--r-- | client/src/components/Input/Input.module.css | 3 | ||||
-rw-r--r-- | client/src/components/RegEx/RegEx.jsx | 9 | ||||
-rw-r--r-- | client/src/components/SubmitButton/SubmitButton.jsx | 4 | ||||
-rw-r--r-- | client/src/pages/Enrollment/Address/Address.jsx | 210 | ||||
-rw-r--r-- | client/src/pages/Enrollment/Address/Address.module.css | 20 | ||||
-rw-r--r-- | client/src/pages/Enrollment/FormOne/FormOne.jsx | 188 | ||||
-rw-r--r-- | client/src/pages/Enrollment/FormTwo/FormTwo.jsx | 34 | ||||
-rw-r--r-- | client/src/pages/Home/Home.jsx | 7 |
11 files changed, 512 insertions, 153 deletions
diff --git a/client/src/App.js b/client/src/App.js index c39f14e..e7ab247 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,10 +1,183 @@ -import React from 'react' -import Index from './routes' +import React, { useState } from 'react' +import Address from './pages/Enrollment/Address/Address' +import Agreement from './pages/Enrollment/Agreement/Agreement' +import DocumentScanner from './pages/Enrollment/DocumentScanner/DocumentScanner' +import FinalSlip from './pages/Enrollment/FinalSlip/FinalSlip' +import Fingerprint from './pages/Enrollment/Fingerprint/Fingerprint' +import FormTwo from './pages/Enrollment/FormTwo/FormTwo' +import IrisScan from './pages/Enrollment/IrisScan/IrisScan' +import PhotoCapture from './pages/Enrollment/PhotoCapture/PhotoCapture' +import SubmitButton from './components/SubmitButton/SubmitButton' +import FormOne from './pages/Enrollment/FormOne/FormOne' +import { validEmail, validMobileNumber, validPincode } from './components/RegEx/RegEx' +import Home from './pages/Home/Home' const App = () => { + const [page, setPage] = useState(9) + + const [formData, setFormData] = useState({ + indianResident: '', + name: '', + gender: '', + dob: new Date().toISOString().slice(0, 10), + mobile: '', + email: '', + country: '', + state: '', + district: '', + village: '', + houseNo: '', + street: '', + locality: '', + postOffice: '', + landmark: '', + pincode: '', + address: '' + }) + + function handleSubmit () { + if (page === 0) { + if (formData.indianResident === '') { + return alert('Please select your residency') + } else if (formData.name === '' || formData.name.length < 1) { + return alert('Please enter your name') + } else if (formData.gender === '') { + return alert('Please select your gender') + } else { + setPage(page + 1) + } + } else if (page === 1) { + if (formData.mobile === '') { + return alert('Please enter your mobile number') + } else if (!validMobileNumber.test(formData.mobile)) { + return alert('Please enter valid mobile number') + } else if (formData.email === '') { + return alert('Please enter your email') + } else if (!validEmail.test(formData.email)) { + return alert('Please enter valid email') + } else { + setPage(page + 1) + } + } else if (page === 2) { + if (formData.country === '') { + return alert('Please select your country') + } else if (formData.state === '') { + return alert('Please select your state') + } else if (formData.district === '') { + return alert('Please select your district') + } else if (formData.village === '') { + return alert('Please enter your village') + } else if (formData.houseNo === '') { + return alert('Please enter your house number') + } else if (formData.street === '') { + return alert('Please enter your street') + } else if (formData.locality === '') { + return alert('Please enter your locality') + } else if (formData.postOffice === '') { + return alert('Please enter your post office') + } else if (formData.landmark === '') { + return alert('Please enter your landmark') + } else if (formData.pincode === '') { + return alert('Please enter your pincode') + } else if (!validPincode.test(formData.pincode)) { + return alert('Please enter valid pincode') + } else { + setFormData({ + ...formData, + address: `${formData.houseNo} ${formData.street}, ${formData.locality}, ${formData.landmark}, ${formData.village}, ${formData.district.label}, ${formData.country.label} ${formData.pincode}` + }) + setPage(page + 1) + } + } else if (page === 3) { + setPage(page + 1) + } else if (page === 4) { + setPage(page + 1) + } else if (page === 5) { + setPage(page + 1) + } else if (page === 6) { + setPage(page + 1) + } else if (page === 7) { + setPage(page + 1) + } else if (page === 8) { + setPage(page + 1) + } else if (page === 9) { + setPage(page + 1) + } else setPage(page + 1) + } + + const conditionalComponent = () => { + switch (page) { + case 0: + return <FormOne formData={formData} setFormData={setFormData} /> + case 1: + return <FormTwo formData={formData} setFormData={setFormData} /> + case 2: + return <Address formData={formData} setFormData={setFormData} /> + case 3: + return <DocumentScanner formData={formData} setFormData={setFormData} /> + case 4: + return <PhotoCapture formData={formData} setFormData={setFormData} /> + case 5: + return <IrisScan formData={formData} setFormData={setFormData} /> + case 6: + return <Fingerprint formData={formData} setFormData={setFormData} /> + case 7: + return <Agreement formData={formData} setFormData={setFormData} /> + case 8: + return <FinalSlip formData={formData} setFormData={setFormData} /> + default: + return <Home page={page} setPage={setPage} /> + } + } + + const conditionalButton = () => { + switch (page) { + case 0: + return <SubmitButton onClick={handleSubmit}> + Next + </SubmitButton> + 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> + case 7: + return <SubmitButton onClick={handleSubmit}> + Submit + </SubmitButton> + case 8: + return <SubmitButton onClick={handleSubmit}> + Exit + </SubmitButton> + default: + return <SubmitButton onClick={handleSubmit}> + Next + </SubmitButton> + } + } return ( <> - <Index /> + {conditionalComponent()} + {conditionalButton()} </> ) } diff --git a/client/src/components/Card/Card.jsx b/client/src/components/Card/Card.jsx index 3d66067..9460955 100644 --- a/client/src/components/Card/Card.jsx +++ b/client/src/components/Card/Card.jsx @@ -1,9 +1,9 @@ import React from 'react' import styles from './Card.module.css' -const Card = ({ title, image }) => { +const Card = ({ title, image, onClick }) => { return ( - <div className={styles.card}> + <div onClick={ onClick } className={styles.card}> <img className={styles.card__image} src={image} alt="" /> <h2 className={styles.card__title}>{title}</h2> </div> diff --git a/client/src/components/Input/Input.jsx b/client/src/components/Input/Input.jsx index 5987e27..08e8fab 100644 --- a/client/src/components/Input/Input.jsx +++ b/client/src/components/Input/Input.jsx @@ -1,7 +1,7 @@ import React from 'react' import styles from './Input.module.css' -const Input = ({ label, id, value, type, name, onChange, placeholder }) => { +const Input = ({ label, id, value, type, name, onChange, placeholder, maxLength, pattern, minLength, onInvalid, onValid }) => { return ( <div className={styles.input}> <div className={styles.input__container}> @@ -15,6 +15,11 @@ const Input = ({ label, id, value, type, name, onChange, placeholder }) => { onChange={onChange} required placeholder={placeholder} + pattern={pattern} + maxLength={maxLength} + minLength={minLength} + onInvalid={onInvalid} + onValid={onValid} /> </div> </div> diff --git a/client/src/components/Input/Input.module.css b/client/src/components/Input/Input.module.css index cafb5f1..b02591c 100644 --- a/client/src/components/Input/Input.module.css +++ b/client/src/components/Input/Input.module.css @@ -13,7 +13,8 @@ .input__field { width: 300px; margin: 10px 0px; - padding: 20px 10px; + padding: 18px 10px; border: 3px solid; border-radius: 10px; + font-size: 1rem; } diff --git a/client/src/components/RegEx/RegEx.jsx b/client/src/components/RegEx/RegEx.jsx new file mode 100644 index 0000000..2df4266 --- /dev/null +++ b/client/src/components/RegEx/RegEx.jsx @@ -0,0 +1,9 @@ +export const validString = /^[a-zA-Z]+$/ + +export const validMobileNumber = /^[0-9]{10}$/ + +export const validNumber = /^[0-9]+$/ + +export const validPincode = /^[0-9]{6}$/ + +export const validEmail = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/ diff --git a/client/src/components/SubmitButton/SubmitButton.jsx b/client/src/components/SubmitButton/SubmitButton.jsx index e1ba305..4437efa 100644 --- a/client/src/components/SubmitButton/SubmitButton.jsx +++ b/client/src/components/SubmitButton/SubmitButton.jsx @@ -1,10 +1,10 @@ import React from 'react' import styles from './SubmitButton.module.css' -const SubmitButton = () => { +const SubmitButton = ({ onClick }) => { return ( <> - <button className={styles.submit} type="submit"> + <button onClick={onClick} className={styles.submit} type="submit"> <img className={styles.submit__image} src={`${process.env.PUBLIC_URL}/assets/images/white-check.svg`} diff --git a/client/src/pages/Enrollment/Address/Address.jsx b/client/src/pages/Enrollment/Address/Address.jsx index 713c8d9..d4ffe81 100644 --- a/client/src/pages/Enrollment/Address/Address.jsx +++ b/client/src/pages/Enrollment/Address/Address.jsx @@ -1,95 +1,209 @@ -import React, { useState } from 'react' -import { useNavigate } from 'react-router-dom' +import React from 'react' import Header from '../../../components/Header/Header' import Input from '../../../components/Input/Input' -import SubmitButton from '../../../components/SubmitButton/SubmitButton' +import { Country, State, City } from 'country-state-city' +import Select from 'react-select' import styles from './Address.module.css' -const Address = () => { - const [address, setAddress] = useState('') +const Address = ({ formData, setFormData }) => { + const countries = Country.getAllCountries() - const navigate = useNavigate() + const updatedCountries = countries.map((country) => ({ + label: country.name, + value: country.id, + ...country + })) - const handleSubmit = () => { - navigate('/enrollment/photo') - } + const updatedStates = (countryId) => + State + .getStatesOfCountry(countryId) + .map((state) => ({ label: state.name, value: state.id, ...state })) + const updatedCities = (countryID, stateId) => + City + .getCitiesOfState(countryID, stateId) + .map((city) => ({ label: city.name, value: city.id, ...city })) + + const customStyles = { + control: (base, state) => ({ + ...base, + width: '330px', + height: '60px', + margin: '10px 0px', + // padding: '20px 10px', + border: '3px solid', + borderRadius: '10px !important' + }), + input: (base, state) => ({ + ...base, + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + padding: '0px', + margin: '0px' + }) + } + + console.log(formData.country, formData.state, formData.district, formData.village) return ( <> <Header subheading="Enrollment" /> - <form onSubmit={() => handleSubmit()} className={styles.address}> + <div className={styles.address}> <div className={styles.address__container}> + <div className={styles.input}> + <div className={styles.input__container}> + <label htmlFor='country'>Country</label> + <Select + id="country" + name="country" + label="country" + options={updatedCountries} + value={formData.country} + onChange={e => { + setFormData({ + ...formData, + country: e + }) + }} + styles={customStyles} + /> + </div> + </div> + <div className={styles.input}> + <div className={styles.input__container}> + <label htmlFor='state'>State</label> + <Select + id="state" + name="state" + options={updatedStates(formData.country.isoCode)} + value={formData.state} + onChange={e => { + setFormData({ + ...formData, + state: e + }) + }} + styles={customStyles} + /> + </div> + </div> + <div className={styles.input}> + <div className={styles.input__container}> + <label htmlFor='city'>District</label> + <Select + id="city" + name="city" + options={updatedCities(formData.country.isoCode, formData.state.isoCode)} + value={formData.district} + onChange={e => { + setFormData({ + ...formData, + district: e + }) + }} + styles={customStyles} + /> + </div> + </div> + <Input + id="town" + label="Village / Town" + value={formData.village} + type="text" + onChange={(e) => { + setFormData({ + ...formData, + village: e.target.value + }) + }} + placeholder="Enter your Village / Town" + /> + </div> + <div className={styles.address__container}> <Input id="houseNo" label="House Number/ Apartment" - value={address} + value={formData.houseNo} type="text" - onChange={(e) => setAddress(e.target.value)} + onChange={(e) => { + setFormData({ + ...formData, + houseNo: e.target.value + }) + }} placeholder="Enter your House Number / Apartment" /> <Input + id="street" + label="Street / Road" + value={formData.street} + type="text" + onChange={(e) => { + setFormData({ + ...formData, + street: e.target.value + }) + }} + placeholder="Enter the Street / Road" + /> + <Input id="locality" label="Area / Locality" - value={address} + value={formData.locality} type="text" - onChange={(e) => setAddress(e.target.value)} + onChange={(e) => { + setFormData({ + ...formData, + locality: e.target.value + }) + }} placeholder="Enter your Area / Locality" /> - <Input id="town" label="Village / Town" value="town" type="text" /> <Input id="postOffice" label="Post Office" - value={address} + value={formData.postOffice} type="text" - onChange={(e) => setAddress(e.target.value)} + onChange={(e) => { + setFormData({ + ...formData, + postOffice: e.target.value + }) + }} placeholder="Enter your Village / Town" /> - </div> + </div> <div className={styles.address__container}> <Input - id="street" - label="Street / Road" - value={address} - type="text" - onChange={(e) => setAddress(e.target.value)} - placeholder="Enter the Street / Road" - /> - <Input id="landmark" label="Landmark" - value={address} + value={formData.landmark} type="text" - onChange={(e) => setAddress(e.target.value)} + onChange={(e) => { + setFormData({ + ...formData, + landmark: e.target.value + }) + }} placeholder="Enter the Landmark" /> <Input - id="district" - label="District" - value={address} - type="text" - onChange={(e) => setAddress(e.target.value)} - placeholder="Enter your District" - /> - <Input id="pincode" label="Pincode" - value={address} + value={formData.pincode} type="text" - onChange={(e) => setAddress(e.target.value)} + onChange={(e) => { + setFormData({ + ...formData, + pincode: e.target.value + }) + }} placeholder="Enter your area Pincode" + pattern="[0-9]+" /> </div> - <Input - id="state" - label="State" - value={address} - type="text" - onChange={(e) => setAddress(e.target.value)} - placeholder="Enter your State" - /> - <SubmitButton /> - </form> + </div> </> ) } diff --git a/client/src/pages/Enrollment/Address/Address.module.css b/client/src/pages/Enrollment/Address/Address.module.css index 60958ba..26ca909 100644 --- a/client/src/pages/Enrollment/Address/Address.module.css +++ b/client/src/pages/Enrollment/Address/Address.module.css @@ -6,3 +6,23 @@ .address__container { margin: 0px 20px; } + +.input { + display: flex; + justify-content: center; + font-family: 'Barlow'; + font-size: var(--font-medium-s); +} + +.input__container { + display: flex; + flex-direction: column; +} + +.input__field { + width: 300px; + margin: 10px 0px; + padding: 20px 10px; + border: 3px solid; + border-radius: 10px; +} diff --git a/client/src/pages/Enrollment/FormOne/FormOne.jsx b/client/src/pages/Enrollment/FormOne/FormOne.jsx index ed83a6f..d245faf 100644 --- a/client/src/pages/Enrollment/FormOne/FormOne.jsx +++ b/client/src/pages/Enrollment/FormOne/FormOne.jsx @@ -1,94 +1,122 @@ -import React, { useState } from 'react' +import React from 'react' +import Header from '../../../components/Header/Header' import Input from '../../../components/Input/Input' import LabelCard from '../../../components/LabelCard/LabelCard' import styles from './FormOne.module.css' -const FormOne = () => { - const [indianResident, setIndianResident] = useState(true) - const [fullName, setFullName] = useState('') - const [gender, setGender] = useState('') - const [dateOfBirth, setDateOfBirth] = useState( - new Date().toISOString().slice(0, 10) - ) +const FormOne = ({ formData, setFormData }) => { + console.log(formData.indianResident, formData.name, formData.dob, formData.gender) - console.log(fullName, indianResident, gender, dateOfBirth) + const handleSubmit = () => { + } return ( - <div className={styles.formone}> - <div className={styles.formone__radio}> - <span className={styles.formone__resident}> - <input - type="radio" - id="indian" - name="resident" - value={indianResident} - onChange={() => setIndianResident(true)} - required - /> - <label htmlFor="indian">Indian Resident</label> - </span> - <span className={styles.formone__resident}> - <input - type="radio" - id="indian" - name="resident" - value="Indian Resident" - onChange={() => setIndianResident(false)} - required - /> - <label htmlFor="indian">Non-Residential Indian</label> - </span> - </div> + <><Header subheading="Enrollment" /><form onSubmit={() => handleSubmit()}> + <div className={styles.formone}> + <div className={styles.formone__radio}> + <span className={styles.formone__resident}> + <input + type="radio" + id="indian" + name="resident" + value={formData.indianResident} + onChange={() => { + setFormData({ + ...formData, + indianResident: true + }) + }} + required /> + <label htmlFor="indian">Indian Resident</label> + </span> + <span className={styles.formone__resident}> + <input + type="radio" + id="indian" + name="resident" + value={formData.indianResident} + onChange={() => { + setFormData({ + ...formData, + indianResident: false + }) + }} + required /> + <label htmlFor="indian">Non-Residential Indian</label> + </span> + </div> - <Input - type="text" - id="fullName" - label="Full Name" - value={fullName} - onChange={(e) => setFullName(e.target.value)} - placeholder="Enter your full name" - /> + <Input + type="text" + id="fullName" + label="Full Name" + value={formData.name} + onChange={(e) => { + setFormData({ + ...formData, + name: e.target.value + }) + }} + placeholder="Enter your full name" + pattern="[a-zA-z]+" /> - <div className={styles.formone__gender}> - <LabelCard - id="male" - name="gender" - title="Male" - value={gender} - onChange={() => setGender('male')} - image={`${process.env.PUBLIC_URL}/assets/images/male.svg`} - /> - <LabelCard - id="female" - name="gender" - value={gender} - title="Female" - onChange={() => setGender('female')} - image={`${process.env.PUBLIC_URL}/assets/images/female.svg`} - /> - <LabelCard - id="trans" - name="gender" - value={gender} - title="Transgender" - onChange={() => setGender('transgender')} - image={`${process.env.PUBLIC_URL}/assets/images/trans.svg`} - /> - </div> + <div className={styles.formone__gender}> + <LabelCard + id="male" + name="gender" + title="Male" + value={formData.gender} + onChange={() => { + setFormData({ + ...formData, + gender: 'Male' + }) + }} + image={`${process.env.PUBLIC_URL}/assets/images/male.svg`} /> + <LabelCard + id="female" + name="gender" + value={formData.gender} + title="Female" + onChange={() => { + setFormData({ + ...formData, + gender: 'Female' + }) + }} + image={`${process.env.PUBLIC_URL}/assets/images/female.svg`} /> + <LabelCard + id="trans" + name="gender" + value={formData.gender} + title="Transgender" + onChange={() => { + setFormData({ + ...formData, + gender: 'Transgender' + }) + }} + image={`${process.env.PUBLIC_URL}/assets/images/trans.svg`} /> + </div> - <div className={styles.formone__dob}> - <label htmlFor="dob">Date of Birth</label> - <input - className={styles.formone__dob_input} - type="date" - id="dob" - name="dob" - value={dateOfBirth} - onChange={(e) => setDateOfBirth(e.target.value)} - required - /> + <div className={styles.formone__dob}> + <label htmlFor="dob">Date of Birth</label> + <input + className={styles.formone__dob_input} + type="date" + id="dob" + name="dob" + value={formData.dob} + onChange={(e) => { + setFormData({ + ...formData, + dob: e.target.value + }) + }} + required /> + </div> </div> - </div> + </form></> ) } diff --git a/client/src/pages/Enrollment/FormTwo/FormTwo.jsx b/client/src/pages/Enrollment/FormTwo/FormTwo.jsx index 3ea8447..91d8f6b 100644 --- a/client/src/pages/Enrollment/FormTwo/FormTwo.jsx +++ b/client/src/pages/Enrollment/FormTwo/FormTwo.jsx @@ -1,35 +1,43 @@ -import React, { useState } from 'react' -import { useNavigate } from 'react-router-dom' +import React from 'react' import Input from '../../../components/Input/Input' import Header from '../../../components/Header/Header' import SubmitButton from '../../../components/SubmitButton/SubmitButton' -const FormTwo = () => { - const [mobileNumber, setMobileNumber] = useState('') - const [email, setEmail] = useState('') - - const navigate = useNavigate() - +const FormTwo = ({ formData, setFormData }) => { return ( <div className="formtwo"> <Header subheading="Enrollment" /> <Input id="mobile" - value={mobileNumber} + value={formData.mobile} label="Mobile" type="text" - onChange={(e) => setMobileNumber(e.target.value)} + onChange={(e) => { + setFormData({ + ...formData, + mobile: e.target.value + }) + }} placeholder="Enter your Mobile Number" + pattern="[0-9]+" + maxLength="10" + minLength="10" /> <Input id="email" - value={email} + value={formData.email} label="Email" type="email" - onChange={(e) => setEmail(e.target.value)} + onChange={(e) => { + setFormData({ + ...formData, + email: e.target.value + }) + }} placeholder="Enter your Email ID" + pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" /> - <SubmitButton onClick={() => navigate('/enrollment/address')} /> + <SubmitButton /> </div> ) } diff --git a/client/src/pages/Home/Home.jsx b/client/src/pages/Home/Home.jsx index b132f12..1c638b1 100644 --- a/client/src/pages/Home/Home.jsx +++ b/client/src/pages/Home/Home.jsx @@ -5,17 +5,18 @@ import Card from '../../components/Card/Card' import Header from '../../components/Header/Header' import styles from './Home.module.css' -const Home = () => { +const Home = ({ page, setPage }) => { return ( <> <Header subheading="Mera Aadhaar Meri Pehchan" /> <div className={styles.card__container}> - <Link to="/enrollment"> <Card title="Enrollment" image={`${process.env.PUBLIC_URL}/assets/images/enrollment.svg`} + onClick={(e) => { + setPage(0) + }} /> - </Link> <Link to="/update"> <Card title="Update" |