Onboarding
Ruta: /teacher/onboarding · Auth: Teacher (pre-dashboard)
Wizard de 5 pasos que se muestra la primera vez que un profesor accede a la plataforma. Una vez completado, redirige al dashboard y no se vuelve a mostrar.
Que hay
Section titled “Que hay”Indicador de progreso
Section titled “Indicador de progreso”Barra sticky con 5 pasos numerados:
- Numeros 1-5 en circulos (Check icon para pasos completados)
- Labels (ocultos en movil)
- Linea de progreso entre pasos (primary-600 para completados)
- “Paso X de 5” (footer, siempre visible)
Paso 1 — Perfil
Section titled “Paso 1 — Perfil”| Campo | Tipo | Requerido |
|---|---|---|
| Nombre | Input texto | Si |
| Biografia | Textarea (4 filas, max 2000, contador chars) | No |
| Zona horaria | Select con deteccion automatica del navegador + 20 presets comunes. Validado contra lista IANA via schema Zod | Si |
Upload de foto: Avatar circular encima de los campos de nombre/bio. Boton de camara superpuesto abre file picker. Acepta JPEG, PNG y WebP hasta 1.5 MB. Se sube automaticamente via POST /teacher/profile/photo. El paso 5 muestra el avatar en el resumen con inicial de letra como fallback. Opcional — no bloquea el progreso del onboarding.
Si la zona horaria detectada del navegador no esta en los presets, se muestra primera con label “(detectado)”. Si esta en la lista, se muestra en su posicion normal con el sufijo “(detectado)”.
Presets de timezone:
- Europa: Madrid, London, Paris, Berlin, Rome, Lisbon
- Americas: New York, Chicago, Denver, LA, Mexico City, Bogota, Lima, Santiago, Buenos Aires, Sao Paulo
- Asia-Pacifico: Tokyo, Shanghai, Seoul, Sydney
Paso 2 — URL publica
Section titled “Paso 2 — URL publica”| Campo | Tipo | Validacion |
|---|---|---|
| Slug | Input con prefijo “pinteach.com/“ | Min 3 chars, regex ^[a-z0-9]+(?:-[a-z0-9]+)*$ |
Auto-formato: lowercase, espacios/underscores → hyphens, chars invalidos removidos.
Check de disponibilidad (debounced 500ms):
- Spinner: “Verificando…”
- Disponible (verde): checkmark
- No disponible (rojo): X + el boton “Siguiente” queda deshabilitado hasta que el slug sea valido y disponible
Paso 3 — Google Calendar
Section titled “Paso 3 — Google Calendar”Muestra estado de conexion con Google Calendar y permite seleccionar que calendarios sincronizar.
Si no conectado: Caja amber con icono de alerta, boton “Conectar con Google” que redirige a /api/auth/google, y mensaje informativo de que se puede omitir por ahora.
Si conectado: Caja verde con icono de exito y el email asociado, seguida de dos secciones de seleccion:
Calendarios de lectura (checkboxes): Lista de todos los calendarios del usuario con checkbox, color indicator (dot con backgroundColor del calendario), nombre y badge “Primary” para el calendario principal. Los seleccionados se destacan con fondo primary-50.
Calendario de escritura (radio): Selector unico para elegir en que calendario se crean los eventos de sesion. Misma lista que lectura, solo puede seleccionarse uno.
Boton “Guardar”: Aparece solo cuando hay cambios pendientes (hasChanges = true) y el writeCalendarId esta seleccionado. Llama a PATCH /teacher/settings/google/calendars.
Si no hay calendarios: Mensaje informativo con opcion de continuar.
Paso 4 — Stripe
Section titled “Paso 4 — Stripe”Paso para conectar Stripe Connect. Puede omitirse y configurarse despues en Ajustes.
Si no conectado:
- Lista de beneficios: cobrar directamente, pagos automaticos, gestionar reembolsos
- Boton “Conectar con Stripe” → llama a
POST /teacher/settings/stripe/connect→ redirige al OAuth flow de Stripe Connect - Boton “Omitir por ahora” (ghost) con icono
SkipForward - Texto informativo de que se puede conectar despues
Si conectado: Caja verde con icono de exito y mensaje de confirmacion.
Paso 5 — Resumen
Section titled “Paso 5 — Resumen”Muestra un preview del perfil publico y un resumen de toda la configuracion realizada.
Preview del perfil: Tarjeta con avatar (foto si esta subida, inicial si no), nombre, URL publica (pinteach.com/slug) y bio truncada en una linea.
Detalles del perfil: Lista con nombre, bio (truncada al 60%), timezone y URL publica.
Resumen de calendario: Estado de conexion con email, y si hay calendarios seleccionados muestra el conteo (ej. ”· 2 calendarios configurados”).
Resumen de Stripe: Estado de conexion o mensaje “no configurado, puedes hacerlo en Ajustes”.
Boton “Completar” que guarda todo y redirige al dashboard.
Auto-redirect
Section titled “Auto-redirect”Si teacher.onboardingCompleted === true al cargar la pagina, redirige automaticamente
a /teacher/dashboard.
Backend auto-complete
Section titled “Backend auto-complete”Si se guardan name + slug + timezone y onboardingCompleted es false, el backend
marca automaticamente onboardingCompleted = true.
Que falta
Section titled “Que falta”| Feature | Descripcion | Estado | Implementado |
|---|---|---|---|
| Slug check bloquea submit | El boton “Siguiente” en el paso 2 queda deshabilitado si el slug no esta disponible | ✅ | Batch 3 |
| Timezone con validacion IANA | El schema Zod valida el timezone contra la lista completa de IANA via Intl.supportedValuesOf('timeZone') | ✅ | Batch 3 |
Que falla
Section titled “Que falla”No hay bugs conocidos en esta pagina.
Que cambiaria
Section titled “Que cambiaria”| Mejora | Descripcion | Dificultad | Estado | Implementado |
|---|---|---|---|---|
| Bloquear submit con slug no disponible | El boton “Siguiente” queda deshabilitado si el slug no esta disponible | Facil | ✅ | Batch 3 |
| Preview del perfil en vivo | StepProfile incluye una tarjeta sticky a la derecha que muestra nombre, bio, timezone y avatar en tiempo real mientras el profesor rellena el formulario | Medio | ✅ | Batch 4 |
Referencia tecnica
Section titled “Referencia tecnica”Archivos clave
Section titled “Archivos clave”| Archivo | Proposito |
|---|---|
apps/web/src/routes/teacher/onboarding.lazy.tsx | Wizard completo (1036 lineas) |
apps/api/src/services/teacher/settings-service.ts | updateProfile (marca onboardingCompleted) |
Componentes internos
Section titled “Componentes internos”| Componente | Paso | Descripcion |
|---|---|---|
StepProfile | 1 | Nombre, bio, timezone con deteccion automatica |
StepSlug | 2 | Slug con check debounced + auto-formato |
StepCalendar | 3 | Conexion Google + seleccion calendarios lectura/escritura |
StepStripe | 4 | Conexion Stripe Connect con opcion de omitir |
StepSummary | 5 | Preview del perfil + resumen de toda la configuracion |
Estado local clave
Section titled “Estado local clave”| Variable | Tipo | Proposito |
|---|---|---|
step | number (1-5) | Paso actual del wizard |
profile | ProfileData | Nombre, bio, timezone |
slugData | SlugData | Slug elegido |
selectedIds | string[] | IDs de calendarios de lectura (en StepCalendar) |
writeCalendarId | string | ID del calendario de escritura (en StepCalendar) |
| Endpoint | Metodo | Proposito |
|---|---|---|
/teacher/settings/profile | PATCH | Guardar nombre, bio, slug, timezone |
/teacher/settings/slug-check | GET | Verificar disponibilidad de slug |
/teacher/settings/google/calendars | GET | Obtener calendarios y seleccion actual |
/teacher/settings/google/calendars | PATCH | Guardar seleccion de calendarios |
/teacher/settings/stripe/status | GET | Comprobar si Stripe Connect esta activo |
/teacher/settings/stripe/connect | POST | Iniciar OAuth flow de Stripe Connect (devuelve { url }) |
/teacher/profile/photo | POST | Subir foto de perfil (multipart) |