Spaces:
Running
Running

"Crea una aplicación web moderna de compartición de archivos similar a PicoShare con la siguiente estructura y funcionalidades específicas: ESTRUCTURA DE LA INTERFAZ: 1. Navegación principal con 3 secciones: Pestaña "Subir Archivos" (Upload) Pestaña "Mis Archivos" (My Files) Pestaña "Configuración" (Settings) 2. PESTAÑA "SUBIR ARCHIVOS": Área central de drag & drop con indicador visual atractivo Botón "Seleccionar archivos" como alternativa al drag & drop Barra de progreso para cada archivo durante la subida Lista en tiempo real de archivos siendo procesados Configuración rápida por archivo: Fecha de expiración (1 día, 1 semana, 1 mes, nunca) Protección con contraseña (opcional) Límite de descargas Generación automática del enlace al completar la subida Botón "Copiar enlace" con confirmación visual Historial de subidas recientes en la parte inferior 3. PESTAÑA "MIS ARCHIVOS": Vista de grilla/lista intercambiable Sistema de vista previa inteligente: Imágenes: Thumbnails reales del archivo (JPG, PNG, GIF, WebP, SVG) Videos: Thumbnail del primer frame + icono de play PDFs: Vista previa de la primera página Documentos: Iconos específicos por tipo (Word, Excel, PowerPoint, etc.) Código fuente: Iconos por lenguaje (JS, Python, Java, etc.) Archivos comprimidos: Iconos de ZIP, RAR, 7z, etc. Audio: Iconos con waveform si es posible Otros: Icono genérico con extensión visible Información por archivo: Nombre del archivo (editable) Tamaño y fecha de subida Número de descargas Estado (activo/expirado) Enlace directo con botón copiar Acciones: Compartir, Descargar, Eliminar, Renovar expiración Funcionalidades adicionales: Búsqueda y filtrado por nombre, tipo, fecha Ordenamiento por nombre, tamaño, fecha, descargas Selección múltiple para acciones en lote Modal de vista previa completa al hacer clic 4. PESTAÑA "CONFIGURACIÓN": Sección Autenticación: Configuración SAML 2.0 (Entity ID, SSO URL, Certificado) Configuración OpenID Connect (Client ID, Secret, Discovery URL) Gestión de proveedores de identidad activos Mapeo de atributos de usuario Sección Apariencia: Toggle modo claro/oscuro Selección de colores de tema principal Configuración de idioma Densidad de información (compacta/cómoda/espaciosa) Sección Archivos: Límites de tamaño por archivo y total por usuario Tipos de archivo permitidos/bloqueados Configuración de retención por defecto Límites de descarga por defecto Configuración de almacenamiento (local/S3/GCS) Sección Seguridad: Configuración de rate limiting Logs de actividad y acceso Configuración de encriptación Políticas de contraseñas para enlaces protegidos Configuración de notificaciones de seguridad Sección Sistema: Información del servidor y uso de almacenamiento Configuración de backups automáticos Configuración de limpieza automática de archivos expirados Logs del sistema y estadísticas de uso ESPECIFICACIONES TÉCNICAS DETALLADAS: Frontend: Framework moderno (React con TypeScript recomendado) Biblioteca de iconos extensa (React Icons o similar) Componentes de UI modernos (Tailwind CSS + shadcn/ui) Manejo de estado global (Zustand o Redux Toolkit) Lazy loading para vistas previas Progressive Web App (PWA) capabilities Backend: API RESTful completa con documentación OpenAPI Endpoints específicos para vistas previas y thumbnails Procesamiento asíncrono para generación de previews Sistema de jobs/queues para tareas pesadas Rate limiting por IP y usuario autenticado Logging estructurado con diferentes niveles Base de datos: Esquema para usuarios, archivos, configuraciones, logs Índices optimizados para búsquedas rápidas Soft delete para archivos (papelera de reciclaje) Metadatos extendidos para cada archivo Funcionalidades específicas del sistema de vista previa: Generación automática de thumbnails para imágenes Extracción de frame para videos usando FFmpeg Conversión de primera página de PDF a imagen Cache inteligente de vistas previas Fallback a iconos cuando no se puede generar preview Detección automática de tipo MIME real vs extensión Despliegue: Docker Compose completo con todos los servicios Variables de entorno para toda la configuración Nginx reverse proxy incluido Certificados SSL automáticos (Let's Encrypt) Scripts de migración de base de datos Documentación completa de instalación y configuración Genera el código completo con esta estructura específica, incluyendo los componentes de UI detallados, la lógica de negocio para vistas previas, y ejemplos de configuración para cada sección de settings." - Initial Deployment
6bf9b5b
verified
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>FileShare - Modern File Sharing Platform</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<script> | |
tailwind.config = { | |
theme: { | |
extend: { | |
colors: { | |
primary: '#3b82f6', | |
secondary: '#10b981', | |
dark: '#1e293b', | |
light: '#f8fafc' | |
} | |
} | |
} | |
} | |
</script> | |
<style> | |
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); | |
body { | |
font-family: 'Inter', sans-serif; | |
background-color: #f1f5f9; | |
} | |
.tab-content { | |
display: none; | |
} | |
.tab-content.active { | |
display: block; | |
} | |
.drag-area { | |
border: 2px dashed #cbd5e1; | |
transition: all 0.3s ease; | |
} | |
.drag-area.active { | |
border-color: #3b82f6; | |
background-color: #dbeafe; | |
} | |
.file-preview { | |
transition: all 0.2s ease; | |
} | |
.file-preview:hover { | |
transform: translateY(-3px); | |
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); | |
} | |
.progress-bar { | |
height: 6px; | |
border-radius: 3px; | |
overflow: hidden; | |
} | |
.progress-fill { | |
height: 100%; | |
transition: width 0.3s ease; | |
} | |
.file-icon { | |
width: 50px; | |
height: 50px; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
border-radius: 8px; | |
} | |
.dark .dark\:bg-dark { | |
background-color: #0f172a; | |
} | |
.dark .dark\:bg-darker { | |
background-color: #1e293b; | |
} | |
.dark .dark\:text-light { | |
color: #f1f5f9; | |
} | |
.dark .dark\:border-dark { | |
border-color: #334155; | |
} | |
.dark .dark\:bg-hover { | |
background-color: #334155; | |
} | |
.dark .dark\:bg-hover:hover { | |
background-color: #475569; | |
} | |
.toggle-checkbox:checked { | |
right: 0; | |
border-color: #68D391; | |
} | |
.toggle-checkbox:checked + .toggle-label { | |
background-color: #68D391; | |
} | |
.fade-in { | |
animation: fadeIn 0.3s ease-in; | |
} | |
@keyframes fadeIn { | |
from { opacity: 0; transform: translateY(10px); } | |
to { opacity: 1; transform: translateY(0); } | |
} | |
</style> | |
</head> | |
<body class="bg-gray-100 dark:bg-dark text-gray-800 dark:text-light min-h-screen"> | |
<div class="flex flex-col min-h-screen"> | |
<!-- Header --> | |
<header class="bg-white dark:bg-darker shadow-md py-4 px-6"> | |
<div class="container mx-auto flex justify-between items-center"> | |
<div class="flex items-center space-x-2"> | |
<div class="bg-primary w-10 h-10 rounded-lg flex items-center justify-center"> | |
<i class="fas fa-cloud-upload-alt text-white text-xl"></i> | |
</div> | |
<h1 class="text-2xl font-bold text-gray-800 dark:text-white">FileShare</h1> | |
</div> | |
<div class="flex items-center space-x-4"> | |
<button id="theme-toggle" class="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"> | |
<i class="fas fa-moon text-gray-600 dark:text-yellow-400"></i> | |
</button> | |
<div class="flex items-center space-x-2"> | |
<div class="w-10 h-10 rounded-full bg-gray-300 flex items-center justify-center"> | |
<i class="fas fa-user text-gray-600"></i> | |
</div> | |
<span class="font-medium">John Doe</span> | |
</div> | |
</div> | |
</div> | |
</header> | |
<!-- Main Content --> | |
<main class="flex-grow container mx-auto py-6 px-4"> | |
<!-- Navigation Tabs --> | |
<div class="mb-8"> | |
<div class="border-b border-gray-200 dark:border-gray-700"> | |
<nav class="flex space-x-8"> | |
<button data-tab="upload" class="tab-button py-4 px-1 border-b-2 border-primary text-primary font-medium text-sm"> | |
<i class="fas fa-upload mr-2"></i> Subir Archivos | |
</button> | |
<button data-tab="files" class="tab-button py-4 px-1 border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300 dark:hover:border-gray-500 font-medium text-sm"> | |
<i class="fas fa-folder mr-2"></i> Mis Archivos | |
</button> | |
<button data-tab="settings" class="tab-button py-4 px-1 border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300 dark:hover:border-gray-500 font-medium text-sm"> | |
<i class="fas fa-cog mr-2"></i> Configuración | |
</button> | |
</nav> | |
</div> | |
</div> | |
<!-- Upload Tab --> | |
<div id="upload-tab" class="tab-content active"> | |
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> | |
<!-- Upload Area --> | |
<div class="lg:col-span-2"> | |
<div class="bg-white dark:bg-darker rounded-xl shadow-md p-6"> | |
<h2 class="text-xl font-bold mb-4">Subir Archivos</h2> | |
<!-- Drag & Drop Area --> | |
<div id="drag-area" class="drag-area rounded-xl p-10 text-center cursor-pointer mb-6"> | |
<div class="flex flex-col items-center justify-center"> | |
<div class="bg-blue-100 dark:bg-blue-900/30 w-16 h-16 rounded-full flex items-center justify-center mb-4"> | |
<i class="fas fa-cloud-upload-alt text-primary text-2xl"></i> | |
</div> | |
<p class="text-lg font-medium mb-2">Arrastra y suelta tus archivos aquí</p> | |
<p class="text-gray-500 dark:text-gray-400 mb-4">o</p> | |
<button id="browse-btn" class="bg-primary hover:bg-blue-600 text-white font-medium py-2 px-6 rounded-lg transition duration-300"> | |
<i class="fas fa-folder-open mr-2"></i> Seleccionar archivos | |
</button> | |
<p class="text-gray-500 dark:text-gray-400 text-sm mt-4">Soporta cualquier tipo de archivo hasta 10GB</p> | |
</div> | |
<input type="file" id="file-input" multiple class="hidden"> | |
</div> | |
<!-- Upload Progress --> | |
<div id="upload-progress-container" class="hidden"> | |
<h3 class="font-medium mb-3">Subiendo archivos...</h3> | |
<div id="progress-list" class="space-y-3"></div> | |
</div> | |
<!-- Share Links --> | |
<div id="share-links-container" class="hidden mt-6"> | |
<h3 class="font-medium mb-3">Archivos subidos</h3> | |
<div id="share-links" class="space-y-3"></div> | |
</div> | |
</div> | |
</div> | |
<!-- Upload Settings --> | |
<div> | |
<div class="bg-white dark:bg-darker rounded-xl shadow-md p-6 mb-6"> | |
<h2 class="text-xl font-bold mb-4">Configuración Rápida</h2> | |
<div class="space-y-4"> | |
<div> | |
<label class="block text-sm font-medium mb-1">Fecha de expiración</label> | |
<select class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
<option>1 día</option> | |
<option selected>1 semana</option> | |
<option>1 mes</option> | |
<option>Nunca</option> | |
</select> | |
</div> | |
<div> | |
<label class="block text-sm font-medium mb-1">Protección con contraseña</label> | |
<input type="password" placeholder="Contraseña (opcional)" class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium mb-1">Límite de descargas</label> | |
<input type="number" value="100" class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
</div> | |
</div> | |
<!-- Recent Uploads --> | |
<div class="bg-white dark:bg-darker rounded-xl shadow-md p-6"> | |
<h2 class="text-xl font-bold mb-4">Subidas Recientes</h2> | |
<div class="space-y-3"> | |
<div class="flex items-center p-3 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-lg"> | |
<div class="bg-blue-100 dark:bg-blue-900/30 w-10 h-10 rounded-lg flex items-center justify-center mr-3"> | |
<i class="fas fa-file-pdf text-red-500"></i> | |
</div> | |
<div class="flex-grow"> | |
<p class="font-medium truncate">reporte_q3_2023.pdf</p> | |
<p class="text-xs text-gray-500 dark:text-gray-400">Hace 2 horas</p> | |
</div> | |
<button class="text-gray-500 hover:text-primary"> | |
<i class="fas fa-copy"></i> | |
</button> | |
</div> | |
<div class="flex items-center p-3 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-lg"> | |
<div class="bg-green-100 dark:bg-green-900/30 w-10 h-10 rounded-lg flex items-center justify-center mr-3"> | |
<i class="fas fa-file-image text-green-500"></i> | |
</div> | |
<div class="flex-grow"> | |
<p class="font-medium truncate">vacaciones.jpg</p> | |
<p class="text-xs text-gray-500 dark:text-gray-400">Hace 1 día</p> | |
</div> | |
<button class="text-gray-500 hover:text-primary"> | |
<i class="fas fa-copy"></i> | |
</button> | |
</div> | |
<div class="flex items-center p-3 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-lg"> | |
<div class="bg-purple-100 dark:bg-purple-900/30 w-10 h-10 rounded-lg flex items-center justify-center mr-3"> | |
<i class="fas fa-file-archive text-purple-500"></i> | |
</div> | |
<div class="flex-grow"> | |
<p class="font-medium truncate">proyecto_final.zip</p> | |
<p class="text-xs text-gray-500 dark:text-gray-400">Hace 3 días</p> | |
</div> | |
<button class="text-gray-500 hover:text-primary"> | |
<i class="fas fa-copy"></i> | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- My Files Tab --> | |
<div id="files-tab" class="tab-content"> | |
<div class="bg-white dark:bg-darker rounded-xl shadow-md p-6"> | |
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-6"> | |
<h2 class="text-xl font-bold mb-4 md:mb-0">Mis Archivos</h2> | |
<div class="flex flex-wrap gap-3"> | |
<div class="relative"> | |
<input type="text" placeholder="Buscar archivos..." class="bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg pl-10 pr-4 py-2 focus:outline-none focus:ring-2 focus:ring-primary w-full md:w-64"> | |
<i class="fas fa-search absolute left-3 top-3 text-gray-400"></i> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 p-2 rounded-lg"> | |
<i class="fas fa-th-large"></i> | |
</button> | |
<button class="bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 p-2 rounded-lg"> | |
<i class="fas fa-list"></i> | |
</button> | |
</div> | |
<select class="bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
<option>Ordenar por fecha</option> | |
<option>Ordenar por nombre</option> | |
<option>Ordenar por tamaño</option> | |
<option>Ordenar por descargas</option> | |
</select> | |
</div> | |
</div> | |
<!-- File Grid --> | |
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"> | |
<!-- File Item 1 --> | |
<div class="file-preview bg-gray-50 dark:bg-gray-800 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow"> | |
<div class="p-4"> | |
<div class="flex justify-between items-start mb-3"> | |
<div class="bg-blue-100 dark:bg-blue-900/30 w-12 h-12 rounded-lg flex items-center justify-center"> | |
<i class="fas fa-file-pdf text-red-500 text-xl"></i> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="text-gray-500 hover:text-primary"> | |
<i class="fas fa-download"></i> | |
</button> | |
<button class="text-gray-500 hover:text-red-500"> | |
<i class="fas fa-trash"></i> | |
</button> | |
</div> | |
</div> | |
<h3 class="font-medium truncate">reporte_q3_2023.pdf</h3> | |
<p class="text-sm text-gray-500 dark:text-gray-400">PDF • 2.4 MB</p> | |
</div> | |
<div class="px-4 pb-4"> | |
<div class="flex justify-between text-xs text-gray-500 dark:text-gray-400 mb-2"> | |
<span>Descargas: 12</span> | |
<span>Activo</span> | |
</div> | |
<div class="flex justify-between"> | |
<button class="text-xs text-primary hover:underline">Compartir</button> | |
<button class="text-xs text-gray-500 dark:text-gray-400">Hace 2 días</button> | |
</div> | |
</div> | |
</div> | |
<!-- File Item 2 --> | |
<div class="file-preview bg-gray-50 dark:bg-gray-800 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow"> | |
<div class="p-4"> | |
<div class="flex justify-between items-start mb-3"> | |
<div class="bg-green-100 dark:bg-green-900/30 w-12 h-12 rounded-lg flex items-center justify-center"> | |
<i class="fas fa-file-image text-green-500 text-xl"></i> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="text-gray-500 hover:text-primary"> | |
<i class="fas fa-download"></i> | |
</button> | |
<button class="text-gray-500 hover:text-red-500"> | |
<i class="fas fa-trash"></i> | |
</button> | |
</div> | |
</div> | |
<h3 class="font-medium truncate">vacaciones.jpg</h3> | |
<p class="text-sm text-gray-500 dark:text-gray-400">JPEG • 4.1 MB</p> | |
</div> | |
<div class="px-4 pb-4"> | |
<div class="flex justify-between text-xs text-gray-500 dark:text-gray-400 mb-2"> | |
<span>Descargas: 8</span> | |
<span>Activo</span> | |
</div> | |
<div class="flex justify-between"> | |
<button class="text-xs text-primary hover:underline">Compartir</button> | |
<button class="text-xs text-gray-500 dark:text-gray-400">Hace 1 semana</button> | |
</div> | |
</div> | |
</div> | |
<!-- File Item 3 --> | |
<div class="file-preview bg-gray-50 dark:bg-gray-800 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow"> | |
<div class="p-4"> | |
<div class="flex justify-between items-start mb-3"> | |
<div class="bg-purple-100 dark:bg-purple-900/30 w-12 h-12 rounded-lg flex items-center justify-center"> | |
<i class="fas fa-file-archive text-purple-500 text-xl"></i> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="text-gray-500 hover:text-primary"> | |
<i class="fas fa-download"></i> | |
</button> | |
<button class="text-gray-500 hover:text-red-500"> | |
<i class="fas fa-trash"></i> | |
</button> | |
</div> | |
</div> | |
<h3 class="font-medium truncate">proyecto_final.zip</h3> | |
<p class="text-sm text-gray-500 dark:text-gray-400">ZIP • 15.7 MB</p> | |
</div> | |
<div class="px-4 pb-4"> | |
<div class="flex justify-between text-xs text-gray-500 dark:text-gray-400 mb-2"> | |
<span>Descargas: 24</span> | |
<span>Expirado</span> | |
</div> | |
<div class="flex justify-between"> | |
<button class="text-xs text-primary hover:underline">Compartir</button> | |
<button class="text-xs text-gray-500 dark:text-gray-400">Hace 3 semanas</button> | |
</div> | |
</div> | |
</div> | |
<!-- File Item 4 --> | |
<div class="file-preview bg-gray-50 dark:bg-gray-800 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow"> | |
<div class="p-4"> | |
<div class="flex justify-between items-start mb-3"> | |
<div class="bg-yellow-100 dark:bg-yellow-900/30 w-12 h-12 rounded-lg flex items-center justify-center"> | |
<i class="fas fa-file-word text-blue-500 text-xl"></i> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="text-gray-500 hover:text-primary"> | |
<i class="fas fa-download"></i> | |
</button> | |
<button class="text-gray-500 hover:text-red-500"> | |
<i class="fas fa-trash"></i> | |
</button> | |
</div> | |
</div> | |
<h3 class="font-medium truncate">contrato_cliente.docx</h3> | |
<p class="text-sm text-gray-500 dark:text-gray-400">DOCX • 1.2 MB</p> | |
</div> | |
<div class="px-4 pb-4"> | |
<div class="flex justify-between text-xs text-gray-500 dark:text-gray-400 mb-2"> | |
<span>Descargas: 5</span> | |
<span>Activo</span> | |
</div> | |
<div class="flex justify-between"> | |
<button class="text-xs text-primary hover:underline">Compartir</button> | |
<button class="text-xs text-gray-500 dark:text-gray-400">Hace 1 mes</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Pagination --> | |
<div class="flex justify-center mt-8"> | |
<nav class="flex items-center space-x-2"> | |
<button class="px-3 py-1 rounded-lg bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700"> | |
<i class="fas fa-chevron-left"></i> | |
</button> | |
<button class="px-3 py-1 rounded-lg bg-primary text-white">1</button> | |
<button class="px-3 py-1 rounded-lg bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700">2</button> | |
<button class="px-3 py-1 rounded-lg bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700">3</button> | |
<button class="px-3 py-1 rounded-lg bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700"> | |
<i class="fas fa-chevron-right"></i> | |
</button> | |
</nav> | |
</div> | |
</div> | |
</div> | |
<!-- Settings Tab --> | |
<div id="settings-tab" class="tab-content"> | |
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> | |
<div class="lg:col-span-2"> | |
<div class="bg-white dark:bg-darker rounded-xl shadow-md p-6 mb-6"> | |
<h2 class="text-xl font-bold mb-6">Configuración del Sistema</h2> | |
<div class="space-y-8"> | |
<!-- Authentication --> | |
<div> | |
<h3 class="text-lg font-semibold mb-4">Autenticación</h3> | |
<div class="space-y-4"> | |
<div> | |
<label class="block text-sm font-medium mb-1">Configuración SAML 2.0</label> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<input type="text" placeholder="Entity ID" class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
<div> | |
<input type="text" placeholder="SSO URL" class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
</div> | |
<textarea placeholder="Certificado" class="mt-3 w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary h-24"></textarea> | |
</div> | |
<div> | |
<label class="block text-sm font-medium mb-1">Configuración OpenID Connect</label> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<input type="text" placeholder="Client ID" class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
<div> | |
<input type="password" placeholder="Secret" class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
</div> | |
<input type="text" placeholder="Discovery URL" class="mt-3 w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
</div> | |
</div> | |
<!-- Appearance --> | |
<div> | |
<h3 class="text-lg font-semibold mb-4">Apariencia</h3> | |
<div class="space-y-4"> | |
<div class="flex items-center justify-between"> | |
<span>Modo oscuro</span> | |
<div class="relative inline-block w-12 align-middle select-none"> | |
<input type="checkbox" name="dark-mode" id="dark-mode-toggle" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"> | |
<label for="dark-mode-toggle" class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium mb-1">Color del tema</label> | |
<div class="flex space-x-3"> | |
<div class="w-8 h-8 rounded-full bg-blue-500 cursor-pointer border-2 border-white"></div> | |
<div class="w-8 h-8 rounded-full bg-green-500 cursor-pointer border-2 border-white"></div> | |
<div class="w-8 h-8 rounded-full bg-purple-500 cursor-pointer border-2 border-white"></div> | |
<div class="w-8 h-8 rounded-full bg-red-500 cursor-pointer border-2 border-white"></div> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium mb-1">Idioma</label> | |
<select class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
<option>Español</option> | |
<option>English</option> | |
<option>Français</option> | |
</select> | |
</div> | |
</div> | |
</div> | |
<!-- Files --> | |
<div> | |
<h3 class="text-lg font-semibold mb-4">Archivos</h3> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium mb-1">Tamaño máximo por archivo</label> | |
<input type="text" value="10 GB" class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium mb-1">Almacenamiento total por usuario</label> | |
<input type="text" value="100 GB" class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
</div> | |
<div class="mt-4"> | |
<label class="block text-sm font-medium mb-1">Tipos de archivo permitidos</label> | |
<input type="text" value="*.jpg, *.png, *.pdf, *.docx, *.zip" class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div> | |
<!-- Security --> | |
<div class="bg-white dark:bg-darker rounded-xl shadow-md p-6 mb-6"> | |
<h3 class="text-lg font-semibold mb-4">Seguridad</h3> | |
<div class="space-y-4"> | |
<div> | |
<label class="block text-sm font-medium mb-1">Rate limiting (peticiones por hora)</label> | |
<input type="number" value="1000" class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium mb-1">Políticas de contraseñas</label> | |
<select class="w-full bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"> | |
<option>Baja (mínimo 6 caracteres)</option> | |
<option selected>Media (8 caracteres, mayúsculas y números)</option> | |
<option>Alta (12 caracteres, símbolos)</option> | |
</select> | |
</div> | |
<div class="flex items-center justify-between"> | |
<span>Encriptación de archivos</span> | |
<div class="relative inline-block w-12 align-middle select-none"> | |
<input type="checkbox" name="encryption" id="encryption-toggle" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer" checked> | |
<label for="encryption-toggle" class="toggle-label block overflow-hidden h-6 rounded-full bg-primary cursor-pointer"></label> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- System Info --> | |
<div class="bg-white dark:bg-darker rounded-xl shadow-md p-6"> | |
<h3 class="text-lg font-semibold mb-4">Información del Sistema</h3> | |
<div class="space-y-3"> | |
<div class="flex justify-between"> | |
<span class="text-gray-600 dark:text-gray-400">Versión</span> | |
<span>v2.1.4</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-gray-600 dark:text-gray-400">Almacenamiento usado</span> | |
<span>42.5 GB / 100 GB</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-gray-600 dark:text-gray-400">Archivos totales</span> | |
<span>1,248</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-gray-600 dark:text-gray-400">Usuarios activos</span> | |
<span>32</span> | |
</div> | |
</div> | |
<div class="mt-6 pt-4 border-t border-gray-200 dark:border-gray-700"> | |
<button class="w-full bg-primary hover:bg-blue-600 text-white font-medium py-2 px-4 rounded-lg transition duration-300"> | |
<i class="fas fa-download mr-2"></i> Descargar logs | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</main> | |
<!-- Footer --> | |
<footer class="bg-white dark:bg-darker border-t border-gray-200 dark:border-gray-800 py-6 px-4"> | |
<div class="container mx-auto text-center text-gray-600 dark:text-gray-400 text-sm"> | |
<p>© 2023 FileShare. Todos los derechos reservados.</p> | |
</div> | |
</footer> | |
</div> | |
<script> | |
// Tab Navigation | |
document.querySelectorAll('.tab-button').forEach(button => { | |
button.addEventListener('click', () => { | |
// Remove active class from all buttons and content | |
document.querySelectorAll('.tab-button').forEach(btn => { | |
btn.classList.remove('text-primary', 'border-primary'); | |
btn.classList.add('text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300', 'dark:text-gray-400', 'dark:hover:text-gray-300', 'dark:hover:border-gray-500'); | |
}); | |
document.querySelectorAll('.tab-content').forEach(content => { | |
content.classList.remove('active'); | |
}); | |
// Add active class to clicked button | |
button.classList.remove('text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300', 'dark:text-gray-400', 'dark:hover:text-gray-300', 'dark:hover:border-gray-500'); | |
button.classList.add('text-primary', 'border-primary'); | |
// Show corresponding content | |
const tabId = button.getAttribute('data-tab'); | |
document.getElementById(`${tabId}-tab`).classList.add('active'); | |
}); | |
}); | |
// Drag and Drop Functionality | |
const dragArea = document.getElementById('drag-area'); | |
const fileInput = document.getElementById('file-input'); | |
const browseBtn = document.getElementById('browse-btn'); | |
const uploadProgressContainer = document.getElementById('upload-progress-container'); | |
const progressList = document.getElementById('progress-list'); | |
const shareLinksContainer = document.getElementById('share-links-container'); | |
const shareLinks = document.getElementById('share-links'); | |
// Browse button click | |
browseBtn.addEventListener('click', () => { | |
fileInput.click(); | |
}); | |
// File input change | |
fileInput.addEventListener('change', handleFiles); | |
// Drag and drop events | |
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { | |
dragArea.addEventListener(eventName, preventDefaults, false); | |
}); | |
function preventDefaults(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
} | |
['dragenter', 'dragover'].forEach(eventName => { | |
dragArea.addEventListener(eventName, highlight, false); | |
}); | |
['dragleave', 'drop'].forEach(eventName => { | |
dragArea.addEventListener(eventName, unhighlight, false); | |
}); | |
function highlight() { | |
dragArea.classList.add('active'); | |
} | |
function unhighlight() { | |
dragArea.classList.remove('active'); | |
} | |
// Handle dropped files | |
dragArea.addEventListener('drop', handleDrop, false); | |
function handleDrop(e) { | |
const dt = e.dataTransfer; | |
const files = dt.files; | |
handleFiles({ target: { files } }); | |
} | |
// Handle files | |
function handleFiles(e) { | |
const files = e.target.files; | |
if (files.length === 0) return; | |
// Show upload progress | |
uploadProgressContainer.classList.remove('hidden'); | |
progressList.innerHTML = ''; | |
// Create progress items for each file | |
Array.from(files).forEach((file, index) => { | |
const progressItem = document.createElement('div'); | |
progressItem.className = 'flex items-center p-3 bg-gray-50 dark:bg-gray-800 rounded-lg'; | |
progressItem.innerHTML = ` | |
<div class="mr-3"> | |
<div class="bg-blue-100 dark:bg-blue-900/30 w-10 h-10 rounded-lg flex items-center justify-center"> | |
<i class="fas fa-file text-blue-500"></i> | |
</div> | |
</div> | |
<div class="flex-grow"> | |
<p class="font-medium truncate">${file.name}</p> | |
<div class="progress-bar bg-gray-200 dark:bg-gray-700 rounded-full mt-1"> | |
<div class="progress-fill bg-primary rounded-full" style="width: 0%"></div> | |
</div> | |
</div> | |
<div class="text-sm text-gray-500 dark:text-gray-400">${formatFileSize(file.size)}</div> | |
`; | |
progressList.appendChild(progressItem); | |
// Simulate upload progress | |
simulateUpload(index, file); | |
}); | |
} | |
// Simulate upload progress | |
function simulateUpload(index, file) { | |
const progressFill = progressList.children[index].querySelector('.progress-fill'); | |
let width = 0; | |
const interval = setInterval(() => { | |
width += Math.random() * 10; | |
if (width >= 100) { | |
width = 100; | |
clearInterval(interval); | |
// After upload completes, show share link | |
setTimeout(() => { | |
showShareLink(file); | |
}, 500); | |
} | |
progressFill.style.width = width + '%'; | |
}, 200); | |
} | |
// Show share link after upload | |
function showShareLink(file) { | |
shareLinksContainer.classList.remove('hidden'); | |
const shareItem = document.createElement('div'); | |
shareItem.className = 'flex items-center p-3 bg-gray-50 dark:bg-gray-800 rounded-lg fade-in'; | |
shareItem.innerHTML = ` | |
<div class="mr-3"> | |
<div class="bg-green-100 dark:bg-green-900/30 w-10 h-10 rounded-lg flex items-center justify-center"> | |
<i class="fas fa-check text-green-500"></i> | |
</div> | |
</div> | |
<div class="flex-grow"> | |
<p class="font-medium truncate">${file.name}</p> | |
<p class="text-sm text-gray-500 dark:text-gray-400">Archivo subido correctamente</p> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="copy-link-btn bg-primary hover:bg-blue-600 text-white px-3 py-1 rounded text-sm"> | |
Copiar enlace | |
</button> | |
</div> | |
`; | |
shareLinks.appendChild(shareItem); | |
// Add copy functionality | |
const copyBtn = shareItem.querySelector('.copy-link-btn'); | |
copyBtn.addEventListener('click', () => { | |
// Simulate copying to clipboard | |
navigator.clipboard.writeText(`https://fileshare.com/${generateRandomString(8)}/${file.name}`); | |
// Show confirmation | |
const originalText = copyBtn.textContent; | |
copyBtn.textContent = '¡Copiado!'; | |
copyBtn.classList.add('bg-green-500', 'hover:bg-green-600'); | |
setTimeout(() => { | |
copyBtn.textContent = originalText; | |
copyBtn.classList.remove('bg-green-500', 'hover:bg-green-600'); | |
}, 2000); | |
}); | |
} | |
// Format file size | |
function formatFileSize(bytes) { | |
if (bytes === 0) return '0 Bytes'; | |
const k = 1024; | |
const sizes = ['Bytes', 'KB', 'MB', 'GB']; | |
const i = Math.floor(Math.log(bytes) / Math.log(k)); | |
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; | |
} | |
// Generate random string for link | |
function generateRandomString(length) { | |
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; | |
let result = ''; | |
for (let i = 0; i < length; i++) { | |
result += characters.charAt(Math.floor(Math.random() * characters.length)); | |
} | |
return result; | |
} | |
// Theme Toggle | |
const themeToggle = document.getElementById('theme-toggle'); | |
const darkModeToggle = document.getElementById('dark-mode-toggle'); | |
themeToggle.addEventListener('click', () => { | |
document.documentElement.classList.toggle('dark'); | |
const icon = themeToggle.querySelector('i'); | |
if (document.documentElement.classList.contains('dark')) { | |
icon.classList.remove('fa-moon'); | |
icon.classList.add('fa-sun'); | |
} else { | |
icon.classList.remove('fa-sun'); | |
icon.classList.add('fa-moon'); | |
} | |
}); | |
darkModeToggle.addEventListener('change', () => { | |
document.documentElement.classList.toggle('dark'); | |
const icon = themeToggle.querySelector('i'); | |
if (document.documentElement.classList.contains('dark')) { | |
icon.classList.remove('fa-moon'); | |
icon.classList.add('fa-sun'); | |
} else { | |
icon.classList.remove('fa-sun'); | |
icon.classList.add('fa-moon'); | |
} | |
}); | |
// Initialize with dark mode if system preference is dark | |
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { | |
document.documentElement.classList.add('dark'); | |
darkModeToggle.checked = true; | |
const icon = themeToggle.querySelector('i'); | |
icon.classList.remove('fa-moon'); | |
icon.classList.add('fa-sun'); | |
} | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=IITheLordII/rser9asdkadkasdk" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |