Important: When you begin this ticket, create a new branch from feat/registration-rework and not main. When you open a PR, open it into feat/registration-rework and not main.
Description
Faculty selection is being capped at 2, and the current "other faculty" free-text field is being replaced by a separate majors section where users can type up to 4 major/specialisation entries. Faculties and majors are independent — majors are not tied to specific faculties.
This replaces the current approach where faculty is an uncapped multi-select checkbox group with an "other" option and free-text fallback.
Requirements
- Cap faculty checkbox selection at 2 (must work without JS — server-side validation in
actions.ts rejecting more than 2, with a clear error message; optional client-side JS enhancement to disable remaining checkboxes once 2 are selected)
- Remove the "Other" faculty checkbox and
otherFaculty free-text field — custom faculties are no longer supported; the fixed checkbox list is the complete set
- Add a majors/specialisation section: up to 4 free-text inputs where the user types their major(s)
- Majors are not faculty-specific — they're a flat list, independent of which faculties are checked
- Each major entry should respect
MAX_LENGTHS (MAX_LENGTHS.major = 40 in constants.ts)
- Remove the
otherFaculty merge logic from actions.ts's case "final" (mergedPrev block) — no longer needed since "other" is gone
- Remove
otherFaculty from RegistrationDraft type, stripIrrelevantFields, and the NewUoaPage component (the useRef + onInput auto-check enhancement is also removed, since it was specifically for the "Other" checkbox)
- Update
actions.ts's case "newUoa" validation for the new constraints (max 2 faculties, max 4 majors, no otherFaculty)
- Update
toParsedSubmission to map majors from the draft to ParsedRegistrationFormSubmission
Acceptance Criteria
Notes
Does not depend on ticket #83 for form UI or server action work - the page components, actions.ts validation, and draft cookie flow
can all be built and tested independently. Ticket #83 's schema changes are only needed for end-to-end persistence (the final submission writing to Postgres), which is wired in ticket #87.
For no-JS, the "add another major" interaction can use the same server-round-trip pattern as back-navigation: a submit button with
intent="addMajor" increments a majorCount in the cookie draft and re-renders the page with one more input. Starts at 1, caps at MAX_MAJORS.
Important: When you begin this ticket, create a new branch from feat/registration-rework and not main. When you open a PR, open it into feat/registration-rework and not main.
Description
Faculty selection is being capped at 2, and the current "other faculty" free-text field is being replaced by a separate majors section where users can type up to 4 major/specialisation entries. Faculties and majors are independent — majors are not tied to specific faculties.
This replaces the current approach where faculty is an uncapped multi-select checkbox group with an "other" option and free-text fallback.
Requirements
actions.tsrejecting more than 2, with a clear error message; optional client-side JS enhancement to disable remaining checkboxes once 2 are selected)otherFacultyfree-text field — custom faculties are no longer supported; the fixed checkbox list is the complete setMAX_LENGTHS(MAX_LENGTHS.major= 40 inconstants.ts)otherFacultymerge logic fromactions.ts'scase "final"(mergedPrevblock) — no longer needed since "other" is goneotherFacultyfromRegistrationDrafttype,stripIrrelevantFields, and theNewUoaPagecomponent (theuseRef+onInputauto-check enhancement is also removed, since it was specifically for the "Other" checkbox)actions.ts'scase "newUoa"validation for the new constraints (max 2 faculties, max 4 majors, nootherFaculty)toParsedSubmissionto mapmajorsfrom the draft toParsedRegistrationFormSubmissionAcceptance Criteria
otherFacultyfield are removed from the UI and fromactions.tsmergedPrev/otherFacultymerge logic incase "final"is removedNotes
Does not depend on ticket #83 for form UI or server action work - the page components, actions.ts validation, and draft cookie flow
can all be built and tested independently. Ticket #83 's schema changes are only needed for end-to-end persistence (the final submission writing to Postgres), which is wired in ticket #87.
For no-JS, the "add another major" interaction can use the same server-round-trip pattern as back-navigation: a submit button with
intent="addMajor" increments a majorCount in the cookie draft and re-renders the page with one more input. Starts at 1, caps at MAX_MAJORS.