Skip to content

Widgets

Ruta: /teacher/widgets · Atajo: g w · Sidebar: Widgets

Configuracion de widgets embebibles para insertar en webs externas. Tres tipos de widget con multiples variantes, preview en vivo y codigo de embed copiable.

Widgets page

Tres filas de tipo de widget, cada una muestra:

  • Icono + nombre + conteo de variantes
  • Descripcion breve
  • Analytics resumidas (30 dias): impresiones, CTR, clicks
  • Chevron de expansion

Al expandir, se muestra:

Fila de botones pill para cada configuracion guardada. Estrella en la variante por defecto. Boton “Nueva variante” para crear configs adicionales.

Columna izquierda — Editor:

  • Input de nombre
  • Boton “Set Default” (si no es la variante por defecto)
  • Formulario de configuracion (segun tipo)
  • Boton “Guardar” (deshabilitado si no hay cambios)
  • Badge de analytics
  • Seccion de codigo embed (copiable)
  • Boton “Eliminar” (rojo, con confirmacion)

Columna derecha — Preview (sticky):

  • Marco de navegador simulado (puntos rojo/amarillo/verde)
  • Iframe en tiempo real con la configuracion actual
  • Auto-resize via postMessage

Modos: inline (pagina completa), popup (modal flotante), button (link)

Configuracion:

  • Modo de display
  • Tema: light / dark / auto
  • Idioma: auto / es / en
  • Label del boton (popup/button)
  • Color del boton (hex picker)
  • Posicion (popup): top-left / top-right / bottom-left / bottom-right
  • Pre-fill nombre del alumno (opcional)
  • Pre-fill email del alumno (opcional)
WidgetFormato
Booking inline<iframe> con handler de resize
Booking popup<script> con boton flotante
Booking button<a> con estilos inline
Storefront<iframe> con handler de resize
Reviews<iframe> con altura responsiva

El embed de booking soporta pre-rellenar campos del formulario via URL params. Los params se agregan automaticamente al generar el embed code segun lo que el profesor configure en el formulario de configuracion.

Param URLCampo
prefill_nameNombre del alumno
prefill_emailEmail del alumno
prefill_serviceID del servicio pre-seleccionado

Los modos inline y button incluyen los params directamente en la URL del iframe/enlace. El modo popup soporta pre-fill via atributos data-* en el tag <script>:

<script
src="https://pinteach.com/widget.js"
data-teacher="maria-garcia"
data-prefill-name="Juan Lopez"
data-prefill-email="juan@ejemplo.com"
></script>

El script de popup lee los atributos data-prefill-name y data-prefill-email al inicializarse y los pasa como prefill_name / prefill_email en la URL del iframe interno cuando el popup se abre.

  • Deteccion de cambios via serializacion JSON (nombre + config)
  • Evento beforeunload para navegacion accidental
  • ConfirmDialog al colapsar fila o cambiar variante con cambios sin guardar

FeatureDescripcionEstadoImplementado
Pre-fill en modo popupEl script de popup acepta atributos data-prefill-name y data-prefill-email y los pasa al iframe interno. El embed code los incluye automaticamenteBatch 3
A/B testing de variantesSe pueden crear multiples variantes pero no hay forma de comparar rendimiento entre ellas. Deberia haber dashboard de comparacion con metricas por varianteImplementado ✅
Custom CSS injectionTextarea en config del widget para CSS personalizado. Sanitizacion XSS (bloquea @import, url(), expression(), javascript:). Endpoint GET /:slug/widget-css?configId=xxx retorna CSS como text/css. Iframes lo inyectan via <style> en mountBatch 4

BugDescripcionEstadoCorregido
Reviews carousel altura inicial de 300pxEl embed de reviews carousel usa 300px como altura inicial del iframe (otros layouts 500px). El auto-resize via postMessage funciona correctamente — el salto visual es breve y solo ocurre en la carga inicial. No requiere fix

MejoraDescripcionDificultadEstadoImplementado
Dashboard de comparacion de variantesTabla comparativa de metricas (impresiones, CTR, conversiones) entre variantes del mismo tipoMedioImplementado ✅
Pre-fill en modo popupEl script de popup acepta atributos data-prefill-*FacilBatch 3
Reviews carousel altura inicial mas precisaAjustar la altura inicial del iframe de reviews carousel (actualmente 300px) para reducir el salto visual antes del auto-resizeFacilImplementado ✅

ArchivoProposito
apps/web/src/routes/teacher/widgets.lazy.tsxPagina principal
apps/web/src/components/widgets/widget-editor.tsxEditor de variante
apps/web/src/components/widgets/widget-preview-panel.tsxPreview en vivo
apps/web/src/components/widgets/widget-embed-section.tsxCodigo embed
apps/web/src/components/widgets/widget-embed-utils.tsGeneracion de embed code
apps/web/src/components/widgets/booking-config-form.tsxConfig booking
apps/web/src/components/widgets/storefront-config-form.tsxConfig storefront
apps/web/src/components/widgets/reviews-config-form.tsxConfig reviews
apps/web/src/components/widgets/widget-analytics-badge.tsxBadge compacto de analytics
apps/web/src/components/widgets/widget-types.tsTipos TypeScript y configuraciones por defecto
apps/web/src/components/widgets/use-widget-dirty-state.tsDeteccion de cambios
apps/api/src/services/teacher/widget-config-service.tsServicio backend
EndpointMetodoProposito
/teacher/widget-configsGETLista por tipo
/teacher/widget-configs/:idGET/PATCH/DELETECRUD individual
/teacher/widget-configsPOSTCrear variante
/teacher/widget-configs/:id/analyticsGETMetricas 30 dias