Docfile commited on
Commit
57e5ab1
·
verified ·
1 Parent(s): 2ac7a3f

Create templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +254 -0
templates/index.html ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Outil de Résumé AI</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <style>
9
+ .fade-in { animation: fadeIn 0.5s; }
10
+ @keyframes fadeIn {
11
+ from { opacity: 0; transform: translateY(10px); }
12
+ to { opacity: 1; transform: translateY(0); }
13
+ }
14
+ </style>
15
+ </head>
16
+ <body class="bg-gradient-to-br from-blue-50 to-indigo-100 min-h-screen">
17
+ <div class="container mx-auto px-4 py-8 max-w-6xl">
18
+ <!-- Header -->
19
+ <header class="text-center mb-12 fade-in">
20
+ <h1 class="text-5xl font-bold text-indigo-900 mb-3">📄 Résumeur AI</h1>
21
+ <p class="text-gray-600 text-lg">Générez des résumés intelligents de vos documents</p>
22
+ </header>
23
+
24
+ <!-- Main Content -->
25
+ <div class="grid md:grid-cols-3 gap-6">
26
+ <!-- Upload Section -->
27
+ <div class="md:col-span-2">
28
+ <div class="bg-white rounded-2xl shadow-xl p-8 fade-in">
29
+ <h2 class="text-2xl font-bold text-gray-800 mb-6">📤 Uploader un document</h2>
30
+
31
+ <form id="uploadForm" class="space-y-6">
32
+ <!-- File Upload -->
33
+ <div class="border-2 border-dashed border-indigo-300 rounded-lg p-8 text-center hover:border-indigo-500 transition-colors cursor-pointer bg-indigo-50/50">
34
+ <input type="file" id="fileInput" name="file" class="hidden" accept=".pdf,.mp3,.mp4,.wav,.txt,.doc,.docx">
35
+ <label for="fileInput" class="cursor-pointer">
36
+ <div class="text-4xl mb-3">📁</div>
37
+ <p class="text-gray-700 font-medium mb-2">Cliquez ou glissez votre fichier</p>
38
+ <p class="text-sm text-gray-500">PDF, Audio (MP3, WAV), Vidéo (MP4), Documents (TXT, DOC, DOCX)</p>
39
+ <p class="text-xs text-gray-400 mt-2">Taille max: 50MB</p>
40
+ </label>
41
+ </div>
42
+
43
+ <div id="fileName" class="hidden bg-indigo-100 rounded-lg p-4 text-indigo-800">
44
+ <span class="font-medium">Fichier sélectionné:</span>
45
+ <span id="fileNameText" class="ml-2"></span>
46
+ </div>
47
+
48
+ <!-- Summary Type -->
49
+ <div>
50
+ <label class="block text-gray-700 font-medium mb-3">Type de résumé</label>
51
+ <div class="grid grid-cols-3 gap-3">
52
+ <label class="cursor-pointer">
53
+ <input type="radio" name="summary_type" value="court" class="peer hidden">
54
+ <div class="border-2 border-gray-300 rounded-lg p-4 text-center peer-checked:border-indigo-500 peer-checked:bg-indigo-50 hover:border-indigo-300 transition-all">
55
+ <div class="text-2xl mb-2">⚡</div>
56
+ <div class="font-bold text-gray-800">Court</div>
57
+ <div class="text-xs text-gray-500 mt-1">2-3 paragraphes</div>
58
+ </div>
59
+ </label>
60
+ <label class="cursor-pointer">
61
+ <input type="radio" name="summary_type" value="moyen" class="peer hidden" checked>
62
+ <div class="border-2 border-gray-300 rounded-lg p-4 text-center peer-checked:border-indigo-500 peer-checked:bg-indigo-50 hover:border-indigo-300 transition-all">
63
+ <div class="text-2xl mb-2">📋</div>
64
+ <div class="font-bold text-gray-800">Moyen</div>
65
+ <div class="text-xs text-gray-500 mt-1">Détails structurés</div>
66
+ </div>
67
+ </label>
68
+ <label class="cursor-pointer">
69
+ <input type="radio" name="summary_type" value="detaille" class="peer hidden">
70
+ <div class="border-2 border-gray-300 rounded-lg p-4 text-center peer-checked:border-indigo-500 peer-checked:bg-indigo-50 hover:border-indigo-300 transition-all">
71
+ <div class="text-2xl mb-2">📖</div>
72
+ <div class="font-bold text-gray-800">Détaillé</div>
73
+ <div class="text-xs text-gray-500 mt-1">Analyse complète</div>
74
+ </div>
75
+ </label>
76
+ </div>
77
+ </div>
78
+
79
+ <!-- Submit Button -->
80
+ <button type="submit" id="submitBtn" class="w-full bg-indigo-600 text-white font-bold py-4 px-6 rounded-lg hover:bg-indigo-700 transition-colors shadow-lg hover:shadow-xl disabled:opacity-50 disabled:cursor-not-allowed">
81
+ Générer le résumé
82
+ </button>
83
+ </form>
84
+
85
+ <!-- Loading -->
86
+ <div id="loading" class="hidden mt-6 text-center">
87
+ <div class="inline-block animate-spin rounded-full h-12 w-12 border-4 border-indigo-600 border-t-transparent"></div>
88
+ <p class="text-gray-600 mt-3">Génération du résumé en cours...</p>
89
+ </div>
90
+
91
+ <!-- Result -->
92
+ <div id="result" class="hidden mt-6">
93
+ <div class="bg-green-50 border-l-4 border-green-500 p-6 rounded-lg">
94
+ <div class="flex justify-between items-start mb-4">
95
+ <h3 class="text-xl font-bold text-green-800">✅ Résumé généré</h3>
96
+ <button id="downloadBtn" class="bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 transition-colors text-sm font-medium">
97
+ 📥 Télécharger PDF
98
+ </button>
99
+ </div>
100
+ <div id="summaryContent" class="text-gray-700 prose max-w-none"></div>
101
+ </div>
102
+ </div>
103
+
104
+ <!-- Error -->
105
+ <div id="error" class="hidden mt-6 bg-red-50 border-l-4 border-red-500 p-6 rounded-lg">
106
+ <h3 class="text-xl font-bold text-red-800 mb-2">❌ Erreur</h3>
107
+ <p id="errorMessage" class="text-red-700"></p>
108
+ </div>
109
+ </div>
110
+ </div>
111
+
112
+ <!-- History Section -->
113
+ <div class="md:col-span-1">
114
+ <div class="bg-white rounded-2xl shadow-xl p-6 fade-in sticky top-8">
115
+ <div class="flex justify-between items-center mb-4">
116
+ <h2 class="text-xl font-bold text-gray-800">📚 Historique</h2>
117
+ <button id="clearHistory" class="text-red-600 hover:text-red-800 text-sm font-medium">
118
+ Effacer
119
+ </button>
120
+ </div>
121
+ <div id="historyList" class="space-y-3 max-h-[600px] overflow-y-auto">
122
+ <p class="text-gray-400 text-center py-8">Aucun résumé pour le moment</p>
123
+ </div>
124
+ </div>
125
+ </div>
126
+ </div>
127
+ </div>
128
+
129
+ <script>
130
+ let currentHistoryId = null;
131
+
132
+ // File input handling
133
+ const fileInput = document.getElementById('fileInput');
134
+ const fileName = document.getElementById('fileName');
135
+ const fileNameText = document.getElementById('fileNameText');
136
+
137
+ fileInput.addEventListener('change', (e) => {
138
+ if (e.target.files.length > 0) {
139
+ fileName.classList.remove('hidden');
140
+ fileNameText.textContent = e.target.files[0].name;
141
+ }
142
+ });
143
+
144
+ // Form submission
145
+ document.getElementById('uploadForm').addEventListener('submit', async (e) => {
146
+ e.preventDefault();
147
+
148
+ const formData = new FormData(e.target);
149
+ const submitBtn = document.getElementById('submitBtn');
150
+ const loading = document.getElementById('loading');
151
+ const result = document.getElementById('result');
152
+ const error = document.getElementById('error');
153
+
154
+ // Hide previous results
155
+ result.classList.add('hidden');
156
+ error.classList.add('hidden');
157
+
158
+ // Show loading
159
+ submitBtn.disabled = true;
160
+ loading.classList.remove('hidden');
161
+
162
+ try {
163
+ const response = await fetch('/upload', {
164
+ method: 'POST',
165
+ body: formData
166
+ });
167
+
168
+ const data = await response.json();
169
+
170
+ if (data.error) {
171
+ throw new Error(data.error);
172
+ }
173
+
174
+ // Show result
175
+ document.getElementById('summaryContent').innerHTML =
176
+ data.summary.replace(/\n/g, '<br>');
177
+ result.classList.remove('hidden');
178
+ currentHistoryId = data.history_id;
179
+
180
+ // Reload history
181
+ loadHistory();
182
+
183
+ } catch (err) {
184
+ document.getElementById('errorMessage').textContent = err.message;
185
+ error.classList.remove('hidden');
186
+ } finally {
187
+ loading.classList.add('hidden');
188
+ submitBtn.disabled = false;
189
+ }
190
+ });
191
+
192
+ // Download PDF
193
+ document.getElementById('downloadBtn').addEventListener('click', () => {
194
+ if (currentHistoryId !== null) {
195
+ window.location.href = `/download/${currentHistoryId}`;
196
+ }
197
+ });
198
+
199
+ // Load history
200
+ async function loadHistory() {
201
+ try {
202
+ const response = await fetch('/history');
203
+ const history = await response.json();
204
+ const historyList = document.getElementById('historyList');
205
+
206
+ if (history.length === 0) {
207
+ historyList.innerHTML = '<p class="text-gray-400 text-center py-8">Aucun résumé pour le moment</p>';
208
+ return;
209
+ }
210
+
211
+ historyList.innerHTML = history.map(item => `
212
+ <div class="border border-gray-200 rounded-lg p-3 hover:bg-gray-50 transition-colors cursor-pointer" onclick="viewSummary(${item.id})">
213
+ <div class="font-medium text-sm text-gray-800 truncate">${item.filename}</div>
214
+ <div class="flex justify-between items-center mt-2">
215
+ <span class="text-xs text-gray-500">${item.date}</span>
216
+ <span class="text-xs px-2 py-1 bg-indigo-100 text-indigo-700 rounded">${item.summary_type}</span>
217
+ </div>
218
+ </div>
219
+ `).reverse().join('');
220
+ } catch (err) {
221
+ console.error('Error loading history:', err);
222
+ }
223
+ }
224
+
225
+ // View summary from history
226
+ function viewSummary(id) {
227
+ fetch('/history')
228
+ .then(res => res.json())
229
+ .then(history => {
230
+ const item = history[id];
231
+ if (item) {
232
+ document.getElementById('summaryContent').innerHTML =
233
+ item.summary.replace(/\n/g, '<br>');
234
+ document.getElementById('result').classList.remove('hidden');
235
+ currentHistoryId = id;
236
+ window.scrollTo({ top: 0, behavior: 'smooth' });
237
+ }
238
+ });
239
+ }
240
+
241
+ // Clear history
242
+ document.getElementById('clearHistory').addEventListener('click', async () => {
243
+ if (confirm('Êtes-vous sûr de vouloir effacer tout l\'historique ?')) {
244
+ await fetch('/clear-history', { method: 'POST' });
245
+ loadHistory();
246
+ document.getElementById('result').classList.add('hidden');
247
+ }
248
+ });
249
+
250
+ // Load history on page load
251
+ loadHistory();
252
+ </script>
253
+ </body>
254
+ </html>