Ir al contenido

TalentBricksAI genera certificados digitales verificables cuando un estudiante completa un curso. Los certificados se generan en el navegador usando Canvas HTML5 e incluyen un código QR para verificación pública.

  • Generacion client-side: Renderizado con Canvas HTML5 (sin servidor)
  • Diseño premium: Soporte para modo claro y oscuro con logo TalentBricks
  • Responsive: Se adapta automaticamente a diferentes tamaños de pantalla
  • verificación pública: URL única sin necesidad de login
  • código QR: Enlace directo a la página de verificación
  • Descarga PNG: Un click para descargar el certificado
  • Datos snapshot: información capturada al momento de completar
Completar todas las lecciones
Curso marcado como completado
Certificado generado automaticamente
Ver en /certificate/:courseId
Descargar PNG o compartir enlace
verificación pública en /verify/:code
RutaAccesodescripción
/certificate/:courseIdAutenticadoVer y descargar certificado propio
/verify/:verificationCodepúblicoVerificar autenticidad del certificado

El certificado guarda datos “snapshot” al momento de generacion:

model Certificate {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
user User @relation(...)
userId String
course Course @relation(...)
courseId Int
verificationCode String @unique @default(uuid())
// Snapshot data
studentName String
courseTitle String
instructorName String
totalDurationMinutes Int
@@unique([userId, courseId])
}

Los datos se guardan como copia (snapshot) porque:

  1. Si el curso cambia de nombre, el certificado mantiene el nombre original
  2. Si el instructor cambia, el certificado refleja quién enseñó al estudiante
  3. Si la duracion del curso cambia, el certificado muestra las horas completadas

El certificado Canvas incluye:

Elementodescripción
LogoLogo TalentBricks (adapta a modo claro/oscuro)
Título”CERTIFICADO DE FiNALIZACION”
Nombre estudianteResaltado en dorado
Nombre cursoCon word-wrap automatico
Duracion totalHoras y minutos del curso
Fecha emisionFormato largo en español
InstructorNombre con línea de firma
código QREnlace a página de verificación
códigoUUID para verificación manual

El certificado se adapta automaticamente al tema del usuario:

Modo Oscuro:

  • Fondo: Gradiente oscuro (#1a1a2e → #16213e → #0f0f23)
  • Borde: Dorado brillante (#ffd700)
  • Texto: Blanco con variaciones de opacidad
  • Logo: Variante oscura (logo-dark.png)

Modo Claro:

  • Fondo: Gradiente claro (#f8f9fa → #e9ecef → #dee2e6)
  • Borde: Dorado oscuro (#d4af37)
  • Texto: Tonos oscuros con variaciones de opacidad
  • Logo: Variante clara (logo.png)

La página /verify/:code es pública y muestra:

  • Badge verde “Verificado”
  • Nombre del estudiante
  • Nombre del curso
  • Instructor
  • Duracion
  • Fecha de emision
  • CTA para explorar cursos
  • Mensaje de error
  • código verificado (para debugging)
  • CTA para ir al inicio

Cuándo un usuario completa todas las lecciones:

// 1. Verificar que todas las lecciones estan completadas
// 2. Calcular duracion total en minutos
// 3. Capturar nombre del estudiante (username o email)
// 4. Crear registro de Certificate con snapshot data
// 5. Marcar Enrollment como completedAt
// 6. Retornar verificationCode
// Requiere autenticación
// Retorna certificado del usuario para un curso específico
// Incluye datos del curso (slug, category, difficulty)
// NO requiere autenticación (público)
// Busca por verificationCode
// Retorna datos publicos del certificado
import { CertificateCanvas } from "./components/CertificateCanvas";
<CertificateCanvas
data={{
studentName: "Juan Perez",
courseTitle: "Python para Data Engineering",
instructorName: "Maria Garcia",
totalDurationMinutes: 180,
issuedAt: new Date(),
verificationCode: "abc-123-def",
}}
isDarkMode={true} // Opcional: controla el tema (claro/oscuro)
locale={{
hours: "horas",
hour: "hora",
minutes: "minutos",
completionText: "ha completado satisfactoriamente el curso",
}}
/>;

Props:

  • data: Datos del certificado (requerido)
  • isDarkMode: Booleano para modo oscuro (opcional, default: false)
  • locale: Textos traducibles (opcional)
  • onReady: Callback cuando el certificado está listo (opcional)
import { downloadCertificateFromCanvas } from "./components/CertificateCanvas";
<Button onClick={downloadCertificateFromCanvas}>Descargar PNG</Button>;
const verificationUrl = `${window.location.origin}/verify/${code}`;
await navigator.clipboard.writeText(verificationUrl);
await navigator.share({
title: "Mi certificado de TalentBricksAI",
text: `He completado el curso ${courseTitle}!`,
url: verificationUrl,
});

El certificado detecta automaticamente el tema del usuario mediante el hook useColorMode():

import useColorMode from "../client/hooks/useColorMode";
const [colorMode] = useColorMode();
const isDarkMode = colorMode === "dark";
<CertificateCanvas data={certificateData} isDarkMode={isDarkMode} />;

En CertificateCanvas.tsx, los colores se definen basados en el modo:

// Modo oscuro
const borderColor = isDarkMode ? "#ffd700" : "#d4af37";
const titleColor = isDarkMode ? "#ffffff" : "#1a1a2e";
const bodyTextColor = isDarkMode ? "rgba(255, 255, 255, 0.8)" : "rgba(50, 50, 50, 0.8)";

Los logos se importan desde app/src/client/static/:

import logoLight from "../../client/static/logo.png";
import logoDark from "../../client/static/logo-dark.png";
// El componente selecciona automaticamente el correcto
const logoSrc = isDarkMode ? logoDark : logoLight;

Para usar logos personalizados, reemplaza los archivos:

  • logo.png - Logo para modo claro
  • logo-dark.png - Logo para modo oscuro
Ventana de terminal
wasp db seed seedAllDummyData

El seed crea un usuario de prueba con certificado. El código de verificación se muestra en la consola.

  1. Crear usuario y inscribirse en un curso
  2. Completar todas las lecciones
  3. Visitar /certificate/:courseId
  4. Verificar que el certificado se renderiza
  5. Probar descarga PNG
  6. Probar enlace de verificación pública

Verificar que qrcode este instalado:

Ventana de terminal
cd app
npm install qrcode @types/qrcode
  • Verificar que los datos del certificado estan completos
  • Revisar la consola del navegador por errores

Verificar Qué:

  1. Todas las lecciones tienen isCompleted: true
  2. El usuario tiene Enrollment para el curso
  3. El Enrollment no tiene completedAt ya seteado