🎬

GC-IPTV

Control Panel

Sistema Online
⚠️ {{ loginError }}

Broadcast Infrastructure Modernization

v1.0.0 • Secure Access

👋 Bienvenido, {{ currentUsername }}

Panel de gestión de tus clientes

Mis Clientes
{{ sellerStats.total_clients || stats.users || 0 }}
{{ sellerStats.active_clients || 0 }} activos
👥
Créditos
{{ sellerCredits }}
{{ sellerStats.credits_applied || 0 }} usados
💳
Conectados
{{ sellerStats.connected_now || 0 }}
Ahora mismo
📺
Por vencer
{{ sellerStats.expiring_soon || 0 }}
Próximos 7 días
Vencidos
{{ sellerStats.expired || 0 }}
Sin servicio
🚫

⚡ Acceso rápido

⚠️ Sin créditos disponibles. Contactá al administrador para recargar.

🔌 CONEXIONES ACTIVAS {{ filteredConnections.length }}

👤 Usuario 🌐 IP 📺 Canal 📱 Dispositivo ⏱️ Tiempo
{{ conn.username }} {{ conn.ip }} {{ conn.stream || '—' }} {{ conn.deviceIcon }} {{ conn.deviceType }} {{ conn.since ? formatDuration(Math.round((Date.now() - new Date(conn.since).getTime()) / 1000)) : '—' }}
📡

Ningún cliente conectado

Usuarios
{{ dashboardReady ? stats.users : '—' }}
Total registrados
👥
Live TV
{{ dashboardReady ? stats.liveStreams : '—' }}
Canales en vivo
📺
VOD
{{ dashboardReady ? stats.vodStreams : '—' }}
Películas
🎬
Series
{{ dashboardReady ? (stats.seriesCount || 0) : '—' }}
Series disponibles
📺
Categorías
{{ dashboardReady ? stats.categories : '—' }}
Grupos creados
📁
Conexiones
{{ dashboardReady ? realtimeStats.connectedUsers : '—' }}
En tiempo real
🔌
Estado del Sistema:
{{ service.name.split(' ')[0] }}
⏱️
Uptime del Sistema
Cargando...

📊 Distribución Usuarios

📡 Streams por Tipo

🏆 Top Streams

{{ index + 1 }}. {{ stream.name }} {{ stream.views || 0 }}

Sin datos

📈 Actividad (3 días)

📡 Ancho de Banda

⬇️ Entrada {{ networkStats.rxMbps }} Mbps
⬆️ Salida {{ networkStats.txMbps }} Mbps

🔌 CONEXIONES ACTIVAS {{ filteredConnections.length }}

👤 Usuario 🌐 IP 📺 Canal 📱 Dispositivo 📡 Servidor ⚡ Acciones
{{ conn.username }} {{ conn.ip }} {{ conn.stream }} {{ conn.deviceIcon }} {{ conn.deviceType }} 🌐 {{ conn.edge_id }} 🏠 Main

No hay conexiones activas

Página {{ connectionPage }} de {{ connectionPages }}

👥 Gestión de Usuarios

{{ filteredUsers.length }} de {{ users.length }} usuarios

👤 Usuario 📧 Email ⚡ Estado 📦 Pack 🔌 Max Conexiones ⏰ Expira 🏪 Sector ⚙️ Acciones
{{ user.username.charAt(0).toUpperCase() }}
{{ user.username }}
{{ user.email || '-' }} {{ user.status === 'active' ? '✓ Activo' : user.status === 'suspended' ? '⏸ Suspendido' : '✕ Inactivo' }} {{ getPackageName(user.package_id) }} Sin pack {{ user.max_connections }} {{ formatDate(user.expires_at) }} {{ getSellerName(user.seller_id) }} -

📺 Live TV - Canales en Vivo 🎬 VOD - Películas 📺 Series 📺 Gestión de Streams

{{ filteredStreams.length }} canales en vivo {{ filteredStreams.length }} películas {{ filteredStreams.length }} series {{ filteredStreams.length }} de {{ streams.length }} items

#️⃣ ID 📺 Nombre 🎭 Tipo 📁 Categoría 🏥 Health ⚡ Estado ⚙️ Acciones
📺 Serie 🎭 Género 📅 Año ⭐ Rating 📊 Temporadas ⚙️ Acciones
{{ stream.stream_id }}
{{ stream.type === 'live' ? '📡' : stream.type === 'vod' ? '🎬' : '📺' }}
{{ stream.name }}
{{ stream.type === 'live' ? '📡 LIVE' : stream.type === 'vod' ? '🎬 VOD' : '📺 SERIES' }} {{ getCategoryName(stream.category_id) }}
🟢 🔴 🟡 {{ stream.check_status || 'Sin verificar' }}
{{ stream.response_time_ms }}ms
{{ stream.codec_info.video }} / {{ stream.codec_info.audio }}
{{ stream.codec_info.resolution }}
{{ stream.status === 'active' ? '✓ Activo' : '✕ Inactivo' }} ⚡ Always On 🌐 Edges 🏠 Main ↗️ Source 📼 DVR ⏸️ Off
🎬
{{ serie.name }}
✅ TMDB
{{ serie.genre || '-' }} {{ serie.release_date || '-' }} ⭐ {{ serie.rating || 'N/A' }} {{ getSeriesSeasonCount(serie.id) || '0' }}

📁 Gestión de Categorías

{{ filteredCategories.length }} de {{ categories.length }} categorías

📁 Nombre 🎭 Tipo 🔢 Orden ⚙️ Acciones
📁
{{ category.name }}
{{ category.type === 'live' ? '📡 LIVE' : category.type === 'vod' ? '🎬 VOD' : '📺 SERIES' }} #{{ category.sort_order }}

🎬 Gestión de Series

{{ series.length }} series disponibles

📺 Serie 🎭 Género 📅 Año ⭐ Rating 📊 Temporadas ⚙️ Acciones
🎬
{{ serie.name }}
✅ TMDB: {{ serie.tmdb_id }}
⚠️ Sin metadata TMDB
{{ serie.genre || '-' }} {{ serie.release_date || '-' }} ⭐ {{ serie.rating || 'N/A' }} {{ getSeriesSeasonCount(serie.id) || '0' }}

⚙️ Configuración del Sistema

{{ systemConfig.length }} parámetros configurables

{{ config.key }} {{ config.category }}

⚠️ {{ Object.keys(configChanges).length }} cambio(s) sin guardar

⚠️ Nota: Cambiar puertos de servicios requiere reiniciar el sistema para aplicar los cambios.

🔧 Configuración de Buffering

Controla el rendimiento y velocidad de streaming

Tamaño del buffer para canales en vivo desde URLs remotas (bytes)

Actual: {{ formatBytes(bufferingSettings.chunk_size_remote) }} | Default: 32 KB | Impacto: ⚡ Zapping ultra rápido, más CPU 🟢 Balanceado 🔵 Más estable, zapping más lento

Tamaño del buffer para películas y series locales (bytes)

Actual: {{ formatBytes(bufferingSettings.chunk_size_local) }} | Default: 64 KB | Impacto: ⚡ Menos latencia inicial 🟢 Óptimo 🔵 Máxima fluidez para 4K

Límite de dispositivos conectados al mismo tiempo

Actual: {{ bufferingSettings.max_connections_per_user }} dispositivo(s) | Default: 3 | Impacto: ⚡ Zapping instantáneo, sin compartir cuenta 🟢 Multi-dispositivo familiar ⚠️ Mayor carga, fácil compartir

Tiempo de validez del token de streaming antes de expirar

Actual: {{ formatDuration(bufferingSettings.stream_token_ttl) }} | Default: 1 hora | Impacto: 🔒 Alta seguridad, reconexión frecuente 🟢 Balanceado ⚠️ Más cómodo, tokens duran más tiempo
✏️ Configuración personalizada activa ✅ Usando valores predeterminados

ℹ️ Nota: Los cambios se aplican inmediatamente a nuevas conexiones. Las sesiones activas mantienen su configuración actual.

📡 Gestión EPG

Editá la URL fuente, guardá con el ícono ✏️ arriba y ejecutá la actualización manual.

⏰ Actualización automática: todos los días a las 04:00 AM

📊 Monitoreo del Sistema

🖥️ CPU
{{ systemMetrics.cpu_usage.toFixed(1) }}%
💾 RAM
{{ (systemMetrics.ram_usage / 1024 / 1024 / 1024).toFixed(1) }} GB
de {{ (systemMetrics.ram_total / 1024 / 1024 / 1024).toFixed(1) }} GB
💽 Disco
{{ (systemMetrics.disk_usage / 1024 / 1024 / 1024).toFixed(0) }} GB
de {{ (systemMetrics.disk_total / 1024 / 1024 / 1024).toFixed(0) }} GB
🌐 Red
↓ {{ formatBytesPerSec(systemMetrics.network.bytes_received) }}
↑ {{ formatBytesPerSec(systemMetrics.network.bytes_sent) }}
⏱️ Uptime
{{ systemMetrics.uptime >= 86400 ? Math.floor(systemMetrics.uptime/86400) + 'd ' + Math.floor((systemMetrics.uptime%86400)/3600) + 'h' : Math.floor(systemMetrics.uptime/3600) + 'h ' + Math.floor((systemMetrics.uptime%3600)/60) + 'm' }}

🚦 Estado de Servicios

{{ service.name.split(' ')[0] }}
{{ service.status === 'online' ? '✅ OK' : '❌ Down' }}
Última actualización: {{ monitoringLastUpdate || 'Cargando...' }}

🔒 Seguridad y Control de Acceso

Gestiona conexiones, bloqueos y límites

🔌 Conexiones Activas

👤 Usuario 🌐 IP 📺 Canal 📡 Servidor 🕒 Desde ⚡ Acciones
{{ conn.username }} {{ conn.ip }} {{ conn.stream }} 🌐 {{ conn.edge_id }} 🏠 Main {{ formatDateTime(conn.since) }}
No hay conexiones activas en este momento

🚫 IPs Bloqueadas

IP Address Razón Bloqueado Expira Estado Acciones
{{ entry.ip_address }} {{ entry.reason || '-' }} {{ formatDateTime(entry.blocked_at) }} {{ entry.expires_at ? formatDateTime(entry.expires_at) : 'Permanente' }} BLOQUEADO EXPIRADO
No hay IPs bloqueadas

⚠️ Intentos de Conexión Bloqueados

Registro de intentos rechazados por límite de conexiones o IP bloqueada

Fecha Usuario IP Razón Stream Acciones
{{ formatDateTime(attempt.attempted_at) }} {{ attempt.username }} {{ attempt.ip_address }} LÍMITE EXCEDIDO IP BLOQUEADA {{ attempt.reason }} {{ attempt.stream_name || '-' }}
No hay intentos bloqueados registrados

📊 Límites de Conexión por Usuario

Configura cuántos dispositivos pueden conectarse simultáneamente

Usuario Email Límite Actual Modo Acciones
{{ user.username }} {{ user.email || '-' }} {{ user.max_connections || 1 }} 🔒 ESTRICTO 🏠 HOUSEHOLD 🌐 FLEXIBLE
No hay usuarios registrados

🚫 Bloquear Dirección IP

Dejar vacío para bloqueo permanente

📊 Configurar Límite de Conexión

Usuario: {{ limitForm.username }}

?

Dispositivos que pueden reproducir al mismo tiempo

?

🔒 El usuario solo puede conectarse desde un mismo IP. Si cambia de red, la sesión anterior se corta. 🏠 Se permiten hasta N IPs distintos. Configurable globalmente en Tab Configuración → Conexiones. 🌐 Sin restricción de origen. El usuario puede conectarse desde cualquier red o dispositivo.

🔐 Cambiar mi contraseña

{{ currentUsername }}

📦 Gestión de Packs

Definí qué contenido ve cada tipo de usuario

{{ packages.length }}
Packs activos
{{ packages.reduce((a,p) => a + (p.user_count || 0), 0) }}
Usuarios con pack
{{ packages.filter(p => p.include_vod && p.include_series).length }}
Packs completos
Pack Categorías 🎬 VOD 📺 Series 👥 Usuarios Acciones
{{ pkg.name }}
{{ pkg.description }}
Default
{{ cat.category_name }} Ninguna
{{ pkg.include_vod ? '✅' : '❌' }} {{ pkg.include_series ? '✅' : '❌' }} {{ pkg.user_count || 0 }}
No hay packs creados

{{ editingPackage ? '✏️ Editar Pack' : '➕ Nuevo Pack' }}

Cargando categorías...
|

🏪 Gestión de Sectores

Administrá tus sectores y sus créditos

{{ sellersTotal }}
Sectores registrados
{{ sellers.reduce((a,s) => a + s.credits_balance, 0) }}
Créditos totales distribuidos
Sector Email Estado 💳 Créditos Registrado Acciones
No hay sectores registrados
{{ seller.username }}
{{ seller.email }} {{ seller.status === 'active' ? 'Activo' : 'Inactivo' }} {{ seller.credits_balance }} {{ formatDate(seller.created_at) }}
{{ sellerError }}

Cada crédito permite crear 1 usuario por 30 días

💳 Agregar Créditos

Sector: {{ selectedSeller?.username }}

Balance actual: {{ selectedSeller?.credits_balance }} créditos

Nuevo balance: {{ (selectedSeller?.credits_balance || 0) + addCreditsAmount }} créditos

🌐 Edge CDN

Nodos de distribución de contenido

{{ edges.length }}
Total Edges
{{ edges.filter(e => e.ws_connected).length }}
Conectados
{{ edges.reduce((sum, e) => sum + (e.health?.active_viewers || 0), 0) }}
Viewers en Edges
{{ edges.reduce((sum, e) => sum + (e.health?.active_channels || 0), 0) }}
Canales en Edges
🌐

Sin Edge Nodes

Agregá un nodo CDN para distribuir el contenido geográficamente

{{ edge.ws_connected ? '📡' : '📴' }}

{{ edge.name }}

{{ edge.id }} · {{ edge.region || 'Sin región' }}

{{ edge.url }}

{{ edge.status }}
{{ edge.health.cpu_percent.toFixed(1) }}%
CPU
{{ edge.health.memory_mb }}MB
RAM
{{ edge.health.active_viewers }}
Viewers
{{ edge.health.active_channels }}
Canales
⬇️{{ (edge.health.rx_mbps || 0).toFixed(1) }} / ⬆️{{ (edge.health.tx_mbps || 0).toFixed(1) }}
Mbps
Sin datos de salud — edge no conectado

📡 Sesiones de Streaming

Historial de reproducciones

{{ sessionLogs.length }}
Sesiones cargadas
{{ sessionLogs.filter(l => l.is_active).length }}
Activas ahora
{{ [...new Set(sessionLogs.map(l => l.username))].length }}
Usuarios únicos
{{ [...new Set(sessionLogs.map(l => l.stream_name))].length }}
Canales distintos
📅 Fecha/Hora 👤 Usuario 📺 Canal 🌐 IP 📱 Dispositivo ⏱️ Duración Estado
{{ formatLogDate(log.started_at) }} {{ log.username }} {{ log.stream_name }} {{ log.ip_address }} {{ log.device_type === 'phone' ? '📱' : log.device_type === 'tv' ? '📺' : '💻' }} {{ log.device_name || log.device_type }} {{ formatSessionDuration(log.started_at, log.ended_at) }} 🟢 Vivo Finalizado

No hay registros

{{ (logsPage - 1) * logsPerPage + 1 }}-{{ Math.min(logsPage * logsPerPage, filteredSessionLogs.length) }} de {{ filteredSessionLogs.length }}

🔑 Intentos de Activación

Códigos de activación utilizados

{{ activationLogs.length }}
Total intentos
{{ activationLogs.filter(l => l.success).length }}
✅ Exitosos
{{ activationLogs.filter(l => !l.success).length }}
❌ Fallidos
📅 Fecha/Hora 🔑 Código 🌐 IP Resultado
{{ formatLogDate(log.attempted_at) }} {{ log.code_tried || '—' }} {{ log.ip_address }} ✅ OK ❌ Fallo

No hay intentos de activación registrados

🔐 Accesos al Sistema

Login exitosos y fallidos (panel + app)

{{ authLogs.length }}
Total eventos
{{ authLogs.filter(l => l.event_type === 'login_success').length }}
✅ Login exitosos
{{ authLogs.filter(l => l.event_type === 'login_failed').length }}
❌ Login fallidos
📅 Fecha/Hora 👤 Usuario 🌐 IP 📱 User-Agent Resultado Motivo
{{ formatLogDate(log.created_at) }} {{ log.username || '—' }} {{ log.ip_address }} {{ log.user_agent || '—' }} ✅ OK ❌ Fallo {{ log.failure_reason || '—' }}

No hay registros de acceso

📝 Auditoría

Cambios administrativos (crear, editar, eliminar)

📅 Fecha/Hora 👤 Quién 🏷️ Rol ⚡ Acción 📦 Recurso 🌐 IP 📋 Detalle
{{ formatLogDate(log.created_at) }} {{ log.actor_username || '—' }} {{ log.actor_role }} {{ log.action }} {{ log.resource_type }} ({{ log.resource_name }}) {{ log.ip_address || '—' }} {{ log.details !== '{}' ? log.details : '—' }}

No hay registros de auditoría

⚠️ Eventos de Seguridad

IPs bloqueadas, tokens rechazados, actividad sospechosa

{{ securityEvents.length }}
Total eventos
{{ securityEvents.filter(e => e.severity === 'critical').length }}
🔴 Críticos
{{ securityEvents.filter(e => e.severity === 'warning').length }}
🟡 Advertencias
📅 Fecha/Hora Severidad Tipo 🌐 IP 👤 Usuario Descripción
{{ formatLogDate(ev.created_at) }} {{ ev.severity === 'critical' ? '🔴' : ev.severity === 'warning' ? '🟡' : '🔵' }} {{ ev.severity }} {{ ev.event_type }} {{ ev.ip_address || '—' }} {{ ev.username || '—' }} {{ ev.description }}

No hay eventos de seguridad registrados

{{ editingEdge ? '✏️ Editar Edge' : '➕ Nuevo Edge' }}

Identificador único (no se puede cambiar)

▶️ Reproductor Web

{{ currentStreamName }}

⏳ Buffereando stream... ✅ Listo - Click PLAY ▶️ 🔴 EN VIVO ⚠️ Error de reproducción ⚪ Detenido
{{ currentStreamURL }}
💡 Tip: Usa los controles del reproductor para pausar, ajustar volumen, o pantalla completa

📱 Dispositivos

Usuario: {{ devicesUser && devicesUser.username }} max {{ devicesUser && devicesUser.max_connections }} dispositivo{{ devicesUser && devicesUser.max_connections !== 1 ? 's' : '' }}

📭

Sin dispositivos

Generá un código de activación para este usuario

{{ slot.activation_code }} {{ deviceStatusLabel(slot.status).text }}
{{ deviceTypeIcon(slot.device_type) }} {{ slot.device_name }} {{ slot.device_model }}
Último acceso: {{ new Date(slot.last_seen_at).toLocaleString('es-AR') }}
Sin activar — compartí el código con el cliente

{{ userDevices.filter(s => s.status === 'active').length }} activos / {{ userDevices.length }} códigos totales