Skip to content

Directorio de profesores

Ruta: /profesores (Astro SSR) · Auth: Ninguna (publica)

Pagina publica que lista todos los profesores con servicios activos. Incluye un quiz de compatibilidad, filtros de busqueda y tarjetas con informacion resumida de cada profesor.


Formulario de 5 preguntas (HTML nativo, sin JavaScript) que redirige a /profesores con query params:

  1. Objetivo (goal): conversation, business, exam, travel, general
  2. Nivel actual (level): beginner, intermediate, advanced
  3. Horario preferido (schedule): morning (6-12h), afternoon (12-18h), evening (18-24h), flexible
  4. Horas por semana (hours): 1-2, 3-4, 5+
  5. Estilo de aprendizaje (style): structured, balanced, conversational

El quiz se muestra solo cuando no hay filtros activos.

La funcion computeCompatibilityScore() calcula un score 0-100% usando 5 dimensiones ponderadas. Solo las dimensiones con respuesta contribuyen al total (normalizacion dinamica).

DimensionPesoMatching
Objetivo30 ptsKeyword matching en subjects del profesor (ej: “conversacion” → conversation, “dele” → exam)
Horario25 ptsOverlap de rango horario con availability_rules activas del profesor
Nivel20 ptsKeywords en subjects + nombres de servicios. Partial score (+10) si no hay match exacto
Estilo15 ptsTipo de servicio: structured → course/package, conversational → single + keyword, balanced → +10 siempre
Horas10 ptsTipo de servicio: 5+ → subscription/package, 3-4 → package/course, 1-2 → +8 siempre

Formula: score = Math.round((earnedPoints / totalPossiblePoints) * 100)

Cuando hay quiz params, cada tarjeta de profesor muestra un badge con el porcentaje:

ScoreColorCSS
70-100%Verdebg-green-50 text-green-700 border-green-200
40-69%Ambarbg-amber-50 text-amber-700 border-amber-200
0-39%Grisbg-gray-50 text-gray-600 border-gray-200

Los profesores se ordenan descendente por compatibilidad cuando hay quiz params.

Panel lateral con:

  • Busqueda por texto (nombre, headline)
  • Especialidad (select con opciones del API)
  • Idioma (select)
  • Rango de precio (minimo/maximo)

Todos los filtros se envian como query params a la misma pagina (SSR, sin JS).

Los links del directorio a perfiles de profesores NO incluyen ?ref=direct. Esto significa que cualquier alumno que llegue desde el directorio se registra con referralSource: 'directory' (lead de PinTeach). Solo los enlaces directos compartidos por el profesor llevan ?ref=direct.

Grid responsive (1-3 columnas) con tarjetas que muestran:

  • Avatar + badge Super Tutor
  • Nombre y headline
  • Materias (tags)
  • Rating promedio + total de resenas
  • Precio desde (servicio mas barato)
  • Badge de disponibilidad proxima
  • Link al perfil completo

ArchivoProposito
apps/web/src/pages/profesores/index.astroPagina del directorio
apps/web/src/components/directory/TeacherCard.astroTarjeta de profesor
apps/web/src/components/directory/CompatibilityQuiz.astroQuiz de compatibilidad
apps/web/src/components/directory/FilterSidebar.astroPanel de filtros
EndpointMetodoProposito
/public/teachersGETListado de profesores con filtros + quiz params (q, specialty, language, minPrice, maxPrice, goal, level, schedule, hours, style, limit, offset)
/public/sitemap-slugsGETSlugs de profesores para sitemap
ParamTipoDescripcion
qstringBusqueda por texto (nombre, headline)
specialtystringFiltro por materia
languagestringFiltro por idioma
minPricenumberPrecio minimo (centavos)
maxPricenumberPrecio maximo (centavos)
goalstringObjetivo del quiz (conversation, business, exam, travel, general)
levelstringNivel actual (beginner, intermediate, advanced)
schedulestringHorario preferido (morning, afternoon, evening, flexible)
hoursstringHoras por semana (1-2, 3-4, 5+)
stylestringEstilo de clase (structured, balanced, conversational)
limitnumberPaginacion (default 20, max 50)
offsetnumberOffset de paginacion
interface DirectoryTeacher {
slug: string;
name: string;
headline: string | null;
avatarUrl: string | null;
timezone: string;
subjects: string[];
languages: { language: string; level: string }[];
priceFrom: number | null;
currency: string;
reviewStats: { averageRating: number | null; totalReviews: number };
nextAvailableDate: string | null;
servicesCount: number;
compatibilityScore?: number | null; // Solo con quiz params
}

Cache-Control: public, s-maxage=300, stale-while-revalidate=600 (5 min cache, 10 min stale).