Dannylova31 commited on
Commit
e0488c3
·
verified ·
1 Parent(s): 6fd0f6f

Upload index.html

Browse files
Files changed (1) hide show
  1. index.html +606 -0
index.html ADDED
@@ -0,0 +1,606 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>NAWEL Translator PRO | Traduction Professionnelle</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
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
11
+
12
+ :root {
13
+ --primary: #2563eb;
14
+ --primary-dark: #1d4ed8;
15
+ --secondary: #7c3aed;
16
+ --accent: #f59e0b;
17
+ --dark: #1e293b;
18
+ --light: #f8fafc;
19
+ }
20
+
21
+ body {
22
+ font-family: 'Inter', sans-serif;
23
+ background-color: #f1f5f9;
24
+ color: var(--dark);
25
+ }
26
+
27
+ .gradient-bg {
28
+ background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
29
+ }
30
+
31
+ .file-dropzone {
32
+ border: 2px dashed #cbd5e1;
33
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
34
+ }
35
+
36
+ .file-dropzone.active {
37
+ border-color: var(--primary);
38
+ background-color: rgba(37, 99, 235, 0.05);
39
+ }
40
+
41
+ .language-flag {
42
+ width: 24px;
43
+ height: 16px;
44
+ display: inline-block;
45
+ background-size: cover;
46
+ border-radius: 2px;
47
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
48
+ }
49
+
50
+ .btn-primary {
51
+ background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
52
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
53
+ }
54
+
55
+ .btn-primary:hover {
56
+ transform: translateY(-1px);
57
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
58
+ background: linear-gradient(135deg, var(--primary-dark) 0%, #6d28d9 100%);
59
+ }
60
+
61
+ .toast {
62
+ animation: fadeIn 0.3s, fadeOut 0.3s 2.7s forwards;
63
+ }
64
+
65
+ @keyframes fadeIn {
66
+ from { opacity: 0; transform: translateY(20px); }
67
+ to { opacity: 1; transform: translateY(0); }
68
+ }
69
+
70
+ @keyframes fadeOut {
71
+ from { opacity: 1; transform: translateY(0); }
72
+ to { opacity: 0; transform: translateY(-20px); }
73
+ }
74
+
75
+ .text-editor {
76
+ min-height: 200px;
77
+ border: 1px solid #e2e8f0;
78
+ border-radius: 0.5rem;
79
+ padding: 1rem;
80
+ background: white;
81
+ }
82
+
83
+ .translation-result {
84
+ border-left: 1px solid #e2e8f0;
85
+ }
86
+
87
+ @media (max-width: 768px) {
88
+ .translation-result {
89
+ border-left: none;
90
+ border-top: 1px solid #e2e8f0;
91
+ margin-top: 1rem;
92
+ padding-top: 1rem;
93
+ }
94
+ }
95
+ </style>
96
+ </head>
97
+ <body class="min-h-screen">
98
+ <!-- Navigation -->
99
+ <nav class="bg-white shadow-sm">
100
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
101
+ <div class="flex justify-between h-16">
102
+ <div class="flex items-center">
103
+ <div class="flex-shrink-0 flex items-center">
104
+ <i class="fas fa-language text-2xl text-indigo-600 mr-2"></i>
105
+ <span class="text-xl font-bold text-gray-900">NAWEL Translator PRO</span>
106
+ </div>
107
+ </div>
108
+ <div class="hidden sm:ml-6 sm:flex sm:items-center">
109
+ <button class="btn-primary text-white font-medium py-2 px-6 rounded-full">
110
+ <i class="fas fa-user mr-2"></i> Mon compte
111
+ </button>
112
+ </div>
113
+ </div>
114
+ </div>
115
+ </nav>
116
+
117
+ <!-- Main Content -->
118
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
119
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
120
+ <!-- Text Input Section -->
121
+ <div class="bg-white rounded-xl shadow-lg p-6">
122
+ <div class="mb-6">
123
+ <h2 class="text-2xl font-bold text-gray-800 mb-2">Traducteur de texte</h2>
124
+ <p class="text-gray-500">Saisissez votre texte à traduire ou collez-le depuis n'importe quelle source</p>
125
+ </div>
126
+
127
+ <!-- Language Selection -->
128
+ <div class="grid grid-cols-2 gap-4 mb-6">
129
+ <div>
130
+ <label class="block text-sm font-medium text-gray-700 mb-1">Langue source</label>
131
+ <select id="textSourceLang" class="block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-lg">
132
+ <option value="auto">Détection automatique</option>
133
+ <option value="fr" selected>Français</option>
134
+ <option value="en">Anglais</option>
135
+ <option value="es">Espagnol</option>
136
+ <option value="de">Allemand</option>
137
+ <option value="it">Italien</option>
138
+ <option value="pt">Portugais</option>
139
+ <option value="ru">Russe</option>
140
+ <option value="zh">Chinois</option>
141
+ <option value="ja">Japonais</option>
142
+ <option value="ar">Arabe</option>
143
+ </select>
144
+ </div>
145
+ <div>
146
+ <label class="block text-sm font-medium text-gray-700 mb-1">Langue cible</label>
147
+ <select id="textTargetLang" class="block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-lg">
148
+ <option value="en" selected>Anglais</option>
149
+ <option value="fr">Français</option>
150
+ <option value="es">Espagnol</option>
151
+ <option value="de">Allemand</option>
152
+ <option value="it">Italien</option>
153
+ <option value="pt">Portugais</option>
154
+ <option value="ru">Russe</option>
155
+ <option value="zh">Chinois</option>
156
+ <option value="ja">Japonais</option>
157
+ <option value="ar">Arabe</option>
158
+ </select>
159
+ </div>
160
+ </div>
161
+
162
+ <!-- Text Editor -->
163
+ <div class="mb-4">
164
+ <div id="textEditor" class="text-editor" contenteditable="true" placeholder="Saisissez votre texte ici..."></div>
165
+ </div>
166
+
167
+ <!-- Character Count -->
168
+ <div class="flex justify-between items-center mb-6">
169
+ <span class="text-sm text-gray-500" id="charCount">0 caractères</span>
170
+ <button id="clearTextBtn" class="text-sm text-gray-500 hover:text-indigo-600">
171
+ <i class="fas fa-trash-alt mr-1"></i> Effacer
172
+ </button>
173
+ </div>
174
+
175
+ <!-- Translate Button -->
176
+ <button id="translateTextBtn" class="w-full btn-primary text-white font-bold py-3 px-4 rounded-lg shadow-md flex items-center justify-center">
177
+ <i class="fas fa-language mr-2"></i> Traduire le texte
178
+ <span id="textLoadingSpinner" class="ml-2 hidden">
179
+ <i class="fas fa-spinner fa-spin"></i>
180
+ </span>
181
+ </button>
182
+ </div>
183
+
184
+ <!-- Translation Result -->
185
+ <div class="bg-white rounded-xl shadow-lg p-6 translation-result">
186
+ <div class="mb-6">
187
+ <h2 class="text-2xl font-bold text-gray-800 mb-2">Résultat de la traduction</h2>
188
+ <div class="flex items-center">
189
+ <span class="language-flag mr-2" id="textSourceFlag"></span>
190
+ <span class="font-medium text-gray-700 mr-3" id="textSourceLangText">Français</span>
191
+ <i class="fas fa-arrow-right text-gray-400 mr-3"></i>
192
+ <span class="language-flag mr-2" id="textTargetFlag"></span>
193
+ <span class="font-medium text-gray-700" id="textTargetLangText">Anglais</span>
194
+ </div>
195
+ </div>
196
+
197
+ <!-- Translation Output -->
198
+ <div id="translationOutput" class="text-editor bg-gray-50 mb-6">
199
+ <p class="text-gray-400">La traduction apparaîtra ici...</p>
200
+ </div>
201
+
202
+ <!-- Export Options -->
203
+ <div class="mb-4">
204
+ <h3 class="text-sm font-medium text-gray-700 mb-2">Exporter la traduction</h3>
205
+ <div class="grid grid-cols-3 gap-3">
206
+ <button id="exportTxtBtn" class="bg-white border border-gray-200 rounded-lg p-3 text-center hover:border-indigo-300 hover:bg-indigo-50 transition-all">
207
+ <i class="fas fa-file-alt text-indigo-500 mb-1"></i>
208
+ <span class="block text-xs">Fichier TXT</span>
209
+ </button>
210
+ <button id="exportExcelBtn" class="bg-white border border-gray-200 rounded-lg p-3 text-center hover:border-green-300 hover:bg-green-50 transition-all">
211
+ <i class="fas fa-file-excel text-green-600 mb-1"></i>
212
+ <span class="block text-xs">Excel</span>
213
+ </button>
214
+ <button id="exportPdfBtn" class="bg-white border border-gray-200 rounded-lg p-3 text-center hover:border-red-300 hover:bg-red-50 transition-all">
215
+ <i class="fas fa-file-pdf text-red-500 mb-1"></i>
216
+ <span class="block text-xs">PDF</span>
217
+ </button>
218
+ </div>
219
+ </div>
220
+
221
+ <!-- Additional Options -->
222
+ <div class="flex justify-between">
223
+ <button id="copyTranslationBtn" class="text-sm text-gray-500 hover:text-indigo-600">
224
+ <i class="fas fa-copy mr-1"></i> Copier
225
+ </button>
226
+ <button id="listenTranslationBtn" class="text-sm text-gray-500 hover:text-indigo-600">
227
+ <i class="fas fa-volume-up mr-1"></i> Écouter
228
+ </button>
229
+ </div>
230
+ </div>
231
+ </div>
232
+
233
+ <!-- Multi-Language Translation Section -->
234
+ <div class="bg-white rounded-xl shadow-lg p-6 mt-8">
235
+ <div class="mb-6">
236
+ <h2 class="text-2xl font-bold text-gray-800 mb-2">Traduction multi-langues</h2>
237
+ <p class="text-gray-500">Traduisez votre texte vers plusieurs langues simultanément et exportez les résultats</p>
238
+ </div>
239
+
240
+ <!-- Source Text -->
241
+ <div class="mb-6">
242
+ <label class="block text-sm font-medium text-gray-700 mb-2">Texte source</label>
243
+ <textarea id="multiSourceText" rows="4" class="block w-full px-3 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" placeholder="Saisissez le texte à traduire..."></textarea>
244
+ </div>
245
+
246
+ <!-- Target Languages -->
247
+ <div class="mb-6">
248
+ <label class="block text-sm font-medium text-gray-700 mb-2">Langues cibles</label>
249
+ <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-5 gap-3">
250
+ <label class="flex items-center p-2 border border-gray-300 rounded-lg cursor-pointer hover:border-indigo-500">
251
+ <input type="checkbox" name="targetLanguages" value="en" class="h-4 w-4 text-indigo-600 focus:ring-indigo-500" checked>
252
+ <span class="ml-2 text-sm text-gray-700">Anglais</span>
253
+ </label>
254
+ <label class="flex items-center p-2 border border-gray-300 rounded-lg cursor-pointer hover:border-indigo-500">
255
+ <input type="checkbox" name="targetLanguages" value="es" class="h-4 w-4 text-indigo-600 focus:ring-indigo-500" checked>
256
+ <span class="ml-2 text-sm text-gray-700">Espagnol</span>
257
+ </label>
258
+ <label class="flex items-center p-2 border border-gray-300 rounded-lg cursor-pointer hover:border-indigo-500">
259
+ <input type="checkbox" name="targetLanguages" value="de" class="h-4 w-4 text-indigo-600 focus:ring-indigo-500">
260
+ <span class="ml-2 text-sm text-gray-700">Allemand</span>
261
+ </label>
262
+ <label class="flex items-center p-2 border border-gray-300 rounded-lg cursor-pointer hover:border-indigo-500">
263
+ <input type="checkbox" name="targetLanguages" value="it" class="h-4 w-4 text-indigo-600 focus:ring-indigo-500">
264
+ <span class="ml-2 text-sm text-gray-700">Italien</span>
265
+ </label>
266
+ <label class="flex items-center p-2 border border-gray-300 rounded-lg cursor-pointer hover:border-indigo-500">
267
+ <input type="checkbox" name="targetLanguages" value="pt" class="h-4 w-4 text-indigo-600 focus:ring-indigo-500">
268
+ <span class="ml-2 text-sm text-gray-700">Portugais</span>
269
+ </label>
270
+ </div>
271
+ </div>
272
+
273
+ <!-- Translate Button -->
274
+ <button id="multiTranslateBtn" class="w-full btn-primary text-white font-bold py-3 px-4 rounded-lg shadow-md flex items-center justify-center mb-6">
275
+ <i class="fas fa-globe-europe mr-2"></i> Traduire vers les langues sélectionnées
276
+ <span id="multiLoadingSpinner" class="ml-2 hidden">
277
+ <i class="fas fa-spinner fa-spin"></i>
278
+ </span>
279
+ </button>
280
+
281
+ <!-- Results Table -->
282
+ <div class="overflow-x-auto">
283
+ <table id="multiResultsTable" class="min-w-full divide-y divide-gray-200 hidden">
284
+ <thead class="bg-gray-50">
285
+ <tr>
286
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Langue</th>
287
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Traduction</th>
288
+ </tr>
289
+ </thead>
290
+ <tbody class="bg-white divide-y divide-gray-200" id="multiResultsBody">
291
+ <!-- Results will be inserted here -->
292
+ </tbody>
293
+ </table>
294
+ </div>
295
+
296
+ <!-- Export Multi Button -->
297
+ <button id="exportMultiExcelBtn" class="btn-primary text-white font-bold py-3 px-4 rounded-lg shadow-md flex items-center justify-center mt-6 hidden">
298
+ <i class="fas fa-file-excel mr-2"></i> Exporter toutes les traductions en Excel
299
+ </button>
300
+ </div>
301
+ </div>
302
+
303
+ <!-- Toast Notification -->
304
+ <div id="toast" class="fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg text-white font-medium hidden toast"></div>
305
+
306
+ <script>
307
+ // Language flags mapping
308
+ const languageFlags = {
309
+ 'fr': 'https://flagcdn.com/w20/fr.png',
310
+ 'en': 'https://flagcdn.com/w20/gb.png',
311
+ 'es': 'https://flagcdn.com/w20/es.png',
312
+ 'de': 'https://flagcdn.com/w20/de.png',
313
+ 'it': 'https://flagcdn.com/w20/it.png',
314
+ 'pt': 'https://flagcdn.com/w20/pt.png',
315
+ 'ru': 'https://flagcdn.com/w20/ru.png',
316
+ 'zh': 'https://flagcdn.com/w20/cn.png',
317
+ 'ja': 'https://flagcdn.com/w20/jp.png',
318
+ 'ar': 'https://flagcdn.com/w20/sa.png',
319
+ 'auto': 'https://flagcdn.com/w20/un.png'
320
+ };
321
+
322
+ // Language names mapping
323
+ const languageNames = {
324
+ 'fr': 'Français',
325
+ 'en': 'Anglais',
326
+ 'es': 'Espagnol',
327
+ 'de': 'Allemand',
328
+ 'it': 'Italien',
329
+ 'pt': 'Portugais',
330
+ 'ru': 'Russe',
331
+ 'zh': 'Chinois',
332
+ 'ja': 'Japonais',
333
+ 'ar': 'Arabe',
334
+ 'auto': 'Détection automatique'
335
+ };
336
+
337
+ // Sample translations for demo
338
+ const sampleTranslations = {
339
+ 'en': "This is a sample translation in English. In a real application, this would be the actual translated text from a translation API.",
340
+ 'es': "Esta es una traducción de muestra en español. En una aplicación real, este sería el texto traducido real de una API de traducción.",
341
+ 'de': "Dies ist eine Beispielübersetzung auf Deutsch. In einer echten Anwendung wäre dies der tatsächlich übersetzte Text von einer Übersetzungs-API.",
342
+ 'it': "Questa è una traduzione di esempio in italiano. In un'applicazione reale, questo sarebbe il testo tradotto effettivo da un'API di traduzione.",
343
+ 'pt': "Esta é uma tradução de exemplo em português. Em um aplicativo real, este seria o texto traduzido real de uma API de tradução."
344
+ };
345
+
346
+ // Initialize the page
347
+ document.addEventListener('DOMContentLoaded', function() {
348
+ // Elements
349
+ const textEditor = document.getElementById('textEditor');
350
+ const charCount = document.getElementById('charCount');
351
+ const clearTextBtn = document.getElementById('clearTextBtn');
352
+ const translateTextBtn = document.getElementById('translateTextBtn');
353
+ const textLoadingSpinner = document.getElementById('textLoadingSpinner');
354
+ const translationOutput = document.getElementById('translationOutput');
355
+ const copyTranslationBtn = document.getElementById('copyTranslationBtn');
356
+ const listenTranslationBtn = document.getElementById('listenTranslationBtn');
357
+ const exportTxtBtn = document.getElementById('exportTxtBtn');
358
+ const exportExcelBtn = document.getElementById('exportExcelBtn');
359
+ const exportPdfBtn = document.getElementById('exportPdfBtn');
360
+ const textSourceLang = document.getElementById('textSourceLang');
361
+ const textTargetLang = document.getElementById('textTargetLang');
362
+ const textSourceFlag = document.getElementById('textSourceFlag');
363
+ const textTargetFlag = document.getElementById('textTargetFlag');
364
+ const textSourceLangText = document.getElementById('textSourceLangText');
365
+ const textTargetLangText = document.getElementById('textTargetLangText');
366
+ const multiSourceText = document.getElementById('multiSourceText');
367
+ const multiTranslateBtn = document.getElementById('multiTranslateBtn');
368
+ const multiLoadingSpinner = document.getElementById('multiLoadingSpinner');
369
+ const multiResultsTable = document.getElementById('multiResultsTable');
370
+ const multiResultsBody = document.getElementById('multiResultsBody');
371
+ const exportMultiExcelBtn = document.getElementById('exportMultiExcelBtn');
372
+ const toast = document.getElementById('toast');
373
+
374
+ // Initialize language display
375
+ updateLanguageDisplay();
376
+
377
+ // Update character count
378
+ textEditor.addEventListener('input', function() {
379
+ const text = textEditor.textContent;
380
+ charCount.textContent = `${text.length} caractères`;
381
+ });
382
+
383
+ // Clear text
384
+ clearTextBtn.addEventListener('click', function() {
385
+ textEditor.innerHTML = '';
386
+ charCount.textContent = '0 caractères';
387
+ });
388
+
389
+ // Translate text
390
+ translateTextBtn.addEventListener('click', function() {
391
+ const text = textEditor.textContent.trim();
392
+ if (!text) {
393
+ showToast('Veuillez saisir du texte à traduire', 'error');
394
+ return;
395
+ }
396
+
397
+ const sourceLang = textSourceLang.value;
398
+ const targetLang = textTargetLang.value;
399
+
400
+ textLoadingSpinner.classList.remove('hidden');
401
+ translateTextBtn.disabled = true;
402
+
403
+ // Simulate API call
404
+ setTimeout(() => {
405
+ textLoadingSpinner.classList.add('hidden');
406
+ translateTextBtn.disabled = false;
407
+
408
+ // In a real app, you would call a translation API here
409
+ translationOutput.innerHTML = `<p>${sampleTranslations[targetLang] || sampleTranslations['en']}</p>`;
410
+ showToast('Texte traduit avec succès!', 'success');
411
+ }, 1500);
412
+ });
413
+
414
+ // Copy translation
415
+ copyTranslationBtn.addEventListener('click', function() {
416
+ const text = translationOutput.textContent;
417
+ if (!text.trim()) {
418
+ showToast('Aucune traduction à copier', 'error');
419
+ return;
420
+ }
421
+
422
+ navigator.clipboard.writeText(text)
423
+ .then(() => showToast('Traduction copiée!', 'success'))
424
+ .catch(() => showToast('Échec de la copie', 'error'));
425
+ });
426
+
427
+ // Listen to translation (text-to-speech)
428
+ listenTranslationBtn.addEventListener('click', function() {
429
+ const text = translationOutput.textContent;
430
+ if (!text.trim()) {
431
+ showToast('Aucune traduction à lire', 'error');
432
+ return;
433
+ }
434
+
435
+ if ('speechSynthesis' in window) {
436
+ const utterance = new SpeechSynthesisUtterance(text);
437
+ utterance.lang = textTargetLang.value;
438
+ speechSynthesis.speak(utterance);
439
+ } else {
440
+ showToast('La synthèse vocale n\'est pas supportée', 'error');
441
+ }
442
+ });
443
+
444
+ // Export as TXT
445
+ exportTxtBtn.addEventListener('click', function() {
446
+ const text = translationOutput.textContent;
447
+ if (!text.trim()) {
448
+ showToast('Aucune traduction à exporter', 'error');
449
+ return;
450
+ }
451
+
452
+ const blob = new Blob([text], { type: 'text/plain' });
453
+ const url = URL.createObjectURL(blob);
454
+ const a = document.createElement('a');
455
+ a.href = url;
456
+ a.download = `traduction_${textTargetLang.value}.txt`;
457
+ a.click();
458
+ URL.revokeObjectURL(url);
459
+
460
+ showToast('Export TXT réussi!', 'success');
461
+ });
462
+
463
+ // Export as Excel
464
+ exportExcelBtn.addEventListener('click', function() {
465
+ const sourceText = textEditor.textContent.trim();
466
+ const translatedText = translationOutput.textContent.trim();
467
+
468
+ if (!sourceText || !translatedText) {
469
+ showToast('Aucune traduction à exporter', 'error');
470
+ return;
471
+ }
472
+
473
+ // Create CSV content
474
+ const csvContent = "Texte original,Texte traduit\n" +
475
+ `"${sourceText.replace(/"/g, '""')}","${translatedText.replace(/"/g, '""')}"`;
476
+
477
+ const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
478
+ const url = URL.createObjectURL(blob);
479
+ const a = document.createElement('a');
480
+ a.href = url;
481
+ a.download = `traduction_${textSourceLang.value}_${textTargetLang.value}.csv`;
482
+ a.click();
483
+ URL.revokeObjectURL(url);
484
+
485
+ showToast('Export Excel réussi!', 'success');
486
+ });
487
+
488
+ // Export as PDF (simulated)
489
+ exportPdfBtn.addEventListener('click', function() {
490
+ const text = translationOutput.textContent;
491
+ if (!text.trim()) {
492
+ showToast('Aucune traduction à exporter', 'error');
493
+ return;
494
+ }
495
+
496
+ // In a real app, you would generate a PDF here
497
+ showToast('Export PDF simulé!', 'success');
498
+ });
499
+
500
+ // Update language display when changed
501
+ textSourceLang.addEventListener('change', updateLanguageDisplay);
502
+ textTargetLang.addEventListener('change', updateLanguageDisplay);
503
+
504
+ // Multi-language translation
505
+ multiTranslateBtn.addEventListener('click', function() {
506
+ const text = multiSourceText.value.trim();
507
+ if (!text) {
508
+ showToast('Veuillez saisir du texte à traduire', 'error');
509
+ return;
510
+ }
511
+
512
+ const selectedLanguages = Array.from(document.querySelectorAll('input[name="targetLanguages"]:checked'))
513
+ .map(el => el.value);
514
+
515
+ if (selectedLanguages.length === 0) {
516
+ showToast('Veuillez sélectionner au moins une langue cible', 'error');
517
+ return;
518
+ }
519
+
520
+ multiLoadingSpinner.classList.remove('hidden');
521
+ multiTranslateBtn.disabled = true;
522
+ multiResultsBody.innerHTML = '';
523
+
524
+ // Simulate API calls for each language
525
+ setTimeout(() => {
526
+ selectedLanguages.forEach(lang => {
527
+ const row = document.createElement('tr');
528
+ row.innerHTML = `
529
+ <td class="px-6 py-4 whitespace-nowrap">
530
+ <div class="flex items-center">
531
+ <span class="language-flag mr-2" style="background-image: url(${languageFlags[lang]})"></span>
532
+ <span class="text-sm font-medium text-gray-900">${languageNames[lang]}</span>
533
+ </div>
534
+ </td>
535
+ <td class="px-6 py-4">
536
+ <div class="text-sm text-gray-900">${sampleTranslations[lang] || sampleTranslations['en']}</div>
537
+ </td>
538
+ `;
539
+ multiResultsBody.appendChild(row);
540
+ });
541
+
542
+ multiResultsTable.classList.remove('hidden');
543
+ exportMultiExcelBtn.classList.remove('hidden');
544
+ multiLoadingSpinner.classList.add('hidden');
545
+ multiTranslateBtn.disabled = false;
546
+ showToast('Traductions multi-langues terminées!', 'success');
547
+ }, 2000);
548
+ });
549
+
550
+ // Export all translations to Excel
551
+ exportMultiExcelBtn.addEventListener('click', function() {
552
+ const sourceText = multiSourceText.value.trim();
553
+ if (!sourceText) {
554
+ showToast('Aucune traduction à exporter', 'error');
555
+ return;
556
+ }
557
+
558
+ // Create CSV content with all translations
559
+ let csvContent = "Langue,Texte original,Texte traduit\n";
560
+
561
+ const rows = multiResultsBody.querySelectorAll('tr');
562
+ rows.forEach(row => {
563
+ const lang = row.querySelector('span.text-gray-900').textContent;
564
+ const translation = row.querySelector('div.text-gray-900').textContent;
565
+ csvContent += `"${lang}","${sourceText.replace(/"/g, '""')}","${translation.replace(/"/g, '""')}"\n`;
566
+ });
567
+
568
+ const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
569
+ const url = URL.createObjectURL(blob);
570
+ const a = document.createElement('a');
571
+ a.href = url;
572
+ a.download = `traductions_multilingues.csv`;
573
+ a.click();
574
+ URL.revokeObjectURL(url);
575
+
576
+ showToast('Export Excel multilingue réussi!', 'success');
577
+ });
578
+
579
+ // Update language display
580
+ function updateLanguageDisplay() {
581
+ const sourceValue = textSourceLang.value;
582
+ const targetValue = textTargetLang.value;
583
+
584
+ textSourceLangText.textContent = languageNames[sourceValue];
585
+ textTargetLangText.textContent = languageNames[targetValue];
586
+
587
+ textSourceFlag.style.backgroundImage = `url(${languageFlags[sourceValue]})`;
588
+ textTargetFlag.style.backgroundImage = `url(${languageFlags[targetValue]})`;
589
+ }
590
+
591
+ // Show toast notification
592
+ function showToast(message, type) {
593
+ toast.textContent = message;
594
+ toast.className = `fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg text-white font-medium hidden toast ${
595
+ type === 'success' ? 'bg-green-500' : 'bg-red-500'
596
+ }`;
597
+ toast.classList.remove('hidden');
598
+
599
+ setTimeout(() => {
600
+ toast.classList.add('hidden');
601
+ }, 3000);
602
+ }
603
+ });
604
+ </script>
605
+ </body>
606
+ </html>