ernestmindres commited on
Commit
e3d0908
·
verified ·
1 Parent(s): 1a0d9fd

Update templates/api_logs.html

Browse files
Files changed (1) hide show
  1. templates/api_logs.html +321 -281
templates/api_logs.html CHANGED
@@ -1,282 +1,322 @@
1
- <!DOCTYPE html>
2
- <html lang="fr" class="dark">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Logs API - Nexus Pro</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <link rel="stylesheet"
9
- href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,0,0" />
10
- <style>
11
- body {
12
- font-family: 'Inter', sans-serif;
13
- /* Appliquer les variables de thème */
14
- background-color: var(--bg-color);
15
- color: var(--text-color-primary); /* Utilisation de la variable primaire pour le texte du body */
16
- transition: background-color 0.3s, color 0.3s; /* Transition pour un effet doux */
17
- }
18
-
19
- /* Étape 2 : Définir les Styles (CSS) - Variables de Thème */
20
- /* Mode Sombre (par défaut - noir très foncé) */
21
- :root, .dark {
22
- --bg-color: #0A0A0A; /* Noir très foncé (pour body, header, footer) */
23
- --bg-card: #1C1C1C; /* Fond des cartes/panneaux */
24
- --text-color-primary: #E3E3E3; /* Texte principal (ancien text-white) */
25
- --text-color-secondary: #A0A0A0; /* Texte secondaire (pour gray-400/500) */
26
- --primary-color: #3B82F6; /* blue-500 par défaut */
27
- --border-color: #4B5563; /* gray-600 */
28
- --border-card-divide: #374151; /* gray-700 pour les séparations dans les cartes */
29
- }
30
-
31
- /* Mode Clair */
32
- html.light {
33
- --bg-color: #F8F8F8;
34
- --bg-card: #FFFFFF;
35
- --text-color-primary: #1F2937; /* Texte principal (gray-800) */
36
- --text-color-secondary: #6B7280; /* Texte secondaire (gray-500) */
37
- --primary-color: #1D4ED8; /* blue-700 */
38
- --border-color: #D1D5DB; /* gray-300 */
39
- --border-card-divide: #E5E7EB; /* gray-200 pour les séparations dans les cartes */
40
- }
41
-
42
- /* Mappage des classes Tailwind aux variables de thème pour le mode sombre/clair */
43
- /* Modification pour que le header et les footers utilisent --bg-color */
44
- .bg-gray-900 { background-color: var(--bg-color); }
45
- /* Modification pour que les cartes et le panneau de logs utilisent --bg-card */
46
- .bg-gray-800 { background-color: var(--bg-card); }
47
-
48
- /* Mappage des couleurs de texte pour le mode sombre/clair */
49
- .text-white { color: var(--text-color-primary); }
50
- /* Pour les textes dans les cartes et le footer qui utilisaient des nuances de gris */
51
- .text-gray-300 { color: var(--text-color-primary); }
52
- .text-gray-400 { color: var(--text-color-secondary); }
53
- .text-gray-500 { color: var(--text-color-secondary); opacity: 0.9; } /* Ajustement léger pour les nuances */
54
-
55
- .border-blue-500\/50 { border-color: var(--primary-color); }
56
- .text-blue-500 { color: var(--primary-color); }
57
- .hover\:text-blue-300:hover { color: var(--primary-color); }
58
- .border-l-4 { border-color: var(--primary-color); }
59
- .border-t-2 { border-color: var(--primary-color); } /* Ajustement pour un meilleur contraste en mode clair */
60
- .border-b { border-color: var(--border-color); }
61
- .divide-y { border-color: var(--border-color); }
62
- /* Pour les séparateurs dans la table des logs */
63
- .border-gray-700 { border-color: var(--border-card-divide); }
64
- .divide-gray-700 { border-color: var(--border-card-divide); }
65
- .border-gray-800 { border-color: var(--border-card-divide); } /* Utilisé dans le footer */
66
-
67
-
68
- /* Classe pour la barre de navigation fixe (stable) */
69
- .header-fixed {
70
- position: fixed;
71
- top: 0;
72
- left: 0;
73
- right: 0;
74
- z-index: 50;
75
- /* Suppression des marges pour un aspect moins haut, tout en restant responsive */
76
- padding-top: 1rem;
77
- padding-bottom: 1rem;
78
- }
79
-
80
- </style>
81
- </head>
82
- <body class="min-h-screen pt-20"> <div class="container mx-auto p-4 sm:p-6 lg:p-8">
83
-
84
- <header class="header-fixed bg-gray-900 text-white flex flex-col sm:flex-row justify-between items-center px-4 sm:px-6 lg:px-8 border-b border-blue-500/50">
85
- <h1 class="text-4xl font-extrabold text-blue-500 tracking-wider mb-4 sm:mb-0">
86
- Historique des Logs API
87
- </h1>
88
- <nav class="flex items-center space-x-4">
89
- <button id="theme-toggle" class="theme-switch" aria-label="Basculer le thème">
90
- <span class="material-symbols-rounded">light_mode</span>
91
- </button>
92
- <a href="/dashboard" class="px-4 py-2 text-white hover:text-blue-300 transition duration-200 font-medium">
93
- Dashboard
94
- </a>
95
- <a href="/profile" class="px-4 py-2 text-white hover:text-blue-300 transition duration-200 font-medium">
96
- Profil
97
- </a>
98
- <button id="logout-button" class="px-4 py-2 bg-red-600 hover:bg-red-700 transition duration-200 font-medium shadow-md">
99
- Déconnexion
100
- </button>
101
- </nav>
102
- </header>
103
-
104
- <main class="space-y-8 mt-4">
105
-
106
- <div class="p-6 bg-gray-800 shadow-2xl border-l-4 border-blue-500">
107
- <h2 class="text-3xl font-bold text-blue-500 mb-2">Statistiques d'Utilisation</h2>
108
- <p class="text-lg text-gray-300">
109
- ID Utilisateur Connecté: <strong class="text-white">{{ user_id }}</strong>
110
- </p>
111
- </div>
112
-
113
- <div class="grid grid-cols-1 sm:grid-cols-3 gap-6">
114
- <div class="p-5 bg-gray-800 shadow-xl border-t-2 border-green-500 text-center">
115
- <p class="text-4xl font-bold text-green-400" id="requestsCount">--</p>
116
- <p class="text-gray-400 mt-1">Requêtes (30 jours)</p>
117
- </div>
118
- <div class="p-5 bg-gray-800 shadow-xl border-t-2 border-yellow-500 text-center">
119
- <p class="text-4xl font-bold text-yellow-400" id="errorsCount">--</p>
120
- <p class="text-gray-400 mt-1">Erreurs 5xx (30 jours)</p>
121
- </div>
122
- <div class="p-5 bg-gray-800 shadow-xl border-t-2 border-purple-500 text-center">
123
- <p class="text-4xl font-bold text-purple-400" id="lastActivity">--</p>
124
- <p class="text-gray-400 mt-1">Dernière Activité</p>
125
- </div>
126
- </div>
127
-
128
- <div class="bg-gray-800 shadow-xl overflow-x-auto">
129
- <h3 class="text-2xl font-semibold text-white p-6 border-b border-gray-700">Logs Récents</h3>
130
- <table class="min-w-full divide-y divide-gray-700">
131
- <thead>
132
- <tr>
133
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Date/Heure</th>
134
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Méthode</th>
135
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Endpoint</th>
136
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Statut</th>
137
- </tr>
138
- </thead>
139
- <tbody class="divide-y divide-gray-700" id="logsTableBody">
140
- <tr class="text-gray-300">
141
- <td class="px-6 py-4 whitespace-nowrap text-sm">2024-10-14 10:30:00</td>
142
- <td class="px-6 py-4 whitespace-nowrap text-sm"><span class="bg-green-600/20 text-green-400 px-2 py-0.5 text-xs font-semibold">GET</span></td>
143
- <td class="px-6 py-4 whitespace-nowrap text-sm">/api/data/fetch</td>
144
- <td class="px-6 py-4 whitespace-nowrap text-sm"><span class="bg-green-600/20 text-green-400 px-2 py-0.5 text-xs font-semibold">200</span></td>
145
- </tr>
146
- <tr class="text-gray-300">
147
- <td class="px-6 py-4 whitespace-nowrap text-sm">2024-10-14 10:29:55</td>
148
- <td class="px-6 py-4 whitespace-nowrap text-sm"><span class="bg-red-600/20 text-red-400 px-2 py-0.5 text-xs font-semibold">POST</span></td>
149
- <td class="px-6 py-4 whitespace-nowrap text-sm">/api/user/update</td>
150
- <td class="px-6 py-4 whitespace-nowrap text-sm"><span class="bg-red-600/20 text-red-400 px-2 py-0.5 text-xs font-semibold">401</span></td>
151
- </tr>
152
- <tr class="text-gray-300">
153
- <td class="px-6 py-4 whitespace-nowrap text-sm">2024-10-14 10:29:01</td>
154
- <td class="px-6 py-4 whitespace-nowrap text-sm"><span class="bg-green-600/20 text-green-400 px-2 py-0.5 text-xs font-semibold">GET</span></td>
155
- <td class="px-6 py-4 whitespace-nowrap text-sm">/api/status</td>
156
- <td class="px-6 py-4 whitespace-nowrap text-sm"><span class="bg-green-600/20 text-green-400 px-2 py-0.5 text-xs font-semibold">200</span></td>
157
- </tr>
158
- </tbody>
159
- </table>
160
- </div>
161
-
162
- <p class="text-sm text-gray-500 text-center">
163
- *Ceci est un exemple. L'intégration finale nécessitera un appel à l'API Nexus (`GET /api/logs/{{ user_id }}`).
164
- </p>
165
-
166
- </main>
167
-
168
- <footer class="mt-12 pt-6 border-t border-gray-700 text-center text-gray-500 text-sm">
169
- &copy; 2024 Nexus. Tous droits réservés. | Espace Sécurisé
170
- </footer>
171
- </div>
172
-
173
- <script>
174
- document.getElementById('logout-button').addEventListener('click', async () => {
175
- const response = await fetch('/logout', { method: 'POST' });
176
- const data = await response.json();
177
- if (data.status === 'Success' && data.redirect) {
178
- window.location.href = data.redirect;
179
- } else {
180
- console.error("Erreur lors de la déconnexion.");
181
- }
182
- });
183
-
184
- // Simuler le chargement des statistiques
185
- document.addEventListener('DOMContentLoaded', () => {
186
- document.getElementById('requestsCount').textContent = '1248';
187
- document.getElementById('errorsCount').textContent = '12';
188
- document.getElementById('lastActivity').textContent = 'Il y a 5 min';
189
- });
190
-
191
- /* Logique de bascule du mode sombre/clair */
192
- const themeToggle = document.getElementById('theme-toggle');
193
- const htmlElement = document.documentElement;
194
- const iconElement = themeToggle.querySelector('.material-symbols-rounded');
195
-
196
- // Charger le thème depuis le localStorage
197
- const savedTheme = localStorage.getItem('theme');
198
-
199
- // Si le thème est sauvegardé, l'appliquer. Sinon, laisser le thème sombre par défaut.
200
- if (savedTheme === 'light') {
201
- htmlElement.classList.add('light');
202
- htmlElement.classList.remove('dark');
203
- iconElement.textContent = 'dark_mode';
204
- } else {
205
- // S'assurer que le mode sombre est appliqué si non light
206
- htmlElement.classList.add('dark');
207
- htmlElement.classList.remove('light');
208
- iconElement.textContent = 'light_mode';
209
- }
210
-
211
- themeToggle.addEventListener('click', () => {
212
- if (htmlElement.classList.contains('light')) {
213
- htmlElement.classList.remove('light');
214
- htmlElement.classList.add('dark');
215
- localStorage.setItem('theme', 'dark');
216
- iconElement.textContent = 'light_mode';
217
- } else {
218
- htmlElement.classList.add('light');
219
- htmlElement.classList.remove('dark');
220
- localStorage.setItem('theme', 'light');
221
- iconElement.textContent = 'dark_mode';
222
- }
223
- });
224
- /* Fin Logique Mode Sombre/Clair */
225
-
226
- </script>
227
-
228
- <footer class="mt-16 border-t border-gray-700 bg-gray-900">
229
- <div class="container mx-auto p-4 sm:p-6 lg:p-8 max-w-7xl">
230
- <div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-8 text-sm">
231
-
232
- <div class="col-span-2 lg:col-span-1">
233
- <a href="/" class="text-3xl font-extrabold text-blue-500 tracking-wider">NEXUS</a>
234
- <p class="mt-3 text-gray-400">
235
- L'infrastructure API qui propulse votre avenir technologique.
236
- </p>
237
- <div class="mt-4 flex space-x-4">
238
- <a href="#" class="text-gray-400 hover:text-blue-500 transition duration-200">
239
- <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.014 4.85.07c3.275.146 4.47 1.583 4.61 4.85.056 1.266.07 1.646.07 4.85s-.014 3.584-.07 4.85c-.14 3.267-1.335 4.704-4.61 4.85-1.266.056-1.646.07-4.85.07s-3.584-.014-4.85-.07c-3.275-.146-4.47-1.583-4.61-4.85-.056-1.266-.07-1.646-.07-4.85s.014-3.584.07-4.85c.14-3.267 1.335-4.704 4.61-4.85 1.266-.056 1.646-.07 4.85-.07zM12 0c-3.784 0-4.285.016-5.773.083-4.722.211-6.755 2.24-6.965 6.965C.016 7.715 0 8.216 0 12s.016 4.285.083 5.773c.21 4.721 2.239 6.755 6.965 6.965 1.488.067 1.99.083 5.773.083s4.285-.016 5.773-.083c4.721-.21 6.755-2.239 6.965-6.965.067-1.488.083-1.99.083-5.773s-.016-4.285-.083-5.773c-.21-4.722-2.239-6.755-6.965-6.965C16.285.016 15.784 0 12 0zm0 14.5c-1.381 0-2.5-1.119-2.5-2.5s1.119-2.5 2.5-2.5 2.5 1.119 2.5 2.5-1.119 2.5-2.5 2.5z"/></svg>
240
- </a>
241
- </div>
242
- </div>
243
-
244
- <div>
245
- <h3 class="text-lg font-semibold text-white mb-4">Plateforme</h3>
246
- <ul class="space-y-3 text-gray-400">
247
- <li><a href="/tarifs" class="hover:text-blue-500 transition duration-200">Tarifs</a></li>
248
- <li><a href="/documentation" class="hover:text-blue-500 transition duration-200">Documentation</a></li>
249
- <li><a href="/connexion" class="hover:text-blue-500 transition duration-200">Connexion</a></li>
250
- <li><a href="/support" class="hover:text-blue-500 transition duration-200">Support</a></li>
251
- </ul>
252
- </div>
253
-
254
- <div>
255
- <h3 class="text-lg font-semibold text-white mb-4">Légal</h3>
256
- <ul class="space-y-3 text-gray-400">
257
- <li><a href="/politique-confidentialite" class="hover:text-blue-500 transition duration-200">Politique de Confidentialité</a></li>
258
- <li><a href="/mentions-legales" class="hover:text-blue-500 transition duration-200">Mentions Légales</a></li>
259
- <li><a href="/conditions-utilisation" class="hover:text-blue-500 transition duration-200">Conditions d'Utilisation</a></li>
260
- <li><a href="/a-propos" class="hover:text-blue-500 transition duration-200">À Propos</a></li>
261
- </ul>
262
- </div>
263
-
264
- <div class="col-span-2 md:col-span-1">
265
- <h3 class="text-lg font-semibold text-white mb-4">Ressources</h3>
266
- <ul class="space-y-3 text-gray-400">
267
- <li><a href="mailto:support@nexus.com" class="hover:text-blue-500 transition duration-200">Contact Email</a></li>
268
- <li><a href="/dashboard" class="hover:text-blue-500 transition duration-200">Espace Client</a></li>
269
- <li><a href="/api-logs" class="hover:text-blue-500 transition duration-200">Statut API</a></li>
270
- </ul>
271
- </div>
272
-
273
- </div>
274
-
275
- <div class="mt-10 pt-6 border-t border-gray-800 text-center text-gray-500 text-sm">
276
- &copy; 2025 Nexus. Tous droits réservés. Construit pour l'ère des microservices.
277
- </div>
278
- </div>
279
- </footer>
280
-
281
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="fr" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Nexus | Logs d'API - Pro</title>
7
+ <link rel="icon" type="image/png" href="https://i.imgur.com/7Gn3toV.png">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <link rel="stylesheet"
10
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,0,0" />
11
+ <style>
12
+ /* Configuration de la police Inter */
13
+ body { font-family: 'Inter', sans-serif; }
14
+
15
+ /* Définition des variables de thème (Ajoutées pour le style) */
16
+ :root {
17
+ /* Couleurs de base (exemple - ajustez si nécessaire) */
18
+ --page-var: #f8fafc; /* light - slate-50 */
19
+ --color-var: #0f172a; /* light - slate-900 */
20
+ --secondary-var: #64748b; /* light - slate-500 */
21
+ --card-var: #ffffff; /* light - white */
22
+ --sidebar-var: #e2e8f0; /* light - slate-200 */
23
+ --sidebar-active-var: #cbd5e1; /* light - slate-300 */
24
+ --input-var: #f1f5f9; /* light - slate-100 */
25
+ --primary-color-var: #4f46e5; /* indigo-600 */
26
+ --primary-hover-var: #4338ca; /* indigo-700 */
27
+ --error-var: #fef2f2; /* red-50 */
28
+ --success-var: #f0fdf4; /* green-50 */
29
+ --warning-var: #fcd34d; /* amber-400 */
30
+ }
31
+
32
+ .dark {
33
+ --page-var: #18181b; /* dark - zinc-900 (Gris très foncé pour l'arrière-plan de la page) */
34
+ --color-var: #f4f4f5; /* dark - zinc-100 (Texte clair) */
35
+ --secondary-var: #a1a1aa; /* dark - zinc-400 (Texte secondaire) */
36
+ --card-var: #27272a; /* dark - zinc-800 (Gris foncé pour les cartes et la sidebar) */
37
+ --sidebar-var: #27272a; /* dark - zinc-800 */
38
+ --sidebar-active-var: #3f3f46; /* dark - zinc-700 (Gris un peu plus clair pour l'actif) */
39
+ --input-var: #18181b; /* dark - zinc-900 (Fond de champ de saisie) */
40
+ --primary-color-var: #6366f1; /* indigo-500 (Couleur primaire inchangée) */
41
+ --primary-hover-var: #4f46e5; /* indigo-600 */
42
+ --error-var: #450a0a; /* red-950 */
43
+ --success-var: #052e16; /* green-950 */
44
+ --warning-var: #b45309; /* amber-800 */
45
+ }
46
+
47
+ /* Transition pour un effet doux des couleurs */
48
+ .transition-colors-theme { transition: background-color 0.3s, color 0.3s, border-color 0.3s; }
49
+
50
+ /* Style et positionnement du bouton de Thème */
51
+ .theme-switch {
52
+ background: none;
53
+ border: none;
54
+ cursor: pointer;
55
+ font-size: 24px;
56
+ transition: color 0.2s;
57
+ position: fixed; /* Reste fixe même si le reste défile */
58
+ top: 1rem;
59
+ right: 1rem;
60
+ z-index: 50; /* Doit être au-dessus du reste */
61
+ }
62
+
63
+ /* Style pour la sidebar responsive */
64
+ .sidebar {
65
+ position: fixed;
66
+ top: 0;
67
+ left: 0;
68
+ height: 100vh;
69
+ z-index: 40;
70
+ transform: translateX(-100%);
71
+ }
72
+
73
+ /* Styles pour le mode desktop/large screen */
74
+ @media (min-width: 1024px) {
75
+ .sidebar {
76
+ transform: translateX(0);
77
+ }
78
+ .main-content {
79
+ margin-left: 16rem; /* 64px width */
80
+ }
81
+ }
82
+
83
+ /* Styles pour le mode mobile/tablet */
84
+ @media (max-width: 1023px) {
85
+ .sidebar {
86
+ transition: transform 0.3s ease-in-out;
87
+ }
88
+ .sidebar.open {
89
+ transform: translateX(0);
90
+ }
91
+ }
92
+
93
+ /* Ajout des styles pour les variables CSS dans Tailwind */
94
+ .bg-page-var { background-color: var(--page-var); }
95
+ .text-color-var { color: var(--color-var); }
96
+ .text-secondary-var { color: var(--secondary-var); }
97
+ .bg-card-var { background-color: var(--card-var); }
98
+ .bg-sidebar-var { background-color: var(--sidebar-var); }
99
+ .border-sidebar-var { border-color: var(--sidebar-var); }
100
+ .bg-sidebar-active-var { background-color: var(--sidebar-active-var); }
101
+ .bg-input-var { background-color: var(--input-var); }
102
+ .border-input-var { border-color: var(--input-var); }
103
+ .text-primary-color-var { color: var(--primary-color-var); }
104
+ .focus\:ring-primary-color-var:focus { --tw-ring-color: var(--primary-color-var); }
105
+ .focus\:border-primary-color-var:focus { border-color: var(--primary-color-var); }
106
+ .bg-primary-color-var { background-color: var(--primary-color-var); }
107
+ .hover\:bg-primary-hover-var:hover { background-color: var(--primary-hover-var); }
108
+ .hover\:bg-sidebar-active-var:hover { background-color: var(--sidebar-active-var); }
109
+ .hover\:bg-sidebar-active-var\/80:hover { background-color: color-mix(in srgb, var(--sidebar-active-var) 80%, transparent); }
110
+
111
+ /* Correction pour les messages flash pour utiliser les variables */
112
+ .bg-red-900\/20 { background-color: color-mix(in srgb, var(--error-var) 20%, transparent); } /* Approximation des couleurs spécifiques */
113
+ .text-red-500 { color: #ef4444; } /* Laissez le rouge spécifique pour les erreurs */
114
+ .border-red-900 { border-color: #7f1d1d; } /* Laissez le rouge spécifique pour les erreurs */
115
+ .bg-green-900\/20 { background-color: color-mix(in srgb, var(--success-var) 20%, transparent); } /* Approximation des couleurs spécifiques */
116
+ .text-green-500 { color: #22c55e; } /* Laissez le vert spécifique pour le succès */
117
+ .border-green-900 { border-color: #064e3b; } /* Laissez le vert spécifique pour le succès */
118
+ .hover\:text-link-hover-var:hover { color: var(--secondary-var); } /* Ajout d'une pseudo-variable pour le hover de l'icône de thème (simple fallback) */
119
+
120
+ </style>
121
+ </head>
122
+
123
+ <body class="bg-page-var text-color-var min-h-screen transition-colors-theme">
124
+
125
+ <button id="theme-switch" class="theme-switch text-color-var hover:text-link-hover-var transition-colors-theme">
126
+ <span class="material-symbols-rounded">dark_mode</span>
127
+ </button>
128
+
129
+ <aside id="sidebar" class="sidebar w-64 bg-sidebar-var border-r border-sidebar-var p-6 lg:block transition-colors-theme">
130
+ <div class="flex items-center mb-10">
131
+ <img src="https://i.imgur.com/7Gn3toV.png" alt="Nexus Pro Logo" class="h-8">
132
+ <span class="text-xl font-bold text-color-var ml-2 transition-colors-theme">Nexus Pro</span>
133
+ </div>
134
+
135
+ <nav class="space-y-3">
136
+ <a href="{{ url_for('user_bp.dashboard') }}" class="flex items-center p-3 text-secondary-var hover:text-color-var hover:bg-sidebar-active-var rounded-lg transition duration-150 transition-colors-theme">
137
+ <span class="material-symbols-rounded">dashboard</span>
138
+ <span class="ml-3">Dashboard</span>
139
+ </a>
140
+ <a href="{{ url_for('user_bp.api_key') }}" class="flex items-center p-3 text-secondary-var hover:text-color-var hover:bg-sidebar-active-var rounded-lg transition duration-150 transition-colors-theme">
141
+ <span class="material-symbols-rounded">key</span>
142
+ <span class="ml-3">Clés API</span>
143
+ </a>
144
+ <a href="{{ url_for('user_bp.profile') }}" class="flex items-center p-3 text-secondary-var hover:text-color-var hover:bg-sidebar-active-var rounded-lg transition duration-150 transition-colors-theme">
145
+ <span class="material-symbols-rounded">person</span>
146
+ <span class="ml-3">Profil</span>
147
+ </a>
148
+ <a href="/api_logs" class="flex items-center p-3 bg-sidebar-active-var text-color-var rounded-lg transition duration-150 transition-colors-theme">
149
+ <span class="material-symbols-rounded">list_alt</span>
150
+ <span class="ml-3">Logs d'API</span>
151
+ </a>
152
+ <a href="/tarifs" class="flex items-center p-3 text-secondary-var hover:text-color-var hover:bg-sidebar-active-var rounded-lg transition duration-150 transition-colors-theme">
153
+ <span class="material-symbols-rounded">payments</span>
154
+ <span class="ml-3">Tarifs</span>
155
+ </a>
156
+ <a href="/statut" class="flex items-center p-3 text-secondary-var hover:text-color-var hover:bg-sidebar-active-var rounded-lg transition duration-150 transition-colors-theme">
157
+ <span class="material-symbols-rounded">monitor_heart</span>
158
+ <span class="ml-3">Statut de l'API</span>
159
+ </a>
160
+ <a href="{{ url_for('user_bp.deconnexion') }}" id="logout-button-sidebar" class="flex items-center p-3 text-red-500 hover:text-red-400 hover:bg-sidebar-active-var rounded-lg transition duration-150 transition-colors-theme">
161
+ <span class="material-symbols-rounded">logout</span>
162
+ <span class="ml-3">Déconnexion</span>
163
+ </a>
164
+ </nav>
165
+
166
+ <div class="absolute bottom-6 w-52 text-xs text-secondary-var transition-colors-theme">
167
+ <p>Connecté en tant que: <span class="font-semibold text-color-var transition-colors-theme">{{ user.email if user and user.email else 'Chargement...' }}</span></p>
168
+ <p>Plan: <span class="font-semibold text-color-var transition-colors-theme">{{ (user.plan | upper) if user and user.plan else 'GRATUIT' }}</span></p>
169
+ </div>
170
+
171
+ </aside>
172
+
173
+ <div id="main-content" class="main-content p-8 transition-colors-theme">
174
+
175
+ <header class="lg:hidden flex justify-between items-center mb-8">
176
+ <div class="flex items-center">
177
+ <img src="https://i.imgur.com/7Gn3toV.png" alt="Nexus Pro Logo" class="h-8">
178
+ <span class="text-xl font-bold text-color-var ml-2 transition-colors-theme">Nexus Pro</span>
179
+ </div>
180
+ <button id="sidebar-toggle" class="p-2 rounded-lg bg-sidebar-active-var hover:bg-sidebar-active-var/80 transition-colors-theme">
181
+ <span class="material-symbols-rounded text-color-var">menu</span>
182
+ </button>
183
+ </header>
184
+
185
+ <h1 class="text-3xl font-bold mb-8 text-color-var transition-colors-theme">Logs d'API Utilisateur</h1>
186
+
187
+ {% with messages = get_flashed_messages(with_categories=true) %}
188
+ {% if messages %}
189
+ {% for category, message in messages %}
190
+ <div class="p-4 mb-4 text-sm rounded-lg border border-transparent
191
+ {{ 'bg-red-900/20 text-red-500 border-red-900' if category == 'error' or category == 'danger' or category == 'warning' else 'bg-green-900/20 text-green-500 border-green-900' }}" role="alert">
192
+ {{ message }}
193
+ </div>
194
+ {% endfor %}
195
+ {% endif %}
196
+ {% endwith %}
197
+
198
+ <div class="bg-card-var p-6 rounded-lg shadow-xl border border-sidebar-var transition-colors-theme mb-8">
199
+ <h2 class="text-xl font-semibold mb-4 flex items-center text-color-var transition-colors-theme">
200
+ <span class="material-symbols-rounded mr-2">history</span>
201
+ Historique des Requêtes API
202
+ </h2>
203
+ <p class="text-secondary-var mb-6 text-sm transition-colors-theme">Retrouvez ici les 100 dernières requêtes effectuées sur l'API Nexus.</p>
204
+
205
+ <div class="overflow-x-auto">
206
+ <table class="min-w-full divide-y divide-sidebar-active-var transition-colors-theme">
207
+ <thead>
208
+ <tr class="text-left text-sm font-semibold text-secondary-var uppercase tracking-wider bg-input-var transition-colors-theme">
209
+ <th class="px-4 py-3">Date</th>
210
+ <th class="px-4 py-3">Endpoint</th>
211
+ <th class="px-4 py-3">Méthode</th>
212
+ <th class="px-4 py-3">Statut</th>
213
+ <th class="px-4 py-3">Temps (ms)</th>
214
+ </tr>
215
+ </thead>
216
+ <tbody class="divide-y divide-sidebar-active-var transition-colors-theme text-sm">
217
+ {% if api_logs and api_logs|length > 0 %}
218
+ {% for log in api_logs %}
219
+ <tr class="text-color-var hover:bg-sidebar-active-var/80 transition-colors-theme">
220
+ <td class="px-4 py-3 whitespace-nowrap">{{ log.timestamp }}</td>
221
+ <td class="px-4 py-3 whitespace-nowrap">{{ log.endpoint }}</td>
222
+ <td class="px-4 py-3 whitespace-nowrap">{{ log.method }}</td>
223
+ <td class="px-4 py-3 whitespace-nowrap">
224
+ {% if log.status_code >= 200 and log.status_code < 300 %}
225
+ <span class="text-green-500 font-medium">Succès ({{ log.status_code }})</span>
226
+ {% elif log.status_code >= 400 and log.status_code < 500 %}
227
+ <span class="text-red-500 font-medium">Erreur Client ({{ log.status_code }})</span>
228
+ {% elif log.status_code >= 500 %}
229
+ <span class="text-red-500 font-medium">Erreur Serveur ({{ log.status_code }})</span>
230
+ {% else %}
231
+ <span class="text-secondary-var">{{ log.status_code }}</span>
232
+ {% endif %}
233
+ </td>
234
+ <td class="px-4 py-3 whitespace-nowrap">{{ log.response_time_ms }}</td>
235
+ </tr>
236
+ {% endfor %}
237
+ {% else %}
238
+ <tr class="text-secondary-var">
239
+ <td colspan="5" class="px-4 py-6 text-center">Aucun log d'API trouvé pour le moment.</td>
240
+ </tr>
241
+ {% endif %}
242
+ </tbody>
243
+ </table>
244
+ </div>
245
+
246
+ </div>
247
+
248
+ </div>
249
+
250
+ <script>
251
+
252
+ // Fonction utilitaire pour appliquer le thème
253
+ function applyTheme(theme) {
254
+ if (theme === 'dark') {
255
+ document.documentElement.classList.add('dark');
256
+ localStorage.setItem('theme', 'dark');
257
+ } else {
258
+ document.documentElement.classList.remove('dark');
259
+ localStorage.setItem('theme', 'light');
260
+ }
261
+ // Mettre à jour l'icône du switch si nécessaire
262
+ const icon = document.querySelector('#theme-switch .material-symbols-rounded');
263
+ if (icon) {
264
+ // S'assurer que l'icône reflète le mode ACTIF
265
+ icon.textContent = theme === 'dark' ? 'light_mode' : 'dark_mode';
266
+ }
267
+ }
268
+
269
+ // 1. Initialisation du thème au chargement
270
+ // Récupérer le thème sauvé ou utiliser 'dark' comme défaut
271
+ const savedTheme = localStorage.getItem('theme') || 'dark';
272
+ applyTheme(savedTheme);
273
+
274
+ // 2. Logique du switch de thème
275
+ document.getElementById('theme-switch').addEventListener('click', () => {
276
+ // Vérifier si la classe 'dark' est présente sur l'élément racine
277
+ const currentTheme = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
278
+ const newTheme = currentTheme === 'light' ? 'dark' : 'light';
279
+ applyTheme(newTheme);
280
+ });
281
+
282
+ // 3. Logique de bascule de la sidebar pour mobile/tablette
283
+ const sidebarToggle = document.getElementById('sidebar-toggle');
284
+ const sidebar = document.getElementById('sidebar');
285
+
286
+ if (sidebarToggle && sidebar) {
287
+ sidebarToggle.addEventListener('click', () => {
288
+ sidebar.classList.toggle('open');
289
+ });
290
+ }
291
+
292
+ // 4. Fermeture de la sidebar lors du clic sur un lien (pour mobile)
293
+ // Note: Assurez-vous que 'sidebar' est défini avant d'appeler querySelectorAll
294
+ if (sidebar) {
295
+ const sidebarLinks = sidebar.querySelectorAll('a');
296
+ if (sidebarLinks) {
297
+ sidebarLinks.forEach(link => {
298
+ link.addEventListener('click', () => {
299
+ // Fermer la sidebar uniquement sur les petits écrans
300
+ if (window.innerWidth < 1024) {
301
+ sidebar.classList.remove('open');
302
+ }
303
+ });
304
+ });
305
+ }
306
+ }
307
+
308
+ // 5. Logique de Déconnexion (Conservée)
309
+ const logoutHandler = async (e) => {
310
+ e.preventDefault();
311
+ // La déconnexion est gérée par la route Flask directe
312
+ window.location.href = document.getElementById('logout-button-sidebar').href;
313
+ };
314
+ // On attache l'événement à la déconnexion dans la sidebar.
315
+ const logoutButtonSidebar = document.getElementById('logout-button-sidebar');
316
+ if (logoutButtonSidebar) {
317
+ logoutButtonSidebar.addEventListener('click', logoutHandler);
318
+ }
319
+
320
+ </script>
321
+ </body>
322
  </html>