styvencm commited on
Commit
a596e49
·
verified ·
1 Parent(s): b897e07

necesito que crees una app que comience con un dashboard y permita ver dos opciones, la primera será registrarse, es donde usuario pondra todos sus datos, nombre, apellido y edad luego quedarán guardados, la segunda opcióndel dashboard debe ser poder ver la base de datos de quienes sehan registrado. La app debe tener un diseño modeno e intuitivo - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +569 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Base De Datos
3
- emoji: 📚
4
- colorFrom: yellow
5
- colorTo: gray
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: base-de-datos
3
+ emoji: 🐳
4
+ colorFrom: green
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,569 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>User Management App</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .fade-in {
11
+ animation: fadeIn 0.3s ease-in-out;
12
+ }
13
+ @keyframes fadeIn {
14
+ from { opacity: 0; transform: translateY(10px); }
15
+ to { opacity: 1; transform: translateY(0); }
16
+ }
17
+ .sidebar {
18
+ transition: all 0.3s ease;
19
+ }
20
+ @media (max-width: 768px) {
21
+ .sidebar {
22
+ transform: translateX(-100%);
23
+ position: fixed;
24
+ z-index: 50;
25
+ height: 100vh;
26
+ }
27
+ .sidebar.open {
28
+ transform: translateX(0);
29
+ }
30
+ }
31
+ </style>
32
+ </head>
33
+ <body class="bg-gray-100 font-sans">
34
+ <!-- Mobile menu button -->
35
+ <div class="md:hidden fixed top-4 left-4 z-50">
36
+ <button id="menuBtn" class="p-2 rounded-md bg-indigo-600 text-white">
37
+ <i class="fas fa-bars"></i>
38
+ </button>
39
+ </div>
40
+
41
+ <!-- Sidebar -->
42
+ <div id="sidebar" class="sidebar w-64 bg-white shadow-lg fixed h-full">
43
+ <div class="p-4 flex items-center space-x-3 border-b border-gray-200">
44
+ <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
45
+ <i class="fas fa-user-cog text-indigo-600"></i>
46
+ </div>
47
+ <h1 class="text-xl font-bold text-gray-800">User Manager</h1>
48
+ </div>
49
+ <nav class="p-4">
50
+ <ul class="space-y-2">
51
+ <li>
52
+ <button id="dashboardBtn" class="w-full flex items-center space-x-3 p-3 rounded-lg bg-indigo-50 text-indigo-700">
53
+ <i class="fas fa-tachometer-alt"></i>
54
+ <span>Dashboard</span>
55
+ </button>
56
+ </li>
57
+ <li>
58
+ <button id="registerBtn" class="w-full flex items-center space-x-3 p-3 rounded-lg hover:bg-gray-100 text-gray-700">
59
+ <i class="fas fa-user-plus"></i>
60
+ <span>Registrar Usuario</span>
61
+ </button>
62
+ </li>
63
+ <li>
64
+ <button id="databaseBtn" class="w-full flex items-center space-x-3 p-3 rounded-lg hover:bg-gray-100 text-gray-700">
65
+ <i class="fas fa-database"></i>
66
+ <span>Base de Datos</span>
67
+ </button>
68
+ </li>
69
+ </ul>
70
+ </nav>
71
+ <div class="absolute bottom-0 w-full p-4 border-t border-gray-200">
72
+ <button class="w-full flex items-center space-x-3 p-3 rounded-lg hover:bg-gray-100 text-gray-700">
73
+ <i class="fas fa-sign-out-alt"></i>
74
+ <span>Cerrar Sesión</span>
75
+ </button>
76
+ </div>
77
+ </div>
78
+
79
+ <!-- Main Content -->
80
+ <div class="md:ml-64 min-h-screen">
81
+ <!-- Header -->
82
+ <header class="bg-white shadow-sm p-4">
83
+ <div class="flex justify-between items-center">
84
+ <h2 class="text-xl font-semibold text-gray-800" id="pageTitle">Dashboard</h2>
85
+ <div class="flex items-center space-x-4">
86
+ <div class="relative">
87
+ <i class="fas fa-bell text-gray-500 hover:text-indigo-600 cursor-pointer"></i>
88
+ <span class="absolute -top-1 -right-1 w-2 h-2 bg-red-500 rounded-full"></span>
89
+ </div>
90
+ <div class="flex items-center space-x-2">
91
+ <div class="w-8 h-8 rounded-full bg-indigo-100 flex items-center justify-center">
92
+ <i class="fas fa-user text-indigo-600 text-sm"></i>
93
+ </div>
94
+ <span class="text-sm font-medium">Admin</span>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </header>
99
+
100
+ <!-- Content Area -->
101
+ <main class="p-6">
102
+ <!-- Dashboard Content -->
103
+ <div id="dashboardContent" class="fade-in">
104
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
105
+ <div class="bg-white rounded-xl shadow-md p-6">
106
+ <div class="flex items-center justify-between">
107
+ <div>
108
+ <p class="text-gray-500">Usuarios registrados</p>
109
+ <h3 class="text-3xl font-bold" id="totalUsers">0</h3>
110
+ </div>
111
+ <div class="w-12 h-12 rounded-full bg-indigo-100 flex items-center justify-center">
112
+ <i class="fas fa-users text-indigo-600"></i>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ <div class="bg-white rounded-xl shadow-md p-6">
117
+ <div class="flex items-center justify-between">
118
+ <div>
119
+ <p class="text-gray-500">Registros hoy</p>
120
+ <h3 class="text-3xl font-bold" id="todayUsers">0</h3>
121
+ </div>
122
+ <div class="w-12 h-12 rounded-full bg-green-100 flex items-center justify-center">
123
+ <i class="fas fa-calendar-day text-green-600"></i>
124
+ </div>
125
+ </div>
126
+ </div>
127
+ </div>
128
+
129
+ <div class="bg-white rounded-xl shadow-md p-6">
130
+ <h3 class="text-xl font-semibold mb-4">Acciones rápidas</h3>
131
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
132
+ <button id="quickRegisterBtn" class="flex items-center space-x-3 p-4 border border-gray-200 rounded-lg hover:border-indigo-300 hover:bg-indigo-50 transition-all">
133
+ <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
134
+ <i class="fas fa-user-plus text-indigo-600"></i>
135
+ </div>
136
+ <div>
137
+ <h4 class="font-medium">Registrar nuevo usuario</h4>
138
+ <p class="text-sm text-gray-500">Agrega un usuario a la base de datos</p>
139
+ </div>
140
+ </button>
141
+ <button id="quickDatabaseBtn" class="flex items-center space-x-3 p-4 border border-gray-200 rounded-lg hover:border-indigo-300 hover:bg-indigo-50 transition-all">
142
+ <div class="w-10 h-10 rounded-full bg-purple-100 flex items-center justify-center">
143
+ <i class="fas fa-database text-purple-600"></i>
144
+ </div>
145
+ <div>
146
+ <h4 class="font-medium">Ver base de datos</h4>
147
+ <p class="text-sm text-gray-500">Consulta todos los usuarios registrados</p>
148
+ </div>
149
+ </button>
150
+ </div>
151
+ </div>
152
+ </div>
153
+
154
+ <!-- Register Form Content -->
155
+ <div id="registerContent" class="hidden fade-in">
156
+ <div class="bg-white rounded-xl shadow-md p-6 max-w-2xl mx-auto">
157
+ <div class="flex items-center justify-between mb-6">
158
+ <h3 class="text-xl font-semibold">Registro de Usuario</h3>
159
+ <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
160
+ <i class="fas fa-user-plus text-indigo-600"></i>
161
+ </div>
162
+ </div>
163
+
164
+ <form id="userForm" class="space-y-4">
165
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
166
+ <div>
167
+ <label for="firstName" class="block text-sm font-medium text-gray-700 mb-1">Nombre</label>
168
+ <input type="text" id="firstName" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-500 outline-none transition">
169
+ </div>
170
+ <div>
171
+ <label for="lastName" class="block text-sm font-medium text-gray-700 mb-1">Apellido</label>
172
+ <input type="text" id="lastName" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-500 outline-none transition">
173
+ </div>
174
+ </div>
175
+
176
+ <div>
177
+ <label for="age" class="block text-sm font-medium text-gray-700 mb-1">Edad</label>
178
+ <input type="number" id="age" min="1" max="120" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-500 outline-none transition">
179
+ </div>
180
+
181
+ <div>
182
+ <label for="email" class="block text-sm font-medium text-gray-700 mb-1">Correo Electrónico</label>
183
+ <input type="email" id="email" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-500 outline-none transition">
184
+ </div>
185
+
186
+ <div class="pt-4">
187
+ <button type="submit" class="w-full bg-indigo-600 text-white py-2 px-4 rounded-lg hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition">
188
+ Registrar Usuario
189
+ </button>
190
+ </div>
191
+ </form>
192
+ </div>
193
+ </div>
194
+
195
+ <!-- Database Content -->
196
+ <div id="databaseContent" class="hidden fade-in">
197
+ <div class="bg-white rounded-xl shadow-md p-6">
198
+ <div class="flex items-center justify-between mb-6">
199
+ <h3 class="text-xl font-semibold">Base de Datos de Usuarios</h3>
200
+ <div class="flex items-center space-x-3">
201
+ <div class="relative">
202
+ <input type="text" id="searchInput" placeholder="Buscar..." class="pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-500 outline-none transition">
203
+ <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
204
+ </div>
205
+ <button class="p-2 rounded-lg bg-gray-100 hover:bg-gray-200">
206
+ <i class="fas fa-filter text-gray-600"></i>
207
+ </button>
208
+ </div>
209
+ </div>
210
+
211
+ <div class="overflow-x-auto">
212
+ <table class="min-w-full divide-y divide-gray-200">
213
+ <thead class="bg-gray-50">
214
+ <tr>
215
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Nombre</th>
216
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Apellido</th>
217
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Edad</th>
218
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Email</th>
219
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Fecha Registro</th>
220
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Acciones</th>
221
+ </tr>
222
+ </thead>
223
+ <tbody id="usersTableBody" class="bg-white divide-y divide-gray-200">
224
+ <!-- Users will be inserted here dynamically -->
225
+ <tr>
226
+ <td colspan="6" class="px-6 py-4 text-center text-gray-500">No hay usuarios registrados</td>
227
+ </tr>
228
+ </tbody>
229
+ </table>
230
+ </div>
231
+
232
+ <div class="flex items-center justify-between mt-4">
233
+ <div class="text-sm text-gray-500">
234
+ Mostrando <span id="showingFrom">0</span> a <span id="showingTo">0</span> de <span id="totalRecords">0</span> registros
235
+ </div>
236
+ <div class="flex space-x-2">
237
+ <button id="prevPage" disabled class="px-3 py-1 border rounded-lg text-gray-500 bg-gray-100 cursor-not-allowed">Anterior</button>
238
+ <button id="nextPage" disabled class="px-3 py-1 border rounded-lg text-gray-500 bg-gray-100 cursor-not-allowed">Siguiente</button>
239
+ </div>
240
+ </div>
241
+ </div>
242
+ </div>
243
+ </main>
244
+ </div>
245
+
246
+ <!-- Toast Notification -->
247
+ <div id="toast" class="fixed bottom-4 right-4 hidden">
248
+ <div class="bg-green-500 text-white px-4 py-2 rounded-lg shadow-lg flex items-center space-x-2">
249
+ <i class="fas fa-check-circle"></i>
250
+ <span id="toastMessage">Usuario registrado exitosamente!</span>
251
+ </div>
252
+ </div>
253
+
254
+ <script>
255
+ // Local storage for users database
256
+ let usersDB = JSON.parse(localStorage.getItem('usersDB')) || [];
257
+
258
+ // DOM Elements
259
+ const menuBtn = document.getElementById('menuBtn');
260
+ const sidebar = document.getElementById('sidebar');
261
+ const pageTitle = document.getElementById('pageTitle');
262
+
263
+ // Content areas
264
+ const dashboardContent = document.getElementById('dashboardContent');
265
+ const registerContent = document.getElementById('registerContent');
266
+ const databaseContent = document.getElementById('databaseContent');
267
+
268
+ // Navigation buttons
269
+ const dashboardBtn = document.getElementById('dashboardBtn');
270
+ const registerBtn = document.getElementById('registerBtn');
271
+ const databaseBtn = document.getElementById('databaseBtn');
272
+ const quickRegisterBtn = document.getElementById('quickRegisterBtn');
273
+ const quickDatabaseBtn = document.getElementById('quickDatabaseBtn');
274
+
275
+ // Form elements
276
+ const userForm = document.getElementById('userForm');
277
+
278
+ // Database elements
279
+ const usersTableBody = document.getElementById('usersTableBody');
280
+ const searchInput = document.getElementById('searchInput');
281
+ const prevPage = document.getElementById('prevPage');
282
+ const nextPage = document.getElementById('nextPage');
283
+ const showingFrom = document.getElementById('showingFrom');
284
+ const showingTo = document.getElementById('showingTo');
285
+ const totalRecords = document.getElementById('totalRecords');
286
+
287
+ // Dashboard counters
288
+ const totalUsers = document.getElementById('totalUsers');
289
+ const todayUsers = document.getElementById('todayUsers');
290
+
291
+ // Toast
292
+ const toast = document.getElementById('toast');
293
+ const toastMessage = document.getElementById('toastMessage');
294
+
295
+ // Pagination
296
+ let currentPage = 1;
297
+ const usersPerPage = 5;
298
+
299
+ // Initialize app
300
+ document.addEventListener('DOMContentLoaded', () => {
301
+ updateDashboardCounters();
302
+ showDashboard();
303
+
304
+ // Mobile menu toggle
305
+ menuBtn.addEventListener('click', () => {
306
+ sidebar.classList.toggle('open');
307
+ });
308
+
309
+ // Navigation
310
+ dashboardBtn.addEventListener('click', showDashboard);
311
+ registerBtn.addEventListener('click', showRegister);
312
+ databaseBtn.addEventListener('click', showDatabase);
313
+ quickRegisterBtn.addEventListener('click', showRegister);
314
+ quickDatabaseBtn.addEventListener('click', showDatabase);
315
+
316
+ // Form submission
317
+ userForm.addEventListener('submit', registerUser);
318
+
319
+ // Database search
320
+ searchInput.addEventListener('input', filterUsers);
321
+
322
+ // Pagination
323
+ prevPage.addEventListener('click', () => {
324
+ if (currentPage > 1) {
325
+ currentPage--;
326
+ renderUsersTable();
327
+ }
328
+ });
329
+
330
+ nextPage.addEventListener('click', () => {
331
+ const totalPages = Math.ceil(usersDB.length / usersPerPage);
332
+ if (currentPage < totalPages) {
333
+ currentPage++;
334
+ renderUsersTable();
335
+ }
336
+ });
337
+ });
338
+
339
+ function showDashboard() {
340
+ dashboardContent.classList.remove('hidden');
341
+ registerContent.classList.add('hidden');
342
+ databaseContent.classList.add('hidden');
343
+
344
+ // Update active button in sidebar
345
+ dashboardBtn.classList.add('bg-indigo-50', 'text-indigo-700');
346
+ dashboardBtn.classList.remove('hover:bg-gray-100', 'text-gray-700');
347
+
348
+ registerBtn.classList.remove('bg-indigo-50', 'text-indigo-700');
349
+ registerBtn.classList.add('hover:bg-gray-100', 'text-gray-700');
350
+
351
+ databaseBtn.classList.remove('bg-indigo-50', 'text-indigo-700');
352
+ databaseBtn.classList.add('hover:bg-gray-100', 'text-gray-700');
353
+
354
+ pageTitle.textContent = 'Dashboard';
355
+
356
+ // Close mobile menu if open
357
+ sidebar.classList.remove('open');
358
+
359
+ // Update counters
360
+ updateDashboardCounters();
361
+ }
362
+
363
+ function showRegister() {
364
+ dashboardContent.classList.add('hidden');
365
+ registerContent.classList.remove('hidden');
366
+ databaseContent.classList.add('hidden');
367
+
368
+ // Update active button in sidebar
369
+ dashboardBtn.classList.remove('bg-indigo-50', 'text-indigo-700');
370
+ dashboardBtn.classList.add('hover:bg-gray-100', 'text-gray-700');
371
+
372
+ registerBtn.classList.add('bg-indigo-50', 'text-indigo-700');
373
+ registerBtn.classList.remove('hover:bg-gray-100', 'text-gray-700');
374
+
375
+ databaseBtn.classList.remove('bg-indigo-50', 'text-indigo-700');
376
+ databaseBtn.classList.add('hover:bg-gray-100', 'text-gray-700');
377
+
378
+ pageTitle.textContent = 'Registrar Usuario';
379
+
380
+ // Close mobile menu if open
381
+ sidebar.classList.remove('open');
382
+
383
+ // Reset form
384
+ userForm.reset();
385
+ }
386
+
387
+ function showDatabase() {
388
+ dashboardContent.classList.add('hidden');
389
+ registerContent.classList.add('hidden');
390
+ databaseContent.classList.remove('hidden');
391
+
392
+ // Update active button in sidebar
393
+ dashboardBtn.classList.remove('bg-indigo-50', 'text-indigo-700');
394
+ dashboardBtn.classList.add('hover:bg-gray-100', 'text-gray-700');
395
+
396
+ registerBtn.classList.remove('bg-indigo-50', 'text-indigo-700');
397
+ registerBtn.classList.add('hover:bg-gray-100', 'text-gray-700');
398
+
399
+ databaseBtn.classList.add('bg-indigo-50', 'text-indigo-700');
400
+ databaseBtn.classList.remove('hover:bg-gray-100', 'text-gray-700');
401
+
402
+ pageTitle.textContent = 'Base de Datos';
403
+
404
+ // Close mobile menu if open
405
+ sidebar.classList.remove('open');
406
+
407
+ // Render users table
408
+ currentPage = 1;
409
+ renderUsersTable();
410
+ }
411
+
412
+ function registerUser(e) {
413
+ e.preventDefault();
414
+
415
+ const firstName = document.getElementById('firstName').value;
416
+ const lastName = document.getElementById('lastName').value;
417
+ const age = document.getElementById('age').value;
418
+ const email = document.getElementById('email').value;
419
+
420
+ const newUser = {
421
+ id: Date.now(),
422
+ firstName,
423
+ lastName,
424
+ age,
425
+ email,
426
+ registrationDate: new Date().toLocaleDateString('es-ES')
427
+ };
428
+
429
+ usersDB.push(newUser);
430
+ localStorage.setItem('usersDB', JSON.stringify(usersDB));
431
+
432
+ // Show success toast
433
+ showToast('Usuario registrado exitosamente!');
434
+
435
+ // Reset form
436
+ userForm.reset();
437
+
438
+ // Update dashboard counters
439
+ updateDashboardCounters();
440
+
441
+ // If on database view, refresh the table
442
+ if (!databaseContent.classList.contains('hidden')) {
443
+ currentPage = 1;
444
+ renderUsersTable();
445
+ }
446
+ }
447
+
448
+ function renderUsersTable(filteredUsers = null) {
449
+ const usersToDisplay = filteredUsers || usersDB;
450
+ const startIndex = (currentPage - 1) * usersPerPage;
451
+ const endIndex = Math.min(startIndex + usersPerPage, usersToDisplay.length);
452
+ const paginatedUsers = usersToDisplay.slice(startIndex, endIndex);
453
+
454
+ // Clear table
455
+ usersTableBody.innerHTML = '';
456
+
457
+ if (paginatedUsers.length === 0) {
458
+ const row = document.createElement('tr');
459
+ row.innerHTML = `
460
+ <td colspan="6" class="px-6 py-4 text-center text-gray-500">No se encontraron usuarios</td>
461
+ `;
462
+ usersTableBody.appendChild(row);
463
+ } else {
464
+ paginatedUsers.forEach(user => {
465
+ const row = document.createElement('tr');
466
+ row.className = 'hover:bg-gray-50';
467
+ row.innerHTML = `
468
+ <td class="px-6 py-4 whitespace-nowrap">${user.firstName}</td>
469
+ <td class="px-6 py-4 whitespace-nowrap">${user.lastName}</td>
470
+ <td class="px-6 py-4 whitespace-nowrap">${user.age}</td>
471
+ <td class="px-6 py-4 whitespace-nowrap">${user.email}</td>
472
+ <td class="px-6 py-4 whitespace-nowrap">${user.registrationDate}</td>
473
+ <td class="px-6 py-4 whitespace-nowrap">
474
+ <button onclick="deleteUser(${user.id})" class="text-red-500 hover:text-red-700">
475
+ <i class="fas fa-trash-alt"></i>
476
+ </button>
477
+ </td>
478
+ `;
479
+ usersTableBody.appendChild(row);
480
+ });
481
+ }
482
+
483
+ // Update pagination info
484
+ showingFrom.textContent = usersToDisplay.length > 0 ? startIndex + 1 : 0;
485
+ showingTo.textContent = endIndex;
486
+ totalRecords.textContent = usersToDisplay.length;
487
+
488
+ // Update pagination buttons
489
+ prevPage.disabled = currentPage === 1;
490
+ nextPage.disabled = endIndex >= usersToDisplay.length;
491
+
492
+ if (prevPage.disabled) {
493
+ prevPage.classList.add('bg-gray-100', 'cursor-not-allowed');
494
+ prevPage.classList.remove('bg-white', 'hover:bg-gray-50', 'cursor-pointer');
495
+ } else {
496
+ prevPage.classList.remove('bg-gray-100', 'cursor-not-allowed');
497
+ prevPage.classList.add('bg-white', 'hover:bg-gray-50', 'cursor-pointer');
498
+ }
499
+
500
+ if (nextPage.disabled) {
501
+ nextPage.classList.add('bg-gray-100', 'cursor-not-allowed');
502
+ nextPage.classList.remove('bg-white', 'hover:bg-gray-50', 'cursor-pointer');
503
+ } else {
504
+ nextPage.classList.remove('bg-gray-100', 'cursor-not-allowed');
505
+ nextPage.classList.add('bg-white', 'hover:bg-gray-50', 'cursor-pointer');
506
+ }
507
+ }
508
+
509
+ function filterUsers() {
510
+ const searchTerm = searchInput.value.toLowerCase();
511
+
512
+ if (searchTerm === '') {
513
+ renderUsersTable();
514
+ return;
515
+ }
516
+
517
+ const filteredUsers = usersDB.filter(user =>
518
+ user.firstName.toLowerCase().includes(searchTerm) ||
519
+ user.lastName.toLowerCase().includes(searchTerm) ||
520
+ user.email.toLowerCase().includes(searchTerm) ||
521
+ user.age.toString().includes(searchTerm)
522
+ );
523
+
524
+ currentPage = 1;
525
+ renderUsersTable(filteredUsers);
526
+ }
527
+
528
+ function deleteUser(userId) {
529
+ if (confirm('¿Estás seguro de que deseas eliminar este usuario?')) {
530
+ usersDB = usersDB.filter(user => user.id !== userId);
531
+ localStorage.setItem('usersDB', JSON.stringify(usersDB));
532
+
533
+ // Update dashboard counters
534
+ updateDashboardCounters();
535
+
536
+ // Re-render table
537
+ renderUsersTable();
538
+
539
+ // Show toast
540
+ showToast('Usuario eliminado correctamente');
541
+ }
542
+ }
543
+
544
+ function updateDashboardCounters() {
545
+ totalUsers.textContent = usersDB.length;
546
+
547
+ const today = new Date().toLocaleDateString('es-ES');
548
+ const todayRegistrations = usersDB.filter(user => user.registrationDate === today).length;
549
+ todayUsers.textContent = todayRegistrations;
550
+ }
551
+
552
+ function showToast(message) {
553
+ toastMessage.textContent = message;
554
+ toast.classList.remove('hidden');
555
+
556
+ setTimeout(() => {
557
+ toast.classList.add('hidden');
558
+ }, 3000);
559
+ }
560
+
561
+ // Close sidebar when clicking outside on mobile
562
+ document.addEventListener('click', (e) => {
563
+ if (window.innerWidth <= 768 && !sidebar.contains(e.target) && e.target !== menuBtn) {
564
+ sidebar.classList.remove('open');
565
+ }
566
+ });
567
+ </script>
568
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=styvencm/base-de-datos" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
569
+ </html>