From 24dda64994dd952fca646f9115f286ac25b03a7c Mon Sep 17 00:00:00 2001 From: Leon Date: Wed, 26 Feb 2025 12:16:01 -0800 Subject: [PATCH 1/2] wip: schemas and fields --- frontend/src/pages/intake-form/IntakeForm.tsx | 89 +++--- frontend/src/pages/intake-form/fields.ts | 274 +++++++++++++++++- frontend/src/pages/intake-form/validation.ts | 149 +++++++++- 3 files changed, 442 insertions(+), 70 deletions(-) diff --git a/frontend/src/pages/intake-form/IntakeForm.tsx b/frontend/src/pages/intake-form/IntakeForm.tsx index 3fabb7b8..c4ebd1bb 100644 --- a/frontend/src/pages/intake-form/IntakeForm.tsx +++ b/frontend/src/pages/intake-form/IntakeForm.tsx @@ -5,66 +5,57 @@ import { ExperienceRoles } from './pages/ExperienceRoles'; import { Skills } from './pages/Skills'; import { ReviewAndSubmit } from './pages/ReviewAndSubmit'; import { Complete } from './pages/Complete'; -import { - experienceRolesSchema, - personalInfoSchema, - programSelectionSchema, - skillsSchema, -} from './validation'; -import { personalInfoFields, programFields } from './fields'; +import { personalDetailsSchema, programSelectionSchema } from './validation'; +import { personalDetails, programFields } from './fields'; import { useRoleContext } from '@/providers'; import { useKeycloak } from '@react-keycloak/web'; - const IntakeForm = () => { const { program } = useRoleContext(); - const {keycloak} = useKeycloak() - const {tokenParsed} = keycloak; + const { keycloak } = useKeycloak(); + const { tokenParsed } = keycloak; - if(!tokenParsed){ - return + if (!tokenParsed) { + return; } return (
- { - // TODO: Update - setTimeout(() => { - alert(JSON.stringify(values, null, 2)); - actions.setSubmitting(false); - }, 1000); - }} - > - - -
-

Intake Form

- {/* no need to pass props - access values and validation via useFormikContext() hook */} - - - - - - - -
-
+ { + // TODO: Update + setTimeout(() => { + alert(JSON.stringify(values, null, 2)); + actions.setSubmitting(false); + }, 1000); + }} + > +
+

Intake Form

+ {/* no need to pass props - access values and validation via useFormikContext() hook */} + + + + + + + +
+ ); }; - export default IntakeForm; - diff --git a/frontend/src/pages/intake-form/fields.ts b/frontend/src/pages/intake-form/fields.ts index 468e4662..cb1bd07d 100644 --- a/frontend/src/pages/intake-form/fields.ts +++ b/frontend/src/pages/intake-form/fields.ts @@ -3,36 +3,282 @@ import { Program } from '@/common'; export interface ProgramFields { program?: Program; } -// program selection +// core team program selection export const programFields: ProgramFields = { program: undefined, }; -export interface PersonalInfoFields { +// acknowledgement for selected program stream(s) +export interface AcknowledgementEmcr { + expectations: boolean; + supervisorApproval: boolean; +} + +export type AcknowledgementBcws = AcknowledgementEmcr & { + training: boolean; + willingnessStatement: boolean; + parQ: boolean; +}; + +export type AcknowledgementBoth = AcknowledgementEmcr & AcknowledgementBcws; + +export const acknowledgementEmcr: AcknowledgementEmcr = { + expectations: false, + supervisorApproval: false, +}; + +export const acknowledgementBcws: AcknowledgementBcws = { + expectations: false, + supervisorApproval: false, + training: false, + willingnessStatement: false, + parQ: false, +}; + +export const acknowledgementBoth: AcknowledgementBoth = { + expectations: false, + supervisorApproval: false, + training: false, + willingnessStatement: false, + parQ: false, +}; + +// personal & employee information + +// personal details + +export interface PersonalDetails { firstName: string; lastName: string; - email: string; - // ...etc + primaryPhone: string; + secondaryPhone?: string; + homeLocation: string; } -// personal info -export const personalInfoFields: PersonalInfoFields = { +export const personalDetails: PersonalDetails = { firstName: '', lastName: '', - email: '', - // ...etc + primaryPhone: '', + secondaryPhone: '', + homeLocation: '', +}; + +// employment details + +export interface EmploymentDetails { + jobTitle: string; + bcGovEmployeeNumber: string; + bcGovEmail: string; + workPhone: string; + ministry: string; + division: string; + deptId: string; + purchaseCardHolder: string; +} + +export const employmentDetails: EmploymentDetails = { + jobTitle: '', + bcGovEmployeeNumber: '', + bcGovEmail: '', + workPhone: '', + ministry: '', + division: '', + deptId: '', + purchaseCardHolder: '', +}; + +// supervisor and liaison details, travel preferences + +export interface SupervisorDetails { + supervisorFirstName: string; + supervisorLastName: string; + supervisorEmail: string; + supervisorPhone?: string; +} +export interface LiaisonDetails { + liaisonUnknown?: boolean; + liaisonFirstName?: string; + liaisonLastName?: string; + liaisonEmail?: string; + liaisonPhone?: string; +} +export interface TravelDetails { + travelPreferences: string; +} + +export const supervisorDetails: SupervisorDetails = { + supervisorFirstName: '', + supervisorLastName: '', + supervisorEmail: '', + supervisorPhone: '', +}; + +export const liaisonDetails: LiaisonDetails = { + liaisonUnknown: false, + liaisonFirstName: '', + liaisonLastName: '', + liaisonEmail: '', + liaisonPhone: '', +}; + +export const travelDetails: TravelDetails = { + travelPreferences: '', +}; + +// emergency contact details + +export interface EmergencyContactDetails { + emergencyFirstName: string; + emergencyLastName: string; + emergencyPhone: string; + emergencyRelationship: string; +} + +export const emergencyContactDetails: EmergencyContactDetails = { + emergencyFirstName: '', + emergencyLastName: '', + emergencyPhone: '', + emergencyRelationship: '', +}; + +// experience and section interests + +// emcr section(s) interest + +export interface GeneralEmergencyManagementExperience { + directExperience: boolean; + preocExperience: boolean; + peccExperience: boolean; + indigenousExperience: boolean; +} + +export const generalEmergencyManagementExperience: GeneralEmergencyManagementExperience = + { + directExperience: false, + preocExperience: false, + peccExperience: false, + indigenousExperience: false, + }; + +export interface SectionChoiceEmcr { + firstChoiceEmcr: string; + secondChoiceEmcr?: string; + thirdChoiceEmcr?: string; +} + +export const sectionChoiceEmcr: SectionChoiceEmcr = { + firstChoiceEmcr: '', + secondChoiceEmcr: '', + thirdChoiceEmcr: '', +}; + +export interface SectionInterestEmcr { + advancePlanningUnit?: boolean; + deputyDirector?: boolean; + ess?: boolean; + finance?: boolean; + firstNationsBranch?: boolean; + liaison?: boolean; + logistics?: boolean; + operations?: boolean; + planning?: boolean; + recovery?: boolean; +} + +export const sectionInterestEmcr: SectionInterestEmcr = { + advancePlanningUnit: false, + deputyDirector: false, + ess: false, + finance: false, + firstNationsBranch: false, + liaison: false, + logistics: false, + operations: false, + planning: false, + recovery: false, +}; + +// bcws section(s) & role(s) interest + +export interface SectionChoiceBcws { + firstChoiceBcws: string; + secondChoiceBcws?: string; + thirdChoiceBcws?: string; +} + +export const sectionChoiceBcws: SectionChoiceBcws = { + firstChoiceBcws: '', + secondChoiceBcws: '', + thirdChoiceBcws: '', +}; + +export interface BcwsRole { + id: string; + name: string; + section: string; +} + +export interface SectionRolesBcws { + planning?: BcwsRole[]; + logistics?: BcwsRole[]; + finance?: BcwsRole[]; + operations?: BcwsRole[]; + command?: BcwsRole[]; + aviation?: BcwsRole[]; +} + +export const sectionRolesBcws: SectionRolesBcws = { + planning: [], + logistics: [], + finance: [], + operations: [], + command: [], + aviation: [], +}; + +// other skills & qualifications + +export interface LanguageSkills { + languages?: { language: string; proficiencyLevel: string }[]; +} + +export const languageSkills: LanguageSkills = { + languages: [], }; -// experience & roles +export interface SoftwareSkills { + tools?: { tool: string; proficiencyLevel: string }[]; +} -// skills +export const softwareSkills: SoftwareSkills = { + tools: [], +}; -// review and submit +export interface Certifications { + highestOfaCompleted?: string; + driverLicenseQualifications?: string[]; + certifiedPfa: string; + otherCertifications?: string[]; +} +export const certifications: Certifications = { + highestOfaCompleted: '', + driverLicenseQualifications: [], + certifiedPfa: '', + otherCertifications: [], +}; +// review & submit + +export interface ReviewAndSubmit { + acknowledgeSubmit: boolean; +} + +export const reviewAndSubmit: ReviewAndSubmit = { + acknowledgeSubmit: false, +}; // form interface export interface IntakeFormInterface { - programFields: ProgramFields - personalInfoFields: PersonalInfoFields - + programFields: ProgramFields; + personalDetails: PersonalDetails; } diff --git a/frontend/src/pages/intake-form/validation.ts b/frontend/src/pages/intake-form/validation.ts index 1af33527..b9d3dd7b 100644 --- a/frontend/src/pages/intake-form/validation.ts +++ b/frontend/src/pages/intake-form/validation.ts @@ -1,16 +1,151 @@ import * as Yup from 'yup'; -export const programSelectionSchema = Yup.object().shape({}) +export const programSelectionSchema = Yup.object().shape({ + program: Yup.string().required('Program is required'), +}); -export const experienceRolesSchema = Yup.object().shape({}) +export const acknowledgementSchemaEmcr = Yup.object().shape({ + expectations: Yup.boolean().required(), + supervisorApproval: Yup.boolean().required(), +}); -export const skillsSchema = Yup.object().shape({}) +export const acknowledgementSchemaBcws = Yup.object().shape({ + expectations: Yup.boolean().required(), + supervisorApproval: Yup.boolean().required(), + training: Yup.boolean().required(), + willingnessStatement: Yup.boolean().required(), + parQ: Yup.boolean().required(), +}); -export const personalInfoSchema = Yup.object().shape({ - firstName: Yup.string().required('First Name is required'), -}) +export const acknowledgementSchemaBoth = Yup.object().shape({ + expectations: Yup.boolean().required(), + supervisorApproval: Yup.boolean().required(), + training: Yup.boolean().required(), + willingnessStatement: Yup.boolean().required(), + parQ: Yup.boolean().required(), +}); -export const reviewAndSubmitSchema = Yup.object().shape({}) +export const personalDetailsSchema = Yup.object().shape({ + firstName: Yup.string().required('First name is required'), + lastName: Yup.string().required('Last name is required'), + primaryPhone: Yup.string().required('Primary phone is required'), + secondaryPhone: Yup.string(), + homeLocation: Yup.string().required('Home location is required'), +}); +export const employmentDetailsSchema = Yup.object().shape({ + jobTitle: Yup.string().required('Job title is required'), + bcGovEmployeeNumber: Yup.string().required('Employee number is required'), + bcGovEmail: Yup.string().required('Email is required'), + workPhone: Yup.string().required('Work phone is required'), + ministry: Yup.string().required('Ministry is required'), + division: Yup.string().required('Division is required'), + deptId: Yup.string().required('Pay list (Dept ID) is required'), + purchaseCardHolder: Yup.string().required('Purchase card holder is required'), +}); +export const supervisorDetailsSchema = Yup.object().shape({ + supervisorFirstName: Yup.string().required("Supervisor's first name is required"), + supervisorLastName: Yup.string().required("Supervisor's last name is required"), + supervisorEmail: Yup.string().required("Supervisor's email is required"), + supervisorPhone: Yup.string(), +}); +export const liaisonDetailsSchema = Yup.object().shape({ + liaisonUnknown: Yup.string(), + liaisonFirstName: Yup.string(), + liaisonLastName: Yup.string(), + liaisonEmail: Yup.string(), + liaisonPhone: Yup.string(), +}); + +export const travelDetailsSchema = Yup.object().shape({ + travelPreferences: Yup.string(), +}); + +export const emergencyContactDetailsSchema = Yup.object().shape({ + emergencyFirstName: Yup.string().required( + "Emergency contact's first name is required", + ), + emergencyLastName: Yup.string().required( + "Emergency contact's last name is required", + ), + emergencyPhone: Yup.string().required("Emergency contact's phone is required"), + emergencyRelationship: Yup.string().required('Relationship is required'), +}); + +export const generalEmergencyManagementExperienceSchema = Yup.object().shape({ + directExperience: Yup.boolean().required(), + preocExperience: Yup.boolean().required(), + peccExperience: Yup.boolean().required(), + indigenousExperience: Yup.boolean().required(), +}); + +export const sectionChoiceEmcrSchema = Yup.object().shape({ + firstChoiceEmcr: Yup.string().required('First choice is required'), + secondChoiceEmcr: Yup.string(), + thirdChoiceEmcr: Yup.string(), +}); + +export const sectionInterestEmcrSchema = Yup.object().shape({ + advancePlanningUnit: Yup.boolean(), + deputyDirector: Yup.boolean(), + ess: Yup.boolean(), + finance: Yup.boolean(), + firstNationsBranch: Yup.boolean(), + liaison: Yup.boolean(), + logistics: Yup.boolean(), + operations: Yup.boolean(), + planning: Yup.boolean(), + recovery: Yup.boolean(), +}); + +export const sectionChoiceBcwsSchema = Yup.object().shape({ + firstChoiceBcws: Yup.string().required('First choice is required'), + secondChoiceBcws: Yup.string(), + thirdChoiceBcws: Yup.string(), +}); + +export const bcwsRoleSchema = Yup.object().shape({ + id: Yup.string(), + name: Yup.string(), + section: Yup.string(), +}); + +export const sectionRolesBcwsSchema = Yup.object().shape({ + planning: Yup.array().of(bcwsRoleSchema), + logistics: Yup.array().of(bcwsRoleSchema), + finance: Yup.array().of(bcwsRoleSchema), + operations: Yup.array().of(bcwsRoleSchema), + command: Yup.array().of(bcwsRoleSchema), + aviation: Yup.array().of(bcwsRoleSchema), +}); + +export const languageSkillsSchema = Yup.object().shape({ + languages: Yup.array().of( + Yup.object().shape({ + language: Yup.string().required('Language is required'), + proficiencyLevel: Yup.string().required('Proficiency level is required'), + }), + ), +}); + +export const softwareSkillsSchema = Yup.object().shape({ + languages: Yup.array().of( + Yup.object().shape({ + tool: Yup.string().required('Tool is required'), + proficiencyLevel: Yup.string().required('Proficiency level is required'), + }), + ), +}); + +export const certificationsSchema = Yup.object().shape({ + highestOfaCompleted: Yup.string(), + driverLicenseQualifications: Yup.array().of(Yup.string()), + certifiedPfa: Yup.string().required('PFA is required'), + otherCertifications: Yup.array().of(Yup.string()), +}); + +export const reviewAndSubmitSchema = Yup.object().shape({ + acknowledgeSubmit: Yup.boolean().required('You must acknowledge your submission'), +}); From 2b82791cb738190d0cf82f45ad7d95f3b102568b Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 27 Feb 2025 10:13:34 -0800 Subject: [PATCH 2/2] fix: make variable names same as in constants.ts --- frontend/src/pages/intake-form/fields.ts | 113 ++++++++++++----------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/frontend/src/pages/intake-form/fields.ts b/frontend/src/pages/intake-form/fields.ts index cb1bd07d..90b0ee67 100644 --- a/frontend/src/pages/intake-form/fields.ts +++ b/frontend/src/pages/intake-form/fields.ts @@ -1,4 +1,11 @@ -import { Program } from '@/common'; +// common +import { + BcwsRoleInterface, + Languages, + Location, + PersonnelTool, + Program, +} from '@/common'; export interface ProgramFields { program?: Program; @@ -11,11 +18,11 @@ export const programFields: ProgramFields = { // acknowledgement for selected program stream(s) export interface AcknowledgementEmcr { expectations: boolean; - supervisorApproval: boolean; + approvedBySupervisor: boolean; } export type AcknowledgementBcws = AcknowledgementEmcr & { - training: boolean; + orientation: boolean; willingnessStatement: boolean; parQ: boolean; }; @@ -24,21 +31,21 @@ export type AcknowledgementBoth = AcknowledgementEmcr & AcknowledgementBcws; export const acknowledgementEmcr: AcknowledgementEmcr = { expectations: false, - supervisorApproval: false, + approvedBySupervisor: false, }; export const acknowledgementBcws: AcknowledgementBcws = { expectations: false, - supervisorApproval: false, - training: false, + approvedBySupervisor: false, + orientation: false, willingnessStatement: false, parQ: false, }; export const acknowledgementBoth: AcknowledgementBoth = { expectations: false, - supervisorApproval: false, - training: false, + approvedBySupervisor: false, + orientation: false, willingnessStatement: false, parQ: false, }; @@ -52,38 +59,38 @@ export interface PersonalDetails { lastName: string; primaryPhone: string; secondaryPhone?: string; - homeLocation: string; + homeLocation?: Location; } export const personalDetails: PersonalDetails = { firstName: '', lastName: '', primaryPhone: '', secondaryPhone: '', - homeLocation: '', + homeLocation: undefined, }; // employment details export interface EmploymentDetails { jobTitle: string; - bcGovEmployeeNumber: string; - bcGovEmail: string; + employeeId: string; + email: string; workPhone: string; ministry: string; division: string; - deptId: string; - purchaseCardHolder: string; + paylistId: string; + purchaseCardHolder: boolean; } export const employmentDetails: EmploymentDetails = { jobTitle: '', - bcGovEmployeeNumber: '', - bcGovEmail: '', + employeeId: '', + email: '', workPhone: '', ministry: '', division: '', - deptId: '', - purchaseCardHolder: '', + paylistId: '', + purchaseCardHolder: false, }; // supervisor and liaison details, travel preferences @@ -99,7 +106,7 @@ export interface LiaisonDetails { liaisonFirstName?: string; liaisonLastName?: string; liaisonEmail?: string; - liaisonPhone?: string; + liaisonPhoneNumber?: string; } export interface TravelDetails { travelPreferences: string; @@ -117,7 +124,7 @@ export const liaisonDetails: LiaisonDetails = { liaisonFirstName: '', liaisonLastName: '', liaisonEmail: '', - liaisonPhone: '', + liaisonPhoneNumber: '', }; export const travelDetails: TravelDetails = { @@ -127,17 +134,17 @@ export const travelDetails: TravelDetails = { // emergency contact details export interface EmergencyContactDetails { - emergencyFirstName: string; - emergencyLastName: string; - emergencyPhone: string; - emergencyRelationship: string; + emergencyContactFirstName: string; + emergencyContactLastName: string; + emergencyContactPhoneNumber: string; + emergencyContactRelationship: string; } export const emergencyContactDetails: EmergencyContactDetails = { - emergencyFirstName: '', - emergencyLastName: '', - emergencyPhone: '', - emergencyRelationship: '', + emergencyContactFirstName: '', + emergencyContactLastName: '', + emergencyContactPhoneNumber: '', + emergencyContactRelationship: '', }; // experience and section interests @@ -160,15 +167,15 @@ export const generalEmergencyManagementExperience: GeneralEmergencyManagementExp }; export interface SectionChoiceEmcr { - firstChoiceEmcr: string; - secondChoiceEmcr?: string; - thirdChoiceEmcr?: string; + firstChoiceFunction: string; + secondChoiceFunction?: string; + thirdChoiceFunction?: string; } export const sectionChoiceEmcr: SectionChoiceEmcr = { - firstChoiceEmcr: '', - secondChoiceEmcr: '', - thirdChoiceEmcr: '', + firstChoiceFunction: '', + secondChoiceFunction: '', + thirdChoiceFunction: '', }; export interface SectionInterestEmcr { @@ -200,30 +207,24 @@ export const sectionInterestEmcr: SectionInterestEmcr = { // bcws section(s) & role(s) interest export interface SectionChoiceBcws { - firstChoiceBcws: string; - secondChoiceBcws?: string; - thirdChoiceBcws?: string; + firstChoiceSection: string; + secondChoiceSection?: string; + thirdChoiceSection?: string; } export const sectionChoiceBcws: SectionChoiceBcws = { - firstChoiceBcws: '', - secondChoiceBcws: '', - thirdChoiceBcws: '', + firstChoiceSection: '', + secondChoiceSection: '', + thirdChoiceSection: '', }; -export interface BcwsRole { - id: string; - name: string; - section: string; -} - export interface SectionRolesBcws { - planning?: BcwsRole[]; - logistics?: BcwsRole[]; - finance?: BcwsRole[]; - operations?: BcwsRole[]; - command?: BcwsRole[]; - aviation?: BcwsRole[]; + planning?: BcwsRoleInterface[]; + logistics?: BcwsRoleInterface[]; + finance?: BcwsRoleInterface[]; + operations?: BcwsRoleInterface[]; + command?: BcwsRoleInterface[]; + aviation?: BcwsRoleInterface[]; } export const sectionRolesBcws: SectionRolesBcws = { @@ -238,7 +239,7 @@ export const sectionRolesBcws: SectionRolesBcws = { // other skills & qualifications export interface LanguageSkills { - languages?: { language: string; proficiencyLevel: string }[]; + languages?: Languages[]; } export const languageSkills: LanguageSkills = { @@ -246,21 +247,21 @@ export const languageSkills: LanguageSkills = { }; export interface SoftwareSkills { - tools?: { tool: string; proficiencyLevel: string }[]; + tools?: PersonnelTool[]; } export const softwareSkills: SoftwareSkills = { tools: [], }; -export interface Certifications { +export interface OtherCertifications { highestOfaCompleted?: string; driverLicenseQualifications?: string[]; certifiedPfa: string; otherCertifications?: string[]; } -export const certifications: Certifications = { +export const otherCertifications: OtherCertifications = { highestOfaCompleted: '', driverLicenseQualifications: [], certifiedPfa: '',