Ejercicios: Componentes Reutilizables con DaisyUI, Tailwind & RSC
En esta guía pondrás a prueba tu capacidad para estructurar y modularizar interfaces web modernas en Next.js (App Router) mediante 20 ejercicios progresivos, utilizando Tailwind CSS y la biblioteca de componentes semánticos DaisyUI bajo la identidad visual institucional oficial de la Universidad Icesi (Manual de Marca 2026: Azul Icesi #5454e9, Morado #865cf0, Verde #4cb979, Naranja #e9683b y Amarillo #e4eb60).
Cada ejercicio se organiza en dos pestañas:
- Componente & Vista: Despliega el componente interactivo en vivo maquetado con DaisyUI y Tailwind CSS junto a su descripción funcional.
- Consejos & Guía: Especifica la ruta recomendada del archivo, su propósito arquitectónico, paleta/tema de DaisyUI sugerido, interfaz de contratos de props, clases base recomendadas y una lista de buenas prácticas sobre qué usar y qué evitar (anti-patrones).
Nivel 1: Átomos Visuales (Fácil)
Elementos de interfaz de propósito único, altamente reutilizables y con dependencias mínimas.
01. Botón de Acción con Estado de Carga y Badge
- Componente & Vista
- Consejos & Guía
Botón de acción interactivo que combina un icono vectorial, etiqueta descriptiva, una insignia (badge) tonal informativa a la derecha (ej. formato de archivo "PDF") y soporte para alternar dinámicamente a un estado de carga (loading spinner).
- Ubicación sugerida:
src/components/ui/action-button.tsx - Propósito: Proveer un botón base estandarizado para toda la aplicación con soporte para estados visuales (normal, cargando, deshabilitado) sin duplicar código CSS.
- Estilo DaisyUI sugerido: Tema institucional
icesicon variante principalbtn-primary(Azul Icesi#5454e9) y badge contextual enbadge-secondary(Morado Icesi#865cf0). - Contrato de Props sugerido (TypeScript):
interface ActionButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {label: string;icon?: React.ReactNode;badgeText?: string;isLoading?: boolean;variant?: 'primary' | 'secondary' | 'outline' | 'ghost';size?: 'sm' | 'md' | 'lg';}
- Clases base de DaisyUI sugeridas:
btn,btn-primary,btn-outline,loading loading-spinner loading-xs,badge,badge-secondary,badge-sm. - Qué usar:
- Mantén el componente como Server Component si solo se utiliza como enlace estilizado (
<Link>), o conviértelo en componente cliente ('use client') únicamente si maneja eventos interactivosonClickcon hooks de estado local. - Extiende
React.ButtonHTMLAttributes<HTMLButtonElement>para heredar nativamente propiedades comotype,disabledyaria-label.
- Mantén el componente como Server Component si solo se utiliza como enlace estilizado (
- Qué EVITAR:
- No crees tu propio spinner SVG personalizado con animaciones manuales cuando DaisyUI ya incluye
loading loading-spinner. - No agregues estilos inline con
style={{ backgroundColor: '#5454e9' }}: utiliza la abstracción de temas semánticos de DaisyUI (btn-primary).
- No crees tu propio spinner SVG personalizado con animaciones manuales cuando DaisyUI ya incluye
02. Insignia de Estado Tonal con Indicador Luminoso
- Componente & Vista
- Consejos & Guía
Micro-componente en forma de píldora que combina un punto luminoso parpadeante (pulsing dot) con una etiqueta textual para comunicar visualmente el estado académico o administrativo de un registro (activo con Verde Icesi #4cb979, en revisión con Morado #865cf0, pendiente con Naranja #e9683b).
- Ubicación sugerida:
src/components/ui/status-badge.tsx - Propósito: Mostrar de manera inmediata el ciclo de vida o condición de una entidad sin sobrecargar la interfaz.
- Estilo DaisyUI sugerido: Modificadores de estado semánticos con la paleta complementaria Icesi: Verde Icesi (
#4cb979/badge-success), Morado Icesi (#865cf0/badge-secondary) y Naranja Icesi (#e9683b/badge-error). - Contrato de Props sugerido (TypeScript):
type BadgeStatus = 'active' | 'pending' | 'danger' | 'neutral';interface StatusBadgeProps {status: BadgeStatus;label: string;hasPulse?: boolean;className?: string;}
- Clases base de DaisyUI & Tailwind sugeridas:
badge,badge-outline, utilidades de Tailwindinline-flex items-center gap-2,w-2 h-2 rounded-full animate-pulse. - Qué usar:
- Server Component 100% puro: este componente es estrictamente visual y jamás requiere
'use client'. - Utiliza un diccionario interno (mapa de objetos o
switch) para asociar cada valor destatuscon sus clases semánticas de color.
- Server Component 100% puro: este componente es estrictamente visual y jamás requiere
- Qué EVITAR:
- No uses nombres de colores arbitrarios en las props (ej.
color="green"ocolor="red"). Utiliza nombres de estado semánticos (status="active"). - No anides contenedores innecesarios: un único elemento semántico
<span>es suficiente.
- No uses nombres de colores arbitrarios en las props (ej.
03. Banner de Alerta Informativa Institucional
- Componente & Vista
- Consejos & Guía
Bloque de notificación destacado que presenta un icono vectorial informativo en Azul Icesi (#5454e9), un título en negrita, cuerpo explicativo y un botón de acción secundaria para dirigir al usuario a la acción correspondiente.
- Ubicación sugerida:
src/components/ui/alert-banner.tsx - Propósito: Desplegar anuncios institucionales importantes (aperturas de matrícula, avisos de sistema, mantenimiento programado) en la cabecera de las vistas.
- Estilo DaisyUI sugerido: Componente
alertcombinado conalert-infoen tonos de Azul Icesi (#5454e9/bg-[#f0f0fd]). - Contrato de Props sugerido (TypeScript):
interface AlertBannerProps {title: string;description: string;type?: 'info' | 'success' | 'warning' | 'error';actionLabel?: string;onActionClick?: () => void;}
- Clases base de DaisyUI sugeridas:
alert,alert-info,alert-warning,alert-success,btn btn-xs btn-outline. - Qué usar:
- Si la acción es una navegación hacia otra ruta (ej. un link a
/calendario), renderiza un componente<Link href="...">de Next.js en lugar de un botón con manejador imperativo. - Añade el atributo accesible
role="alert"oaria-live="polite"para lectores de pantalla.
- Si la acción es una navegación hacia otra ruta (ej. un link a
- Qué EVITAR:
- No fuerces
'use client'si el banner solo renderiza texto y un enlace hacia otra página. - No coloques textos de alerta con contrastes deficientes que no cumplan con el estándar WCAG AA.
- No fuerces
04. Avatar de Usuario con Anillo de Presencia y Rol
- Componente & Vista
- Consejos & Guía
Conjunto atómico que incluye fotografía circular del usuario con anillo exterior (ring) en color Azul Icesi (#5454e9), indicador verde de conexión en vivo con Verde Icesi (#4cb979), nombre, badge de rol académico y ubicación actual.
- Ubicación sugerida:
src/components/ui/user-avatar.tsx - Propósito: Identificar visualmente a profesores, monitores de laboratorio o compañeros de equipo en paneles de contacto y listas de tutoría.
- Estilo DaisyUI sugerido: Clases
avatar online(uoffline) combinadas conring ring-primary ring-offset-2. - Contrato de Props sugerido (TypeScript):
interface UserAvatarProps {name: string;role: string;program?: string;avatarUrl: string;isOnline?: boolean;locationText?: string;size?: 'sm' | 'md' | 'lg';}
- Clases base de DaisyUI sugeridas:
avatar,avatar online,avatar offline,rounded-full ring ring-primary ring-offset-base-100,badge badge-primary badge-xs. - Qué usar:
- En proyectos Next.js productivos, utiliza
next/image(<Image />) con dimensioneswidth={56}yheight={56}para optimización automática de imágenes en el servidor. - Añade texto alternativo semántico descriptivo con el nombre del usuario (
alt="Fotografía de perfil de...").
- En proyectos Next.js productivos, utiliza
- Qué EVITAR:
- No calcules manualmente la posición absoluta del punto verde con coordenadas fijas: la clase
avatar onlinede DaisyUI posiciona automáticamente el indicador. - No olvides incluir un fallback tipográfico con las iniciales del nombre si la URL de la imagen falla o es nula.
- No calcules manualmente la posición absoluta del punto verde con coordenadas fijas: la clase
05. Píldora de Atajo de Teclado con Kbd
- Componente & Vista
- Consejos & Guía
Fila compacta con etiqueta descriptiva a la izquierda y teclas físicas simuladas mediante elementos semánticos <kbd> a la derecha, ideal para paletas de comandos o menús de navegación rápida.
- Ubicación sugerida:
src/components/ui/shortcut-pill.tsx - Propósito: Informar al usuario de atajos rápidos de teclado para potenciar la productividad y accesibilidad.
- Estilo DaisyUI sugerido: Clases
kbd kbd-smcon fondo blanco y sombra sutil sobre un contenedor neutrobg-base-200y borde en Gris 2 (#cecfd4). - Contrato de Props sugerido (TypeScript):
interface ShortcutPillProps {label: string;keys: string[]; // Ej: ['⌘ Cmd', 'K'] o ['Ctrl', 'Shift', 'P']}
- Clases base de DaisyUI sugeridas:
kbd,kbd-sm,kbd-xs, combinadas con flexboxflex items-center justify-between. - Qué usar:
- Renderiza los elementos con la etiqueta semántica HTML
<kbd>. - Utiliza un
.map()sobre el arreglokeysintercalando un separador sutil+entre teclas.
- Renderiza los elementos con la etiqueta semántica HTML
- Qué EVITAR:
- No hagas este componente cliente: el mapeo de teclas es estático y se renderiza eficientemente en el servidor.
- No uses tamaños desproporcionados: los elementos
kbddeben ser discretos y armonizar con la tipografía del cuerpo.
06. Indicador de Calificación por Estrellas
- Componente & Vista
- Consejos & Guía
Componente visual de valoración que despliega estrellas con soporte para medias calificaciones (half stars), puntuación numérica destacada y cantidad total de evaluaciones registradas.
- Ubicación sugerida:
src/components/ui/rating-display.tsx - Propósito: Mostrar calificaciones de asignaturas, talleres o valoraciones docentes en catálogos y fichas de curso.
- Estilo DaisyUI sugerido: Componente
rating rating-sm rating-halfcon máscarasmask mask-star-2 bg-[#e9683b](Naranja Icesi) o amarillo institucional. - Contrato de Props sugerido (TypeScript):
interface RatingDisplayProps {score: number; // Ej: 4.8 sobre 5.0totalReviews?: number;showScoreText?: boolean;maxScore?: number;}
- Clases base de DaisyUI sugeridas:
rating,rating-sm,rating-half,mask mask-star-2. - Qué usar:
- Si el componente solo muestra una puntuación existente (modo solo lectura), desmarca los inputs con
disabledo renderiza estrellas vectoriales SVG estáticas. - Asegura el atributo de accesibilidad para lectores de pantalla (
aria-label="Calificación de...").
- Si el componente solo muestra una puntuación existente (modo solo lectura), desmarca los inputs con
- Qué EVITAR:
- No instales librerías externas pesadas cuando DaisyUI resuelve el sistema de máscaras de estrellas con CSS puro.
- No redondees números bruscamente en el renderizado sin permitir un decimal claro (
score.toFixed(1)).
07. Caja Bento de Métrica Académica
- Componente & Vista
- Consejos & Guía
Tarjeta informativa estilo bento que presenta un indicador cuantitativo principal (ej. Promedio Acumulado GPA), icono institucional en contenedor tonal Azul Icesi (#5454e9), y tendencia porcentual con comparativa semestral en Verde Icesi (#4cb979).
- Ubicación sugerida:
src/components/ui/metric-bento-stat.tsx - Propósito: Presentar KPIs académicos en paneles de control y dashboards de estudiante o profesor.
- Estilo DaisyUI sugerido: Componente
statcon fondo blanco, bordes en Gris 2 (#cecfd4) y textos en Azul Icesitext-primary(#5454e9). - Contrato de Props sugerido (TypeScript):
interface MetricBentoStatProps {title: string;value: string | number;maxValue?: string | number;trendText?: string;trendType?: 'positive' | 'negative' | 'neutral';icon: React.ReactNode;}
- Clases base de DaisyUI sugeridas:
stat,stat-figure,stat-title,stat-value,stat-desc. - Qué usar:
- Excelente candidato para un React Server Component asíncrono (
async function MetricBentoStat(...)) que consulte directamente la métrica en la base de datos o servicio antes de renderizar el HTML. - Aplica
text-primary(#5454e9) para el valor numérico principal ytext-[#4cb979]para tendencias positivas.
- Excelente candidato para un React Server Component asíncrono (
- Qué EVITAR:
- No uses fuentes de texto desordenadas: mantén coherencia tipográfica utilizando la jerarquía estandarizada de DaisyUI (
stat-title,stat-value). - No uses hooks de estado (
useState) para datos numéricos estáticos provenientes del servidor.
- No uses fuentes de texto desordenadas: mantén coherencia tipográfica utilizando la jerarquía estandarizada de DaisyUI (
Nivel 2: Moléculas Modulares (Media)
Componentes compuestos que agrupan múltiples átomos y gestionan estructuras de datos complejas.
08. Tarjeta de Asignatura con Barra de Progreso
- Componente & Vista
- Consejos & Guía
Tarjeta modular que resume la información de un curso universitario: cabecera con gradiente institucional (Azul Icesi #5454e9 a Morado Icesi #865cf0), código de asignatura, badge de créditos académicos, docente a cargo, salón, barra de progreso del semestre y acciones de acceso.
- Ubicación sugerida:
src/components/modules/course-card.tsx - Propósito: Tarjeta principal para la grilla del catálogo de asignaturas matriculadas del estudiante.
- Estilo DaisyUI sugerido:
card bg-base-100 shadow-sm border border-[#cecfd4], barraprogress progress-primaryy botones de acción encard-actions. - Contrato de Props sugerido (TypeScript):
interface CourseCardProps {courseCode: string;title: string;instructor: string;room: string;credits: number;progressPercentage: number;courseUrl: string;syllabusUrl?: string;}
- Clases base de DaisyUI sugeridas:
card,card-body,card-title,card-actions,progress progress-primary,badge badge-outline,btn btn-sm btn-primary. - Qué usar:
- Enlaza el botón "Entrar al Aula" con el componente
<Link href="...">de Next.js para habilitar navegación instantánea (client-side routing) y precarga (prefetching). - Maneja un borde superior o cabecera decorativa con el degradado oficial
bg-gradient-to-r from-[#5454e9] to-[#865cf0].
- Enlaza el botón "Entrar al Aula" con el componente
- Qué EVITAR:
- No satures la tarjeta con más de dos botones primarios; respeta la jerarquía visual destinando un botón transparente/fantasma (
btn-ghost) para el sílabo y uno relleno (btn-primary) para la acción principal. - No olvides acotar valores del progreso: el valor de
progressPercentagedebe estar normalizado entre 0 y 100.
- No satures la tarjeta con más de dos botones primarios; respeta la jerarquía visual destinando un botón transparente/fantasma (
09. Panel de Analítica Bento Multi-Métrica
- Componente & Vista
- Consejos & Guía
Panel horizontal que acopla múltiples indicadores de rendimiento académico en una sola unidad cohesiva con divisores internos, iconos vectoriales y subtítulos porcentuales en Verde Icesi (#4cb979) y Morado Icesi (#865cf0).
- Ubicación sugerida:
src/components/modules/analytics-bento-grid.tsx - Propósito: Mostrar una vista sinóptica del progreso curricular del estudiante en la cabecera del portal académico.
- Estilo DaisyUI sugerido: Agrupador
stats stats-horizontal shadow-sm border border-[#cecfd4] bg-base-100. - Contrato de Props sugerido (TypeScript):
interface StatItem {label: string;value: string | number;total?: string | number;description: string;icon: React.ReactNode;colorVariant?: 'primary' | 'secondary';}interface AnalyticsBentoGridProps {stats: StatItem[];}
- Clases base de DaisyUI sugeridas:
stats,stats-vertical lg:stats-horizontal,stat,stat-figure,stat-title,stat-value,stat-desc. - Qué usar:
- Utiliza la clase adaptativa
stats-vertical lg:stats-horizontalpara que en pantallas móviles los bloques se apilen verticalmente y en monitores de escritorio se alineen en fila. - Utiliza un
.map()tipado sobre el arreglostatspara asegurar que el componente pueda renderizar 2, 3 o 4 métricas dinámicamente.
- Utiliza la clase adaptativa
- Qué EVITAR:
- No construyas el contenedor con divs manuales y bordes independientes cuando DaisyUI ya gestiona los divisores internos del grupo
stats. - No repitas iconos idénticos para métricas distintas.
- No construyas el contenedor con divs manuales y bordes independientes cuando DaisyUI ya gestiona los divisores internos del grupo
10. Notificación Flotante Estilo Toast Institucional
- Componente & Vista
- Consejos & Guía
Tarjeta flotante de confirmación de eventos con icono circular de éxito en Verde Icesi (#4cb979), mensaje descriptivo, identificador de transacción o commit y botón de descarte rápido.
- Ubicación sugerida:
src/components/ui/toast-notification.tsx - Propósito: Notificar al estudiante cuando una entrega de laboratorio ha sido recibida y confirmada exitosamente.
- Estilo DaisyUI sugerido:
alert alert-success shadow-md rounded-2xlcon fondo blanco y acentos en Verde Icesi (#4cb979). - Contrato de Props sugerido (TypeScript):
interface ToastNotificationProps {title: string;message: string;variant?: 'success' | 'info' | 'warning' | 'error';onClose?: () => void;}
- Clases base de DaisyUI sugeridas:
toast,toast-top toast-end,alert,alert-success,btn btn-xs btn-ghost. - Qué usar:
- Si vas a posicionarlo de forma flotante fija en la ventana del navegador, envuelve la alerta en el contenedor
toast toast-top toast-end. - Diseña el componente con estado controlado para permitir que el usuario lo cierre manualmente o que desaparezca tras un temporizador en componentes cliente.
- Si vas a posicionarlo de forma flotante fija en la ventana del navegador, envuelve la alerta en el contenedor
- Qué EVITAR:
- No uses colores de alerta demasiado oscuros que tapen la información; el estilo contemporáneo prefiere fondos blancos con bordes y acentos semánticos tenues.
- No olvides incluir el botón de cierre con accesibilidad (
aria-label="Cerrar notificación").
11. Globo de Conversación de Asesoría Académica
- Componente & Vista
- Consejos & Guía
Hilo de mensajería asincrónica que posiciona los mensajes del estudiante a la izquierda y las respuestas del docente o monitor a la derecha con Azul Icesi (#5454e9), marcas de tiempo y avatar de usuario.
- Ubicación sugerida:
src/components/modules/advisor-chat-bubble.tsx - Propósito: Estructurar canales de consulta y retroalimentación académica uno a uno entre estudiantes y docentes.
- Estilo DaisyUI sugerido: Componentes
chat chat-startychat chat-endcon burbuja docente enchat-bubble chat-bubble-primary(#5454e9). - Contrato de Props sugerido (TypeScript):
interface ChatMessageProps {senderName: string;senderRole?: string;message: string;timestamp: string;avatarUrl: string;isSenderTeacher?: boolean;deliveryStatus?: string;}
- Clases base de DaisyUI sugeridas:
chat,chat-start,chat-end,chat-image,chat-header,chat-bubble,chat-bubble-primary,chat-footer. - Qué usar:
- Aprovecha la estructura semántica de DaisyUI:
chat-headerpara el nombre y la hora,chat-bubblepara el texto ychat-footerpara el acuse de recibo. - Permite que el booleano
isSenderTeacheralterne limpiamente entre la alineaciónchat-startychat-end.
- Aprovecha la estructura semántica de DaisyUI:
- Qué EVITAR:
- No maquetes las colas de las burbujas de diálogo con trucos complejos de CSS cuando DaisyUI ya las calcula con precisión de diseño nativo.
- No mezcles lógica de sockets o streaming directamente dentro de este componente de presentación.
12. Fila de Directorio Estudiantil con Menú de Acciones
- Componente & Vista
- Consejos & Guía
Fila de tabla de datos administrativos que organiza avatar con máscara de esquinas redondeadas (squircle), nombre y código del estudiante, programa académico, badge de estado en Verde Icesi (#4cb979) y botón de acción en Azul Icesi (#5454e9).
- Ubicación sugerida:
src/components/modules/student-table-row.tsx - Propósito: Renderizar cada elemento de una lista tabular de inscritos o participantes de un laboratorio.
- Estilo DaisyUI sugerido:
table table-smcon efectohover:bg-slate-50, máscaramask mask-squircleen el avatar y botónbtn-ghost btn-xs text-primary. - Contrato de Props sugerido (TypeScript):
interface StudentTableRowProps {studentId: string;studentCode: string;fullName: string;program: string;avatarUrl: string;status: 'active' | 'inactive' | 'graduated';onViewGradesClick?: () => void;}
- Clases base de DaisyUI sugeridas:
table,mask mask-squircle,avatar,badge,btn btn-ghost btn-xs. - Qué usar:
- Renderiza el componente como un elemento
<tr>puro para respetar la jerarquía HTML nativa de tablas dentro de un<tbody>. - Es ideal para ser renderizado dentro de un Server Component que itere sobre un arreglo de estudiantes traído de una consulta de base de datos.
- Renderiza el componente como un elemento
- Qué EVITAR:
- No envuelvas el
<tr>en un<div>: romperás la validez del DOM de la tabla HTML. - No dejes los avatares sin máscara cuando DaisyUI ofrece la elegante clase
mask mask-squircle.
- No envuelvas el
13. Rastreador de Hitos de Entrega por Pasos
- Componente & Vista
- Consejos & Guía
Línea de tiempo secuencial que ilustra los hitos o sprints de un proyecto de desarrollo, indicando qué etapas han sido completadas con Azul Icesi (#5454e9), cuál se encuentra activa hoy y cuáles están pendientes.
- Ubicación sugerida:
src/components/modules/step-progress-tracker.tsx - Propósito: Ofrecer retroalimentación visual clara sobre el flujo de entregables de un proyecto integrador o taller.
- Estilo DaisyUI sugerido: Lista no ordenada
<ul className="steps steps-horizontal">con pasos activos enstep-primary(#5454e9). - Contrato de Props sugerido (TypeScript):
interface StepItem {label: string;isCompleted: boolean;isCurrent?: boolean;stepNumber?: number | string;}interface StepProgressTrackerProps {steps: StepItem[];}
- Clases base de DaisyUI sugeridas:
steps,steps-horizontal,step,step-primary, atributodata-content="✓". - Qué usar:
- Utiliza el atributo HTML
data-contentde DaisyUI para personalizar el contenido del círculo del paso (ej.data-content="✓"para pasos completados). - Soporta diseño responsive con
steps-vertical md:steps-horizontalsi la lista tiene más de 4 hitos.
- Utiliza el atributo HTML
- Qué EVITAR:
- No calcules líneas horizontales con bordes absolutos: DaisyUI calcula los conectores entre nodos automáticamente mediante CSS.
- No omitas etiquetas de texto accesibles para lectores de pantalla.
14. Selector de Etiquetas Temáticas con Checkboxes
- Componente & Vista
- Consejos & Guía
Grupo interactivo de filtros temáticos presentados como píldoras de insignia (badges) activables, donde las etiquetas seleccionadas adoptan el Azul Icesi (#5454e9) y las disponibles permanecen neutras en Gris 2 (#cecfd4).
- Ubicación sugerida:
src/components/modules/tag-filter-group.tsx - Propósito: Permitir al estudiante o docente filtrar recursos, módulos o temas de estudio por categorías tecnológicas.
- Estilo DaisyUI sugerido:
badge badge-lgestilizados como controles de formulario mediante el truco CSSpeer-checked. - Contrato de Props sugerido (TypeScript):
interface TagOption {id: string;name: string;isSelected: boolean;}interface TagFilterGroupProps {title: string;tags: TagOption[];onTagToggle?: (tagId: string) => void;}
- Clases base de DaisyUI & Tailwind sugeridas:
badge,badge-lg,cursor-pointer,hidden peer,peer-checked:bg-primary peer-checked:text-white. - Qué usar:
- Oculta el
<input type="checkbox" className="hidden peer" />dentro del<label>y estiliza el<span>adyacente con modificadorespeer-checked:de Tailwind. - Si la selección altera los parámetros de búsqueda en la URL, enlaza cada tag con un
<Link href="...">que manipule lossearchParamsen un Server Component.
- Oculta el
- Qué EVITAR:
- No fuerces estados imperativos si los filtros pueden persistirse de forma canónica en la URL (
?tech=tailwind&tech=daisyui). - No olvides proporcionar foco por teclado (
focus-visible:ring-2) para usuarios que navegan conTab.
- No fuerces estados imperativos si los filtros pueden persistirse de forma canónica en la URL (
Nivel 3: Organismos Complejos (Alta)
Estructuras completas de interfaz que orquestan múltiples moléculas, layouts y flujos de acción.
15. Tarjeta de Evento o Hackathon con Cuenta Regresiva
- Componente & Vista
- Consejos & Guía
Tarjeta de convocatoria institucional que incluye distintivo de evento, indicador de cupos restantes en Naranja Icesi (#e9683b), título, horario y auditorio, un reloj modular de cuenta regresiva en tipografía monoespaciada con dígitos en Azul Icesi (#5454e9) y botón de registro de equipo.
- Ubicación sugerida:
src/components/organisms/event-countdown-card.tsx - Propósito: Promover talleres extracurriculares, retos de desarrollo y eventos de la facultad de ingeniería.
- Estilo DaisyUI sugerido:
card bg-base-100 border border-[#cecfd4], componentecountdown font-monoy botón prominentebtn-primary(#5454e9). - Contrato de Props sugerido (TypeScript):
interface EventCountdownCardProps {eventTitle: string;categoryTag: string;spotsLeft: number;location: string;dateText: string;countdown: {days: number;hours: number;minutes: number;};onRegisterClick?: () => void;}
- Clases base de DaisyUI sugeridas:
card,countdown font-mono text-2xl font-bold text-primary,badge badge-primary,btn btn-primary w-full. - Qué usar:
- DaisyUI provee la clase
countdownque sincroniza estilos de dígitos tabulares. - Si la cuenta regresiva disminuye en tiempo real cada segundo, encapsula únicamente el reloj en una frontera
'use client', permitiendo que el resto de la tarjeta se renderice como Server Component.
- DaisyUI provee la clase
- Qué EVITAR:
- No coloques todo el evento bajo
'use client'solo porque el reloj se actualiza; aprovecha el patrón de composición pasando el cliente como hijo de un Server Component. - No omitas el indicador de urgencia cuando queden pocos cupos.
- No coloques todo el evento bajo
16. Barra de Navegación de Aplicación con Menú de Usuario
- Componente & Vista
- Consejos & Guía
Barra de cabecera que unifica el logo institucional en Azul Icesi (#5454e9), nombre del portal y período académico a la izquierda, junto a un botón de notificaciones con badge contador en Morado Icesi (#865cf0) y avatar con menú desplegable a la derecha.
- Ubicación sugerida:
src/components/organisms/academic-app-navbar.tsx - Propósito: Cabecera principal persistente para la navegación del portal dentro de los layouts (
layout.tsx) de Next.js. - Estilo DaisyUI sugerido:
navbar bg-base-100 border-b border-[#cecfd4], indicador de notificacionesindicatorconbadge-secondary(#865cf0). - Contrato de Props sugerido (TypeScript):
interface UserSessionData {name: string;avatarUrl: string;notificationsCount: number;currentTerm: string;}interface AcademicAppNavbarProps {brandName: string;user: UserSessionData;}
- Clases base de DaisyUI sugeridas:
navbar,navbar-start,navbar-end,indicator,indicator-item,badge badge-xs badge-secondary,avatar online. - Qué usar:
- Es el candidato ideal para vivir en
app/layout.tsxcomo un Server Component que reciba la sesión autenticada del servidor sin revelar credenciales en el cliente. - Utiliza un componente
<Link href="/">para el logotipo para retornar siempre a la raíz del portal.
- Es el candidato ideal para vivir en
- Qué EVITAR:
- No agregues
'use client'a toda la barra de navegación; si el dropdown requiere interacción, aísla solo el menú desplegable en un componente cliente independiente. - No fijes alturas rígidas en píxeles que colapsen el diseño en dispositivos móviles.
- No agregues
17. Formulario Modular de Solicitud de Tutoría
- Componente & Vista
- Consejos & Guía
Formulario en tarjeta modular que incluye selector desplegable de tema de asesoría, área de texto multilínea para describir la inquietud técnica y botón primario de envío de solicitud en Azul Icesi (#5454e9).
- Ubicación sugerida:
src/components/organisms/tutoring-request-form.tsx - Propósito: Permitir a los estudiantes agendar asesorías de apoyo técnico con monitores o profesores de la asignatura.
- Estilo DaisyUI sugerido:
card bg-base-100 border border-[#cecfd4], camposselect select-bordered select-smytextarea textarea-bordered textarea-sm. - Contrato de Props sugerido (TypeScript):
interface TutoringTopicOption {id: string;label: string;}interface TutoringRequestFormProps {availableTopics: TutoringTopicOption[];actionHandler?: (formData: FormData) => Promise<void>; // Server Action}
- Clases base de DaisyUI sugeridas:
form-control,label,label-text,select select-bordered,textarea textarea-bordered,btn btn-primary btn-sm. - Qué usar:
- En Next.js 15, puedes conectar este formulario directamente con una Server Action mediante
<form action={...}>utilizando el atributo de acción sin requerir'use client'nipreventDefault(). - Utiliza los atributos semánticos
required,placeholderynameen cada campo para que el objetoFormDatase procese de forma nativa en el servidor.
- En Next.js 15, puedes conectar este formulario directamente con una Server Action mediante
- Qué EVITAR:
- No utilices
onChangecon unuseStatepara cada campo de texto a menos que requieras validación en vivo carácter por carácter. - No olvides especificar el atributo
nameen los elementos<select>y<textarea>.
- No utilices
18. Diálogo Modal de Confirmación de Entrega
- Componente & Vista
- Consejos & Guía
Cuadro de diálogo de confirmación que advierte sobre una acción irreversible, con icono de advertencia en Naranja Icesi (#e9683b), título en negrita, texto descriptivo del archivo a enviar y barra de acciones con opciones de cancelar o enviar definitivamente en Azul Icesi (#5454e9).
- Ubicación sugerida:
src/components/organisms/submission-confirm-modal.tsx - Propósito: Prevenir envíos accidentales o sustituciones de archivo en entregables calificados.
- Estilo DaisyUI sugerido: Componente modal
modal-box bg-base-100 border border-[#cecfd4] shadow-xly barramodal-action. - Contrato de Props sugerido (TypeScript):
interface SubmissionConfirmModalProps {isOpen: boolean;assignmentName: string;warningMessage?: string;onConfirm: () => void;onCancel: () => void;}
- Clases base de DaisyUI sugeridas:
modal,modal-open,modal-box,modal-action,btn btn-sm btn-ghost,btn btn-sm btn-primary. - Qué usar:
- Puedes implementarlo utilizando la etiqueta nativa HTML
<dialog>combinada con la clasemodalde DaisyUI, invocando.showModal()o controlando la clasemodal-open. - Asegura que el usuario pueda presionar la tecla
Escapepara cerrar el modal de manera natural.
- Puedes implementarlo utilizando la etiqueta nativa HTML
- Qué EVITAR:
- No utilices portales manuales de React con manipulación directa de
document.bodycuando la etiqueta<dialog>nativa y DaisyUI manejan el backdrop automáticamente. - No omitas el foco accesible: el botón de acción principal debe ser fácilmente identificable por el usuario.
- No utilices portales manuales de React con manipulación directa de
19. Tarjeta de Perfil Docente con Pestañas y Horarios
- Componente & Vista
- Consejos & Guía
Tarjeta de presentación de profesor que integra avatar con anillo en Azul Icesi (#5454e9), información departamental, sistema de pestañas (boxed tabs) para alternar entre asignaturas, horarios de asesoría y publicaciones, y botón de contacto.
- Ubicación sugerida:
src/components/organisms/faculty-profile-card.tsx - Propósito: Mostrar la ficha completa de profesores del departamento de TI en el portal de la carrera.
- Estilo DaisyUI sugerido:
card bg-base-100 border border-[#cecfd4],tabs tabs-boxed bg-slate-100y pestaña activatab-active text-primary(#5454e9). - Contrato de Props sugerido (TypeScript):
interface FacultyTabContent {id: string;label: string;content: React.ReactNode;}interface FacultyProfileCardProps {fullName: string;academicRole: string;department: string;avatarUrl: string;tabs: FacultyTabContent[];onContactClick?: () => void;}
- Clases base de DaisyUI sugeridas:
card,avatar,tabs tabs-boxed,tab,tab-active,btn btn-xs btn-outline btn-primary. - Qué usar:
- Si alternar entre pestañas cambia la vista sin recargar la página, este sub-panel de pestañas sí requiere
'use client'para gestionar el índice de la pestaña activa conuseState. - La tarjeta contenedora exterior puede mantenerse como Server Component pasando los datos del docente.
- Si alternar entre pestañas cambia la vista sin recargar la página, este sub-panel de pestañas sí requiere
- Qué EVITAR:
- No descargues todas las publicaciones pesadas en el bundle del cliente; renderiza el contenido inicial desde el servidor.
- No rompas la armonía de radios: si la tarjeta exterior tiene
rounded-2xl, el contenedor de tabs boxed debe tenerrounded-xl.
20. Tablero de Entregables de Sprint en Acordeón Colapsable
- Componente & Vista
- Consejos & Guía
Acordeón colapsable compuesto mediante el componente join de DaisyUI, que agrupa los sprints de la materia con distintivos de estado en Verde Icesi (#4cb979 para completado) y Amarillo Icesi (#e4eb60 para en progreso), flechas animadas e ítems de verificación técnica en el interior.
- Ubicación sugerida:
src/components/organisms/sprint-accordion-panel.tsx - Propósito: Organizar el backlog de sprints del proyecto semestral permitiendo expandir y contraer fases de entrega.
- Estilo DaisyUI sugerido: Contenedor unificado
join join-vertical w-fullcon bloquescollapse collapse-arrow join-item border border-[#cecfd4]. - Contrato de Props sugerido (TypeScript):
interface SprintTask {description: string;isDone: boolean;}interface SprintPhase {sprintNumber: number;title: string;status: 'completed' | 'in_progress' | 'pending';tasks: SprintTask[];isDefaultOpen?: boolean;}interface SprintAccordionPanelProps {sprints: SprintPhase[];}
- Clases base de DaisyUI sugeridas:
join join-vertical,collapse collapse-arrow join-item,collapse-title,collapse-content,badge. - Qué usar:
- DaisyUI permite hacer acordeones colapsables 100% en CSS puro sin necesidad de
'use client'ni JavaScript, simplemente colocando un elemento<input type="radio" name="sprint-accordion" defaultChecked />dentro del bloquecollapse. - La clase
collapse-arrowagrega automáticamente la animación de giro de la flecha cuando el input cambia de estado.
- DaisyUI permite hacer acordeones colapsables 100% en CSS puro sin necesidad de
- Qué EVITAR:
- ¡Gran anti-patrón! No escribas manejadores de evento
onClickmanuales con booleanos de estado para abrir y cerrar acordeones cuando la solución nativa con<input type="radio">o<details>de DaisyUI es más rápida, accesible y funciona como Server Component sin Javascript en el cliente. - No olvides incluir la clase
join-itemen cada elementocollapsepara que las esquinas redondeadas y bordes compartidos encajen a la perfección.
- ¡Gran anti-patrón! No escribas manejadores de evento
Matriz Resumen de Buenas Prácticas
Aplica esta matriz de decisión antes de programar cada uno de tus componentes en Next.js:
| Dimensión | Enfoque Recomendado | Anti-patrón a Evitar |
|---|---|---|
Directiva 'use client' | Solo en componentes con eventos interactivos (onClick, onChange), hooks (useState, useEffect) o APIs del navegador. | Poner 'use client' en todos los archivos por defecto "por si acaso". |
| Estilos & Paleta | Clases semánticas de DaisyUI (btn-primary, badge-secondary, bg-base-100) configuradas en el tema institucional icesi (Azul #5454e9, Morado #865cf0, Verde #4cb979, Naranja #e9683b, Amarillo #e4eb60). | Estilos en línea (style={{...}}) o clases de color hexadecimal arbitrarias (bg-[#0033a0]). |
| Contrato de Props | Interfaces TypeScript claras y explícitas con tipos unión ('sm' | 'md' | 'lg'). | Props con tipo any o sin valores por defecto. |
| Estructura HTML | Etiquetas semánticas nativas (<button>, <dialog>, <nav>, <kbd>, <progress>). | Anidar múltiples <div> vacíos sin significado semántico ni accesibilidad. |
| Navegación | Componente <Link href="..."> de Next.js para rutas internas del portal. | Etiquetas <a> convencionales que fuerzan una recarga completa de la página. |