feat: basic onboarding flow\

This commit is contained in:
Jose Selesan
2026-09-15 15:41:45 -03:00
parent 874b6e0cff
commit a92e9e77c3
37 changed files with 1775 additions and 42 deletions

View File

@@ -0,0 +1,84 @@
import { useNavigate } from '@tanstack/react-router'
import { useQueryClient } from '@tanstack/react-query'
import type { OnboardingGroupDto } from '@gruperly/shared'
import { ArrowRight, CheckCircle2, CreditCard } from 'lucide-react'
import { useAuth } from '../../context/AuthProvider'
import { Badge, Button } from '../ui'
import { BILLING_LABELS, formatPrice, formatSchedule } from './constants'
type ConfirmationStepProps = {
group: OnboardingGroupDto
providerName?: string
}
export function ConfirmationStep({ group, providerName }: ConfirmationStepProps) {
const navigate = useNavigate()
const queryClient = useQueryClient()
const { refresh } = useAuth()
const goToDashboard = () => {
// Revalida la caché (estado del onboarding, sesión, grupos) antes de redirigir.
void queryClient.invalidateQueries()
void refresh()
void navigate({ to: '/' })
}
return (
<section className="space-y-6">
<header className="space-y-2 text-center">
<span className="mx-auto flex size-14 items-center justify-center rounded-2xl bg-success-soft">
<CheckCircle2 className="size-7 text-success" />
</span>
<h2 className="text-2xl font-bold text-primary">¡Todo listo!</h2>
<p className="text-sm text-foreground/60">
Tu grupo se creó y ya podés empezar a cobrar a tus alumnos.
</p>
</header>
<div className="rounded-xl border border-border bg-white p-5">
<div className="flex items-start justify-between gap-3">
<div className="min-w-0">
<h3 className="truncate text-base font-semibold text-primary">{group.name}</h3>
<p className="mt-0.5 text-sm text-foreground/60">
{formatSchedule(group.days ?? [], group.time)}
</p>
</div>
<Badge variant="success">Activo</Badge>
</div>
<dl className="mt-4 divide-y divide-border text-sm">
<div className="flex items-center justify-between py-2.5">
<dt className="text-foreground/60">Precio</dt>
<dd className="font-semibold text-primary">
{formatPrice(group.price)}
{group.billingType ? ` · ${BILLING_LABELS[group.billingType]}` : ''}
</dd>
</div>
<div className="flex items-center justify-between py-2.5">
<dt className="text-foreground/60">Cupo</dt>
<dd className="font-semibold text-primary">{group.capacity ?? '—'} alumnos</dd>
</div>
<div className="flex items-center justify-between py-2.5">
<dt className="text-foreground/60">Vencimiento</dt>
<dd className="font-semibold text-primary">Día {group.dueDay ?? '—'} de cada mes</dd>
</div>
</dl>
</div>
{providerName ? (
<div className="flex items-center gap-2 rounded-xl bg-primary-soft px-4 py-3">
<CreditCard className="size-4 shrink-0 text-accent" />
<p className="text-xs text-primary">
Vas a cobrar con <span className="font-semibold">{providerName}</span> en modo
prueba.
</p>
</div>
) : null}
<Button variant="primary" className="w-full" onClick={goToDashboard}>
Ir a mi Panel
<ArrowRight className="size-4" />
</Button>
</section>
)
}