diff --git a/package.json b/package.json
index 4946556688..7e91ddd465 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
"@gsap/react": "2.1.1",
"@headlessui/react": "2.1.0",
"@hookform/error-message": "2.0.1",
- "@hookform/resolvers": "3.3.4",
+ "@hookform/resolvers": "3.9.0",
"@paypal/react-paypal-js": "8.3.0",
"@radix-ui/react-slider": "1.1.2",
"@radix-ui/react-tooltip": "1.1.2",
@@ -62,7 +62,7 @@
"react-dropzone": "14.2.3",
"react-fast-marquee": "1.6.4",
"react-helmet": "6.1.0",
- "react-hook-form": "7.51.5",
+ "react-hook-form": "7.53.0",
"react-player": "2.16.0",
"react-redux": "9.1.2",
"react-router-dom": "6.23.0",
diff --git a/src/pages/Registration/Steps/ContactDetails/Form/ReferralMethodSelector.tsx b/src/pages/Registration/Steps/ContactDetails/Form/ReferralMethodSelector.tsx
new file mode 100644
index 0000000000..cd49dd1491
--- /dev/null
+++ b/src/pages/Registration/Steps/ContactDetails/Form/ReferralMethodSelector.tsx
@@ -0,0 +1,73 @@
+import {
+ Field,
+ Label,
+ Listbox,
+ ListboxButton,
+ ListboxOption,
+ ListboxOptions,
+} from "@headlessui/react";
+import Icon from "components/Icon";
+import { forwardRef } from "react";
+import { referralOptions } from "../constants";
+import type { ReferralOption } from "./schema";
+
+interface Props {
+ disabled?: boolean;
+ value: ReferralOption;
+ onChange: (value: ReferralOption) => void;
+ error?: string;
+ classes?: string;
+}
+
+function Star() {
+ return *;
+}
+
+export const ReferralMethodSelector = forwardRef(
+ function List({ classes = "", ...props }, ref) {
+ return (
+
+
+
+
+ {props.value.label}
+
+
+
+ {referralOptions.map((o) => (
+
+ {o.label}
+
+ ))}
+
+
+ {props.error}
+
+
+
+ );
+ }
+);
diff --git a/src/pages/Registration/Steps/ContactDetails/Form/RoleSelector.tsx b/src/pages/Registration/Steps/ContactDetails/Form/RoleSelector.tsx
new file mode 100644
index 0000000000..83a79620e4
--- /dev/null
+++ b/src/pages/Registration/Steps/ContactDetails/Form/RoleSelector.tsx
@@ -0,0 +1,74 @@
+import {
+ Field,
+ Label,
+ Listbox,
+ ListboxButton,
+ ListboxOption,
+ ListboxOptions,
+} from "@headlessui/react";
+import Icon from "components/Icon";
+import { forwardRef } from "react";
+import { roleOptions } from "../constants";
+import type { RoleOption } from "./schema";
+
+interface Props {
+ disabled?: boolean;
+ value: RoleOption;
+ onChange: (value: RoleOption) => void;
+ error?: string;
+ classes?: string;
+}
+
+function Star() {
+ return *;
+}
+
+export const RoleSelector = forwardRef(function List(
+ { classes = "", ...props },
+ ref
+) {
+ return (
+
+
+
+
+ {props.value.label}
+
+
+
+ {roleOptions.map((o) => (
+
+ {o.label}
+
+ ))}
+
+
+ {props.error}
+
+
+
+ );
+});
diff --git a/src/pages/Registration/Steps/ContactDetails/Form/index.tsx b/src/pages/Registration/Steps/ContactDetails/Form/index.tsx
index 1d1e6dda89..08588b9a00 100644
--- a/src/pages/Registration/Steps/ContactDetails/Form/index.tsx
+++ b/src/pages/Registration/Steps/ContactDetails/Form/index.tsx
@@ -1,18 +1,72 @@
-import type { ReferralMethod, Role } from "@better-giving/registration/models";
+import { Field, Input, Label } from "@headlessui/react";
import LoadText from "components/LoadText";
-import { Selector } from "components/Selector";
-import { Field, Label } from "components/form";
import { APP_NAME } from "constants/env";
-import { referralOptions, roleOptions } from "../constants";
-import type { FormValues as FV } from "../types";
-import useSubmit from "./useSubmit";
+import { useAuthenticatedUser } from "contexts/Auth";
+import { useErrorContext } from "contexts/ErrorContext";
+import type { SubmitHandler } from "react-hook-form";
+import { useNavigate } from "react-router-dom";
+import { useUpdateRegMutation } from "services/aws/registration";
+import { steps } from "../../../routes";
+import { useRegState } from "../../StepGuard";
+import { ReferralMethodSelector } from "./ReferralMethodSelector";
+import { RoleSelector } from "./RoleSelector";
+import type { FV } from "./schema";
+import { useRhf } from "./useRhf";
+
+function Star() {
+ return *;
+}
export default function Form({ classes = "" }: { classes?: string }) {
- const { submit, isSubmitting } = useSubmit();
+ const state = useRegState<1>();
+ const user = useAuthenticatedUser();
+ const {
+ register,
+ errors,
+ orgRole,
+ onOrgRoleChange,
+ orgRoleRef,
+ referralMethod,
+ onReferralMethodChange,
+ referralMethodRef,
+ isDirty,
+ handleSubmit,
+ isSubmitting,
+ } = useRhf(state.data, user);
+ const navigate = useNavigate();
+
+ const [updateReg] = useUpdateRegMutation();
+ const { handleError } = useErrorContext();
+
+ const submit: SubmitHandler = async (fv) => {
+ try {
+ if (!isDirty && state.data.contact) {
+ return navigate(`../${steps.orgDetails}`, { state: state.data.init }); // go to latest step
+ }
+
+ const { org_role, referral_method, registrant_id, ...rest } = fv;
+
+ await updateReg({
+ type: "contact",
+ ...rest,
+ org_role: org_role.value,
+ referral_method: referral_method.value,
+ id: state.data.init.id,
+ }).unwrap();
+
+ navigate(`../${steps.orgDetails}`, { state: state.data.init });
+ } catch (err) {
+ handleError(err, { context: "updating registration" });
+ }
+ };
+
+ console.log({ errors });
+
return (
Personal information
-
- name="first_name"
- label="First name"
- placeholder="e.g. John"
- required
- classes={{ container: "mb-4" }}
- />
-
- name="last_name"
- label="Last name"
- placeholder="e.g. Doe"
- required
- classes={{ container: "mb-4" }}
- />
-
- name="contact_number"
- label="Phone number"
- placeholder="000000000"
- required={false}
- classes={{ container: "mb-4" }}
- />
-
- name="registrant_id"
- label="E-mail address"
- required
- disabled
- />
+
+
+
+
+
+ {errors.first_name?.message}
+
+
+
+
+
+
+ {errors.last_name?.message}
+
+
+
+
+
+
+ {errors.contact_number?.message}
+
+
+
+
+
+
+
+
Organization information
-
- name="org_name"
- label="Name of your organization"
- placeholder="Organization name"
- classes={{ container: "mb-4" }}
- required
+
+
+
+
+
+ {errors.org_name?.message}
+
+
+
+
-
-
- name="org_role"
- options={roleOptions}
- classes={{ options: "text-sm" }}
- >
- {({ value }) =>
- value === "other" && (
-
- name="other_role"
- label="Specify your role"
- required
- classes={{ container: "mt-4" }}
- />
- )
- }
-
+ {orgRole.value === "other" && (
+
+
+
+
+ {errors.other_role?.message}
+
+
+ )}
Other information
-
-
- name="referral_method"
- options={referralOptions}
- classes={{ options: "text-sm" }}
- >
- {({ value }) => (
- <>
- {value === "other" && (
-
- name="other_referral_method"
- label="Please provide additional information"
- required
- classes={{ container: "mt-4" }}
- />
- )}
- {value === "referral" && (
-
- name="referral_code"
- label="Referral Code"
- required
- classes={{ container: "mt-4" }}
- />
- )}
- >
- )}
-
-
- name="goals"
- label="Goals"
- placeholder={`What is your goal working with ${APP_NAME}?`}
- classes={{ container: "mt-4" }}
- required
+
+ {referralMethod.value === "other" && (
+
+
+
+
+ {errors.other_referral_method?.message}
+
+
+ )}
+
+ {referralMethod.value === "referral" && (
+
+
+
+
+ {errors.referral_code?.message}
+
+
+ )}
+
+
+
+
+
+ {errors.goals?.message}
+
+
+