"use client"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; import { createClient } from "@/lib/supabase/client"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Card, CardContent } from "@/components/ui/card"; import { HardHat, Keyboard, Mic, ArrowLeft, ArrowRight, Loader2, CheckCircle2, Sparkles, MapPin, Clock, Shield, Edit3, Wrench, Calendar, Globe2, } from "lucide-react"; type Step = "auth" | "method" | "trade" | "experience" | "location" | "availability" | "certs" | "review"; const TRADES = [ "Labourer", "Steel Fixer", "Formworker", "Carpenter", "Electrician", "Plumber", "Concreter", "Bricklayer", "Painter", "Roofer", "Scaffolder", "Tiler", "Plasterer", "Welder", "Crane Operator", "Excavator Operator", ]; const EXPERIENCE_OPTIONS = [ { label: "Less than 1 year", value: 0 }, { label: "1-3 years", value: 2 }, { label: "3-5 years", value: 4 }, { label: "5-10 years", value: 7 }, { label: "10+ years", value: 12 }, ]; const AVAILABILITY_OPTIONS = [ { label: "Full-time", value: "full-time" as const, desc: "Mon-Fri, regular hours" }, { label: "Casual", value: "casual" as const, desc: "As needed, flexible" }, { label: "Weekends", value: "weekends" as const, desc: "Saturday & Sunday" }, { label: "Flexible", value: "flexible" as const, desc: "Any time, any days" }, ]; const CERT_OPTIONS = [ "White Card", "Forklift Licence", "EWP (Elevated Work Platform)", "Working at Heights", "First Aid", "Traffic Control", "Rigging", "Dogging", "Confined Spaces", ]; interface WorkerData { trades: string[]; experience: number; suburb: string; availability: "full-time" | "casual" | "weekends" | "flexible"; certifications: string[]; } function generateBio(data: WorkerData): string { const tradeStr = data.trades.join(" and "); const expStr = data.experience === 0 ? "under 1 year" : data.experience >= 12 ? "10+ years" : `${data.experience} years`; const certStr = data.certifications.length > 0 ? ` Holds ${data.certifications.join(", ")}.` : ""; return `Experienced ${tradeStr.toLowerCase()} with ${expStr} in the construction industry. Based in ${data.suburb}, available for ${data.availability} work.${certStr}`; } export default function WorkerSignupPage() { const [step, setStep] = useState("auth"); const [isAuthenticated, setIsAuthenticated] = useState(false); const [loading, setLoading] = useState(true); // Auth state const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [authError, setAuthError] = useState(null); const [authLoading, setAuthLoading] = useState(false); // Worker data const [selectedTrades, setSelectedTrades] = useState([]); const [experience, setExperience] = useState(null); const [suburb, setSuburb] = useState(""); const [availability, setAvailability] = useState(null); const [certifications, setCertifications] = useState([]); const [saving, setSaving] = useState(false); const router = useRouter(); const supabase = createClient(); useEffect(() => { async function checkAuth() { const { data: { user }, } = await supabase.auth.getUser(); if (user) { setIsAuthenticated(true); setStep("method"); } setLoading(false); } checkAuth(); }, [supabase.auth]); async function handleAuth(e: React.FormEvent) { e.preventDefault(); setAuthLoading(true); setAuthError(null); const { error } = await supabase.auth.signUp({ email, password, options: { data: { type: "worker" }, emailRedirectTo: `${window.location.origin}/auth/callback`, }, }); if (error) { if (error.message.includes("already registered")) { const { error: loginError } = await supabase.auth.signInWithPassword({ email, password, }); if (loginError) { setAuthError(loginError.message); setAuthLoading(false); return; } // If login successful, check if email is verified const { data: { user } } = await supabase.auth.getUser(); if (user && !user.email_confirmed_at) { // Email not verified, redirect to verification page router.push("/auth/verify-email"); return; } } else { setAuthError(error.message); setAuthLoading(false); return; } } // Check if email verification is required const { data: { user } } = await supabase.auth.getUser(); if (user && !user.email_confirmed_at) { // Email not verified, redirect to verification page router.push("/auth/verify-email"); return; } setIsAuthenticated(true); setStep("method"); setAuthLoading(false); } function toggleTrade(trade: string) { setSelectedTrades((prev) => prev.includes(trade) ? prev.filter((t) => t !== trade) : [...prev, trade] ); } function toggleCert(cert: string) { setCertifications((prev) => prev.includes(cert) ? prev.filter((c) => c !== cert) : [...prev, cert] ); } async function handleConfirm() { if (!availability || experience === null) return; setSaving(true); const { data: { user }, } = await supabase.auth.getUser(); if (!user) return; const workerData: WorkerData = { trades: selectedTrades, experience, suburb, availability, certifications, }; const bio = generateBio(workerData); await supabase.from("profiles").update({ name: user.email?.split("@")[0] ?? "", suburb, onboarding_completed: true, }).eq("id", user.id); await supabase.from("worker_profiles").insert({ profile_id: user.id, trades: selectedTrades, experience_years: experience, availability, certifications, bio, ai_extracted: { source: "typed_answers", created_at: new Date().toISOString(), }, }); router.push("/dashboard"); router.refresh(); } const workerData: WorkerData | null = selectedTrades.length > 0 && experience !== null && suburb && availability ? { trades: selectedTrades, experience, suburb, availability, certifications } : null; const stepOrder: Step[] = ["auth", "method", "trade", "experience", "location", "availability", "certs", "review"]; const activeSteps = isAuthenticated ? stepOrder.slice(1) : stepOrder; const currentIndex = activeSteps.indexOf(step); const totalSteps = activeSteps.length; if (loading) { return (
); } return (
{/* Header */}
RateRight
{/* Progress bar */}
{Array.from({ length: totalSteps }, (_, i) => (
))}
{/* Step: Auth */} {step === "auth" && (

Create your account

Always free for workers

setEmail(e.target.value)} required autoComplete="email" className="h-12 text-base" />
setPassword(e.target.value)} required minLength={6} autoComplete="new-password" className="h-12 text-base" />
{authError && (

{authError}

)}

Already have an account?{" "} Sign in

)} {/* Step: Choose method */} {step === "method" && (

Build your profile

How do you want to get started?

)} {/* Step: Select trade */} {step === "trade" && (
} title="What's your trade?" subtitle="Select one or more" />
{TRADES.map((trade) => ( ))}
)} {/* Step: Experience */} {step === "experience" && (
} title="How much experience?" subtitle="In construction overall" />
{EXPERIENCE_OPTIONS.map((opt) => ( ))}
)} {/* Step: Location */} {step === "location" && (
} title="Where are you based?" subtitle="Your suburb or area" />
{ e.preventDefault(); if (suburb.trim()) setStep("availability"); }} className="mt-6 space-y-4" > setSuburb(e.target.value)} required autoFocus className="h-12 text-base" />

We'll match you to jobs near this location.

)} {/* Step: Availability */} {step === "availability" && (
} title="Your availability?" subtitle="When can you work?" />
{AVAILABILITY_OPTIONS.map((opt) => ( ))}
)} {/* Step: Certifications */} {step === "certs" && (
} title="Your certifications" subtitle="Select all that apply (optional)" />
{CERT_OPTIONS.map((cert) => ( ))}
)} {/* Step: Review */} {step === "review" && workerData && (

Your profile

Review and confirm

} label="Trade" value={workerData.trades.join(", ")} onEdit={() => setStep("trade")} /> } label="Experience" value={ workerData.experience === 0 ? "Less than 1 year" : workerData.experience >= 12 ? "10+ years" : `${workerData.experience} years` } onEdit={() => setStep("experience")} /> } label="Location" value={workerData.suburb} onEdit={() => setStep("location")} /> } label="Availability" value={ AVAILABILITY_OPTIONS.find( (o) => o.value === workerData.availability )?.label ?? workerData.availability } onEdit={() => setStep("availability")} /> } label="Certifications" value={ workerData.certifications.length > 0 ? workerData.certifications.join(", ") : "None added" } onEdit={() => setStep("certs")} /> {/* AI-generated bio */}

AI-generated bio

{generateBio(workerData)}

)}
); } function StepHeader({ icon, title, subtitle, }: { icon: React.ReactNode; title: string; subtitle: string; }) { return (
{icon}

{title}

{subtitle}

); } function ReviewField({ icon, label, value, onEdit, }: { icon: React.ReactNode; label: string; value: string; onEdit: () => void; }) { return ( ); }