feat: gate registration behind 16 March 2026 19:00 opening date

- Add REGISTRATION_OPENS_AT const in lib/opening.ts as single source of truth
- Add useRegistrationOpen hook with live 1s countdown ticker
- Add CountdownBanner component (DD/HH/MM/SS) with canvas-confetti on open
- EventRegistrationForm shows countdown instead of form while closed
- Login page hides/disables signup while closed; login always available
- WatcherForm AccountModal guards signUp call as defence-in-depth

Closes #2
This commit is contained in:
2026-03-10 13:18:30 +01:00
parent 2f0dc46469
commit cf47f25a4d
8 changed files with 305 additions and 58 deletions

View File

@@ -12,6 +12,7 @@ import {
validatePhone,
validateTextField,
} from "@/lib/registration";
import { useRegistrationOpen } from "@/lib/useRegistrationOpen";
import { client, orpc } from "@/utils/orpc";
import { GiftSelector } from "./GiftSelector";
import { GuestList } from "./GuestList";
@@ -49,6 +50,7 @@ function AccountModal({
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [passwordError, setPasswordError] = useState<string | undefined>();
const { isOpen } = useRegistrationOpen();
const signupMutation = useMutation({
mutationFn: async () => {
@@ -83,6 +85,10 @@ function AccountModal({
const handleSignup = (e: React.FormEvent) => {
e.preventDefault();
if (!isOpen) {
toast.error("Registratie is nog niet open");
return;
}
if (password.length < 8) {
setPasswordError("Wachtwoord moet minstens 8 tekens zijn");
return;