Nuestro conocimiento compartido. Nuestro tesoro compartido. Wikipedia.
ShareCode
Permalink: http://www.treeweb.es/u/974/ 01/02/2011

ShareCode

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: