Skip to content

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.


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)
CampoTipoRequerido
NombreInput textoSi
BiografiaTextarea (4 filas, max 2000, contador chars)No
Zona horariaSelect con deteccion automatica del navegador + 20 presets comunes. Validado contra lista IANA via schema ZodSi

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
CampoTipoValidacion
SlugInput 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

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 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.

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.

Si teacher.onboardingCompleted === true al cargar la pagina, redirige automaticamente a /teacher/dashboard.

Si se guardan name + slug + timezone y onboardingCompleted es false, el backend marca automaticamente onboardingCompleted = true.


FeatureDescripcionEstadoImplementado
Slug check bloquea submitEl boton “Siguiente” en el paso 2 queda deshabilitado si el slug no esta disponibleBatch 3
Timezone con validacion IANAEl schema Zod valida el timezone contra la lista completa de IANA via Intl.supportedValuesOf('timeZone')Batch 3

No hay bugs conocidos en esta pagina.


MejoraDescripcionDificultadEstadoImplementado
Bloquear submit con slug no disponibleEl boton “Siguiente” queda deshabilitado si el slug no esta disponibleFacilBatch 3
Preview del perfil en vivoStepProfile incluye una tarjeta sticky a la derecha que muestra nombre, bio, timezone y avatar en tiempo real mientras el profesor rellena el formularioMedioBatch 4

ArchivoProposito
apps/web/src/routes/teacher/onboarding.lazy.tsxWizard completo (1036 lineas)
apps/api/src/services/teacher/settings-service.tsupdateProfile (marca onboardingCompleted)
ComponentePasoDescripcion
StepProfile1Nombre, bio, timezone con deteccion automatica
StepSlug2Slug con check debounced + auto-formato
StepCalendar3Conexion Google + seleccion calendarios lectura/escritura
StepStripe4Conexion Stripe Connect con opcion de omitir
StepSummary5Preview del perfil + resumen de toda la configuracion
VariableTipoProposito
stepnumber (1-5)Paso actual del wizard
profileProfileDataNombre, bio, timezone
slugDataSlugDataSlug elegido
selectedIdsstring[]IDs de calendarios de lectura (en StepCalendar)
writeCalendarIdstringID del calendario de escritura (en StepCalendar)
EndpointMetodoProposito
/teacher/settings/profilePATCHGuardar nombre, bio, slug, timezone
/teacher/settings/slug-checkGETVerificar disponibilidad de slug
/teacher/settings/google/calendarsGETObtener calendarios y seleccion actual
/teacher/settings/google/calendarsPATCHGuardar seleccion de calendarios
/teacher/settings/stripe/statusGETComprobar si Stripe Connect esta activo
/teacher/settings/stripe/connectPOSTIniciar OAuth flow de Stripe Connect (devuelve { url })
/teacher/profile/photoPOSTSubir foto de perfil (multipart)