**INFORME TÉCNICO COMPLETO** **I. Estructura y Componentes Lógicos:** La página presenta una estructura de panel de control (`dashboard`) dividida en un diseño de dos columnas principales: una barra lateral de navegación fija a la izquierda y un área de contenido principal dinámica a la derecha. * **Componentes Lógicos Modulares:** 1. **`PageContainer.tsx`:** Actúa como el contenedor principal, organizando la disposición global. * **Jerarquía DOM:** Un `div` principal que encapsula una `aside` para la barra lateral y una `main` para el contenido principal. * **Medidas Clave:** * Layout: `display: flex;` para posicionar la barra lateral y el contenido. * Ancho de `aside` (barra lateral): Aproximadamente `260px` (fijo). * `main` (contenido principal): `flex-grow: 1;` para ocupar el espacio restante. * El contenido dentro de `main` tiene un `padding` horizontal de aproximadamente `32px`. * No se observa un `max-width` global para toda la aplicación; el diseño se adapta al ancho de la ventana, con el contenido interno centrado o con padding. 2. **`Sidebar.tsx`:** Contiene la navegación principal de la aplicación. * **Jerarquía DOM:** `aside` (contenedor) > `div` (logo y título "StreamYard") > `nav` (para enlaces de navegación) > `ul` > `li` (elementos de menú) > `div` (sección de almacenamiento) > `div` (sección de configuración y ayuda). * **Medidas Clave:** * Ancho: `260px` (fijo). * Altura: `100vh` (altura completa de la ventana). * Fondo: Blanco. * Items de menú: `padding` vertical de `10px` y horizontal de `20px`. * Elemento activo: `background-color` (azul claro) y `border-left` (azul primario) de `4px`. * Separación entre grupos de enlaces y secciones: `margin-top` de `20px` a `30px`. 3. **`Header.tsx`:** La barra superior del área de contenido principal. * **Jerarquía DOM:** `header` (contenedor) > `div` (botones "Mejora tu plan") > `div` (grupo de iconos y "Mi cuenta"). * **Medidas Clave:** * Altura: Aproximadamente `64px` (fija). * Fondo: Blanco. * Layout: `display: flex; justify-content: flex-end; align-items: center;` (elementos alineados a la derecha, con espacio entre ellos). `padding` horizontal de `32px`. * Borde inferior sutil: `border-bottom: 1px solid` con color gris claro. 4. **`HeroSection.tsx`:** La sección "Crear", que presenta las opciones principales al usuario. * **Jerarquía DOM:** `section` (contenedor) > `h2` (título "Crear") > `div` (contenedor de tarjetas) > `div` (tarjeta individual, por ejemplo, "Transmisión en vivo"). * **Medidas Clave:** * Sistema de Rejilla: `display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;` (para escritorio). * Tarjetas: `min-height` de aproximadamente `120px` - `150px`. `padding: 20px;`. * Radio de borde: `border-radius: 8px`. * Separación: `margin-bottom` de `40px` después de la sección. 5. **`TransmissionsTable.tsx`:** La sección de "Transmisiones y grabaciones". * **Jerarquía DOM:** `section` (contenedor) > `h2` (título "Transmisiones y grabaciones") > `div` (contenedor de pestañas) > `button` (pestañas "Próximamente" y "Anteriores") > `div` (contenedor de la tabla) > `table` > `thead`, `tbody`, `tr`, `th`, `td`. * **Medidas Clave:** * Pestañas: `display: flex;` con `padding: 10px 0; margin-right: 20px;` para cada botón. La pestaña activa tiene `border-bottom: 3px solid` (azul primario). * Tabla: `width: 100%; border-collapse: collapse;`. * Celdas de tabla: `padding: 12px 15px;`. * Filas de tabla: `border-bottom: 1px solid` (gris claro). * Separación: `margin-bottom` de `30px` después del título de la sección, `margin-bottom` de `20px` después de las pestañas. **II. Métricas Pixel-Perfect:** * **Tipografía:** * **Familia de Fuentes:** 'Inter', 'Roboto', sans-serif (estimado visualmente). Se utilizará 'Inter' como principal. * **Títulos (H1/H2, por ejemplo, "Crear", "Transmisiones y grabaciones"):** * `font-size`: `22px` * `font-weight`: `600` (Semi-bold) * `line-height`: `1.4` * **Subtítulos (ej. "Próximamente", "Anteriores"):** * `font-size`: `16px` * `font-weight`: `500` (Medium) * `line-height`: `1.5` * **Texto Principal (P, elementos de menú, contenido de tabla):** * `font-size`: `14px` * `font-weight`: `400` (Regular) * `line-height`: `1.6` * **Texto Secundario/Pequeño (ej. "0 de 5 horas", "Agregar más"):** * `font-size`: `12px` * `font-weight`: `400` (Regular) * `line-height`: `1.5` * **Paleta de Colores (Códigos HEX/RGB estimados):** * **Fondo de Página (Main Background):** `#F7F8FA` (`rgb(247, 248, 250)`) - Gris muy claro. * **Fondo de Componentes/Tarjetas/Sidebar/Header:** `#FFFFFF` (`rgb(255, 255, 255)`) - Blanco. * **Texto Principal (Dark Grey):** `#212121` (`rgb(33, 33, 33)`) - Casi negro. * **Texto Secundario (Medium Grey):** `#6B7280` (`rgb(107, 114, 128)`) - Gris medio para subtítulos y texto menos prominente. * **Color de Acento (Primary Blue):** `#1876F2` (`rgb(24, 118, 242)`) - Azul vibrante para elementos interactivos. * **Fondo Activo de Sidebar/Hover:** `#EBF3FF` (`rgb(235, 243, 255)`) - Azul muy claro. * **Bordes/Divisores (Light Grey):** `#E5E7EB` (`rgb(229, 231, 235)`) - Gris claro. * **Sombras (Box Shadow):** `0px 1px 3px rgba(0, 0, 0, 0.08)` (sutil para tarjetas y botón flotante). * **Color de Iconos (Grey):** `#6B7280` * **Espaciado y Bordeado:** * **Separación vertical entre secciones:** `margin-top: 32px;` o `padding-top: 32px;`. * **Padding horizontal global en contenido principal:** `32px`. * **Padding vertical en Header:** `16px`. * **Radius de Borde:** * Botones ("Mejora tu plan", "Entrar al estudio", "Ayuda"): `border-radius: 6px`. * Tarjetas ("Crear" section): `border-radius: 8px`. * Alternadores (Theme Toggle): `border-radius: 9999px` (píldora). **III. Funcionalidad y Scripts Internos:** * **Funcionalidad del Aplicativo Web:** 1. **Navegación Interactiva del Sidebar:** Los elementos del menú en la barra lateral son clicables. El elemento actualmente seleccionado ("Inicio") se destaca con un fondo azul claro y un borde azul a la izquierda para indicar su estado activo. 2. **Toggle de Tema (Modo Claro/Oscuro):** En la esquina superior derecha del área de contenido principal, hay un control que permite al usuario alternar entre modos de visualización (claro y oscuro), representado por iconos de sol y luna. El modo "claro" (sol) está activo por defecto. 3. **Pestañas de Contenido (Transmisiones y Grabaciones):** La sección "Transmisiones y grabaciones" contiene dos pestañas ("Próximamente" y "Anteriores"). Al hacer clic en cada pestaña, el contenido de la tabla subyacente debe actualizarse para mostrar las transmisiones correspondientes a la selección. La pestaña "Próximamente" está activa. 4. **Botón de Acción Flotante ("Ayuda"):** Un botón persistente en la parte inferior derecha de la pantalla que ofrece acceso rápido a la ayuda o soporte. Este botón tiene una sombra para darle un efecto elevado. 5. **Estados de Interacción (Hover/Active):** Botones, enlaces de navegación y tarjetas presentan cambios visuales (ej. cambio de color de fondo, elevación de sombra) al pasar el cursor (hover) y al hacer clic (active) para proporcionar retroalimentación al usuario. * **Scripts Internos (Comportamiento):** 1. **Manejo de Estado para Navegación Activa:** Se utilizará `useState` en el componente `Sidebar` para controlar el `id` o la `ruta` del elemento de navegación activo, aplicando dinámicamente las clases CSS (`styles.activeLink`) al elemento seleccionado. 2. **Lógica de Toggle de Tema:** Un `useState` en `PageContainer` o un contexto global para gestionar el estado del tema (`light`/`dark`). Se aplicará una clase CSS (`.theme-dark` o similar) al `body` o al contenedor principal para modificar los colores a través de variables CSS (ej. `--background-color`, `--text-color`). 3. **Manejo de Estado para Pestañas:** Dentro del componente `TransmissionsTable`, se utilizará `useState` para mantener el control de la pestaña activa. Esto determinará qué conjunto de datos de transmisiones se renderiza en la tabla. 4. **Renderizado Condicional y Mapeo de Datos:** El contenido de la tabla en `TransmissionsTable` se renderizará condicionalmente o mediante `.map()` basándose en el estado de la pestaña activa y un array de objetos de transmisiones. 5. **Event Handlers:** Funciones de `onClick` serán implementadas en los elementos interactivos (enlaces de navegación, botones de tema, pestañas) para actualizar los estados correspondientes y desencadenar los cambios en la UI. 6. **Desplazamiento Suave (Scroll Behavior):** Aunque no es explícitamente interactivo, la barra lateral debe permanecer fija mientras el contenido principal es desplazable. El botón "Ayuda" también se fijará en la esquina inferior derecha (`position: fixed`). --- **GENERACIÓN DE CÓDIGO** A continuación, se presenta el código para los componentes React/TypeScript y sus módulos CSS, siguiendo las métricas y la funcionalidad descritas en el informe técnico. Se incluirá un componente `Sidebar` adicional por su relevancia estructural en el diseño. **1. `src/components/PageContainer.tsx`** ```tsx import React, { useState } from 'react'; import styles from './PageContainer.module.css'; import Sidebar from './Sidebar/Sidebar'; // Assuming Sidebar component import Header from './Header/Header'; // Assuming Header component import HeroSection from './HeroSection/HeroSection'; // Assuming HeroSection component import TransmissionsTable from './TransmissionsTable/TransmissionsTable'; // Assuming TransmissionsTable component const PageContainer: React.FC = () => { // Estado para manejar el tema (claro/oscuro) const [theme, setTheme] = useState<'light' | 'dark'>('light'); const toggleTheme = () => { setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light')); }; // Aplica la clase del tema al body o al contenedor principal // En un proyecto real, esto podría hacerse con un contexto o CSS variables // document.body.className = theme === 'dark' ? 'theme-dark' : 'theme-light'; return (
{/* Sidebar - componente lateral de navegación */} {/* Main Content Area */}
{/* Header - barra superior del contenido principal */}
{/* Hero Section - sección "Crear" */} {/* Transmissions Table - sección de tablas */}
{/* Botón flotante de Ayuda */}
); }; export default PageContainer; ``` **2. `src/components/PageContainer.module.css`** ```css /* Variables CSS para el tema */ :root { --background-color: #f7f8fa; /* Gris muy claro para el fondo de la página */ --surface-color: #ffffff; /* Blanco para componentes/tarjetas */ --text-primary: #212121; /* Gris oscuro casi negro */ --text-secondary: #6b7280; /* Gris medio para texto secundario */ --primary-blue: #1876f2; /* Azul vibrante */ --active-bg-light: #ebf3ff; /* Azul muy claro para activo/hover */ --border-light: #e5e7eb; /* Gris claro para bordes */ --shadow-light: rgba(0, 0, 0, 0.08); /* Sombra sutil */ } /* Tema oscuro (ejemplo, no completamente implementado en la imagen) */ .themeDark { --background-color: #1a1a1a; --surface-color: #2c2c2c; --text-primary: #f0f0f0; --text-secondary: #a0a0a0; --border-light: #444; /* Otros colores oscuros */ } .pageContainer { display: flex; min-height: 100vh; /* Asegura que ocupe al menos la altura de la ventana */ background-color: var(--background-color); font-family: 'Inter', 'Roboto', sans-serif; /* Familia de fuentes */ color: var(--text-primary); } .mainContent { flex-grow: 1; /* Ocupa el espacio restante */ display: flex; flex-direction: column; position: relative; /* Para el botón flotante */ background-color: var(--background-color); /* Fondo del área de contenido */ overflow-y: auto; /* Permite el scroll vertical en el contenido principal */ } .contentWrapper { padding: 32px; /* Padding global para el contenido principal */ flex-grow: 1; } .helpButton { position: fixed; bottom: 24px; right: 24px; background-color: var(--primary-blue); color: #ffffff; padding: 12px 20px; border: none; border-radius: 6px; box-shadow: 0px 4px 12px var(--shadow-light); /* Sombra para elevarlo */ cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 500; z-index: 1000; /* Asegura que esté por encima de otros elementos */ } .helpButton:hover { background-color: #146bdc; /* Azul un poco más oscuro al hacer hover */ } /* Media Queries para responsividad */ @media (max-width: 768px) { .pageContainer { flex-direction: column; /* La barra lateral se apilará en móviles */ } .mainContent { width: 100%; /* El contenido principal ocupa todo el ancho */ } .contentWrapper { padding: 20px; /* Reducir padding en móviles */ } .helpButton { bottom: 16px; right: 16px; padding: 10px 16px; } } ``` **3. `src/components/Sidebar/Sidebar.tsx`** ```tsx import React from 'react'; import styles from './Sidebar.module.css'; interface SidebarProps { activeLink: string; } const Sidebar: React.FC = ({ activeLink }) => { const navItems = [ { id: 'Inicio', label: 'Inicio', icon: }, { id: 'Biblioteca', label: 'Biblioteca', icon: }, { id: 'Destinos', label: 'Destinos', icon: }, { id: 'Miembros', label: 'Miembros', icon: }, ]; const secondaryItems = [ { id: 'Referidos', label: 'Referidos', icon: }, { id: 'Configuracion', label: 'Configuración del equipo', icon: }, { id: 'Estado', label: 'Estado del sistema', icon: }, ]; return ( ); }; export default Sidebar; ``` **4. `src/components/Sidebar/Sidebar.module.css`** ```css .sidebar { width: 260px; /* Ancho fijo */ min-width: 260px; height: 100vh; /* Ocupa toda la altura */ background-color: var(--surface-color); padding: 20px 0; /* Padding vertical */ box-shadow: 1px 0 5px rgba(0, 0, 0, 0.05); /* Sombra sutil a la derecha */ display: flex; flex-direction: column; overflow-y: auto; /* Para permitir scroll si el contenido es largo */ } .logoSection { display: flex; align-items: center; padding: 0 20px 20px; /* Padding bottom para separación */ border-bottom: 1px solid var(--border-light); /* Separador sutil */ margin-bottom: 20px; } .logoIcon { width: 32px; height: 32px; margin-right: 10px; } .logoText { font-size: 20px; font-weight: 600; color: var(--text-primary); } .navMenu { flex-grow: 1; /* Permite que el menú crezca y ocupe el espacio */ } .navList { list-style: none; padding: 0; margin: 0; } .navItem { margin-bottom: 4px; /* Pequeña separación entre items */ } .navLink { display: flex; align-items: center; padding: 10px 20px; color: var(--text-secondary); /* Color por defecto */ text-decoration: none; font-size: 14px; font-weight: 500; border-left: 4px solid transparent; /* Borde transparente por defecto */ transition: all 0.2s ease-in-out; gap: 10px; } .navLink svg { color: var(--text-secondary); /* Color de icono por defecto */ } .navLink:hover { background-color: var(--active-bg-light); /* Fondo azul claro al hover */ color: var(--primary-blue); /* Texto azul al hover */ } .navLink:hover svg { color: var(--primary-blue); /* Icono azul al hover */ } .activeLink .navLink { background-color: var(--active-bg-light); /* Fondo azul claro para activo */ color: var(--primary-blue); /* Texto azul para activo */ border-left-color: var(--primary-blue); /* Borde azul para activo */ } .activeLink .navLink svg { color: var(--primary-blue); /* Icono azul para activo */ } .secondaryNavGroup { margin-top: 30px; /* Separación para el segundo grupo */ padding-top: 20px; border-top: 1px solid var(--border-light); } .storageInfo { padding: 20px; margin-top: auto; /* Empuja el almacenamiento al final */ border-top: 1px solid var(--border-light); /* Separador */ } .storageTitle { font-size: 14px; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; display: flex; align-items: center; gap: 4px; } .infoIcon { background-color: var(--border-light); border-radius: 50%; width: 16px; height: 16px; display: flex; justify-content: center; align-items: center; font-size: 10px; color: var(--text-secondary); font-weight: 500; } .progressBarContainer { width: 100%; height: 6px; background-color: var(--border-light); border-radius: 3px; margin-bottom: 8px; } .progressBarFill { height: 100%; background-color: var(--primary-blue); border-radius: 3px; width: 0%; /* Se controlará con JS para el progreso real */ } .storageUsage { font-size: 12px; color: var(--text-secondary); margin-bottom: 8px; } .addMoreLink { font-size: 12px; color: var(--primary-blue); text-decoration: none; font-weight: 500; } .addMoreLink:hover { text-decoration: underline; } /* Media Queries para responsividad */ @media (max-width: 768px) { .sidebar { width: 100%; /* Ocupa todo el ancho en móviles */ height: auto; /* Altura automática */ padding: 10px 0; box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05); /* Sombra inferior */ position: relative; z-index: 100; /* Asegura que esté encima de otros elementos */ } .navMenu { display: none; /* Ocultar el menú de navegación principal en móvil por defecto */ /* En un caso real, aquí iría la lógica para un menú hamburguesa */ } .logoSection { padding: 10px 20px; border-bottom: none; margin-bottom: 0; justify-content: center; /* Centrar logo en móvil */ } .storageInfo { display: none; /* Ocultar info de almacenamiento en móvil */ } } ``` **5. `src/components/Header/Header.tsx`** ```tsx import React from 'react'; import styles from './Header.module.css'; interface HeaderProps { currentTheme: 'light' | 'dark'; onToggleTheme: () => void; } const Header: React.FC = ({ currentTheme, onToggleTheme }) => { return (
Mi cuenta
); }; export default Header; ``` **6. `src/components/Header/Header.module.css`** ```css .header { height: 64px; /* Altura fija del header */ background-color: var(--surface-color); border-bottom: 1px solid var(--border-light); /* Borde inferior sutil */ display: flex; justify-content: flex-end; /* Alinea el contenido a la derecha */ align-items: center; padding: 0 32px; /* Padding horizontal */ flex-shrink: 0; /* Previene que el header se encoja */ } .headerActions { display: flex; align-items: center; gap: 20px; /* Espacio entre los grupos de elementos */ } .planButton { background-color: transparent; color: var(--primary-blue); border: 1px solid var(--primary-blue); padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.2s ease-in-out; } .planButton:hover { background-color: var(--primary-blue); color: #ffffff; } .themeToggleGroup { display: flex; background-color: var(--background-color); /* Fondo gris claro */ border-radius: 9999px; /* Forma de píldora */ padding: 4px; gap: 4px; } .themeToggleButton { background-color: transparent; border: none; border-radius: 9999px; /* Forma redonda */ padding: 8px; cursor: pointer; color: var(--text-secondary); /* Icono gris por defecto */ transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; display: flex; align-items: center; justify-content: center; } .themeToggleButton.active { background-color: var(--surface-color); /* Fondo blanco para el activo */ color: var(--text-primary); /* Icono oscuro para el activo */ box-shadow: 0px 1px 3px var(--shadow-light); /* Sombra sutil para el activo */ } .themeToggleButton:hover:not(.active) { background-color: var(--border-light); /* Fondo ligeramente más oscuro al hover */ } .notificationButton { background-color: transparent; border: none; cursor: pointer; color: var(--text-secondary); position: relative; padding: 0; /* Eliminar padding para que el icono se centre mejor */ display: flex; /* Asegura que el SVG se centre */ align-items: center; justify-content: center; height: 36px; /* Ajusta la altura para que coincida con otros elementos interactivos */ width: 36px; border-radius: 50%; transition: background-color 0.2s ease-in-out; } .notificationButton:hover { background-color: var(--border-light); } .notificationDot { position: absolute; top: 6px; right: 6px; width: 8px; height: 8px; background-color: var(--primary-blue); /* Color del punto de notificación */ border-radius: 50%; border: 1px solid var(--surface-color); /* Pequeño borde blanco */ } .userMenu { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; color: var(--text-primary); font-weight: 500; } .userMenu svg { color: var(--text-secondary); } /* Media Queries para responsividad */ @media (max-width: 768px) { .header { padding: 0 16px; height: 56px; justify-content: space-between; /* Alinear elementos al principio y al final */ } .headerActions { gap: 10px; } .planButton { padding: 6px 12px; font-size: 13px; } .themeToggleGroup { display: none; /* Ocultar el selector de tema en móviles para simplificar */ } .notificationButton, .userMenu { /* Ajustes menores si es necesario */ } } ``` **7. `src/components/HeroSection/HeroSection.tsx`** ```tsx import React from 'react'; import styles from './HeroSection.module.css'; interface CardProps { icon: React.ReactNode; title: string; } const CreateCard: React.FC = ({ icon, title }) => { return (
{icon}

{title}

); }; const HeroSection: React.FC = () => { return (

Crear

} title="Transmisión en vivo" /> } title="Grabación" /> } title="Seminario web On-Air" />
); }; export default HeroSection; ``` **8. `src/components/HeroSection/HeroSection.module.css`** ```css .heroSection { margin-bottom: 40px; /* Separación con la siguiente sección */ } .sectionTitle { font-size: 22px; font-weight: 600; color: var(--text-primary); margin-bottom: 24px; /* Espacio debajo del título */ } .cardGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); /* Adaptativo */ gap: 20px; /* Espacio entre las tarjetas */ } .createCard { background-color: var(--surface-color); border: 1px solid var(--border-light); border-radius: 8px; padding: 20px; display: flex; flex-direction: column; align-items: flex-start; /* Alinea los elementos a la izquierda */ cursor: pointer; transition: all 0.2s ease-in-out; min-height: 120px; /* Altura mínima para la tarjeta */ box-shadow: 0px 1px 3px var(--shadow-light); /* Sombra sutil */ } .createCard:hover { border-color: var(--primary-blue); /* Borde azul al hover */ box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.12); /* Sombra más pronunciada */ } .cardIcon { color: var(--primary-blue); /* Color del icono */ margin-bottom: 12px; width: 32px; height: 32px; } .cardTitle { font-size: 16px; font-weight: 500; color: var(--text-primary); margin: 0; line-height: 1.5; } /* Media Queries para responsividad */ @media (max-width: 768px) { .heroSection { margin-bottom: 30px; } .sectionTitle { font-size: 20px; margin-bottom: 16px; } .cardGrid { grid-template-columns: 1fr; /* Una columna en móviles */ gap: 16px; } .createCard { padding: 16px; min-height: 100px; } .cardIcon { width: 28px; height: 28px; margin-bottom: 8px; } .cardTitle { font-size: 15px; } } ``` **9. `src/components/TransmissionsTable/TransmissionsTable.tsx`** ```tsx import React, { useState } from 'react'; import styles from './TransmissionsTable.module.css'; interface Transmission { id: string; title: string; platformIcon: React.ReactNode; created: string; scheduled: string; } const dummyTransmissions: Transmission[] = [ { id: '1', title: 'Transmision', platformIcon: , created: '01:56', scheduled: '-', }, // Más datos de transmisiones pueden ir aquí ]; const TransmissionsTable: React.FC = () => { const [activeTab, setActiveTab] = useState<'upcoming' | 'past'>('upcoming'); // Datos simulados para las pestañas const upcomingTransmissions: Transmission[] = dummyTransmissions; // De momento, los mismos datos const pastTransmissions: Transmission[] = []; // Sin datos pasados por ahora const displayedTransmissions = activeTab === 'upcoming' ? upcomingTransmissions : pastTransmissions; return (

Transmisiones y grabaciones

{displayedTransmissions.length > 0 ? ( displayedTransmissions.map((transmission) => ( )) ) : ( )}
Título Creada Programado Acciones
{/* Avatar simulado con "a" o imagen de usuario */} a
{transmission.title} {transmission.platformIcon}
{transmission.created} {transmission.scheduled}
No hay transmisiones en esta categoría.
); }; export default TransmissionsTable; ``` **10. `src/components/TransmissionsTable/TransmissionsTable.module.css`** ```css .transmissionsSection { margin-bottom: 40px; /* Separación con el pie de página o final */ } .sectionTitle { font-size: 22px; font-weight: 600; color: var(--text-primary); margin-bottom: 24px; } .tabContainer { display: flex; border-bottom: 1px solid var(--border-light); /* Borde debajo de las pestañas */ margin-bottom: 20px; /* Espacio debajo del contenedor de pestañas */ } .tabButton { background-color: transparent; border: none; padding: 10px 0; margin-right: 20px; /* Espacio entre pestañas */ font-size: 16px; font-weight: 500; color: var(--text-secondary); cursor: pointer; position: relative; transition: color 0.2s ease-in-out; } .tabButton:hover { color: var(--primary-blue); } .tabButton.activeTab { color: var(--primary-blue); border-bottom: 3px solid var(--primary-blue); /* Borde azul para la pestaña activa */ padding-bottom: 7px; /* Ajustar padding para compensar el borde */ } .tableWrapper { overflow-x: auto; /* Permite el scroll horizontal en tablas grandes */ background-color: var(--surface-color); border-radius: 8px; box-shadow: 0px 1px 3px var(--shadow-light); border: 1px solid var(--border-light); } .transmissionsTable { width: 100%; border-collapse: collapse; /* Elimina los espacios entre bordes de celda */ } .tableHeader { text-align: left; padding: 12px 15px; font-size: 12px; font-weight: 500; color: var(--text-secondary); text-transform: uppercase; border-bottom: 1px solid var(--border-light); } .tableRow { transition: background-color 0.2s ease-in-out; } .tableRow:hover { background-color: var(--active-bg-light); /* Fondo suave al hover en la fila */ } .tableCell { padding: 12px 15px; font-size: 14px; color: var(--text-primary); border-bottom: 1px solid var(--border-light); } .tableRow:last-child .tableCell { border-bottom: none; /* Elimina el borde inferior de la última fila */ } .titleCellContent { display: flex; align-items: center; gap: 12px; } .platformAvatar { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background-color: var(--border-light); /* Fondo para el avatar genérico */ flex-shrink: 0; /* Evita que el avatar se encoja */ } .transmissionTitle { font-weight: 500; color: var(--text-primary); } .transmissionPlatformIcon { margin-left: 8px; /* Espacio entre el título y el icono de la plataforma */ display: inline-flex; /* Para alinear el SVG correctamente */ vertical-align: middle; } .transmissionPlatformIcon svg { width: 16px; height: 16px; } .actionsCell { white-space: nowrap; /* Evita que los botones se rompan en varias líneas */ text-align: right; } .enterStudioButton { background-color: transparent; color: var(--primary-blue); border: 1px solid var(--primary-blue); padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.2s ease-in-out; margin-right: 8px; } .enterStudioButton:hover { background-color: var(--primary-blue); color: #ffffff; } .moreOptionsButton { background-color: transparent; border: none; padding: 8px; border-radius: 6px; cursor: pointer; color: var(--text-secondary); transition: background-color 0.2s ease-in-out; } .moreOptionsButton:hover { background-color: var(--border-light); } .noDataCell { text-align: center; padding: 40px; color: var(--text-secondary); font-style: italic; } /* Media Queries para responsividad */ @media (max-width: 768px) { .sectionTitle { font-size: 20px; margin-bottom: 16px; } .tabButton { font-size: 15px; margin-right: 15px; padding-bottom: 5px; } .tabButton.activeTab { padding-bottom: 2px; /* Ajustar por el borde */ } .tableWrapper { /* El overflow-x: auto ya maneja el responsive */ } .tableHeader, .tableCell { padding: 10px 12px; font-size: 13px; } .titleCellContent { gap: 8px; } .platformAvatar { width: 28px; height: 28px; } .platformAvatar text { font-size: 10px; } .transmissionTitle { font-size: 13px; } .enterStudioButton { padding: 6px 12px; font-size: 13px; margin-right: 4px; } .moreOptionsButton { padding: 6px; } } ```