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 <label for="file-permissions">Asignar Permisos a Usuarios:</label>421 <select id="file-permissions" multiple>422 <!-- Opciones de usuarios se agregarán dinámicamente -->423 </select>424 <div class="modal-actions">425 <button class="cancel-btn" id="cancel-file-btn">Cancelar</button>426 <button class="save-btn" id="save-file-btn">Subir</button>427 </div>428 </div>429 </div>430 431 <!-- Add Folder Modal -->432 <div id="folder-modal" class="modal">433 <div class="modal-content">434 <h3>Crear Carpeta</h3>435 <input type="text" id="folder-name" placeholder="Nombre de la Carpeta">436 <label for="folder-permissions">Asignar Permisos a Usuarios:</label>437 <select id="folder-permissions" multiple>438 <!-- Opciones de usuarios se agregarán dinámicamente -->439 </select>440 <div class="modal-actions">441 <button class="cancel-btn" id="cancel-folder-btn">Cancelar</button>442 <button class="save-btn" id="save-folder-btn">Crear</button>443 </div>444 </div>445 </div>446 447 <script>448 // Inicialización de Datos en localStorage si no existen449 if (!localStorage.getItem('securestore_users')) {450 const initialUsers = [451 { id: 1, name: 'Administrador', email: 'admin@securestore.com', role: 'Administrador', status: 'Activo' },452 { id: 2, name: 'Juan Pérez', email: 'juan.perez@example.com', role: 'Usuario', status: 'Activo' },453 { id: 3, name: 'Pepe García', email: 'pepe.garcia@example.com', role: 'Usuario', status: 'Activo' }454 ];455 localStorage.setItem('securestore_users', JSON.stringify(initialUsers));456 }457 458 if (!localStorage.getItem('securestore_files')) {459 const initialFiles = [460 { id: 1, name: 'Reporte.pdf', type: 'file', permissions: [1, 2] },461 { id: 2, name: 'Imagen.png', type: 'file', permissions: [1] },462 { id: 3, name: 'Carpeta1', type: 'folder', permissions: [1, 2] },463 { id: 4, name: 'Carpeta2', type: 'folder', permissions: [1, 2, 3] },464 { id: 5, name: 'Carpeta3', type: 'folder', permissions: [1, 3] }465 ];466 localStorage.setItem('securestore_files', JSON.stringify(initialFiles));467 }468 469 // Variables Globales470 let users = JSON.parse(localStorage.getItem('securestore_users'));471 let files = JSON.parse(localStorage.getItem('securestore_files'));472 let currentUser = users[0]; // Por defecto, el primer usuario es el actual473 let editingUserId = null;474 475 // Elementos del DOM476 const userSelect = document.getElementById('current-user');477 const usersTableBody = document.querySelector('#users-table tbody');478 const addUserBtn = document.getElementById('add-user-btn');479 const userModal = document.getElementById('user-modal');480 const modalTitle = document.getElementById('modal-title');481 const cancelUserBtn = document.getElementById('cancel-user-btn');482 const saveUserBtn = document.getElementById('save-user-btn');483 const userNameInput = document.getElementById('user-name');484 const userEmailInput = document.getElementById('user-email');485 const userPasswordInput = document.getElementById('user-password');486 const userConfirmPasswordInput = document.getElementById('user-confirm-password');487 const userRoleSelect = document.getElementById('user-role');488 const userStatusSelect = document.getElementById('user-status');489 490 const addFileBtn = document.getElementById('add-file-btn');491 const fileModal = document.getElementById('file-modal');492 const cancelFileBtn = document.getElementById('cancel-file-btn');493 const saveFileBtn = document.getElementById('save-file-btn');494 const fileInput = document.getElementById('file-input');495 const filePermissionsSelect = document.getElementById('file-permissions');496 497 const addFolderBtn = document.getElementById('add-folder-btn');498 const folderModal = document.getElementById('folder-modal');499 const cancelFolderBtn = document.getElementById('cancel-folder-btn');500 const saveFolderBtn = document.getElementById('save-folder-btn');501 const folderNameInput = document.getElementById('folder-name');502 const folderPermissionsSelect = document.getElementById('folder-permissions');503 504 const filesGrid = document.getElementById('files-grid');505 506 const tabs = document.querySelectorAll('.tabs button');507 const sections = document.querySelectorAll('.section');508 509 // Función para actualizar localStorage510 function updateLocalStorage() {511 localStorage.setItem('securestore_users', JSON.stringify(users));512 localStorage.setItem('securestore_files', JSON.stringify(files));513 }514 515 // Función para renderizar el selector de usuarios516 function renderUserSelect() {517 userSelect.innerHTML = '';518 users.forEach(user => {519 const option = document.createElement('option');520 option.value = user.id;521 option.textContent = `${user.name} (${user.email})`;522 if (user.id === currentUser.id) {523 option.selected = true;524 }525 userSelect.appendChild(option);526 });527 528 // Renderizar opciones en los modales de permisos529 renderPermissionsOptions();530 }531 532 // Función para renderizar opciones de permisos en los modales533 function renderPermissionsOptions() {534 // Limpiar opciones existentes535 filePermissionsSelect.innerHTML = '';536 folderPermissionsSelect.innerHTML = '';537 538 users.forEach(user => {539 const option1 = document.createElement('option');540 option1.value = user.id;541 option1.textContent = `${user.name} (${user.email})`;542 filePermissionsSelect.appendChild(option1);543 544 const option2 = document.createElement('option');545 option2.value = user.id;546 option2.textContent = `${user.name} (${user.email})`;547 folderPermissionsSelect.appendChild(option2);548 });549 }550 551 // Función para renderizar la tabla de usuarios552 function renderUsersTable() {553 usersTableBody.innerHTML = '';554 users.forEach(user => {555 const tr = document.createElement('tr');556 557 const nameTd = document.createElement('td');558 nameTd.textContent = user.name;559 tr.appendChild(nameTd);560 561 const emailTd = document.createElement('td');562 emailTd.textContent = user.email;563 tr.appendChild(emailTd);564 565 const roleTd = document.createElement('td');566 roleTd.textContent = user.role;567 tr.appendChild(roleTd);568 569 const statusTd = document.createElement('td');570 statusTd.textContent = user.status;571 tr.appendChild(statusTd);572 573 const actionsTd = document.createElement('td');574 actionsTd.classList.add('action-buttons');575 576 const editBtn = document.createElement('button');577 editBtn.classList.add('edit');578 editBtn.innerHTML = '✏️';579 editBtn.title = 'Editar Usuario';580 editBtn.onclick = () => openEditUserModal(user.id);581 actionsTd.appendChild(editBtn);582 583 const deleteBtn = document.createElement('button');584 deleteBtn.classList.add('delete');585 deleteBtn.innerHTML = '🗑️';586 deleteBtn.title = 'Eliminar Usuario';587 deleteBtn.onclick = () => deleteUser(user.id);588 actionsTd.appendChild(deleteBtn);589 590 tr.appendChild(actionsTd);591 592 usersTableBody.appendChild(tr);593 });594 }595 596 // Función para renderizar la sección de archivos597 function renderFiles() {598 filesGrid.innerHTML = '';599 files.forEach(file => {600 // Verificar permisos601 if (!file.permissions.includes(currentUser.id)) {602 return; // El usuario no tiene permisos para ver este archivo/carpeta603 }604 605 const fileDiv = document.createElement('div');606 fileDiv.classList.add('file-item');607 608 const icon = document.createElement('img');609 icon.src = file.type === 'folder' ? 'https://img.icons8.com/fluency/48/000000/folder-invoices.png' :610 'https://img.icons8.com/fluency/48/000000/file.png';611 icon.alt = file.type === 'folder' ? 'Carpeta' : 'Archivo';612 fileDiv.appendChild(icon);613 614 const nameDiv = document.createElement('div');615 nameDiv.classList.add('file-name');616 nameDiv.textContent = file.name;617 fileDiv.appendChild(nameDiv);618 619 const actionsDiv = document.createElement('div');620 actionsDiv.classList.add('actions');621 622 if (file.type === 'file') {623 const downloadBtn = document.createElement('button');624 downloadBtn.innerHTML = '⬇️';625 downloadBtn.title = 'Descargar Archivo';626 downloadBtn.onclick = () => downloadFile(file.name);627 actionsDiv.appendChild(downloadBtn);628 }629 630 // Solo Administradores pueden eliminar archivos/carpetas631 if (currentUser.role === 'Administrador') {632 const deleteBtn = document.createElement('button');633 deleteBtn.innerHTML = '🗑️';634 deleteBtn.title = 'Eliminar';635 deleteBtn.onclick = () => deleteFile(file.id);636 actionsDiv.appendChild(deleteBtn);637 }638 639 fileDiv.appendChild(actionsDiv);640 filesGrid.appendChild(fileDiv);641 });642 }643 644 // Función para agregar o editar usuario645 function saveUser() {646 const name = userNameInput.value.trim();647 const email = userEmailInput.value.trim().toLowerCase();648 const password = userPasswordInput.value;649 const confirmPassword = userConfirmPasswordInput.value;650 const role = userRoleSelect.value;651 const status = userStatusSelect.value;652 653 if (!name || !email || !role || !status) {654 alert('Por favor, completa todos los campos requeridos.');655 return;656 }657 658 if (editingUserId === null && (!password || !confirmPassword)) {659 alert('Por favor, establece una contraseña.');660 return;661 }662 663 if (password !== confirmPassword) {664 alert('Las contraseñas no coinciden.');665 return;666 }667 668 if (editingUserId === null) {669 // Verificar si el email ya existe670 if (users.some(user => user.email === email)) {671 alert('El correo electrónico ya está en uso.');672 return;673 }674 675 // Agregar nuevo usuario676 const newUser = {677 id: Date.now(),678 name,679 email,680 role,681 status682 };683 users.push(newUser);684 } else {685 // Editar usuario existente686 const user = users.find(u => u.id === editingUserId);687 if (user) {688 user.name = name;689 user.email = email;690 user.role = role;691 user.status = status;692 // Contraseña no manejada en este ejemplo693 }694 }695 696 updateLocalStorage();697 renderUserSelect();698 renderUsersTable();699 renderFiles();700 closeUserModal();701 }702 703 // Función para abrir el modal de agregar usuario704 function openAddUserModal() {705 editingUserId = null;706 modalTitle.textContent = 'Agregar Usuario';707 userNameInput.value = '';708 userEmailInput.value = '';709 userPasswordInput.value = '';710 userConfirmPasswordInput.value = '';711 userRoleSelect.value = '';712 userStatusSelect.value = '';713 userModal.style.display = 'block';714 }715 716 // Función para abrir el modal de editar usuario717 function openEditUserModal(userId) {718 const user = users.find(u => u.id === userId);719 if (user) {720 editingUserId = userId;721 modalTitle.textContent = 'Editar Usuario';722 userNameInput.value = user.name;723 userEmailInput.value = user.email;724 userPasswordInput.value = '';725 userConfirmPasswordInput.value = '';726 userRoleSelect.value = user.role;727 userStatusSelect.value = user.status;728 userModal.style.display = 'block';729 }730 }731 732 // Función para eliminar usuario (no se permite eliminar al Administrador)733 function deleteUser(userId) {734 const user = users.find(u => u.id === userId);735 if (user.role === 'Administrador') {736 alert('No se puede eliminar al Administrador.');737 return;738 }739 740 if (confirm('¿Estás seguro de que deseas eliminar este usuario?')) {741 users = users.filter(u => u.id !== userId);742 // Además, remover permisos de este usuario en archivos y carpetas743 files.forEach(file => {744 file.permissions = file.permissions.filter(uid => uid !== userId);745 });746 updateLocalStorage();747 renderUserSelect();748 renderUsersTable();749 renderFiles();750 }751 }752 753 // Función para cerrar el modal de usuario754 function closeUserModal() {755 userModal.style.display = 'none';756 }757 758 // Función para agregar archivo759 function addFile() {760 const file = fileInput.files[0];761 if (file) {762 const selectedOptions = Array.from(filePermissionsSelect.selectedOptions);763 const permissions = selectedOptions.map(option => parseInt(option.value));764 765 if (permissions.length === 0) {766 alert('Por favor, asigna al menos un usuario con permisos para este archivo.');767 return;768 }769 770 const newFile = {771 id: Date.now(),772 name: file.name,773 type: 'file',774 permissions: permissions775 };776 files.push(newFile);777 updateLocalStorage();778 renderFiles();779 fileModal.style.display = 'none';780 fileInput.value = '';781 } else {782 alert('Por favor, selecciona un archivo para subir.');783 }784 }785 786 // Función para crear carpeta787 function addFolder() {788 const folderName = folderNameInput.value.trim();789 if (folderName) {790 // Verificar si la carpeta ya existe791 if (files.some(f => f.name === folderName && f.type === 'folder')) {792 alert('La carpeta ya existe.');793 return;794 }795 796 const selectedOptions = Array.from(folderPermissionsSelect.selectedOptions);797 const permissions = selectedOptions.map(option => parseInt(option.value));798 799 if (permissions.length === 0) {800 alert('Por favor, asigna al menos un usuario con permisos para esta carpeta.');801 return;802 }803 804 const newFolder = {805 id: Date.now(),806 name: folderName,807 type: 'folder',808 permissions: permissions809 };810 files.push(newFolder);811 updateLocalStorage();812 renderFiles();813 folderModal.style.display = 'none';814 folderNameInput.value = '';815 } else {816 alert('Por favor, introduce un nombre para la carpeta.');817 }818 }819 820 // Función para eliminar archivo/carpeta821 function deleteFile(fileId) {822 if (confirm('¿Estás seguro de que deseas eliminar este archivo/carpeta?')) {823 files = files.filter(f => f.id !== fileId);824 updateLocalStorage();825 renderFiles();826 }827 }828 829 // Función para descargar archivo (simulación)830 function downloadFile(fileName) {831 alert(`Descargando archivo: ${fileName}`);832 // Aquí podrías implementar la lógica real de descarga si tienes backend833 }834 835 // Función para renderizar usuarios en el selector836 function renderUserSelect() {837 userSelect.innerHTML = '';838 users.forEach(user => {839 const option = document.createElement('option');840 option.value = user.id;841 option.textContent = `${user.name} (${user.email})`;842 if (user.id === currentUser.id) {843 option.selected = true;844 }845 userSelect.appendChild(option);846 });847 848 // Renderizar opciones en los modales de permisos849 renderPermissionsOptions();850 }851 852 // Función para renderizar opciones de permisos en los modales853 function renderPermissionsOptions() {854 // Limpiar opciones existentes855 filePermissionsSelect.innerHTML = '';856 folderPermissionsSelect.innerHTML = '';857 858 users.forEach(user => {859 const option1 = document.createElement('option');860 option1.value = user.id;861 option1.textContent = `${user.name} (${user.email})`;862 filePermissionsSelect.appendChild(option1);863 864 const option2 = document.createElement('option');865 option2.value = user.id;866 option2.textContent = `${user.name} (${user.email})`;867 folderPermissionsSelect.appendChild(option2);868 });869 }870 871 // Función para renderizar la tabla de usuarios872 function renderUsersTable() {873 usersTableBody.innerHTML = '';874 users.forEach(user => {875 const tr = document.createElement('tr');876 877 const nameTd = document.createElement('td');878 nameTd.textContent = user.name;879 tr.appendChild(nameTd);880 881 const emailTd = document.createElement('td');882 emailTd.textContent = user.email;883 tr.appendChild(emailTd);884 885 const roleTd = document.createElement('td');886 roleTd.textContent = user.role;887 tr.appendChild(roleTd);888 889 const statusTd = document.createElement('td');890 statusTd.textContent = user.status;891 tr.appendChild(statusTd);892 893 const actionsTd = document.createElement('td');894 actionsTd.classList.add('action-buttons');895 896 const editBtn = document.createElement('button');897 editBtn.classList.add('edit');898 editBtn.innerHTML = '✏️';899 editBtn.title = 'Editar Usuario';900 editBtn.onclick = () => openEditUserModal(user.id);901 actionsTd.appendChild(editBtn);902 903 const deleteBtn = document.createElement('button');904 deleteBtn.classList.add('delete');905 deleteBtn.innerHTML = '🗑️';906 deleteBtn.title = 'Eliminar Usuario';907 deleteBtn.onclick = () => deleteUser(user.id);908 actionsTd.appendChild(deleteBtn);909 910 tr.appendChild(actionsTd);911 912 usersTableBody.appendChild(tr);913 });914 }915 916 // Función para renderizar la sección de archivos917 function renderFiles() {918 filesGrid.innerHTML = '';919 files.forEach(file => {920 // Verificar permisos921 if (!file.permissions.includes(currentUser.id)) {922 return; // El usuario no tiene permisos para ver este archivo/carpeta923 }924 925 const fileDiv = document.createElement('div');926 fileDiv.classList.add('file-item');927 928 const icon = document.createElement('img');929 icon.src = file.type === 'folder' ? 'https://img.icons8.com/fluency/48/000000/folder-invoices.png' :930 'https://img.icons8.com/fluency/48/000000/file.png';931 icon.alt = file.type === 'folder' ? 'Carpeta' : 'Archivo';932 fileDiv.appendChild(icon);933 934 const nameDiv = document.createElement('div');935 nameDiv.classList.add('file-name');936 nameDiv.textContent = file.name;937 fileDiv.appendChild(nameDiv);938 939 const actionsDiv = document.createElement('div');940 actionsDiv.classList.add('actions');941 942 if (file.type === 'file') {943 const downloadBtn = document.createElement('button');944 downloadBtn.innerHTML = '⬇️';945 downloadBtn.title = 'Descargar Archivo';946 downloadBtn.onclick = () => downloadFile(file.name);947 actionsDiv.appendChild(downloadBtn);948 }949 950 // Solo Administradores pueden eliminar archivos/carpetas951 if (currentUser.role === 'Administrador') {952 const deleteBtn = document.createElement('button');953 deleteBtn.innerHTML = '🗑️';954 deleteBtn.title = 'Eliminar';955 deleteBtn.onclick = () => deleteFile(file.id);956 actionsDiv.appendChild(deleteBtn);957 }958 959 fileDiv.appendChild(actionsDiv);960 filesGrid.appendChild(fileDiv);961 });962 }963 964 // Función para agregar o editar usuario965 function saveUser() {966 const name = userNameInput.value.trim();967 const email = userEmailInput.value.trim().toLowerCase();968 const password = userPasswordInput.value;969 const confirmPassword = userConfirmPasswordInput.value;970 const role = userRoleSelect.value;971 const status = userStatusSelect.value;972 973 if (!name || !email || !role || !status) {974 alert('Por favor, completa todos los campos requeridos.');975 return;976 }977 978 if (editingUserId === null && (!password || !confirmPassword)) {979 alert('Por favor, establece una contraseña.');980 return;981 }982 983 if (password !== confirmPassword) {984 alert('Las contraseñas no coinciden.');985 return;986 }987 988 if (editingUserId === null) {989 // Verificar si el email ya existe990 if (users.some(user => user.email === email)) {991 alert('El correo electrónico ya está en uso.');992 return;993 }994 995 // Agregar nuevo usuario996 const newUser = {997 id: Date.now(),998 name,999 email,1000 role,1001 status1002 };1003 users.push(newUser);1004 } else {1005 // Editar usuario existente1006 const user = users.find(u => u.id === editingUserId);1007 if (user) {1008 user.name = name;1009 user.email = email;1010 user.role = role;1011 user.status = status;1012 // Contraseña no manejada en este ejemplo1013 }1014 }1015 1016 updateLocalStorage();1017 renderUserSelect();1018 renderUsersTable();1019 renderFiles();1020 closeUserModal();1021 }1022 1023 // Función para abrir el modal de agregar usuario1024 function openAddUserModal() {1025 editingUserId = null;1026 modalTitle.textContent = 'Agregar Usuario';1027 userNameInput.value = '';1028 userEmailInput.value = '';1029 userPasswordInput.value = '';1030 userConfirmPasswordInput.value = '';1031 userRoleSelect.value = '';1032 userStatusSelect.value = '';1033 userModal.style.display = 'block';1034 }1035 1036 // Función para abrir el modal de editar usuario1037 function openEditUserModal(userId) {1038 const user = users.find(u => u.id === userId);1039 if (user) {1040 editingUserId = userId;1041 modalTitle.textContent = 'Editar Usuario';1042 userNameInput.value = user.name;1043 userEmailInput.value = user.email;1044 userPasswordInput.value = '';1045 userConfirmPasswordInput.value = '';1046 userRoleSelect.value = user.role;1047 userStatusSelect.value = user.status;1048 userModal.style.display = 'block';1049 }1050 }1051 1052 // Función para eliminar usuario (no se permite eliminar al Administrador)1053 function deleteUser(userId) {1054 const user = users.find(u => u.id === userId);1055 if (user.role === 'Administrador') {1056 alert('No se puede eliminar al Administrador.');1057 return;1058 }1059 1060 if (confirm('¿Estás seguro de que deseas eliminar este usuario?')) {1061 users = users.filter(u => u.id !== userId);1062 // Además, remover permisos de este usuario en archivos y carpetas1063 files.forEach(file => {1064 file.permissions = file.permissions.filter(uid => uid !== userId);1065 });1066 updateLocalStorage();1067 renderUserSelect();1068 renderUsersTable();1069 renderFiles();1070 }1071 }1072 1073 // Función para cerrar el modal de usuario1074 function closeUserModal() {1075 userModal.style.display = 'none';1076 }1077 1078 // Función para agregar archivo1079 function addFile() {1080 const file = fileInput.files[0];1081 if (file) {1082 const selectedOptions = Array.from(filePermissionsSelect.selectedOptions);1083 const permissions = selectedOptions.map(option => parseInt(option.value));1084 1085 if (permissions.length === 0) {1086 alert('Por favor, asigna al menos un usuario con permisos para este archivo.');1087 return;1088 }1089 1090 const newFile = {1091 id: Date.now(),1092 name: file.name,1093 type: 'file',1094 permissions: permissions1095 };1096 files.push(newFile);1097 updateLocalStorage();1098 renderFiles();1099 fileModal.style.display = 'none';1100 fileInput.value = '';1101 } else {1102 alert('Por favor, selecciona un archivo para subir.');1103 }1104 }1105 1106 // Función para crear carpeta1107 function addFolder() {1108 const folderName = folderNameInput.value.trim();1109 if (folderName) {1110 // Verificar si la carpeta ya existe1111 if (files.some(f => f.name === folderName && f.type === 'folder')) {1112 alert('La carpeta ya existe.');1113 return;1114 }1115 1116 const selectedOptions = Array.from(folderPermissionsSelect.selectedOptions);1117 const permissions = selectedOptions.map(option => parseInt(option.value));1118 1119 if (permissions.length === 0) {1120 alert('Por favor, asigna al menos un usuario con permisos para esta carpeta.');1121 return;1122 }1123 1124 const newFolder = {1125 id: Date.now(),1126 name: folderName,1127 type: 'folder',1128 permissions: permissions1129 };1130 files.push(newFolder);1131 updateLocalStorage();1132 renderFiles();1133 folderModal.style.display = 'none';1134 folderNameInput.value = '';1135 } else {1136 alert('Por favor, introduce un nombre para la carpeta.');1137 }1138 }1139 1140 // Función para eliminar archivo/carpeta1141 function deleteFile(fileId) {1142 if (confirm('¿Estás seguro de que deseas eliminar este archivo/carpeta?')) {1143 files = files.filter(f => f.id !== fileId);1144 updateLocalStorage();1145 renderFiles();1146 }1147 }1148 1149 // Función para descargar archivo (simulación)1150 function downloadFile(fileName) {1151 alert(`Descargando archivo: ${fileName}`);1152 // Aquí podrías implementar la lógica real de descarga si tienes backend1153 }1154 1155 // Función para renderizar usuarios en el selector1156 function renderUserSelect() {1157 userSelect.innerHTML = '';1158 users.forEach(user => {1159 const option = document.createElement('option');1160 option.value = user.id;1161 option.textContent = `${user.name} (${user.email})`;1162 if (user.id === currentUser.id) {1163 option.selected = true;1164 }1165 userSelect.appendChild(option);1166 });1167 1168 // Renderizar opciones en los modales de permisos1169 renderPermissionsOptions();1170 }1171 1172 // Función para renderizar opciones de permisos en los modales1173 function renderPermissionsOptions() {1174 // Limpiar opciones existentes1175 filePermissionsSelect.innerHTML = '';1176 folderPermissionsSelect.innerHTML = '';1177 1178 users.forEach(user => {1179 const option1 = document.createElement('option');1180 option1.value = user.id;1181 option1.textContent = `${user.name} (${user.email})`;1182 filePermissionsSelect.appendChild(option1);1183 1184 const option2 = document.createElement('option');1185 option2.value = user.id;1186 option2.textContent = `${user.name} (${user.email})`;1187 folderPermissionsSelect.appendChild(option2);1188 });1189 }1190 1191 // Función para cambiar de sección en el sidebar1192 function switchSection(section) {1193 // Ocultar todas las secciones1194 sections.forEach(sec => sec.classList.remove('active'));1195 // Mostrar la sección seleccionada1196 document.getElementById(section).classList.add('active');1197 // Actualizar la clase 'active' en el sidebar1198 Array.from(document.getElementById('sidebar-menu').children).forEach(li => {1199 li.classList.toggle('active', li.dataset.section === section);1200 });1201 }1202 1203 // Función para manejar las pestañas1204 tabs.forEach(tab => {1205 tab.addEventListener('click', function() {1206 // Remover clase 'active' de todas las pestañas1207 tabs.forEach(t => t.classList.remove('active'));1208 // Agregar clase 'active' a la pestaña actual1209 this.classList.add('active');1210 1211 const target = this.getAttribute('data-tab');1212 1213 // Ocultar todas las secciones1214 sections.forEach(section => section.classList.remove('active'));1215 // Mostrar la sección correspondiente1216 document.getElementById(target).classList.add('active');1217 });1218 });1219 1220 // Función para renderizar la tabla de usuarios1221 function renderUsersTable() {1222 usersTableBody.innerHTML = '';1223 users.forEach(user => {1224 const tr = document.createElement('tr');1225 1226 const nameTd = document.createElement('td');1227 nameTd.textContent = user.name;1228 tr.appendChild(nameTd);1229 1230 const emailTd = document.createElement('td');1231 emailTd.textContent = user.email;1232 tr.appendChild(emailTd);1233 1234 const roleTd = document.createElement('td');1235 roleTd.textContent = user.role;1236 tr.appendChild(roleTd);1237 1238 const statusTd = document.createElement('td');1239 statusTd.textContent = user.status;1240 tr.appendChild(statusTd);1241 1242 const actionsTd = document.createElement('td');1243 actionsTd.classList.add('action-buttons');1244 1245 const editBtn = document.createElement('button');1246 editBtn.classList.add('edit');1247 editBtn.innerHTML = '✏️';1248 editBtn.title = 'Editar Usuario';1249 editBtn.onclick = () => openEditUserModal(user.id);1250 actionsTd.appendChild(editBtn);1251 1252 const deleteBtn = document.createElement('button');1253 deleteBtn.classList.add('delete');1254 deleteBtn.innerHTML = '🗑️';1255 deleteBtn.title = 'Eliminar Usuario';1256 deleteBtn.onclick = () => deleteUser(user.id);1257 actionsTd.appendChild(deleteBtn);1258 1259 tr.appendChild(actionsTd);1260 1261 usersTableBody.appendChild(tr);1262 });1263 }1264 1265 // Función para renderizar la sección de archivos1266 function renderFiles() {1267 filesGrid.innerHTML = '';1268 files.forEach(file => {1269 // Verificar permisos1270 if (!file.permissions.includes(currentUser.id)) {1271 return; // El usuario no tiene permisos para ver este archivo/carpeta1272 }1273 1274 const fileDiv = document.createElement('div');1275 fileDiv.classList.add('file-item');1276 1277 const icon = document.createElement('img');1278 icon.src = file.type === 'folder' ? 'https://img.icons8.com/fluency/48/000000/folder-invoices.png' :1279 'https://img.icons8.com/fluency/48/000000/file.png';1280 icon.alt = file.type === 'folder' ? 'Carpeta' : 'Archivo';1281 fileDiv.appendChild(icon);1282 1283 const nameDiv = document.createElement('div');1284 nameDiv.classList.add('file-name');1285 nameDiv.textContent = file.name;1286 fileDiv.appendChild(nameDiv);1287 1288 const actionsDiv = document.createElement('div');1289 actionsDiv.classList.add('actions');1290 1291 if (file.type === 'file') {1292 const downloadBtn = document.createElement('button');1293 downloadBtn.innerHTML = '⬇️';1294 downloadBtn.title = 'Descargar Archivo';1295 downloadBtn.onclick = () => downloadFile(file.name);1296 actionsDiv.appendChild(downloadBtn);1297 }1298 1299 // Solo Administradores pueden eliminar archivos/carpetas1300 if (currentUser.role === 'Administrador') {1301 const deleteBtn = document.createElement('button');1302 deleteBtn.innerHTML = '🗑️';1303 deleteBtn.title = 'Eliminar';1304 deleteBtn.onclick = () => deleteFile(file.id);1305 actionsDiv.appendChild(deleteBtn);1306 }1307 1308 fileDiv.appendChild(actionsDiv);1309 filesGrid.appendChild(fileDiv);1310 });1311 }1312 1313 // Función para agregar o editar usuario1314 function saveUser() {1315 const name = userNameInput.value.trim();1316 const email = userEmailInput.value.trim().toLowerCase();1317 const password = userPasswordInput.value;1318 const confirmPassword = userConfirmPasswordInput.value;1319 const role = userRoleSelect.value;1320 const status = userStatusSelect.value;1321 1322 if (!name || !email || !role || !status) {1323 alert('Por favor, completa todos los campos requeridos.');1324 return;1325 }1326 1327 if (editingUserId === null && (!password || !confirmPassword)) {1328 alert('Por favor, establece una contraseña.');1329 return;1330 }1331 1332 if (password !== confirmPassword) {1333 alert('Las contraseñas no coinciden.');1334 return;1335 }1336 1337 if (editingUserId === null) {1338 // Verificar si el email ya existe1339 if (users.some(user => user.email === email)) {1340 alert('El correo electrónico ya está en uso.');1341 return;1342 }1343 1344 // Agregar nuevo usuario1345 const newUser = {1346 id: Date.now(),1347 name,1348 email,1349 role,1350 status1351 };1352 users.push(newUser);1353 } else {1354 // Editar usuario existente1355 const user = users.find(u => u.id === editingUserId);1356 if (user) {1357 user.name = name;1358 user.email = email;1359 user.role = role;1360 user.status = status;1361 // Contraseña no manejada en este ejemplo1362 }1363 }1364 1365 updateLocalStorage();1366 renderUserSelect();1367 renderUsersTable();1368 renderFiles();1369 closeUserModal();1370 }1371 1372 // Función para abrir el modal de agregar usuario1373 function openAddUserModal() {1374 editingUserId = null;1375 modalTitle.textContent = 'Agregar Usuario';1376 userNameInput.value = '';1377 userEmailInput.value = '';1378 userPasswordInput.value = '';1379 userConfirmPasswordInput.value = '';1380 userRoleSelect.value = '';1381 userStatusSelect.value = '';1382 userModal.style.display = 'block';1383 }1384 1385 // Función para abrir el modal de editar usuario1386 function openEditUserModal(userId) {1387 const user = users.find(u => u.id === userId);1388 if (user) {1389 editingUserId = userId;1390 modalTitle.textContent = 'Editar Usuario';1391 userNameInput.value = user.name;1392 userEmailInput.value = user.email;1393 userPasswordInput.value = '';1394 userConfirmPasswordInput.value = '';1395 userRoleSelect.value = user.role;1396 userStatusSelect.value = user.status;1397 userModal.style.display = 'block';1398 }1399 }1400 1401 // Función para eliminar usuario (no se permite eliminar al Administrador)1402 function deleteUser(userId) {1403 const user = users.find(u => u.id === userId);1404 if (user.role === 'Administrador') {1405 alert('No se puede eliminar al Administrador.');1406 return;1407 }1408 1409 if (confirm('¿Estás seguro de que deseas eliminar este usuario?')) {1410 users = users.filter(u => u.id !== userId);1411 // Además, remover permisos de este usuario en archivos y carpetas1412 files.forEach(file => {1413 file.permissions = file.permissions.filter(uid => uid !== userId);1414 });1415 updateLocalStorage();1416 renderUserSelect();1417 renderUsersTable();1418 renderFiles();1419 }1420 }1421 1422 // Función para cerrar el modal de usuario1423 function closeUserModal() {1424 userModal.style.display = 'none';1425 }1426 1427 // Función para agregar archivo1428 function addFile() {1429 const file = fileInput.files[0];1430 if (file) {1431 const selectedOptions = Array.from(filePermissionsSelect.selectedOptions);1432 const permissions = selectedOptions.map(option => parseInt(option.value));1433 1434 if (permissions.length === 0) {1435 alert('Por favor, asigna al menos un usuario con permisos para este archivo.');1436 return;1437 }1438 1439 const newFile = {1440 id: Date.now(),1441 name: file.name,1442 type: 'file',1443 permissions: permissions1444 };1445 files.push(newFile);1446 updateLocalStorage();1447 renderFiles();1448 fileModal.style.display = 'none';1449 fileInput.value = '';1450 } else {1451 alert('Por favor, selecciona un archivo para subir.');1452 }1453 }1454 1455 // Función para crear carpeta1456 function addFolder() {1457 const folderName = folderNameInput.value.trim();1458 if (folderName) {1459 // Verificar si la carpeta ya existe1460 if (files.some(f => f.name === folderName && f.type === 'folder')) {1461 alert('La carpeta ya existe.');1462 return;1463 }1464 1465 const selectedOptions = Array.from(folderPermissionsSelect.selectedOptions);1466 const permissions = selectedOptions.map(option => parseInt(option.value));1467 1468 if (permissions.length === 0) {1469 alert('Por favor, asigna al menos un usuario con permisos para esta carpeta.');1470 return;1471 }1472 1473 const newFolder = {1474 id: Date.now(),1475 name: folderName,1476 type: 'folder',1477 permissions: permissions1478 };1479 files.push(newFolder);1480 updateLocalStorage();1481 renderFiles();1482 folderModal.style.display = 'none';1483 folderNameInput.value = '';1484 } else {1485 alert('Por favor, introduce un nombre para la carpeta.');1486 }1487 }1488 1489 // Función para eliminar archivo/carpeta1490 function deleteFile(fileId) {1491 if (confirm('¿Estás seguro de que deseas eliminar este archivo/carpeta?')) {1492 files = files.filter(f => f.id !== fileId);1493 updateLocalStorage();1494 renderFiles();1495 }1496 }1497 1498 // Función para descargar archivo (simulación)1499 function downloadFile(fileName) {1500 alert(`Descargando archivo: ${fileName}`);1501 // Aquí podrías implementar la lógica real de descarga si tienes backend1502 }1503 1504 // Función para cambiar de usuario1505 userSelect.addEventListener('change', function() {1506 const selectedId = parseInt(this.value);1507 currentUser = users.find(u => u.id === selectedId);1508 renderFiles();1509 });1510 1511 // Función para manejar las pestañas1512 tabs.forEach(tab => {1513 tab.addEventListener('click', function() {1514 // Remover clase 'active' de todas las pestañas1515 tabs.forEach(t => t.classList.remove('active'));1516 // Agregar clase 'active' a la pestaña actual1517 this.classList.add('active');1518 1519 const target = this.getAttribute('data-tab');1520 1521 // Ocultar todas las secciones1522 sections.forEach(section => section.classList.remove('active'));1523 // Mostrar la sección correspondiente1524 document.getElementById(target).classList.add('active');1525 });1526 });1527 1528 // Función para renderizar la tabla de usuarios1529 function renderUsersTable() {1530 usersTableBody.innerHTML = '';1531 users.forEach(user => {1532 const tr = document.createElement('tr');1533 1534 const nameTd = document.createElement('td');1535 nameTd.textContent = user.name;1536 tr.appendChild(nameTd);1537 1538 const emailTd = document.createElement('td');1539 emailTd.textContent = user.email;1540 tr.appendChild(emailTd);1541 1542 const roleTd = document.createElement('td');1543 roleTd.textContent = user.role;1544 tr.appendChild(roleTd);1545 1546 const statusTd = document.createElement('td');1547 statusTd.textContent = user.status;1548 tr.appendChild(statusTd);1549 1550 const actionsTd = document.createElement('td');1551 actionsTd.classList.add('action-buttons');1552 1553 const editBtn = document.createElement('button');1554 editBtn.classList.add('edit');1555 editBtn.innerHTML = '✏️';1556 editBtn.title = 'Editar Usuario';1557 editBtn.onclick = () => openEditUserModal(user.id);1558 actionsTd.appendChild(editBtn);1559 1560 const deleteBtn = document.createElement('button');1561 deleteBtn.classList.add('delete');1562 deleteBtn.innerHTML = '🗑️';1563 deleteBtn.title = 'Eliminar Usuario';1564 deleteBtn.onclick = () => deleteUser(user.id);1565 actionsTd.appendChild(deleteBtn);1566 1567 tr.appendChild(actionsTd);1568 1569 usersTableBody.appendChild(tr);1570 });1571 }1572 1573 // Función para renderizar la sección de archivos1574 function renderFiles() {1575 filesGrid.innerHTML = '';1576 files.forEach(file => {1577 // Verificar permisos1578 if (!file.permissions.includes(currentUser.id)) {1579 return; // El usuario no tiene permisos para ver este archivo/carpeta1580 }1581 1582 const fileDiv = document.createElement('div');1583 fileDiv.classList.add('file-item');1584 1585 const icon = document.createElement('img');1586 icon.src = file.type === 'folder' ? 'https://img.icons8.com/fluency/48/000000/folder-invoices.png' :1587 'https://img.icons8.com/fluency/48/000000/file.png';1588 icon.alt = file.type === 'folder' ? 'Carpeta' : 'Archivo';1589 fileDiv.appendChild(icon);1590 1591 const nameDiv = document.createElement('div');1592 nameDiv.classList.add('file-name');1593 nameDiv.textContent = file.name;1594 fileDiv.appendChild(nameDiv);1595 1596 const actionsDiv = document.createElement('div');1597 actionsDiv.classList.add('actions');1598 1599 if (file.type === 'file') {1600 const downloadBtn = document.createElement('button');1601 downloadBtn.innerHTML = '⬇️';1602 downloadBtn.title = 'Descargar Archivo';1603 downloadBtn.onclick = () => downloadFile(file.name);1604 actionsDiv.appendChild(downloadBtn);1605 }1606 1607 // Solo Administradores pueden eliminar archivos/carpetas1608 if (currentUser.role === 'Administrador') {1609 const deleteBtn = document.createElement('button');1610 deleteBtn.innerHTML = '🗑️';1611 deleteBtn.title = 'Eliminar';1612 deleteBtn.onclick = () => deleteFile(file.id);1613 actionsDiv.appendChild(deleteBtn);1614 }1615 1616 fileDiv.appendChild(actionsDiv);1617 filesGrid.appendChild(fileDiv);1618 });1619 }1620 1621 // Función para renderizar la tabla de usuarios1622 function renderUsersTable() {1623 usersTableBody.innerHTML = '';1624 users.forEach(user => {1625 const tr = document.createElement('tr');1626 1627 const nameTd = document.createElement('td');1628 nameTd.textContent = user.name;1629 tr.appendChild(nameTd);1630 1631 const emailTd = document.createElement('td');1632 emailTd.textContent = user.email;1633 tr.appendChild(emailTd);1634 1635 const roleTd = document.createElement('td');1636 roleTd.textContent = user.role;1637 tr.appendChild(roleTd);1638 1639 const statusTd = document.createElement('td');1640 statusTd.textContent = user.status;1641 tr.appendChild(statusTd);1642 1643 const actionsTd = document.createElement('td');1644 actionsTd.classList.add('action-buttons');1645 1646 const editBtn = document.createElement('button');1647 editBtn.classList.add('edit');1648 editBtn.innerHTML = '✏️';1649 editBtn.title = 'Editar Usuario';1650 editBtn.onclick = () => openEditUserModal(user.id);1651 actionsTd.appendChild(editBtn);1652 1653 const deleteBtn = document.createElement('button');1654 deleteBtn.classList.add('delete');1655 deleteBtn.innerHTML = '🗑️';1656 deleteBtn.title = 'Eliminar Usuario';1657 deleteBtn.onclick = () => deleteUser(user.id);1658 actionsTd.appendChild(deleteBtn);1659 1660 tr.appendChild(actionsTd);1661 1662 usersTableBody.appendChild(tr);1663 });1664 }1665 1666 // Función para manejar permisos específicos a archivos/carpetas1667 function assignPermissions(fileId, userIds) {1668 const file = files.find(f => f.id === fileId);1669 if (file) {1670 file.permissions = userIds;1671 updateLocalStorage();1672 renderFiles();1673 }1674 }1675 1676 // Función para asignar permisos (para futuras implementaciones)1677 // Actualmente, permisos se asignan durante la creación de archivos/carpetas1678 1679 // Event Listeners1680 addUserBtn.addEventListener('click', openAddUserModal);1681 cancelUserBtn.addEventListener('click', closeUserModal);1682 saveUserBtn.addEventListener('click', saveUser);1683 1684 addFileBtn.addEventListener('click', () => {1685 fileModal.style.display = 'block';1686 });1687 cancelFileBtn.addEventListener('click', () => {1688 fileModal.style.display = 'none';1689 fileInput.value = '';1690 });1691 saveFileBtn.addEventListener('click', addFile);1692 1693 addFolderBtn.addEventListener('click', () => {1694 folderModal.style.display = 'block';1695 });1696 cancelFolderBtn.addEventListener('click', () => {1697 folderModal.style.display = 'none';1698 folderNameInput.value = '';1699 });1700 saveFolderBtn.addEventListener('click', addFolder);1701 1702 // Cerrar modales al hacer clic fuera de ellos1703 window.onclick = function(event) {1704 if (event.target == userModal) {1705 userModal.style.display = 'none';1706 }1707 if (event.target == fileModal) {1708 fileModal.style.display = 'none';1709 fileInput.value = '';1710 }1711 if (event.target == folderModal) {1712 folderModal.style.display = 'none';1713 folderNameInput.value = '';1714 }1715 }1716 1717 // Inicialización1718 renderUserSelect();1719 renderUsersTable();1720 renderFiles();1721 1722 </script>1723 </body>1724 </html>1725
Enlace
El enlace para compartir es: