Created
February 4, 2025 08:25
-
-
Save niftynihal/407392559c20db45b75c950f8fe47fa7 to your computer and use it in GitHub Desktop.
changes to be done in apps/student-experience/src/components/LegalAgreementModal/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
First, update the DetailFormData interface: | |
``` | |
interface DetailFormData { | |
name: string; | |
address: string; | |
panNumber: string; | |
aadharNumber: string; | |
dateOfBirth: string; | |
gender: string; | |
parentsName: string; | |
parentsEmail: string; | |
parentsMobileCountry: string; | |
parentsMobile: string; | |
currentStatus: string; | |
studyYear: string; | |
workDomain: string; | |
educationDetails: string; | |
graduationYear: string; | |
collegeName: string; | |
companyName: string; | |
workExperience: string; | |
ctc: string; | |
location: string; | |
} | |
``` | |
Add the country codes data and validation functions just before the EnterDetailsStep component: | |
``` | |
const countryCodes = [ | |
{ code: '+91', country: 'India', length: 10 }, | |
{ code: '+1', country: 'USA/Canada', length: 10 }, | |
{ code: '+44', country: 'UK', length: 11 }, | |
{ code: '+61', country: 'Australia', length: 9 }, | |
// Add more countries as needed | |
]; | |
const isValidPhoneNumber = (phone: string, countryCode: string) => { | |
const country = countryCodes.find(c => c.code === countryCode); | |
if (!country) return false; | |
return phone.length === country.length; | |
}; | |
const getMaxDate = () => { | |
const today = new Date(); | |
return today.toISOString().split('T')[0]; | |
}; | |
``` | |
Update the initial state in the main component: | |
``` | |
const [detailFormData, setDetailFormData] = useState<DetailFormData>({ | |
name: data?.legalData?.name || '', | |
address: data?.legalData?.address || '', | |
panNumber: data?.legalData?.panNumber || '', | |
aadharNumber: data?.legalData?.aadharNumber || '', | |
dateOfBirth: data?.legalData?.dateOfBirth || '', | |
gender: data?.legalData?.gender || '', | |
parentsName: data?.legalData?.parentsName || '', | |
parentsEmail: data?.legalData?.parentsEmail || '', | |
parentsMobileCountry: data?.legalData?.parentsMobileCountry || '', | |
parentsMobile: data?.legalData?.parentsMobile || '', | |
currentStatus: data?.legalData?.currentStatus || '', | |
studyYear: data?.legalData?.studyYear || '', | |
workDomain: data?.legalData?.workDomain || '', | |
educationDetails: data?.legalData?.educationDetails || '', | |
graduationYear: data?.legalData?.graduationYear || '', | |
collegeName: data?.legalData?.collegeName || '', | |
companyName: data?.legalData?.companyName || '', | |
workExperience: data?.legalData?.workExperience || '', | |
ctc: data?.legalData?.ctc || '', | |
location: '', | |
}); | |
``` | |
Replace the EnterDetailsStep component with this updated version: | |
``` | |
function EnterDetailsStep({ formData, handleChange }: EnterDetailsStepProps) { | |
const isInValidPan = formData.panNumber && formData.panNumber?.length < 10; | |
const isInValidAadhar = formData.aadharNumber && formData.aadharNumber?.length < 12; | |
const isInvalidParentMobile = formData.parentsMobile && | |
!isValidPhoneNumber(formData.parentsMobile, formData.parentsMobileCountry); | |
const isInvalidGradYear = formData.graduationYear && !/^\d{4}$/.test(formData.graduationYear); | |
const isInvalidEmail = formData.parentsEmail && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.parentsEmail); | |
return ( | |
<div className="p-6 py-2"> | |
<div className="space-y-4 px-32 py-4 border rounded-[12px] overflow-y-scroll scrollbar-hide max-h-[60%] xl:max-h-[64%]"> | |
{/* Existing Name field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Name<span className="text-xs ml-1 text-gray-600">(As per aadhar card)</span> | |
<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<input | |
type="text" | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
placeholder="Enter Name" | |
value={formData.name} | |
onChange={e => handleChange('name', e.target.value)} | |
/> | |
</div> | |
{/* Existing Address field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Address<span className="text-xs ml-1 text-gray-600">(As per aadhar card)</span> | |
<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<input | |
type="text" | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
placeholder="Enter Address" | |
value={formData.address} | |
onChange={e => handleChange('address', e.target.value)} | |
/> | |
</div> | |
{/* Date of Birth field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Date of Birth<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<input | |
type="date" | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
value={formData.dateOfBirth} | |
onChange={e => handleChange('dateOfBirth', e.target.value)} | |
max={getMaxDate()} | |
/> | |
</div> | |
{/* Gender field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Gender<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<select | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
value={formData.gender} | |
onChange={e => handleChange('gender', e.target.value)} | |
> | |
<option value="">Select Gender</option> | |
<option value="male">Male</option> | |
<option value="female">Female</option> | |
<option value="prefer_not_to_say">Prefer not to say</option> | |
</select> | |
</div> | |
{/* Parent's Name field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Parent's Name<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<input | |
type="text" | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
placeholder="Enter Parent's Name" | |
value={formData.parentsName} | |
onChange={e => handleChange('parentsName', e.target.value)} | |
/> | |
</div> | |
{/* Parent's Email field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Parent's Email ID<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<input | |
type="email" | |
className={`w-full px-3 py-2 border ${ | |
isInvalidEmail ? 'border-red-500' : 'border-gray-300' | |
} bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm`} | |
placeholder="Enter Parent's Email" | |
value={formData.parentsEmail} | |
onChange={e => handleChange('parentsEmail', e.target.value)} | |
/> | |
{isInvalidEmail && <span className="text-red-600 text-xs">Please enter a valid email address</span>} | |
</div> | |
{/* Parent's Mobile Number field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Parent's Mobile Number<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<div className="flex gap-2"> | |
<select | |
className="px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
value={formData.parentsMobileCountry} | |
onChange={e => handleChange('parentsMobileCountry', e.target.value)} | |
> | |
<option value="">Select</option> | |
{countryCodes.map(country => ( | |
<option key={country.code} value={country.code}> | |
{country.code} ({country.country}) | |
</option> | |
))} | |
</select> | |
<input | |
type="text" | |
className={`flex-1 px-3 py-2 border ${ | |
isInvalidParentMobile ? 'border-red-500' : 'border-gray-300' | |
} bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm`} | |
placeholder="Enter Parent's Mobile Number" | |
value={formData.parentsMobile} | |
onChange={e => handleChange('parentsMobile', e.target.value.replace(/\D/g, ''))} | |
/> | |
</div> | |
{isInvalidParentMobile && ( | |
<span className="text-red-600 text-xs"> | |
Please enter a valid phone number for the selected country | |
</span> | |
)} | |
</div> | |
{/* Current Status field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Current Status<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<div className="space-y-2"> | |
<select | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
value={formData.currentStatus} | |
onChange={e => { | |
handleChange('currentStatus', e.target.value); | |
handleChange('studyYear', ''); | |
handleChange('workDomain', ''); | |
}} | |
> | |
<option value="">Select Current Status</option> | |
<option value="completed_12th">Completed 12th</option> | |
<option value="graduated_not_working">Graduated but not working</option> | |
<option value="studying">Studying</option> | |
<option value="working">Working</option> | |
</select> | |
{formData.currentStatus === 'studying' && ( | |
<select | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
value={formData.studyYear} | |
onChange={e => handleChange('studyYear', e.target.value)} | |
> | |
<option value="">Select Year</option> | |
<option value="first_year">I Year</option> | |
<option value="second_year">II Year</option> | |
<option value="pre_final">Pre-final Year</option> | |
<option value="final_year">Final Year</option> | |
</select> | |
)} | |
{formData.currentStatus === 'working' && ( | |
<select | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
value={formData.workDomain} | |
onChange={e => handleChange('workDomain', e.target.value)} | |
> | |
<option value="">Select Domain</option> | |
<option value="tech">Tech Domain</option> | |
<option value="non_tech">Non-tech Domain</option> | |
</select> | |
)} | |
</div> | |
</div> | |
{/* Education Details field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Education Details<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<select | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
value={formData.educationDetails} | |
onChange={e => handleChange('educationDetails', e.target.value)} | |
> | |
<option value="">Select Education Details</option> | |
<option value="btech_cs">BTech/B.E (CS)</option> | |
<option value="btech_non_cs">BTech/B.E (Non-CS)</option> | |
<option value="graduation_cs">Graduation (CS, e.g., B.Sc Computer Science, BCA)</option> | |
<option value="graduation_non_cs">Graduation (Non-CS, e.g., BA, BCom)</option> | |
<option value="post_graduation">Post Graduation</option> | |
<option value="completed_12th">Completed 12th/Diploma</option> | |
</select> | |
</div> | |
{/* Year of Graduation field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Year of Graduation (Bachelors)<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<input | |
type="text" | |
className={`w-full px-3 py-2 border ${ | |
isInvalidGradYear ? 'border-red-500' : 'border-gray-300' | |
} bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm`} | |
placeholder="If you have not completed graduation or are a college dropout, mention the year of completion of your college" | |
value={formData.graduationYear} | |
onChange={e => handleChange('graduationYear', e.target.value)} | |
maxLength={4} | |
/> | |
{isInvalidGradYear && <span className="text-red-600 text-xs">Please enter a valid year (YYYY)</span>} | |
</div> | |
``` | |
I'll continue with the remaining fields in the EnterDetailsStep component: | |
``` | |
{/* College Name field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
College Name<span className="ml-1 text-xs text-red-600">*</span> | |
</label> | |
<input | |
type="text" | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
placeholder="If you are not currently studying, mention the last studied college name and school name if you completed only 12th" | |
value={formData.collegeName} | |
onChange={e => handleChange('collegeName', e.target.value)} | |
/> | |
</div> | |
{/* Current Company Name field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Current Company Name | |
</label> | |
<input | |
type="text" | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
placeholder="Mention NA if you are not working" | |
value={formData.companyName} | |
onChange={e => handleChange('companyName', e.target.value)} | |
/> | |
</div> | |
{/* Work Experience field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
Number of Years of Work Experience | |
</label> | |
<input | |
type="number" | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
placeholder="Enter 0 for no experience" | |
value={formData.workExperience} | |
onChange={e => handleChange('workExperience', e.target.value)} | |
min="0" | |
step="0.1" | |
/> | |
</div> | |
{/* CTC field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1"> | |
CTC p.a (if working) | |
</label> | |
<input | |
type="number" | |
className="w-full px-3 py-2 border border-gray-300 bg-[#F5F5F5] rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" | |
placeholder="Enter annual CTC" | |
value={formData.ctc} | |
onChange={e => handleChange('ctc', e.target.value)} | |
min="0" | |
/> | |
</div> | |
{/* Existing PAN Number field */} | |
<div> | |
<label className="block text-sm font-medium text-gray-700 mb-1">PAN Number</label> | |
<input | |
type="text" | |
className={`w-full px-3 py-2 bg-[#F5F5F5] border ${ | |
isInValidPan ? 'border-red-500' : 'border-gray-300' | |
} rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm`} | |
placeholder="Enter PAN Number" | |
value={formData.panNumber?.toUpperCase()} | |
onChange={e => handleChange('panNumber', e.target.value?.toUpperCase())} | |
maxLength={10} | |
/> | |
{isInValidPan && <span className="text-red-600 text-xs">Please enter valid PAN number</span>} | |
</div> | |
<div className="flex justify-between items-center gap-1"> | |
<div className="flex-1 h-[1px] rounded-lg bg-gray-300" aria-hidden="true" /> | |
<p className="text-sm text-gray-400"> | |
OR <span className="text-xs text-red-600">*</span> | |
</p> | |
<div className="flex-1 h-[1px] rounded-lg bg-gray-300" aria-hidden="true" /> | |
</div> | |
{/* Existing Aadhar Number field */} | |
<div> | |
<label htmlFor="aadharNumber" className="block text-sm font-medium text-gray-700 mb-1"> | |
Aadhar Number | |
</label> | |
<input | |
type="text" | |
id="aadharNumber" | |
className={`w-full px-3 py-2 border ${ | |
isInValidAadhar ? 'border-red-500' : 'border-gray-300' | |
} bg-[#F5F5F5] rounded-md shadow-sm focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 text-sm`} | |
placeholder="Enter Aadhar Number" | |
value={formData.aadharNumber} | |
onChange={e => handleChange('aadharNumber', e.target.value)} | |
pattern="\d*" | |
onKeyPress={e => { | |
if (!/[0-9]/.test(e.key)) { | |
e.preventDefault(); | |
} | |
}} | |
maxLength={12} | |
/> | |
{isInValidAadhar && <span className="text-red-600 text-xs">Please enter valid Aadhar number</span>} | |
</div> | |
</div> | |
</div> | |
); | |
} | |
``` | |
Also, you'll want to update the isDisabled function in the main component to include validation for the new required fields: | |
``` | |
const isDisabled = () => { | |
switch (currentStep) { | |
case 1: | |
const isAadharValid = detailFormData?.aadharNumber?.length === 12; | |
const isPanValid = detailFormData?.panNumber?.length === 10; | |
const hasName = !!detailFormData?.name; | |
const hasAddress = !!detailFormData?.address; | |
const hasRequiredFields = | |
!!detailFormData?.dateOfBirth && | |
!!detailFormData?.gender && | |
!!detailFormData?.parentsName && | |
!!detailFormData?.parentsEmail && | |
!!detailFormData?.parentsMobileCountry && | |
!!detailFormData?.parentsMobile && | |
!!detailFormData?.currentStatus && | |
!!detailFormData?.educationDetails && | |
!!detailFormData?.graduationYear && | |
!!detailFormData?.collegeName; | |
// Additional validation for sub-dropdowns | |
const hasStudyYearIfStudying = detailFormData?.currentStatus !== 'studying' || !!detailFormData?.studyYear; | |
const hasWorkDomainIfWorking = detailFormData?.currentStatus !== 'working' || !!detailFormData?.workDomain; | |
if (!hasName || !hasAddress || !hasRequiredFields || !hasStudyYearIfStudying || !hasWorkDomainIfWorking) { | |
return true; | |
} | |
if (detailFormData?.aadharNumber && detailFormData?.panNumber) { | |
return !isAadharValid || !isPanValid; | |
} else if (detailFormData?.aadharNumber) { | |
return !isAadharValid; | |
} else if (detailFormData?.panNumber) { | |
return !isPanValid; | |
} else { | |
return true; | |
} | |
// ... rest of the cases remain the same | |
} | |
}; | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment