1 <!DOCTYPE html>2 <html lang="es">3 <head>4 <meta charset="UTF-8">5 <meta name="viewport" content="width=device-width, initial-scale=1.0">6 <title>SecureStore Pro - Gestión de Usuarios y Archivos</title>7 <style>8 /* Reset y estilos básicos */9 * {10 box-sizing: border-box;11 margin: 0;12 padding: 0;13 font-family: Arial, sans-serif;14 }15 16 body {17 display: flex;18 height: 100vh;19 background-color: #f4f6f8;20 }21 22 /* Sidebar */23 .sidebar {24 width: 250px;25 background-color: #2c3e50;26 color: #ecf0f1;27 padding: 20px;28 }29 30 .sidebar h2 {31 margin-bottom: 20px;32 font-size: 1.5em;33 text-align: center;34 }35 36 .sidebar ul {37 list-style: none;38 }39 40 .sidebar ul li {41 padding: 10px;42 cursor: pointer;43 border-radius: 4px;44 transition: background-color 0.3s;45 text-align: center;46 }47 48 .sidebar ul li:hover, .sidebar ul li.active {49 background-color: #34495e;50 }51 52 /* Main Content */53 .main-content {54 flex: 1;55 padding: 20px;56 overflow-y: auto;57 }58 59 .main-content h2 {60 margin-bottom: 20px;61 color: #2c3e50;62 }63 64 /* User Selector */65 .user-selector {66 margin-bottom: 20px;67 display: flex;68 justify-content: flex-end;69 align-items: center;70 }71 72 .user-selector label {73 margin-right: 10px;74 font-weight: bold;75 }76 77 .user-selector select {78 padding: 8px 12px;79 border: 1px solid #bdc3c7;80 border-radius: 4px;81 }82 83 /* Tabs */84 .tabs {85 margin-bottom: 20px;86 display: flex;87 gap: 10px;88 }89 90 .tabs button {91 padding: 10px 15px;92 background-color: #2980b9;93 border: none;94 color: #fff;95 cursor: pointer;96 border-radius: 4px;97 transition: background-color 0.3s;98 }99 100 .tabs button:hover, .tabs button.active {101 background-color: #3498db;102 }103 104 /* Section Content */105 .section {106 display: none;107 }108 109 .section.active {110 display: block;111 }112 113 /* Users Table */114 table {115 width: 100%;116 border-collapse: collapse;117 background-color: #fff;118 border-radius: 8px;119 overflow: hidden;120 box-shadow: 0px 2px 4px rgba(0,0,0,0.1);121 }122 123 th, td {124 padding: 12px 15px;125 text-align: left;126 }127 128 th {129 background-color: #2c3e50;130 color: #ecf0f1;131 }132 133 tr:nth-child(even) {134 background-color: #f9f9f9;135 }136 137 tr:hover {138 background-color: #f1f1f1;139 }140 141 /* Action Buttons */142 .action-buttons button {143 background: none;144 border: none;145 cursor: pointer;146 margin-right: 5px;147 font-size: 1.2em;148 }149 150 .action-buttons button.edit {151 color: #27ae60;152 }153 154 .action-buttons button.delete {155 color: #e74c3c;156 }157 158 /* Add User Button */159 .add-user-btn {160 padding: 10px 15px;161 background-color: #27ae60;162 border: none;163 color: #fff;164 cursor: pointer;165 border-radius: 4px;166 transition: background-color 0.3s;167 margin-bottom: 10px;168 }169 170 .add-user-btn:hover {171 background-color: #2ecc71;172 }173 174 /* Files Section */175 .files-actions {176 margin-bottom: 20px;177 display: flex;178 gap: 10px;179 flex-wrap: wrap;180 }181 182 .files-actions button {183 padding: 10px 15px;184 background-color: #2980b9;185 border: none;186 color: #fff;187 cursor: pointer;188 border-radius: 4px;189 transition: background-color 0.3s;190 }191 192 .files-actions button:hover {193 background-color: #3498db;194 }195 196 .files-grid {197 display: grid;198 grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));199 gap: 20px;200 }201 202 .file-item {203 background-color: #fff;204 padding: 15px;205 border-radius: 8px;206 box-shadow: 0px 2px 4px rgba(0,0,0,0.1);207 text-align: center;208 position: relative;209 }210 211 .file-item img {212 width: 50px;213 height: 50px;214 margin-bottom: 10px;215 }216 217 .file-item .file-name {218 word-wrap: break-word;219 font-size: 1em;220 color: #34495e;221 }222 223 .file-item .actions {224 position: absolute;225 top: 10px;226 right: 10px;227 display: flex;228 gap: 5px;229 }230 231 .file-item .actions button {232 background-color: transparent;233 border: none;234 cursor: pointer;235 color: #7f8c8d;236 transition: color 0.3s;237 }238 239 .file-item .actions button:hover {240 color: #2c3e50;241 }242 243 /* Modal */244 .modal {245 display: none; 246 position: fixed; 247 z-index: 10; 248 left: 0;249 top: 0;250 width: 100%; 251 height: 100%; 252 overflow: auto; 253 background-color: rgba(0,0,0,0.4); 254 }255 256 .modal-content {257 background-color: #fefefe;258 margin: 5% auto; 259 padding: 20px;260 border: 1px solid #888;261 width: 400px; 262 border-radius: 8px;263 }264 265 .modal-content h3 {266 margin-bottom: 15px;267 color: #2c3e50;268 }269 270 .modal-content input, .modal-content select {271 width: 100%;272 padding: 10px;273 margin-bottom: 15px;274 border: 1px solid #bdc3c7;275 border-radius: 4px;276 }277 278 .modal-content .modal-actions {279 text-align: right;280 }281 282 .modal-content .modal-actions button {283 padding: 8px 12px;284 margin-left: 10px;285 border: none;286 border-radius: 4px;287 cursor: pointer;288 }289 290 .modal-content .modal-actions .cancel-btn {291 background-color: #e74c3c;292 color: #fff;293 }294 295 .modal-content .modal-actions .save-btn {296 background-color: #27ae60;297 color: #fff;298 }299 300 /* Responsive */301 @media (max-width: 768px) {302 body {303 flex-direction: column;304 }305 306 .sidebar {307 width: 100%;308 }309 310 .main-content {311 padding: 10px;312 }313 314 .modal-content {315 width: 90%;316 }317 }318 </style>319 </head>320 <body>321 322 <!-- Sidebar -->323 <div class="sidebar">324 <h2>SecureStore Pro</h2>325 <ul id="sidebar-menu">326 <li class="active" data-section="dashboard">Dashboard</li>327 <li data-section="archivos">Archivos</li>328 <li data-section="usuarios">Usuarios</li>329 <li data-section="configuracion">Configuración</li>330 <li data-section="soporte">Soporte</li>331 </ul>332 </div>333 334 <!-- Main Content -->335 <div class="main-content" id="main-content">336 <!-- User Selector -->337 <div class="user-selector">338 <label for="current-user">Usuario Actual:</label>339 <select id="current-user">340 <!-- Opciones de usuarios se agregarán dinámicamente -->341 </select>342 </div>343 344 <!-- Tabs -->345 <div class="tabs">346 <button class="active" data-tab="dashboard">Dashboard</button>347 <button data-tab="archivos">Archivos</button>348 <button data-tab="usuarios">Usuarios</button>349 </div>350 351 <!-- Dashboard Section -->352 <div class="section active" id="dashboard">353 <h2>Dashboard</h2>354 <p>Bienvenido a SecureStore Pro. Selecciona una sección desde la barra de navegación para comenzar.</p>355 </div>356 357 <!-- Archivos Section -->358 <div class="section" id="archivos">359 <h2>Gestión de Archivos</h2>360 <div class="files-actions">361 <button id="add-file-btn">+ Subir Archivo</button>362 <button id="add-folder-btn">+ Crear Carpeta</button>363 </div>364 <div class="files-grid" id="files-grid">365 <!-- Archivos y Carpetas aparecerán aquí -->366 </div>367 </div>368 369 <!-- Usuarios Section -->370 <div class="section" id="usuarios">371 <h2>Gestión de Usuarios</h2>372 <button class="add-user-btn" id="add-user-btn">+ Agregar Usuario</button>373 <table id="users-table">374 <thead>375 <tr>376 <th>Nombre</th>377 <th>Email</th>378 <th>Rol</th>379 <th>Estado</th>380 <th>Acciones</th>381 </tr>382 </thead>383 <tbody>384 <!-- Filas de usuarios se agregarán dinámicamente -->385 </tbody>386 </table>387 </div>388 </div>389 390 <!-- Add/Edit User Modal -->391 <div id="user-modal" class="modal">392 <div class="modal-content">393 <h3 id="modal-title">Agregar Usuario</h3>394 <input type="text" id="user-name" placeholder="Nombre Completo">395 <input type="email" id="user-email" placeholder="Correo Electrónico">396 <input type="password" id="user-password" placeholder="Contraseña">397 <input type="password" id="user-confirm-password" placeholder="Confirmar Contraseña">398 <select id="user-role">399 <option value="">Seleccionar Rol</option>400 <option value="Administrador">Administrador</option>401 <option value="Usuario">Usuario</option>402 </select>403 <select id="user-status">404 <option value="">Seleccionar Estado</option>405 <option value="Activo">Activo</option>406 <option value="Inactivo">Inactivo</option>407 </select>408 <div class="modal-actions">409 <button class="cancel-btn" id="cancel-user-btn">Cancelar</button>410 <button class="save-btn" id="save-user-btn">Guardar</button>411 </div>412 </div>413 </div>414 415 <!-- Add File Modal -->416 <div id="file-modal" class="modal">417 <div class="modal-content">418 <h3>Subir Archivo</h3>419 <input type="file" id="file-input">420 <div class="modal-actions">421 <button class="cancel-btn" id="cancel-file-btn">Cancelar</button>422 <button class="save-btn" id="save-file-btn">Subir</button>423 </div>424 </div>425 </div>426 427 <!-- Add Folder Modal -->428 <div id="folder-modal" class="modal">429 <div class="modal-content">430 <h3>Crear Carpeta</h3>431 <input type="text" id="folder-name" placeholder="Nombre de la Carpeta">432 <div class="modal-actions">433 <button class="cancel-btn" id="cancel-folder-btn">Cancelar</button>434 <button class="save-btn" id="save-folder-btn">Crear</button>435 </div>436 </div>437 </div>438 439 <script>440 // Inicialización de Datos en localStorage si no existen441 if (!localStorage.getItem('securestore_users')) {442 const initialUsers = [443 { id: 1, name: 'Administrador', email: 'admin@securestore.com', role: 'Administrador', status: 'Activo' },444 { id: 2, name: 'Juan Pérez', email: 'juan.perez@example.com', role: 'Usuario', status: 'Activo' },445 { id: 3, name: 'Pepe Rodríguez', email: 'pepe.rodriguez@example.com', role: 'Usuario', status: 'Activo' }446 ];447 localStorage.setItem('securestore_users', JSON.stringify(initialUsers));448 }449 450 if (!localStorage.getItem('securestore_files')) {451 const initialFiles = [452 { id: 1, name: 'Carpeta1', type: 'folder', permissions: [1, 2] }, // Administrador y Juan453 { id: 2, name: 'Carpeta2', type: 'folder', permissions: [1, 2, 3] }, // Administrador, Juan y Pepe454 { id: 3, name: 'Carpeta3', type: 'folder', permissions: [1, 3] }, // Administrador y Pepe455 { id: 4, name: 'reporte.pdf', type: 'file', permissions: [1, 2] },456 { id: 5, name: 'foto.jpg', type: 'file', permissions: [1, 3] }457 ];458 localStorage.setItem('securestore_files', JSON.stringify(initialFiles));459 }460 461 // Variables Globales462 let users = JSON.parse(localStorage.getItem('securestore_users'));463 let files = JSON.parse(localStorage.getItem('securestore_files'));464 let currentUser = users[0]; // Por defecto, el primer usuario es el actual465 let editingUserId = null;466 467 // Elementos del DOM468 const userSelect = document.getElementById('current-user');469 const usersTableBody = document.querySelector('#users-table tbody');470 const addUserBtn = document.getElementById('add-user-btn');471 const userModal = document.getElementById('user-modal');472 const modalTitle = document.getElementById('modal-title');473 const cancelUserBtn = document.getElementById('cancel-user-btn');474 const saveUserBtn = document.getElementById('save-user-btn');475 const userNameInput = document.getElementById('user-name');476 const userEmailInput = document.getElementById('user-email');477 const userPasswordInput = document.getElementById('user-password');478 const userConfirmPasswordInput = document.getElementById('user-confirm-password');479 const userRoleSelect = document.getElementById('user-role');480 const userStatusSelect = document.getElementById('user-status');481 482 const addFileBtn = document.getElementById('add-file-btn');483 const fileModal = document.getElementById('file-modal');484 const cancelFileBtn = document.getElementById('cancel-file-btn');485 const saveFileBtn = document.getElementById('save-file-btn');486 const fileInput = document.getElementById('file-input');487 488 const addFolderBtn = document.getElementById('add-folder-btn');489 const folderModal = document.getElementById('folder-modal');490 const cancelFolderBtn = document.getElementById('cancel-folder-btn');491 const saveFolderBtn = document.getElementById('save-folder-btn');492 const folderNameInput = document.getElementById('folder-name');493 494 const filesGrid = document.getElementById('files-grid');495 496 const tabs = document.querySelectorAll('.tabs button');497 const sections = document.querySelectorAll('.section');498 499 // Función para actualizar localStorage500 function updateLocalStorage() {501 localStorage.setItem('securestore_users', JSON.stringify(users));502 localStorage.setItem('securestore_files', JSON.stringify(files));503 }504 505 // Función para renderizar el selector de usuarios506 function renderUserSelect() {507 userSelect.innerHTML = '';508 users.forEach(user => {509 const option = document.createElement('option');510 option.value = user.id;511 option.textContent = `${user.name} (${user.email})`;512 if (user.id === currentUser.id) {513 option.selected = true;514 }515 userSelect.appendChild(option);516 });517 }518 519 // Función para renderizar la tabla de usuarios520 function renderUsersTable() {521 usersTableBody.innerHTML = '';522 users.forEach(user => {523 const tr = document.createElement('tr');524 525 const nameTd = document.createElement('td');526 nameTd.textContent = user.name;527 tr.appendChild(nameTd);528 529 const emailTd = document.createElement('td');530 emailTd.textContent = user.email;531 tr.appendChild(emailTd);532 533 const roleTd = document.createElement('td');534 roleTd.textContent = user.role;535 tr.appendChild(roleTd);536 537 const statusTd = document.createElement('td');538 statusTd.textContent = user.status;539 tr.appendChild(statusTd);540 541 const actionsTd = document.createElement('td');542 actionsTd.classList.add('action-buttons');543 544 const editBtn = document.createElement('button');545 editBtn.classList.add('edit');546 editBtn.innerHTML = '✏️';547 editBtn.title = 'Editar Usuario';548 editBtn.onclick = () => openEditUserModal(user.id);549 actionsTd.appendChild(editBtn);550 551 const deleteBtn = document.createElement('button');552 deleteBtn.classList.add('delete');553 deleteBtn.innerHTML = '🗑️';554 deleteBtn.title = 'Eliminar Usuario';555 // No permitir eliminar al Administrador556 if (user.role !== 'Administrador') {557 deleteBtn.onclick = () => deleteUser(user.id);558 } else {559 deleteBtn.disabled = true;560 deleteBtn.style.color = '#bdc3c7';561 deleteBtn.title = 'No se puede eliminar al Administrador';562 }563 actionsTd.appendChild(deleteBtn);564 565 tr.appendChild(actionsTd);566 567 usersTableBody.appendChild(tr);568 });569 }570 571 // Función para renderizar la sección de archivos572 function renderFiles() {573 filesGrid.innerHTML = '';574 files.forEach(file => {575 // Verificar permisos576 if (!file.permissions.includes(currentUser.id)) {577 return; // El usuario no tiene permisos para ver este archivo/carpeta578 }579 580 const fileDiv = document.createElement('div');581 fileDiv.classList.add('file-item');582 583 const icon = document.createElement('img');584 icon.src = file.type === 'folder' ? 'https://img.icons8.com/fluency/48/000000/folder-invoices.png' :585 'https://img.icons8.com/fluency/48/000000/file.png';586 icon.alt = file.type === 'folder' ? 'Carpeta' : 'Archivo';587 fileDiv.appendChild(icon);588 589 const nameDiv = document.createElement('div');590 nameDiv.classList.add('file-name');591 nameDiv.textContent = file.name;592 fileDiv.appendChild(nameDiv);593 594 const actionsDiv = document.createElement('div');595 actionsDiv.classList.add('actions');596 597 if (file.type === 'file') {598 const downloadBtn = document.createElement('button');599 downloadBtn.innerHTML = '⬇️';600 downloadBtn.title = 'Descargar Archivo';601 downloadBtn.onclick = () => downloadFile(file.name);602 actionsDiv.appendChild(downloadBtn);603 }604 605 // Solo Administradores pueden eliminar archivos/carpetas y gestionar permisos606 if (currentUser.role === 'Administrador') {607 const deleteBtn = document.createElement('button');608 deleteBtn.innerHTML = '🗑️';609 deleteBtn.title = 'Eliminar';610 deleteBtn.onclick = () => deleteFile(file.id);611 actionsDiv.appendChild(deleteBtn);612 613 const permissionsBtn = document.createElement('button');614 permissionsBtn.innerHTML = '🔒';615 permissionsBtn.title = 'Gestionar Permisos';616 permissionsBtn.onclick = () => openManagePermissionsModal(file.id);617 actionsDiv.appendChild(permissionsBtn);618 }619 620 fileDiv.appendChild(actionsDiv);621 filesGrid.appendChild(fileDiv);622 });623 }624 625 // Función para agregar o editar usuario626 function saveUser() {627 const name = userNameInput.value.trim();628 const email = userEmailInput.value.trim().toLowerCase();629 const password = userPasswordInput.value;630 const confirmPassword = userConfirmPasswordInput.value;631 const role = userRoleSelect.value;632 const status = userStatusSelect.value;633 634 if (!name || !email || !role || !status) {635 alert('Por favor, completa todos los campos requeridos.');636 return;637 }638 639 if (editingUserId === null && (!password || !confirmPassword)) {640 alert('Por favor, establece una contraseña.');641 return;642 }643 644 if (password !== confirmPassword) {645 alert('Las contraseñas no coinciden.');646 return;647 }648 649 if (editingUserId === null) {650 // Verificar si el email ya existe651 if (users.some(user => user.email === email)) {652 alert('El correo electrónico ya está en uso.');653 return;654 }655 656 // Agregar nuevo usuario657 const newUser = {658 id: Date.now(),659 name,660 email,661 role,662 status663 };664 users.push(newUser);665 } else {666 // Editar usuario existente667 const user = users.find(u => u.id === editingUserId);668 if (user) {669 // Verificar si el email está siendo usado por otro usuario670 if (users.some(u => u.email === email && u.id !== editingUserId)) {671 alert('El correo electrónico ya está en uso por otro usuario.');672 return;673 }674 675 user.name = name;676 user.email = email;677 user.role = role;678 user.status = status;679 // Contraseña no manejada en este ejemplo680 }681 }682 683 updateLocalStorage();684 renderUserSelect();685 renderUsersTable();686 renderFiles();687 closeUserModal();688 }689 690 // Función para abrir el modal de agregar usuario691 function openAddUserModal() {692 editingUserId = null;693 modalTitle.textContent = 'Agregar Usuario';694 userNameInput.value = '';695 userEmailInput.value = '';696 userPasswordInput.value = '';697 userConfirmPasswordInput.value = '';698 userRoleSelect.value = '';699 userStatusSelect.value = '';700 userModal.style.display = 'block';701 }702 703 // Función para abrir el modal de editar usuario704 function openEditUserModal(userId) {705 const user = users.find(u => u.id === userId);706 if (user) {707 editingUserId = userId;708 modalTitle.textContent = 'Editar Usuario';709 userNameInput.value = user.name;710 userEmailInput.value = user.email;711 userPasswordInput.value = '';712 userConfirmPasswordInput.value = '';713 userRoleSelect.value = user.role;714 userStatusSelect.value = user.status;715 userModal.style.display = 'block';716 }717 }718 719 // Función para eliminar usuario720 function deleteUser(userId) {721 const user = users.find(u => u.id === userId);722 if (user.role === 'Administrador') {723 alert('No se puede eliminar al Administrador.');724 return;725 }726 727 if (confirm('¿Estás seguro de que deseas eliminar este usuario?')) {728 // Eliminar permisos de archivos729 files.forEach(file => {730 file.permissions = file.permissions.filter(uid => uid !== userId);731 });732 733 users = users.filter(u => u.id !== userId);734 updateLocalStorage();735 renderUserSelect();736 renderUsersTable();737 renderFiles();738 }739 }740 741 // Función para cerrar el modal de usuario742 function closeUserModal() {743 userModal.style.display = 'none';744 }745 746 // Función para agregar archivo747 function addFile() {748 const file = fileInput.files[0];749 if (file) {750 // Seleccionar usuarios con acceso751 const allowedUsers = prompt('Introduce los IDs de usuarios con acceso al archivo, separados por comas (e.g., 1,2):');752 if (allowedUsers !== null) {753 const userIds = allowedUsers.split(',').map(id => parseInt(id.trim())).filter(id => users.some(u => u.id === id));754 if (userIds.length === 0) {755 alert('No se ha seleccionado ningún usuario válido.');756 return;757 }758 759 const newFile = {760 id: Date.now(),761 name: file.name,762 type: 'file',763 permissions: userIds764 };765 files.push(newFile);766 updateLocalStorage();767 renderFiles();768 fileModal.style.display = 'none';769 fileInput.value = '';770 }771 } else {772 alert('Por favor, selecciona un archivo para subir.');773 }774 }775 776 // Función para crear carpeta777 function addFolder() {778 const folderName = folderNameInput.value.trim();779 if (folderName) {780 // Verificar si la carpeta ya existe781 if (files.some(f => f.name === folderName && f.type === 'folder')) {782 alert('La carpeta ya existe.');783 return;784 }785 786 // Seleccionar usuarios con acceso787 const allowedUsers = prompt('Introduce los IDs de usuarios con acceso a la carpeta, separados por comas (e.g., 1,2):');788 if (allowedUsers !== null) {789 const userIds = allowedUsers.split(',').map(id => parseInt(id.trim())).filter(id => users.some(u => u.id === id));790 if (userIds.length === 0) {791 alert('No se ha seleccionado ningún usuario válido.');792 return;793 }794 795 const newFolder = {796 id: Date.now(),797 name: folderName,798 type: 'folder',799 permissions: userIds800 };801 files.push(newFolder);802 updateLocalStorage();803 renderFiles();804 folderModal.style.display = 'none';805 folderNameInput.value = '';806 }807 } else {808 alert('Por favor, introduce un nombre para la carpeta.');809 }810 }811 812 // Función para eliminar archivo/carpeta813 function deleteFile(fileId) {814 if (confirm('¿Estás seguro de que deseas eliminar este archivo/carpeta?')) {815 files = files.filter(f => f.id !== fileId);816 updateLocalStorage();817 renderFiles();818 }819 }820 821 // Función para descargar archivo (simulación)822 function downloadFile(fileName) {823 alert(`Descargando archivo: ${fileName}`);824 // Aquí podrías implementar la lógica real de descarga si tienes backend825 }826 827 // Función para abrir el modal de gestionar permisos828 function openManagePermissionsModal(fileId) {829 const file = files.find(f => f.id === fileId);830 if (file) {831 const allowedUsers = prompt('Introduce los IDs de usuarios con acceso al archivo/carpeta, separados por comas (e.g., 1,2):', file.permissions.join(','));832 if (allowedUsers !== null) {833 const userIds = allowedUsers.split(',').map(id => parseInt(id.trim())).filter(id => users.some(u => u.id === id));834 if (userIds.length === 0) {835 alert('No se ha seleccionado ningún usuario válido.');836 return;837 }838 file.permissions = userIds;839 updateLocalStorage();840 renderFiles();841 }842 }843 }844 845 // Función para renderizar archivos846 function renderFiles() {847 filesGrid.innerHTML = '';848 files.forEach(file => {849 // Verificar permisos850 if (!file.permissions.includes(currentUser.id)) {851 return; // El usuario no tiene permisos para ver este archivo/carpeta852 }853 854 const fileDiv = document.createElement('div');855 fileDiv.classList.add('file-item');856 857 const icon = document.createElement('img');858 icon.src = file.type === 'folder' ? 'https://img.icons8.com/fluency/48/000000/folder-invoices.png' :859 'https://img.icons8.com/fluency/48/000000/file.png';860 icon.alt = file.type === 'folder' ? 'Carpeta' : 'Archivo';861 fileDiv.appendChild(icon);862 863 const nameDiv = document.createElement('div');864 nameDiv.classList.add('file-name');865 nameDiv.textContent = file.name;866 fileDiv.appendChild(nameDiv);867 868 const actionsDiv = document.createElement('div');869 actionsDiv.classList.add('actions');870 871 if (file.type === 'file') {872 const downloadBtn = document.createElement('button');873 downloadBtn.innerHTML = '⬇️';874 downloadBtn.title = 'Descargar Archivo';875 downloadBtn.onclick = () => downloadFile(file.name);876 actionsDiv.appendChild(downloadBtn);877 }878 879 // Solo Administradores pueden eliminar archivos/carpetas y gestionar permisos880 if (currentUser.role === 'Administrador') {881 const deleteBtn = document.createElement('button');882 deleteBtn.innerHTML = '🗑️';883 deleteBtn.title = 'Eliminar';884 deleteBtn.onclick = () => deleteFile(file.id);885 actionsDiv.appendChild(deleteBtn);886 887 const permissionsBtn = document.createElement('button');888 permissionsBtn.innerHTML = '🔒';889 permissionsBtn.title = 'Gestionar Permisos';890 permissionsBtn.onclick = () => openManagePermissionsModal(file.id);891 actionsDiv.appendChild(permissionsBtn);892 }893 894 fileDiv.appendChild(actionsDiv);895 filesGrid.appendChild(fileDiv);896 });897 }898 899 // Función para renderizar usuarios en el selector900 function renderUserSelect() {901 userSelect.innerHTML = '';902 users.forEach(user => {903 const option = document.createElement('option');904 option.value = user.id;905 option.textContent = `${user.name} (${user.email})`;906 if (user.id === currentUser.id) {907 option.selected = true;908 }909 userSelect.appendChild(option);910 });911 }912 913 // Función para manejar el cambio de usuario914 userSelect.addEventListener('change', function() {915 const selectedId = parseInt(this.value);916 currentUser = users.find(u => u.id === selectedId);917 renderFiles();918 });919 920 // Función para manejar las pestañas921 tabs.forEach(tab => {922 tab.addEventListener('click', function() {923 // Remover clase 'active' de todas las pestañas924 tabs.forEach(t => t.classList.remove('active'));925 // Agregar clase 'active' a la pestaña actual926 this.classList.add('active');927 928 const target = this.getAttribute('data-tab');929 930 // Ocultar todas las secciones931 sections.forEach(section => section.classList.remove('active'));932 // Mostrar la sección correspondiente933 document.getElementById(target).classList.add('active');934 });935 });936 937 // Funciones para modales de usuario938 addUserBtn.addEventListener('click', openAddUserModal);939 cancelUserBtn.addEventListener('click', closeUserModal);940 saveUserBtn.addEventListener('click', saveUser);941 942 // Funciones para modales de archivo943 addFileBtn.addEventListener('click', () => {944 fileModal.style.display = 'block';945 });946 cancelFileBtn.addEventListener('click', () => {947 fileModal.style.display = 'none';948 fileInput.value = '';949 });950 saveFileBtn.addEventListener('click', addFile);951 952 // Funciones para modales de carpeta953 addFolderBtn.addEventListener('click', () => {954 folderModal.style.display = 'block';955 });956 cancelFolderBtn.addEventListener('click', () => {957 folderModal.style.display = 'none';958 folderNameInput.value = '';959 });960 saveFolderBtn.addEventListener('click', addFolder);961 962 // Cerrar modales al hacer clic fuera de ellos963 window.onclick = function(event) {964 if (event.target == userModal) {965 userModal.style.display = 'none';966 }967 if (event.target == fileModal) {968 fileModal.style.display = 'none';969 fileInput.value = '';970 }971 if (event.target == folderModal) {972 folderModal.style.display = 'none';973 folderNameInput.value = '';974 }975 }976 977 // Inicialización978 renderUserSelect();979 renderUsersTable();980 renderFiles();981 982 // Función para renderizar la tabla de usuarios983 function renderUsersTable() {984 usersTableBody.innerHTML = '';985 users.forEach(user => {986 const tr = document.createElement('tr');987 988 const nameTd = document.createElement('td');989 nameTd.textContent = user.name;990 tr.appendChild(nameTd);991 992 const emailTd = document.createElement('td');993 emailTd.textContent = user.email;994 tr.appendChild(emailTd);995 996 const roleTd = document.createElement('td');997 roleTd.textContent = user.role;998 tr.appendChild(roleTd);999 1000 const statusTd = document.createElement('td');1001 statusTd.textContent = user.status;1002 tr.appendChild(statusTd);1003 1004 const actionsTd = document.createElement('td');1005 actionsTd.classList.add('action-buttons');1006 1007 const editBtn = document.createElement('button');1008 editBtn.classList.add('edit');1009 editBtn.innerHTML = '✏️';1010 editBtn.title = 'Editar Usuario';1011 editBtn.onclick = () => openEditUserModal(user.id);1012 actionsTd.appendChild(editBtn);1013 1014 const deleteBtn = document.createElement('button');1015 deleteBtn.classList.add('delete');1016 deleteBtn.innerHTML = '🗑️';1017 deleteBtn.title = 'Eliminar Usuario';1018 // No permitir eliminar al Administrador1019 if (user.role !== 'Administrador') {1020 deleteBtn.onclick = () => deleteUser(user.id);1021 } else {1022 deleteBtn.disabled = true;1023 deleteBtn.style.color = '#bdc3c7';1024 deleteBtn.title = 'No se puede eliminar al Administrador';1025 }1026 actionsTd.appendChild(deleteBtn);1027 1028 tr.appendChild(actionsTd);1029 1030 usersTableBody.appendChild(tr);1031 });1032 }1033 1034 // Función para gestionar permisos de archivos/carpetas1035 function openManagePermissionsModal(fileId) {1036 const file = files.find(f => f.id === fileId);1037 if (file) {1038 const allowedUsers = prompt('Introduce los IDs de usuarios con acceso al archivo/carpeta, separados por comas (e.g., 1,2):', file.permissions.join(','));1039 if (allowedUsers !== null) {1040 const userIds = allowedUsers.split(',').map(id => parseInt(id.trim())).filter(id => users.some(u => u.id === id));1041 if (userIds.length === 0) {1042 alert('No se ha seleccionado ningún usuario válido.');1043 return;1044 }1045 file.permissions = userIds;1046 updateLocalStorage();1047 renderFiles();1048 }1049 }1050 }1051 </script>1052 </body>1053 </html>1054
Enlace
El enlace para compartir es: