From 300c4d0ce5bc12b9d4a1dc508604bf2b3215ef39 Mon Sep 17 00:00:00 2001 From: Anna-Maria Date: Wed, 16 Jul 2025 12:42:09 +0100 Subject: [PATCH 1/6] add travel reimbursement form changes --- .../post-travel_reimbursment form/form.tsx | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx b/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx new file mode 100644 index 00000000..5809b804 --- /dev/null +++ b/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx @@ -0,0 +1,253 @@ +"use client" + +import { zodResolver } from "@hookform/resolvers/zod" +import { useRouter } from "next/navigation" +import * as React from "react" +import { useForm } from "react-hook-form" +import { z } from "zod" + +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@durhack/web-components/ui/form" +import { Input } from "@durhack/web-components/ui/input" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, + SelectValueClipper, +} from "@durhack/web-components/ui/select" + +import { FormSkeleton } from "@/components/dashboard/form-skeleton" +import { FormSubmitButton } from "@/components/dashboard/form-submit-button" +import type { Application } from "@/hooks/use-application" +import { useApplicationContext } from "@/hooks/use-application-context" +import { isLoaded } from "@/lib/is-loaded" +import { updateApplication } from "@/lib/update-application" + +type travelReimbursmentFormFields = { + firstNames: string + lastNames: string + email: string + phoneNumber: string + travelFromCity: string + travelDate1: string + travelDate2: string + transport: string + returnJourney: boolean +} + +const travelReimbursmentFormSchema = z.object({ + firstNames: z.string().trim().min(1, { message: "Please provide your first name(s)" }).max(256), + lastNames: z.string().trim().min(1, { message: "Please provide your last name(s)" }).max(256), + email: z.string().trim().min(1,{ message: "Please provide your email address" }).max(256), + phoneNumber:z.string().trim().min(1,{ message: "Please provide your phone number" }).max(15), + travelFromCity: z.string().trim().min(1, { message: "Please provide the city you are travelling from" }).max(256), + travelDate1: z.string().trim().min(1, { message: "Please provide the date you are travelling to Durham in the format DD/MM/YYYY" }).max(256), + travelDate2: z.string().trim().optional(), + transport: z.enum(["train", "bus", "car", "other"]), + returnJourney: z.boolean({required_error: "Please indicate if you require a return journey",}), +}) + +/** + * This component accepts application via props, rather than via + * useApplicationContext, because it requires the application to already be loaded before being rendered. + */ +function travelReimbursmentForm({ application }: { application: Application }) { + const router = useRouter() + const { mutateApplication } = useApplicationContext() + + const form = useForm>({ + resolver: zodResolver(travelReimbursmentFormSchema), + defaultValues: { + firstNames: application.firstNames ?? "", + lastNames: application.lastNames ?? "", + }, + }) + + async function onSubmit(values: z.infer): Promise { + await updateApplication("personal", values) + await mutateApplication({ ...application, ...values }) + if (application.age == null) router.push("/dashboard/contact") + } + + return ( +
+ +
+
+ ( + + First name(s) + + + + + + )} + /> +
+
+ ( + + Last name(s) + + + + + + )} + /> +
+
+
+
+ ( + + Preferred name(s) + + + + + + )} + /> +
+
+ ( + + Pronouns +
+ + {value === "other" && } +
+ +
+ )} + /> +
+
+
+ ( + + Age as of 1st November 2025 + + + + + + )} + /> +
+ +
+ ( + + Gender + + + + )} + /> +
+ +
+ ( + + Race/Ethnicity + + + + )} + /> +
+ +
+ Save Progress +
+
+ + ) +} + +function travelReimbursmentFormSkeleton() { + return +} + +export default function PersonalPage() { + const { application, applicationIsLoading } = useApplicationContext() + + if (!isLoaded(application, applicationIsLoading)) { + return + } + + return +} From 575468ba75cdbb244e2039664c28b1dcb3c0b9b5 Mon Sep 17 00:00:00 2001 From: Anna-Maria Date: Wed, 16 Jul 2025 13:51:46 +0100 Subject: [PATCH 2/6] changes to the form --- .../post-travel_reimbursment form/form.tsx | 131 +----------------- 1 file changed, 3 insertions(+), 128 deletions(-) diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx b/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx index 5809b804..b877565d 100644 --- a/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx +++ b/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx @@ -105,131 +105,6 @@ function travelReimbursmentForm({ application }: { application: Application }) { /> -
-
- ( - - Preferred name(s) - - - - - - )} - /> -
-
- ( - - Pronouns -
- - {value === "other" && } -
- -
- )} - /> -
-
-
- ( - - Age as of 1st November 2025 - - - - - - )} - /> -
- -
- ( - - Gender - - - - )} - /> -
- -
- ( - - Race/Ethnicity - - - - )} - /> -
-
Save Progress
@@ -238,7 +113,7 @@ function travelReimbursmentForm({ application }: { application: Application }) { ) } -function travelReimbursmentFormSkeleton() { +function TravelReimbursmentFormSkeleton() { return } @@ -246,8 +121,8 @@ export default function PersonalPage() { const { application, applicationIsLoading } = useApplicationContext() if (!isLoaded(application, applicationIsLoading)) { - return + return } - return + return } From 2c1a162db4d71cc3290b225172aa78fafde58436 Mon Sep 17 00:00:00 2001 From: Anna-Maria Date: Wed, 16 Jul 2025 14:16:31 +0100 Subject: [PATCH 3/6] updates to the form (error and layout) --- .../post-travel_reimbursment form/error.tsx | 3 +++ .../post-travel_reimbursment form/form.tsx | 2 +- .../post-travel_reimbursment form/layout.tsx | 11 +++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 client/src/app/dashboard/(application)/post-travel_reimbursment form/error.tsx create mode 100644 client/src/app/dashboard/(application)/post-travel_reimbursment form/layout.tsx diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursment form/error.tsx b/client/src/app/dashboard/(application)/post-travel_reimbursment form/error.tsx new file mode 100644 index 00000000..5611be6d --- /dev/null +++ b/client/src/app/dashboard/(application)/post-travel_reimbursment form/error.tsx @@ -0,0 +1,3 @@ +"use client" + +export { FormLoadingError as default } from "@/components/dashboard/form-loading-error" diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx b/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx index b877565d..95cc82c6 100644 --- a/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx +++ b/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx @@ -117,7 +117,7 @@ function TravelReimbursmentFormSkeleton() { return } -export default function PersonalPage() { +export default function TravelReimbursmentForm() { const { application, applicationIsLoading } = useApplicationContext() if (!isLoaded(application, applicationIsLoading)) { diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursment form/layout.tsx b/client/src/app/dashboard/(application)/post-travel_reimbursment form/layout.tsx new file mode 100644 index 00000000..16f19daa --- /dev/null +++ b/client/src/app/dashboard/(application)/post-travel_reimbursment form/layout.tsx @@ -0,0 +1,11 @@ +import type * as React from "react" + +export default function PostTravelReimbursmentFormLayout({ children }: { children: React.ReactNode }) { + return ( + <> +

Post Travel Reimbursement Form +

+ {children} + + ) +} From 8f8fba1bc6f0be5f34330536605db6c57466216c Mon Sep 17 00:00:00 2001 From: Anna-Maria Date: Thu, 17 Jul 2025 14:56:30 +0100 Subject: [PATCH 4/6] name change --- .../error.tsx | 0 .../form.tsx | 67 ++++++++++++++++--- .../layout.tsx | 2 +- 3 files changed, 57 insertions(+), 12 deletions(-) rename client/src/app/dashboard/(application)/{post-travel_reimbursment form => post-travel_reimbursement form}/error.tsx (100%) rename client/src/app/dashboard/(application)/{post-travel_reimbursment form => post-travel_reimbursement form}/form.tsx (63%) rename client/src/app/dashboard/(application)/{post-travel_reimbursment form => post-travel_reimbursement form}/layout.tsx (60%) diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursment form/error.tsx b/client/src/app/dashboard/(application)/post-travel_reimbursement form/error.tsx similarity index 100% rename from client/src/app/dashboard/(application)/post-travel_reimbursment form/error.tsx rename to client/src/app/dashboard/(application)/post-travel_reimbursement form/error.tsx diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx b/client/src/app/dashboard/(application)/post-travel_reimbursement form/form.tsx similarity index 63% rename from client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx rename to client/src/app/dashboard/(application)/post-travel_reimbursement form/form.tsx index 95cc82c6..10c394c1 100644 --- a/client/src/app/dashboard/(application)/post-travel_reimbursment form/form.tsx +++ b/client/src/app/dashboard/(application)/post-travel_reimbursement form/form.tsx @@ -24,7 +24,7 @@ import { useApplicationContext } from "@/hooks/use-application-context" import { isLoaded } from "@/lib/is-loaded" import { updateApplication } from "@/lib/update-application" -type travelReimbursmentFormFields = { +type travelReimbursementFormFields = { firstNames: string lastNames: string email: string @@ -36,7 +36,7 @@ type travelReimbursmentFormFields = { returnJourney: boolean } -const travelReimbursmentFormSchema = z.object({ +const travelReimbursementFormSchema = z.object({ firstNames: z.string().trim().min(1, { message: "Please provide your first name(s)" }).max(256), lastNames: z.string().trim().min(1, { message: "Please provide your last name(s)" }).max(256), email: z.string().trim().min(1,{ message: "Please provide your email address" }).max(256), @@ -52,19 +52,19 @@ const travelReimbursmentFormSchema = z.object({ * This component accepts application via props, rather than via * useApplicationContext, because it requires the application to already be loaded before being rendered. */ -function travelReimbursmentForm({ application }: { application: Application }) { +function travelReimbursementForm({ application }: { application: Application }) { const router = useRouter() const { mutateApplication } = useApplicationContext() - const form = useForm>({ - resolver: zodResolver(travelReimbursmentFormSchema), + const form = useForm>({ + resolver: zodResolver(travelReimbursementFormSchema), defaultValues: { firstNames: application.firstNames ?? "", lastNames: application.lastNames ?? "", }, }) - async function onSubmit(values: z.infer): Promise { + async function onSubmit(values: z.infer): Promise { await updateApplication("personal", values) await mutateApplication({ ...application, ...values }) if (application.age == null) router.push("/dashboard/contact") @@ -104,25 +104,70 @@ function travelReimbursmentForm({ application }: { application: Application }) { )} /> +
+ ( + + Email + + + + + + )} + /> +
+
+ ( + + Phone number + + + + + + )} + /> +
+
+ ( + + Travel From City + + + + + + )} + /> +
- Save Progress + Submit travel reimbursement request
) } -function TravelReimbursmentFormSkeleton() { +function TravelReimbursementFormSkeleton() { return } -export default function TravelReimbursmentForm() { +export default function travelReimbursementForm() { const { application, applicationIsLoading } = useApplicationContext() if (!isLoaded(application, applicationIsLoading)) { - return + return } - return + return } diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursment form/layout.tsx b/client/src/app/dashboard/(application)/post-travel_reimbursement form/layout.tsx similarity index 60% rename from client/src/app/dashboard/(application)/post-travel_reimbursment form/layout.tsx rename to client/src/app/dashboard/(application)/post-travel_reimbursement form/layout.tsx index 16f19daa..dff76c58 100644 --- a/client/src/app/dashboard/(application)/post-travel_reimbursment form/layout.tsx +++ b/client/src/app/dashboard/(application)/post-travel_reimbursement form/layout.tsx @@ -1,6 +1,6 @@ import type * as React from "react" -export default function PostTravelReimbursmentFormLayout({ children }: { children: React.ReactNode }) { +export default function PostTravelReimbursementFormLayout({ children }: { children: React.ReactNode }) { return ( <>

Post Travel Reimbursement Form From 9c79e13955c9b390c843ae162f00f762409298d0 Mon Sep 17 00:00:00 2001 From: Anna-Maria Date: Thu, 17 Jul 2025 15:56:22 +0100 Subject: [PATCH 5/6] renamed form to page, post-travel to travel --- .../error.tsx | 0 .../layout.tsx | 0 .../page.tsx} | 14 +++++++------- 3 files changed, 7 insertions(+), 7 deletions(-) rename client/src/app/dashboard/(application)/{post-travel_reimbursement form => travel_reimbursement form}/error.tsx (100%) rename client/src/app/dashboard/(application)/{post-travel_reimbursement form => travel_reimbursement form}/layout.tsx (100%) rename client/src/app/dashboard/(application)/{post-travel_reimbursement form/form.tsx => travel_reimbursement form/page.tsx} (92%) diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursement form/error.tsx b/client/src/app/dashboard/(application)/travel_reimbursement form/error.tsx similarity index 100% rename from client/src/app/dashboard/(application)/post-travel_reimbursement form/error.tsx rename to client/src/app/dashboard/(application)/travel_reimbursement form/error.tsx diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursement form/layout.tsx b/client/src/app/dashboard/(application)/travel_reimbursement form/layout.tsx similarity index 100% rename from client/src/app/dashboard/(application)/post-travel_reimbursement form/layout.tsx rename to client/src/app/dashboard/(application)/travel_reimbursement form/layout.tsx diff --git a/client/src/app/dashboard/(application)/post-travel_reimbursement form/form.tsx b/client/src/app/dashboard/(application)/travel_reimbursement form/page.tsx similarity index 92% rename from client/src/app/dashboard/(application)/post-travel_reimbursement form/form.tsx rename to client/src/app/dashboard/(application)/travel_reimbursement form/page.tsx index 10c394c1..5a11d88c 100644 --- a/client/src/app/dashboard/(application)/post-travel_reimbursement form/form.tsx +++ b/client/src/app/dashboard/(application)/travel_reimbursement form/page.tsx @@ -24,7 +24,7 @@ import { useApplicationContext } from "@/hooks/use-application-context" import { isLoaded } from "@/lib/is-loaded" import { updateApplication } from "@/lib/update-application" -type travelReimbursementFormFields = { +type TravelReimbursementFormFields = { firstNames: string lastNames: string email: string @@ -36,7 +36,7 @@ type travelReimbursementFormFields = { returnJourney: boolean } -const travelReimbursementFormSchema = z.object({ +const TravelReimbursementFormSchema = z.object({ firstNames: z.string().trim().min(1, { message: "Please provide your first name(s)" }).max(256), lastNames: z.string().trim().min(1, { message: "Please provide your last name(s)" }).max(256), email: z.string().trim().min(1,{ message: "Please provide your email address" }).max(256), @@ -52,19 +52,19 @@ const travelReimbursementFormSchema = z.object({ * This component accepts application via props, rather than via * useApplicationContext, because it requires the application to already be loaded before being rendered. */ -function travelReimbursementForm({ application }: { application: Application }) { +function TravelReimbursementForm({ application }: { application: Application }) { const router = useRouter() const { mutateApplication } = useApplicationContext() - const form = useForm>({ - resolver: zodResolver(travelReimbursementFormSchema), + const form = useForm>({ + resolver: zodResolver(TravelReimbursementFormSchema), defaultValues: { firstNames: application.firstNames ?? "", lastNames: application.lastNames ?? "", }, }) - async function onSubmit(values: z.infer): Promise { + async function onSubmit(values: z.infer): Promise { await updateApplication("personal", values) await mutateApplication({ ...application, ...values }) if (application.age == null) router.push("/dashboard/contact") @@ -162,7 +162,7 @@ function TravelReimbursementFormSkeleton() { return } -export default function travelReimbursementForm() { +export default function TravelReimbursementFormPage() { const { application, applicationIsLoading } = useApplicationContext() if (!isLoaded(application, applicationIsLoading)) { From 090fd904ce294b630102e550ea7697d13b91659b Mon Sep 17 00:00:00 2001 From: Anna-Maria Date: Thu, 17 Jul 2025 16:05:41 +0100 Subject: [PATCH 6/6] renamed files --- .../{travel_reimbursement form => travel-reimbursement}/error.tsx | 0 .../layout.tsx | 0 .../{travel_reimbursement form => travel-reimbursement}/page.tsx | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename client/src/app/dashboard/(application)/{travel_reimbursement form => travel-reimbursement}/error.tsx (100%) rename client/src/app/dashboard/(application)/{travel_reimbursement form => travel-reimbursement}/layout.tsx (100%) rename client/src/app/dashboard/(application)/{travel_reimbursement form => travel-reimbursement}/page.tsx (100%) diff --git a/client/src/app/dashboard/(application)/travel_reimbursement form/error.tsx b/client/src/app/dashboard/(application)/travel-reimbursement/error.tsx similarity index 100% rename from client/src/app/dashboard/(application)/travel_reimbursement form/error.tsx rename to client/src/app/dashboard/(application)/travel-reimbursement/error.tsx diff --git a/client/src/app/dashboard/(application)/travel_reimbursement form/layout.tsx b/client/src/app/dashboard/(application)/travel-reimbursement/layout.tsx similarity index 100% rename from client/src/app/dashboard/(application)/travel_reimbursement form/layout.tsx rename to client/src/app/dashboard/(application)/travel-reimbursement/layout.tsx diff --git a/client/src/app/dashboard/(application)/travel_reimbursement form/page.tsx b/client/src/app/dashboard/(application)/travel-reimbursement/page.tsx similarity index 100% rename from client/src/app/dashboard/(application)/travel_reimbursement form/page.tsx rename to client/src/app/dashboard/(application)/travel-reimbursement/page.tsx