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: 'Usuario 1', email: 'user1@securestore.com', role: 'Usuario', status: 'Activo' },445 { id: 3, name: 'Usuario 2', email: 'user2@securestore.com', role: 'Usuario', status: 'Inactivo' }446 ];447 localStorage.setItem('securestore_users', JSON.stringify(initialUsers));448 }449 450 if (!localStorage.getItem('securestore_files')) {451 const initialFiles = [452 { id: 1, name: 'Reporte.pdf', type: 'file', permissions: ['Administrador', 'Usuario'] },453 { id: 2, name: 'Imagen.png', type: 'file', permissions: ['Administrador'] },454 { id: 3, name: 'Documentos', type: 'folder', permissions: ['Administrador', 'Usuario'] },455 { id: 4, name: 'Proyecto', type: 'folder', permissions: ['Administrador'] }456 ];457 localStorage.setItem('securestore_files', JSON.stringify(initialFiles));458 }459 460 // Variables Globales461 let users = JSON.parse(localStorage.getItem('securestore_users'));462 let files = JSON.parse(localStorage.getItem('securestore_files'));463 let currentUser = users[0]; // Por defecto, el primer usuario es el actual464 465 // Elementos del DOM466 const userSelect = document.getElementById('current-user');467 const usersTableBody = document.querySelector('#users-table tbody');468 const addUserBtn = document.getElementById('add-user-btn');469 const userModal = document.getElementById('user-modal');470 const modalTitle = document.getElementById('modal-title');471 const cancelUserBtn = document.getElementById('cancel-user-btn');472 const saveUserBtn = document.getElementById('save-user-btn');473 const userNameInput = document.getElementById('user-name');474 const userEmailInput = document.getElementById('user-email');475 const userPasswordInput = document.getElementById('user-password');476 const userConfirmPasswordInput = document.getElementById('user-confirm-password');477 const userRoleSelect = document.getElementById('user-role');478 const userStatusSelect = document.getElementById('user-status');479 480 const addFileBtn = document.getElementById('add-file-btn');481 const fileModal = document.getElementById('file-modal');482 const cancelFileBtn = document.getElementById('cancel-file-btn');483 const saveFileBtn = document.getElementById('save-file-btn');484 const fileInput = document.getElementById('file-input');485 486 const addFolderBtn = document.getElementById('add-folder-btn');487 const folderModal = document.getElementById('folder-modal');488 const cancelFolderBtn = document.getElementById('cancel-folder-btn');489 const saveFolderBtn = document.getElementById('save-folder-btn');490 const folderNameInput = document.getElementById('folder-name');491 492 const filesGrid = document.getElementById('files-grid');493 494 const tabs = document.querySelectorAll('.tabs button');495 const sections = document.querySelectorAll('.section');496 497 // Función para actualizar localStorage498 function updateLocalStorage() {499 localStorage.setItem('securestore_users', JSON.stringify(users));500 localStorage.setItem('securestore_files', JSON.stringify(files));501 }502 503 // Función para renderizar el selector de usuarios504 function renderUserSelect() {505 userSelect.innerHTML = '';506 users.forEach(user => {507 const option = document.createElement('option');508 option.value = user.id;509 option.textContent = `${user.name} (${user.email})`;510 if (user.id === currentUser.id) {511 option.selected = true;512 }513 userSelect.appendChild(option);514 });515 }516 517 // Función para renderizar la tabla de usuarios518 function renderUsersTable() {519 usersTableBody.innerHTML = '';520 users.forEach(user => {521 const tr = document.createElement('tr');522 523 const nameTd = document.createElement('td');524 nameTd.textContent = user.name;525 tr.appendChild(nameTd);526 527 const emailTd = document.createElement('td');528 emailTd.textContent = user.email;529 tr.appendChild(emailTd);530 531 const roleTd = document.createElement('td');532 roleTd.textContent = user.role;533 tr.appendChild(roleTd);534 535 const statusTd = document.createElement('td');536 statusTd.textContent = user.status;537 tr.appendChild(statusTd);538 539 const actionsTd = document.createElement('td');540 actionsTd.classList.add('action-buttons');541 542 const editBtn = document.createElement('button');543 editBtn.classList.add('edit');544 editBtn.innerHTML = '✏️';545 editBtn.title = 'Editar Usuario';546 editBtn.onclick = () => openEditUserModal(user.id);547 actionsTd.appendChild(editBtn);548 549 const deleteBtn = document.createElement('button');550 deleteBtn.classList.add('delete');551 deleteBtn.innerHTML = '🗑️';552 deleteBtn.title = 'Eliminar Usuario';553 deleteBtn.onclick = () => deleteUser(user.id);554 actionsTd.appendChild(deleteBtn);555 556 tr.appendChild(actionsTd);557 558 usersTableBody.appendChild(tr);559 });560 }561 562 // Función para renderizar la sección de archivos563 function renderFiles() {564 filesGrid.innerHTML = '';565 files.forEach(file => {566 // Verificar permisos567 if (!file.permissions.includes(currentUser.role)) {568 return; // El usuario no tiene permisos para ver este archivo/carpeta569 }570 571 const fileDiv = document.createElement('div');572 fileDiv.classList.add('file-item');573 574 const icon = document.createElement('img');575 icon.src = file.type === 'folder' ? 'https://img.icons8.com/fluency/48/000000/folder-invoices.png' :576 'https://img.icons8.com/fluency/48/000000/file.png';577 icon.alt = file.type === 'folder' ? 'Carpeta' : 'Archivo';578 fileDiv.appendChild(icon);579 580 const nameDiv = document.createElement('div');581 nameDiv.classList.add('file-name');582 nameDiv.textContent = file.name;583 fileDiv.appendChild(nameDiv);584 585 const actionsDiv = document.createElement('div');586 actionsDiv.classList.add('actions');587 588 if (file.type === 'file') {589 const downloadBtn = document.createElement('button');590 downloadBtn.innerHTML = '⬇️';591 downloadBtn.title = 'Descargar Archivo';592 downloadBtn.onclick = () => downloadFile(file.name);593 actionsDiv.appendChild(downloadBtn);594 }595 596 // Solo Administradores pueden eliminar archivos/carpetas597 if (currentUser.role === 'Administrador') {598 const deleteBtn = document.createElement('button');599 deleteBtn.innerHTML = '🗑️';600 deleteBtn.title = 'Eliminar';601 deleteBtn.onclick = () => deleteFile(file.id);602 actionsDiv.appendChild(deleteBtn);603 }604 605 fileDiv.appendChild(actionsDiv);606 filesGrid.appendChild(fileDiv);607 });608 }609 610 // Función para agregar o editar usuario611 function saveUser() {612 const name = userNameInput.value.trim();613 const email = userEmailInput.value.trim().toLowerCase();614 const password = userPasswordInput.value;615 const confirmPassword = userConfirmPasswordInput.value;616 const role = userRoleSelect.value;617 const status = userStatusSelect.value;618 619 if (!name || !email || !role || !status) {620 alert('Por favor, completa todos los campos requeridos.');621 return;622 }623 624 if (editingUserId === null && (!password || !confirmPassword)) {625 alert('Por favor, establece una contraseña.');626 return;627 }628 629 if (password !== confirmPassword) {630 alert('Las contraseñas no coinciden.');631 return;632 }633 634 if (editingUserId === null) {635 // Verificar si el email ya existe636 if (users.some(user => user.email === email)) {637 alert('El correo electrónico ya está en uso.');638 return;639 }640 641 // Agregar nuevo usuario642 const newUser = {643 id: Date.now(),644 name,645 email,646 role,647 status648 };649 users.push(newUser);650 } else {651 // Editar usuario existente652 const user = users.find(u => u.id === editingUserId);653 if (user) {654 user.name = name;655 user.email = email;656 user.role = role;657 user.status = status;658 // Contraseña no manejada en este ejemplo659 }660 }661 662 updateLocalStorage();663 renderUserSelect();664 renderUsersTable();665 renderFiles();666 closeUserModal();667 }668 669 // Función para abrir el modal de agregar usuario670 function openAddUserModal() {671 editingUserId = null;672 modalTitle.textContent = 'Agregar Usuario';673 userNameInput.value = '';674 userEmailInput.value = '';675 userPasswordInput.value = '';676 userConfirmPasswordInput.value = '';677 userRoleSelect.value = '';678 userStatusSelect.value = '';679 userModal.style.display = 'block';680 }681 682 // Función para abrir el modal de editar usuario683 function openEditUserModal(userId) {684 const user = users.find(u => u.id === userId);685 if (user) {686 editingUserId = userId;687 modalTitle.textContent = 'Editar Usuario';688 userNameInput.value = user.name;689 userEmailInput.value = user.email;690 userPasswordInput.value = '';691 userConfirmPasswordInput.value = '';692 userRoleSelect.value = user.role;693 userStatusSelect.value = user.status;694 userModal.style.display = 'block';695 }696 }697 698 // Función para eliminar usuario699 function deleteUser(userId) {700 if (confirm('¿Estás seguro de que deseas eliminar este usuario?')) {701 users = users.filter(u => u.id !== userId);702 updateLocalStorage();703 renderUserSelect();704 renderUsersTable();705 renderFiles();706 }707 }708 709 // Función para cerrar el modal de usuario710 function closeUserModal() {711 userModal.style.display = 'none';712 }713 714 // Función para agregar archivo715 function addFile() {716 const file = fileInput.files[0];717 if (file) {718 const newFile = {719 id: Date.now(),720 name: file.name,721 type: 'file',722 permissions: ['Administrador', 'Usuario'] // Por defecto, ambos roles tienen acceso723 };724 files.push(newFile);725 updateLocalStorage();726 renderFiles();727 fileModal.style.display = 'none';728 fileInput.value = '';729 } else {730 alert('Por favor, selecciona un archivo para subir.');731 }732 }733 734 // Función para crear carpeta735 function addFolder() {736 const folderName = folderNameInput.value.trim();737 if (folderName) {738 // Verificar si la carpeta ya existe739 if (files.some(f => f.name === folderName && f.type === 'folder')) {740 alert('La carpeta ya existe.');741 return;742 }743 744 const newFolder = {745 id: Date.now(),746 name: folderName,747 type: 'folder',748 permissions: ['Administrador', 'Usuario'] // Por defecto, ambos roles tienen acceso749 };750 files.push(newFolder);751 updateLocalStorage();752 renderFiles();753 folderModal.style.display = 'none';754 folderNameInput.value = '';755 } else {756 alert('Por favor, introduce un nombre para la carpeta.');757 }758 }759 760 // Función para eliminar archivo/carpeta761 function deleteFile(fileId) {762 if (confirm('¿Estás seguro de que deseas eliminar este archivo/carpeta?')) {763 files = files.filter(f => f.id !== fileId);764 updateLocalStorage();765 renderFiles();766 }767 }768 769 // Función para descargar archivo (simulación)770 function downloadFile(fileName) {771 alert(`Descargando archivo: ${fileName}`);772 // Aquí podrías implementar la lógica real de descarga si tienes backend773 }774 775 // Función para renderizar archivos776 function renderFiles() {777 filesGrid.innerHTML = '';778 files.forEach(file => {779 // Verificar permisos780 if (!file.permissions.includes(currentUser.role)) {781 return; // El usuario no tiene permisos para ver este archivo/carpeta782 }783 784 const fileDiv = document.createElement('div');785 fileDiv.classList.add('file-item');786 787 const icon = document.createElement('img');788 icon.src = file.type === 'folder' ? 'https://img.icons8.com/fluency/48/000000/folder-invoices.png' :789 'https://img.icons8.com/fluency/48/000000/file.png';790 icon.alt = file.type === 'folder' ? 'Carpeta' : 'Archivo';791 fileDiv.appendChild(icon);792 793 const nameDiv = document.createElement('div');794 nameDiv.classList.add('file-name');795 nameDiv.textContent = file.name;796 fileDiv.appendChild(nameDiv);797 798 const actionsDiv = document.createElement('div');799 actionsDiv.classList.add('actions');800 801 if (file.type === 'file') {802 const downloadBtn = document.createElement('button');803 downloadBtn.innerHTML = '⬇️';804 downloadBtn.title = 'Descargar Archivo';805 downloadBtn.onclick = () => downloadFile(file.name);806 actionsDiv.appendChild(downloadBtn);807 }808 809 // Solo Administradores pueden eliminar archivos/carpetas810 if (currentUser.role === 'Administrador') {811 const deleteBtn = document.createElement('button');812 deleteBtn.innerHTML = '🗑️';813 deleteBtn.title = 'Eliminar';814 deleteBtn.onclick = () => deleteFile(file.id);815 actionsDiv.appendChild(deleteBtn);816 }817 818 fileDiv.appendChild(actionsDiv);819 filesGrid.appendChild(fileDiv);820 });821 }822 823 // Función para renderizar usuarios en el selector824 function renderUserSelect() {825 userSelect.innerHTML = '';826 users.forEach(user => {827 const option = document.createElement('option');828 option.value = user.id;829 option.textContent = `${user.name} (${user.email})`;830 if (user.id === currentUser.id) {831 option.selected = true;832 }833 userSelect.appendChild(option);834 });835 }836 837 // Función para manejar el cambio de usuario838 userSelect.addEventListener('change', function() {839 const selectedId = parseInt(this.value);840 currentUser = users.find(u => u.id === selectedId);841 renderFiles();842 });843 844 // Función para manejar las pestañas845 tabs.forEach(tab => {846 tab.addEventListener('click', function() {847 // Remover clase 'active' de todas las pestañas848 tabs.forEach(t => t.classList.remove('active'));849 // Agregar clase 'active' a la pestaña actual850 this.classList.add('active');851 852 const target = this.getAttribute('data-tab');853 854 // Ocultar todas las secciones855 sections.forEach(section => section.classList.remove('active'));856 // Mostrar la sección correspondiente857 document.getElementById(target).classList.add('active');858 });859 });860 861 // Funciones para modales de usuario862 addUserBtn.addEventListener('click', openAddUserModal);863 cancelUserBtn.addEventListener('click', closeUserModal);864 saveUserBtn.addEventListener('click', saveUser);865 866 // Funciones para modales de archivo867 addFileBtn.addEventListener('click', () => {868 fileModal.style.display = 'block';869 });870 cancelFileBtn.addEventListener('click', () => {871 fileModal.style.display = 'none';872 fileInput.value = '';873 });874 saveFileBtn.addEventListener('click', addFile);875 876 // Funciones para modales de carpeta877 addFolderBtn.addEventListener('click', () => {878 folderModal.style.display = 'block';879 });880 cancelFolderBtn.addEventListener('click', () => {881 folderModal.style.display = 'none';882 folderNameInput.value = '';883 });884 saveFolderBtn.addEventListener('click', addFolder);885 886 // Cerrar modales al hacer clic fuera de ellos887 window.onclick = function(event) {888 if (event.target == userModal) {889 userModal.style.display = 'none';890 }891 if (event.target == fileModal) {892 fileModal.style.display = 'none';893 fileInput.value = '';894 }895 if (event.target == folderModal) {896 folderModal.style.display = 'none';897 folderNameInput.value = '';898 }899 }900 901 // Inicialización902 renderUserSelect();903 renderUsersTable();904 renderFiles();905 906 // Función para renderizar la tabla de usuarios907 function renderUsersTable() {908 usersTableBody.innerHTML = '';909 users.forEach(user => {910 const tr = document.createElement('tr');911 912 const nameTd = document.createElement('td');913 nameTd.textContent = user.name;914 tr.appendChild(nameTd);915 916 const emailTd = document.createElement('td');917 emailTd.textContent = user.email;918 tr.appendChild(emailTd);919 920 const roleTd = document.createElement('td');921 roleTd.textContent = user.role;922 tr.appendChild(roleTd);923 924 const statusTd = document.createElement('td');925 statusTd.textContent = user.status;926 tr.appendChild(statusTd);927 928 const actionsTd = document.createElement('td');929 actionsTd.classList.add('action-buttons');930 931 const editBtn = document.createElement('button');932 editBtn.classList.add('edit');933 editBtn.innerHTML = '✏️';934 editBtn.title = 'Editar Usuario';935 editBtn.onclick = () => openEditUserModal(user.id);936 actionsTd.appendChild(editBtn);937 938 const deleteBtn = document.createElement('button');939 deleteBtn.classList.add('delete');940 deleteBtn.innerHTML = '🗑️';941 deleteBtn.title = 'Eliminar Usuario';942 deleteBtn.onclick = () => deleteUser(user.id);943 actionsTd.appendChild(deleteBtn);944 945 tr.appendChild(actionsTd);946 947 usersTableBody.appendChild(tr);948 });949 }950 951 // Función para eliminar usuario (no se permite eliminar al Administrador)952 function deleteUser(userId) {953 const user = users.find(u => u.id === userId);954 if (user.role === 'Administrador') {955 alert('No se puede eliminar al Administrador.');956 return;957 }958 959 if (confirm('¿Estás seguro de que deseas eliminar este usuario?')) {960 users = users.filter(u => u.id !== userId);961 updateLocalStorage();962 renderUserSelect();963 renderUsersTable();964 renderFiles();965 }966 }967 </script>968 </body>969 </html>970
Enlace
El enlace para compartir es: