Adding UI of FeedBack, Registration, Admin console

This commit is contained in:
2026-05-12 20:54:15 +07:00
parent 6a48d6351c
commit dd95ff5a21
30 changed files with 10038 additions and 36 deletions
+48 -15
View File
@@ -1,9 +1,20 @@
"use client";
import SubmitToast from "@/app/components/ui/SubmitToast";
import { useMemo, useState } from "react";
type IndustryOption = { value: string; label: string };
const emptyRegistration = {
fullName: "",
phone: "",
email: "",
company: "",
jobTitle: "",
industry: "",
notes: "",
};
export default function RegistrationForm({
data,
}: {
@@ -18,24 +29,34 @@ export default function RegistrationForm({
};
}) {
const industries = useMemo(() => data.sections.industry.options, [data.sections.industry.options]);
const [form, setForm] = useState({
fullName: "",
phone: "",
email: "",
company: "",
jobTitle: "",
industry: "",
notes: "",
});
const [form, setForm] = useState(emptyRegistration);
const [submitState, setSubmitState] = useState<"idle" | "sending" | "ok" | "error">("idle");
return (
<form
className="space-y-[32px]"
onSubmit={(e) => {
onSubmit={async (e) => {
e.preventDefault();
// frontend-only scope
console.log("[registration]", form);
alert("Saved locally (frontend-only).");
setSubmitState("sending");
const industryLabel = industries.find((o) => o.value === form.industry)?.label ?? "";
try {
const res = await fetch("/api/submissions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
type: "registration",
...form,
industryLabel,
}),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(typeof err?.error === "string" ? err.error : res.statusText);
}
setSubmitState("ok");
} catch {
setSubmitState("error");
}
}}
>
<div className="space-y-[16px]">
@@ -152,11 +173,23 @@ export default function RegistrationForm({
<div className="pt-[16px]">
<button
className="w-full gold-gradient-bg py-5 rounded-lg text-on-primary font-[var(--font-display-lg)] text-[18px] font-bold shadow-[0_10px_30px_rgba(197,160,89,0.15)] hover:shadow-[0_15px_40px_rgba(197,160,89,0.25)] hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.98] transition-all"
className="w-full gold-gradient-bg py-5 rounded-lg text-on-primary font-[var(--font-display-lg)] text-[18px] font-bold shadow-[0_10px_30px_rgba(197,160,89,0.15)] hover:shadow-[0_15px_40px_rgba(197,160,89,0.25)] hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.98] transition-all disabled:opacity-60 disabled:pointer-events-none"
type="submit"
disabled={submitState === "sending"}
>
{data.submit.label}
{submitState === "sending" ? "Submitting…" : data.submit.label}
</button>
<SubmitToast
state={submitState}
successTitle="Registration received"
successMessage="Thank you. Your registration was saved and will appear in the admin console under Pending."
onDismiss={() => {
setSubmitState("idle");
setForm({ ...emptyRegistration });
}}
/>
<p className="mt-[16px] text-center text-outline text-[11px] tracking-widest opacity-60 uppercase">
{data.submit.disclaimer}
</p>