From 047476af2a3dcb2f5b8bfd2b112dc858fdd44b2b Mon Sep 17 00:00:00 2001 From: EETagent Date: Tue, 6 Dec 2022 16:01:23 +0100 Subject: [PATCH] feat: nested form --- frontend/src/lib/stores/candidate.ts | 34 +-- .../(authenticated)/register/+page.svelte | 196 +++++++++++------- 2 files changed, 139 insertions(+), 91 deletions(-) diff --git a/frontend/src/lib/stores/candidate.ts b/frontend/src/lib/stores/candidate.ts index 0d152af..e0ba7ee 100644 --- a/frontend/src/lib/stores/candidate.ts +++ b/frontend/src/lib/stores/candidate.ts @@ -1,21 +1,25 @@ import { writable } from 'svelte/store'; export interface CandidateData { - name?: string; - surname?: string; - birthplace?: string; - birthdate?: string; - address?: string; - telephone?: string; - citizenship?: string; - email?: string; - sex?: string; - study?: string; - personalIdNumber?: string; - parentName?: string; - parentSurname?: string; - parentTelephone?: string; - parentEmail?: string; + candidate: { + name?: string; + surname?: string; + birthplace?: string; + birthdate?: string; + address?: string; + telephone?: string; + citizenship?: string; + email?: string; + sex?: string; + study?: string; + personalIdNumber?: string; + }; + parents: Array<{ + name?: string; + surname?: string; + telephone?: string; + email?: string; + }>; } export interface CandidatePreview { diff --git a/frontend/src/routes/(candidate)/(authenticated)/register/+page.svelte b/frontend/src/routes/(candidate)/(authenticated)/register/+page.svelte index 107bdc6..534a62f 100644 --- a/frontend/src/routes/(candidate)/(authenticated)/register/+page.svelte +++ b/frontend/src/routes/(candidate)/(authenticated)/register/+page.svelte @@ -14,54 +14,96 @@ import TextField from '$lib/components/textfield/TextField.svelte'; import { createForm } from 'svelte-forms-lib'; + import type { Writable } from 'svelte/store'; import * as yup from 'yup'; const pageCount = 3; let pageIndex = 0; let pagesFilled = 0; - const formInitialValues = { - name: '', - surname: '', - email: '', - telephone: '', - birthplace: '', - birthdate: '', - sex: '', - address: '', - citizenship: '', - personalIdNumber: '', - study: '', - parentName: '', - parentSurname: '', - parentTelephone: '', - parentEmail: '' + interface FormInterface + { + candidate: { + name: string; + surname: string; + email: string; + telephone: string; + birthplace: string; + birthdate: string; + sex: string; + address: string; + citizenship: string; + personalIdNumber: string; + study: string; + } + parents: Array<{ + name: string; + surname: string; + email: string; + telephone: string; + }>; + + } + const formInitialValues: FormInterface = { + candidate: { + name: '', + surname: '', + email: '', + telephone: '', + birthplace: '', + birthdate: '', + sex: '', + address: '', + citizenship: '', + personalIdNumber: '', + study: '' + }, + parents: [ + { + name: '', + surname: '', + email: '', + telephone: '' + }, + { + name: '', + surname: '', + email: '', + telephone: '' + } + ] }; const { form, errors, handleSubmit, handleChange } = createForm({ initialValues: formInitialValues, validationSchema: yup.object().shape({ - name: yup.string().required(), - surname: yup.string(), - email: yup.string().email().required(), - telephone: yup - .string() - .required() - .matches(/^\+\d{1,3} \d{3} \d{3} \d{3}$/), - birthplace: yup.string().required(), - birthdate: yup.string().required(), - sex: yup.string(), - address: yup.string().required(), - citizenship: yup.string().required(), - personalIdNumber: yup.string().required(), - study: yup.string().required(), - parentName: yup.string(), - parentSurname: yup.string(), - parentTelephone: yup - .string() - .required() - .matches(/^\+\d{1,3} \d{3} \d{3} \d{3}$/), - parentEmail: yup.string().email().required() + candidate: yup.object().shape({ + name: yup.string().required(), + surname: yup.string(), + email: yup.string().email().required(), + telephone: yup + .string() + .required() + .matches(/^\+\d{1,3} \d{3} \d{3} \d{3}$/), + birthplace: yup.string().required(), + birthdate: yup.string().required(), + sex: yup.string(), + address: yup.string().required(), + citizenship: yup.string().required(), + personalIdNumber: yup.string().required(), + study: yup.string().required() + }).required(), + parents: yup.array().of( + yup.object().shape({ + name: yup.string().required(), + surname: yup.string().required(), + email: yup.string().email().required(), + telephone: yup + .string() + .required() + .matches(/^\+\d{1,3} \d{3} \d{3} \d{3}$/), + }) + ).required() }), onSubmit: async (values) => { @@ -70,7 +112,7 @@ console.log('submit'); // @ts-ignore // love javascript delete values.undefined; - values.birthdate = '2000-01-01'; // TODO: reformat user typed date + values.candidate.birthdate = '2000-01-01'; // TODO: reformat user typed date await apiFillDetails(values); goto('/dashboard'); } catch (e) { @@ -80,35 +122,35 @@ } }); - $: console.log($errors); + $: typedErrors = errors as Writable; const isPageInvalid = (): boolean => { switch (pageIndex) { case 0: - if ($errors.name || $errors.email || $errors.telephone) { + if ($typedErrors["candidate"]["name"] || $typedErrors["candidate"]["email"] || $typedErrors["candidate"]["telephone"]) { return true; } break; case 1: if ( - /* $errors.birthdurname || */ $errors.birthplace || - $errors.birthdate /* || $errors.sex */ + /* $typedErrors.birthdurname || */ $typedErrors["candidate"]["birthplace"] || + $typedErrors["candidate"]["birthdate"] /* || $typedErrors.sex */ ) { return true; } break; case 2: - if ($errors.address || $errors.parentEmail || $errors.parentTelephone) { + if ($typedErrors["candidate"]["address"] || $typedErrors["parents"][0]["email"] || $typedErrors["parents"][0]["telephone"]) { return true; } break; case 3: if ( - $errors.citizenship || - $errors.personalIdNumber || - $errors.study //|| - // $errors.applicationId + $typedErrors["candidate"]["citizenship"] || + $typedErrors["candidate"]["personalIdNumber"] || + $typedErrors["candidate"]["study"] //|| + // $typedErrors.applicationId ) { return true; } @@ -135,27 +177,27 @@
@@ -169,23 +211,23 @@
-
+
@@ -194,17 +236,17 @@
@@ -219,9 +261,9 @@
@@ -229,17 +271,17 @@
@@ -254,9 +296,9 @@
@@ -267,16 +309,16 @@
@@ -295,6 +337,7 @@ pagesFilled++; pageIndex++; } + // @ts-ignore errors.set(formInitialValues); }} value={pageIndex === pageCount ? 'Odeslat' : 'Pokračovat'} @@ -315,6 +358,7 @@ if (isPageInvalid()) return; pagesFilled++; pageIndex++; + // @ts-ignore errors.set(formInitialValues); } }}