import { useMutation, useQuery } from "@tanstack/react-query"; import { createFileRoute, Link, useNavigate } from "@tanstack/react-router"; import { useState } from "react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { authClient } from "@/lib/auth-client"; import { REGISTRATION_OPENS_AT } from "@/lib/opening"; import { useRegistrationOpen } from "@/lib/useRegistrationOpen"; import { orpc } from "@/utils/orpc"; export const Route = createFileRoute("/login")({ validateSearch: (search: Record) => { const signup = search.signup === "1" || search.signup === "true" ? "1" : undefined; const email = typeof search.email === "string" ? search.email : undefined; // Only return defined keys so redirects without search still typecheck return { ...(signup !== undefined && { signup }), ...(email !== undefined && { email }), } as { signup?: "1"; email?: string }; }, component: LoginPage, }); function LoginPage() { const navigate = useNavigate(); const search = Route.useSearch(); const { isOpen } = useRegistrationOpen(); const [isSignup, setIsSignup] = useState(() => search.signup === "1"); const [email, setEmail] = useState(() => search.email ?? ""); const [password, setPassword] = useState(""); const [name, setName] = useState(""); const sessionQuery = useQuery({ queryKey: ["session"], queryFn: () => authClient.getSession(), }); const loginMutation = useMutation({ mutationFn: async ({ email, password, }: { email: string; password: string; }) => { const result = await authClient.signIn.email({ email, password, }); if (result.error) { throw new Error(result.error.message); } return result.data; }, onSuccess: () => { toast.success("Succesvol ingelogd!"); authClient.getSession().then((session) => { const user = session.data?.user as { role?: string } | undefined; if (user?.role === "admin") { navigate({ to: "/admin" }); } else { navigate({ to: "/account" }); } }); }, onError: (error) => { toast.error(`Login mislukt: ${error.message}`); }, }); const signupMutation = useMutation({ mutationFn: async ({ email, password, name, }: { email: string; password: string; name: string; }) => { const result = await authClient.signUp.email({ email, password, name, }); if (result.error) { throw new Error(result.error.message); } return result.data; }, onSuccess: () => { navigate({ to: "/account", search: { welkom: "1" } }); }, onError: (error) => { toast.error(`Registratie mislukt: ${error.message}`); }, }); const requestAdminMutation = useMutation({ ...orpc.requestAdminAccess.mutationOptions(), onSuccess: () => { toast.success("Admin toegang aangevraagd!"); }, onError: (error) => { toast.error(`Aanvraag mislukt: ${error.message}`); }, }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (isSignup) { signupMutation.mutate({ email, password, name }); } else { loginMutation.mutate({ email, password }); } }; const handleRequestAdmin = () => { requestAdminMutation.mutate(undefined); }; // If already logged in, redirect to appropriate page if (sessionQuery.data?.data?.user) { const user = sessionQuery.data.data.user as { role?: string }; if (user.role === "admin") { navigate({ to: "/admin" }); } else { navigate({ to: "/account" }); } return null; } const isLoggedIn = !!sessionQuery.data?.data?.user; const user = sessionQuery.data?.data?.user as | { role?: string; name?: string } | undefined; return (
{isLoggedIn ? `Welkom, ${user?.name}` : isSignup ? "Account Aanmaken" : "Inloggen"} {isLoggedIn ? "Je bent al ingelogd" : isSignup ? "Maak een gratis account aan voor je Drinkkaart en inschrijving" : "Log in om je account te bekijken"} {isLoggedIn ? (
{/* Primary CTA: go to account */} {/* Secondary: request admin access */}

Admin-toegang aanvragen?

← Terug naar website
) : isSignup && !isOpen ? ( /* Signup is closed until registration opens */

Registratie nog niet open

Accounts aanmaken kan vanaf{" "} {REGISTRATION_OPENS_AT.toLocaleDateString("nl-BE", { weekday: "long", day: "numeric", month: "long", })}{" "} om{" "} {REGISTRATION_OPENS_AT.toLocaleTimeString("nl-BE", { hour: "2-digit", minute: "2-digit", })} .

← Terug naar website
) : (
{isSignup && (
setName(e.target.value)} required className="border-white/20 bg-white/10 text-white placeholder:text-white/40" />
)}
setEmail(e.target.value)} required className="border-white/20 bg-white/10 text-white placeholder:text-white/40" />
setPassword(e.target.value)} required className="border-white/20 bg-white/10 text-white placeholder:text-white/40" />
{!isSignup && (
Wachtwoord vergeten?
)}
{/* Only show signup toggle when registration is open */} {isOpen && ( )} {!isOpen && isSignup === false && ( )} ← Terug naar website
)}
); }