'use client'; import type { LookupDto, Obligation, Relationship } from '@impuestos/contracts'; import { formatGsAmount, isLocale } from '@impuestos/i18n'; import { useMutation } from '@tanstack/react-query'; import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { Card } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Switch } from '@/components/ui/switch'; import { useRouter } from '@/i18n/navigation'; import { useT } from '@/i18n/t'; import { api } from '@/lib/api'; import { cn } from '@/lib/utils'; const TOTAL_STEPS = 3; const RELATIONSHIPS: Relationship[] = ['conyuge', 'hijo', 'padre', 'otro']; interface Dependent { displayName: string; relationship: Relationship; } /** Flow A5: three steps, progress dots, nothing that cannot be changed later in /perfil. */ export function SetupWizard({ locale }: { locale: string }) { const t = useT(); const router = useRouter(); const [step, setStep] = useState(1); const [fullName, setFullName] = useState(''); const [doc, setDoc] = useState(''); const [lookup, setLookup] = useState(null); const [taxpayerKind, setTaxpayerKind] = useState<'individual' | 'company'>('individual'); const [hasIva, setHasIva] = useState(false); const [hasIrp, setHasIrp] = useState(false); const [income, setIncome] = useState(''); const [dependents, setDependents] = useState([]); const [emailAlerts, setEmailAlerts] = useState(true); const check = useMutation({ mutationFn: (value: string) => api.lookupRuc(value), onSuccess: setLookup, }); const save = useMutation({ mutationFn: async () => { const resolved = lookup?.valid ? lookup : await api.lookupRuc(doc.trim()); if (!resolved.valid) throw new Error('invalid_document'); const since = new Date().toISOString().slice(0, 10); const obligations: Obligation[] = []; // "No estoy seguro" leaves both off, which lands on the IRP view (FLOWS.md A5). if (hasIva) obligations.push({ code: 'iva_120', active: true, since }); if (hasIrp || (!hasIva && !hasIrp)) obligations.push({ code: 'irp_515', active: true, since }); await api.putProfile({ fullName: fullName.trim(), docType: resolved.docType, ruc: resolved.docType === 'ruc' ? resolved.base : null, rucDv: resolved.dv === null ? null : String(resolved.dv), ci: resolved.docType === 'ci' ? resolved.base : resolved.base, taxpayerKind, obligations, irpGrossEstimate: income === '' ? null : Number(income.replace(/\D/g, '')), autoConfirmDays: 7, locale: isLocale(locale) ? locale : 'es', }); for (const dependent of dependents) { await api.createDependent(dependent); } await api.patchNotificationPrefs({ emailEnabled: emailAlerts }); }, onSuccess: () => router.push('/inicio'), }); const canContinue = step === 1 ? fullName.trim().length > 0 && lookup?.valid === true : true; return (
{step === 1 ? (

{t('setup.step1.title')}

setFullName(event.target.value)} />
{ setDoc(event.target.value); setLookup(null); }} onBlur={() => { if (doc.trim().length > 0) check.mutate(doc.trim()); }} />

{t('setup.docHelp')}

{lookup !== null && !lookup.valid ? (

{t('landing.invalidDoc')}

) : null} {lookup?.valid ? (

{t('setup.deadlineNote', { day: lookup.deadlineDay })}

) : null}
{t('setup.taxpayerKind.q')}
setTaxpayerKind('individual')} title={t('setup.taxpayerKind.ind')} /> setTaxpayerKind('company')} title={t('setup.taxpayerKind.com')} />
) : null} {step === 2 ? (

{t('setup.step2.title')}

setHasIva(!hasIva)} title={t('setup.oblig.iva.title')} body={t('setup.oblig.iva.body')} /> setHasIrp(!hasIrp)} title={t('setup.oblig.irp.title')} body={t('setup.oblig.irp.body')} />
{hasIrp ? ( <>
setIncome(event.target.value.replace(/\D/g, ''))} />

{t('setup.income.help')}

) : null}
) : null} {step === 3 ? (

{t('setup.step3.title')}

{t('setup.push.body')}

{save.isError ? (

{t('common.error.generic')}

) : null}
) : null}
{step > 1 ? ( ) : null} {step < TOTAL_STEPS ? ( ) : ( )}
); } function ProgressDots({ step }: { step: number }) { const t = useT(); return (
{Array.from({ length: TOTAL_STEPS }).map((_, index) => ( ))}
); } function ChoiceCard({ selected, onSelect, title, body, }: { selected: boolean; onSelect: () => void; title: string; body?: string; }) { return ( ); } function DependentsEditor({ dependents, onChange, relationships, }: { dependents: Dependent[]; onChange: (next: Dependent[]) => void; relationships: Relationship[]; }) { const t = useT(); const [name, setName] = useState(''); const [relationship, setRelationship] = useState('hijo'); return (

{t('setup.dependents.title')}

{t('setup.dependents.help')}

{dependents.length > 0 ? (
    {dependents.map((dependent, index) => (
  • {dependent.displayName} ({t(`relationship.${dependent.relationship}` as const)})
  • ))}
) : null}
setName(event.target.value)} />
); }