From c2e6371d38d669dae423e706c9fae86a66f2b4d8 Mon Sep 17 00:00:00 2001 From: TheSKBroook Date: Wed, 29 Apr 2026 16:18:16 +1200 Subject: [PATCH 01/25] feat: direct join-us button to a new page. Install react hook form. --- bun.lock | 3 +++ package.json | 1 + src/app/pages/join-us/page.tsx | 9 +++++++++ src/components/join-us.tsx | 37 ++++++++++++++++++++++++++++++++++ src/components/navbar.tsx | 9 ++------- 5 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 src/app/pages/join-us/page.tsx create mode 100644 src/components/join-us.tsx diff --git a/bun.lock b/bun.lock index 0e58a75..80c435a 100644 --- a/bun.lock +++ b/bun.lock @@ -20,6 +20,7 @@ "prisma": "^7.6.0", "react": "^19.2.4", "react-dom": "^19.2.4", + "react-hook-form": "^7.74.0", "tailwind-merge": "^3.3.1", "viem": "^2.47.6", "wagmi": "^3.6.0", @@ -1030,6 +1031,8 @@ "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], + "react-hook-form": ["react-hook-form@7.74.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-yR6wHr99p9wFv686jhRWVSFhUvDvNbdUf2dKlbno8/VKOCuoNobDGC6S+M2dua9A9Yo8vpcrp8assIYbsZCQ9g=="], + "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], "real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="], diff --git a/package.json b/package.json index 184394d..047169e 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "prisma": "^7.6.0", "react": "^19.2.4", "react-dom": "^19.2.4", + "react-hook-form": "^7.74.0", "tailwind-merge": "^3.3.1", "viem": "^2.47.6", "wagmi": "^3.6.0" diff --git a/src/app/pages/join-us/page.tsx b/src/app/pages/join-us/page.tsx new file mode 100644 index 0000000..bafce9e --- /dev/null +++ b/src/app/pages/join-us/page.tsx @@ -0,0 +1,9 @@ +import { JoinUs } from "@/components/join-us"; + +export default function JoinUsPage() { + return ( +
+ +
+ ); +} diff --git a/src/components/join-us.tsx b/src/components/join-us.tsx new file mode 100644 index 0000000..a6dbb34 --- /dev/null +++ b/src/components/join-us.tsx @@ -0,0 +1,37 @@ +import { Code2, Users, Rocket } from "lucide-react"; + +export function JoinUs() { + return ( +
+
+ {/* Section header */} +
+ + / Join Us + +

+ Join our Web3 Club +

+

+ A student-led club at the University of Auckland for anyone + interested in blockchain, AI, and the wider Web3 space. Sign up to + learn, connect, and stay updated on events. +
+
+ Bitcoin runs on Proof of Work. We run on Proof of Learn ✅ +

+
+ + {/* Sign up grid */} +
+ + + +
+
+
+ ); +} diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index 7db2c27..3852c64 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -4,6 +4,7 @@ import { Button } from "@/components/ui/button"; import { Menu, X } from "lucide-react"; import { useAccount } from "wagmi"; import { isAllowedAdminAddress } from "@/lib/admin-auth"; +import Link from "next/link"; const navLinks = [ { label: "About", href: "#about" }, @@ -60,13 +61,7 @@ export function Navbar() { className="rounded-xl px-6 py-5 font-bold shadow-md hover:shadow-lg transition-transform hover:-translate-y-0.5" asChild > - - Join Us - + Join Us From 04ceeb0ea33ef1f74cb631a80b00842019e2deb4 Mon Sep 17 00:00:00 2001 From: TheSKBroook Date: Wed, 6 May 2026 07:50:07 +1200 Subject: [PATCH 02/25] feat: add react-hook-form and basic form structure --- package-lock.json | 18 ++++++++++++++++++ package.json | 2 +- src/components/join-us-form.tsx | 25 +++++++++++++++++++++++++ src/components/join-us.tsx | 5 ++--- 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 src/components/join-us-form.tsx diff --git a/package-lock.json b/package-lock.json index e7b9da8..19c4971 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "web3uoa", "version": "0.0.0", + "hasInstallScript": true, "dependencies": { "@prisma/adapter-pg": "^7.6.0", "@prisma/client": "^7.6.0", @@ -23,6 +24,7 @@ "prisma": "^7.6.0", "react": "^19.2.4", "react-dom": "^19.2.4", + "react-hook-form": "^7.75.0", "tailwind-merge": "^3.3.1", "viem": "^2.47.6", "wagmi": "^3.6.0" @@ -7393,6 +7395,22 @@ "react": "^19.2.4" } }, + "node_modules/react-hook-form": { + "version": "7.75.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.75.0.tgz", + "integrity": "sha512-Ovv94H+0p3sJ7B9B5QxPuCP1u8V/cHuVGyH55cSwodYDtoJwK+fqk3vjfIgSX59I2U/bU4z0nRJ9HMLpNiWEmw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, "node_modules/readdirp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", diff --git a/package.json b/package.json index 047169e..48bd00b 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "prisma": "^7.6.0", "react": "^19.2.4", "react-dom": "^19.2.4", - "react-hook-form": "^7.74.0", + "react-hook-form": "^7.75.0", "tailwind-merge": "^3.3.1", "viem": "^2.47.6", "wagmi": "^3.6.0" diff --git a/src/components/join-us-form.tsx b/src/components/join-us-form.tsx new file mode 100644 index 0000000..3fe05d0 --- /dev/null +++ b/src/components/join-us-form.tsx @@ -0,0 +1,25 @@ +"use client"; + +import { useForm, SubmitHandler } from "react-hook-form"; + +type joinUsFormProp = { + name: string; +}; + +export function JoinUsForm() { + const { + register, + handleSubmit, + formState: { errors }, + } = useForm(); + const onSubmit: SubmitHandler = (data) => { + console.log(data); + }; + + return ( +
+ + +
+ ); +} diff --git a/src/components/join-us.tsx b/src/components/join-us.tsx index a6dbb34..440b1cd 100644 --- a/src/components/join-us.tsx +++ b/src/components/join-us.tsx @@ -1,4 +1,5 @@ import { Code2, Users, Rocket } from "lucide-react"; +import { JoinUsForm } from "./join-us-form"; export function JoinUs() { return ( @@ -27,9 +28,7 @@ export function JoinUs() { {/* Sign up grid */}
- - - +
From 7df77dff4c03dfd92a5a775779e0af4657eaac00 Mon Sep 17 00:00:00 2001 From: TheSKBroook Date: Wed, 6 May 2026 10:56:21 +1200 Subject: [PATCH 03/25] feat: add all input fields and install zod --- bun.lock | 14 ++++- package.json | 4 +- src/components/join-us-form.tsx | 99 +++++++++++++++++++++++++++++---- 3 files changed, 103 insertions(+), 14 deletions(-) diff --git a/bun.lock b/bun.lock index 80c435a..21f91b6 100644 --- a/bun.lock +++ b/bun.lock @@ -5,6 +5,7 @@ "": { "name": "web3uoa", "dependencies": { + "@hookform/resolvers": "^5.2.2", "@prisma/adapter-pg": "^7.6.0", "@prisma/client": "^7.6.0", "@radix-ui/react-slot": "^1.2.3", @@ -20,10 +21,11 @@ "prisma": "^7.6.0", "react": "^19.2.4", "react-dom": "^19.2.4", - "react-hook-form": "^7.74.0", + "react-hook-form": "^7.75.0", "tailwind-merge": "^3.3.1", "viem": "^2.47.6", "wagmi": "^3.6.0", + "zod": "^4.4.3", }, "devDependencies": { "@eslint/js": "^9.36.0", @@ -93,6 +95,8 @@ "@hono/node-server": ["@hono/node-server@1.19.11", "", { "peerDependencies": { "hono": "^4" } }, "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g=="], + "@hookform/resolvers": ["@hookform/resolvers@5.2.2", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA=="], + "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], "@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="], @@ -369,6 +373,8 @@ "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="], + "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], "@tailwindcss/node": ["@tailwindcss/node@4.1.14", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.0", "lightningcss": "1.30.1", "magic-string": "^0.30.19", "source-map-js": "^1.2.1", "tailwindcss": "4.1.14" } }, "sha512-hpz+8vFk3Ic2xssIA3e01R6jkmsAhvkQdXlEbRTk6S10xDAtiQiM3FyvZVGsucefq764euO/b8WUW9ysLdThHw=="], @@ -1031,7 +1037,7 @@ "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], - "react-hook-form": ["react-hook-form@7.74.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-yR6wHr99p9wFv686jhRWVSFhUvDvNbdUf2dKlbno8/VKOCuoNobDGC6S+M2dua9A9Yo8vpcrp8assIYbsZCQ9g=="], + "react-hook-form": ["react-hook-form@7.75.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-Ovv94H+0p3sJ7B9B5QxPuCP1u8V/cHuVGyH55cSwodYDtoJwK+fqk3vjfIgSX59I2U/bU4z0nRJ9HMLpNiWEmw=="], "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], @@ -1191,7 +1197,7 @@ "zeptomatch": ["zeptomatch@2.1.0", "", { "dependencies": { "grammex": "^3.1.11", "graphmatch": "^1.1.0" } }, "sha512-KiGErG2J0G82LSpniV0CtIzjlJ10E04j02VOudJsPyPwNZgGnRKQy7I1R7GMyg/QswnE4l7ohSGrQbQbjXPPDA=="], - "zod": ["zod@3.22.4", "", {}, "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg=="], + "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], "zustand": ["zustand@5.0.0", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ=="], @@ -1219,6 +1225,8 @@ "@prisma/streams-local/ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], + "@reown/appkit-wallet/zod": ["zod@3.22.4", "", {}, "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg=="], + "@solana/codecs/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], "@solana/codecs-data-structures/@solana/codecs-numbers": ["@solana/codecs-numbers@5.5.1", "", { "dependencies": { "@solana/codecs-core": "5.5.1", "@solana/errors": "5.5.1" }, "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw=="], diff --git a/package.json b/package.json index 48bd00b..5788722 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "start": "next start" }, "dependencies": { + "@hookform/resolvers": "^5.2.2", "@prisma/adapter-pg": "^7.6.0", "@prisma/client": "^7.6.0", "@radix-ui/react-slot": "^1.2.3", @@ -31,7 +32,8 @@ "react-hook-form": "^7.75.0", "tailwind-merge": "^3.3.1", "viem": "^2.47.6", - "wagmi": "^3.6.0" + "wagmi": "^3.6.0", + "zod": "^4.4.3" }, "devDependencies": { "@eslint/js": "^9.36.0", diff --git a/src/components/join-us-form.tsx b/src/components/join-us-form.tsx index 3fe05d0..dbf6809 100644 --- a/src/components/join-us-form.tsx +++ b/src/components/join-us-form.tsx @@ -1,25 +1,104 @@ "use client"; import { useForm, SubmitHandler } from "react-hook-form"; - -type joinUsFormProp = { - name: string; -}; +import { + joinUsFormSchema, + JoinUsFormData, +} from "../lib/schemas/join-us-form.schema"; +import { + UniversityType, + DegreeType, + FacultyType, +} from "../lib/schemas/join-us-form.schema"; +import { zodResolver } from "@hookform/resolvers/zod"; export function JoinUsForm() { const { register, handleSubmit, formState: { errors }, - } = useForm(); - const onSubmit: SubmitHandler = (data) => { + } = useForm({ + resolver: zodResolver(joinUsFormSchema), + }); + + const onSubmit: SubmitHandler = (data) => { console.log(data); }; + console.log("Current errors state:", errors); + + // Storing the shared styles in a variable keeps the JSX clean! + const inputClass = + "w-full px-4 py-3 border border-gray-300 rounded-lg bg-white text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all"; + return ( -
- - -
+
+
+

+ Join Our Team +

+ + + + + + + + + + + + + + +