'use client'; import { useState } from 'react'; import { useRouter } from 'next/navigation'; import { Check, Loader2, Upload } from 'lucide-react'; import type { RouterOutputs } from '@/lib/trpc'; import { api } from '@/lib/trpc'; import { DEFAULT_SERVICE_RADIUS_M, MAX_SERVICE_RADIUS_M, MIN_SERVICE_RADIUS_M, } from '@linkder/shared'; import { cn } from '@/lib/utils'; import { uploadFile } from '@/lib/upload'; import { Button, Chip, Field, FieldNote, FieldSet, FormError, Input, Section, StickyAction, Textarea, } from '@/components/ui'; type Categories = RouterOutputs['job']['categories']; type Profile = RouterOutputs['pro']['me']; const CITY = { lat: Number(process.env.NEXT_PUBLIC_CITY_LAT ?? 41.3874), lng: Number(process.env.NEXT_PUBLIC_CITY_LNG ?? 2.1686), }; const STEPS = ['Trade', 'About you', 'Photos', 'Documents'] as const; export function OnboardingWizard({ categories, initialProfile, hasContactableEmail, }: { categories: Categories; initialProfile: Profile; hasContactableEmail: boolean; }) { const router = useRouter(); const [step, setStep] = useState(0); const [error, setError] = useState(null); const [categoryIds, setCategoryIds] = useState(initialProfile?.categoryIds ?? []); const [headline, setHeadline] = useState(initialProfile?.headline ?? ''); const [bio, setBio] = useState(initialProfile?.bio ?? ''); const [hourlyRate, setHourlyRate] = useState( initialProfile ? String(initialProfile.hourlyRateCents / 100) : '', ); const [yearsExperience, setYearsExperience] = useState( String(initialProfile?.yearsExperience ?? ''), ); const [radiusKm, setRadiusKm] = useState( (initialProfile?.serviceRadiusM ?? DEFAULT_SERVICE_RADIUS_M) / 1000, ); const [location, setLocation] = useState(initialProfile?.baseLocation ?? CITY); const [email, setEmail] = useState(''); const utils = api.useUtils(); const upsert = api.pro.upsertProfile.useMutation(); const addMedia = api.pro.addMedia.useMutation(); const addCredential = api.pro.addCredential.useMutation(); const setEmailMutation = api.user.setEmail.useMutation(); const submit = api.pro.submitForReview.useMutation({ onSuccess: () => router.push('/pro'), onError: (e) => setError(e.message), }); const media = initialProfile?.media ?? []; const credentials = initialProfile?.credentials ?? []; async function saveProfile() { setError(null); const rateCents = Math.round(Number(hourlyRate) * 100); if (!Number.isFinite(rateCents) || rateCents <= 0) { setError('Enter your hourly rate.'); return false; } try { await upsert.mutateAsync({ headline, bio, hourlyRateCents: rateCents, yearsExperience: Number(yearsExperience) || 0, categoryIds, location, serviceRadiusM: Math.round(radiusKm * 1000), }); await utils.pro.me.invalidate(); return true; } catch (e) { setError((e as Error).message); return false; } } return (
    {STEPS.map((label, i) => (
  1. {label}
  2. ))}
{step === 0 && (
{categories.map((c) => { const selected = categoryIds.includes(c.id); return ( setCategoryIds((prev) => selected ? prev.filter((id) => id !== c.id) : [...prev, c.id].slice(0, 5), ) } > {c.name} ); })}
)} {step === 1 && (
setHeadline(e.target.value)} maxLength={100} />