Spaces:
Running
Running
Update templates/index.html
Browse files- templates/index.html +87 -67
templates/index.html
CHANGED
@@ -7,7 +7,6 @@
|
|
7 |
<title>Mariam AI - Assistant Français Intelligent</title>
|
8 |
<script src="https://cdn.tailwindcss.com"></script>
|
9 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
|
10 |
-
<!-- MathJax retiré -->
|
11 |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
12 |
<style>
|
13 |
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap');
|
@@ -29,48 +28,48 @@
|
|
29 |
font-family: 'Plus Jakarta Sans', sans-serif;
|
30 |
background-color: #fafafa;
|
31 |
scroll-behavior: smooth;
|
32 |
-
-webkit-tap-highlight-color: transparent;
|
|
|
|
|
|
|
|
|
|
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
.glassmorphism {
|
36 |
background: rgba(255, 255, 255, 0.95);
|
37 |
backdrop-filter: blur(10px);
|
38 |
-
-webkit-backdrop-filter: blur(10px);
|
39 |
border: 1px solid rgba(255, 255, 255, 0.3);
|
40 |
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.07);
|
41 |
}
|
42 |
|
43 |
-
.card-hover {
|
44 |
-
|
45 |
-
}
|
46 |
-
|
47 |
-
.card-hover:hover {
|
48 |
-
transform: translateY(-4px);
|
49 |
-
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.08);
|
50 |
-
}
|
51 |
|
52 |
-
.gradient-text {
|
53 |
-
background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 100%);
|
54 |
-
-webkit-background-clip: text;
|
55 |
-
background-clip: text;
|
56 |
-
-webkit-text-fill-color: transparent;
|
57 |
-
text-fill-color: transparent; /* Standard property */
|
58 |
-
}
|
59 |
|
60 |
-
.loading-dot {
|
61 |
-
animation: bounce 1.4s infinite;
|
62 |
-
}
|
63 |
.loading-dot:nth-child(2) { animation-delay: 0.2s; }
|
64 |
.loading-dot:nth-child(3) { animation-delay: 0.4s; }
|
65 |
@keyframes bounce { 0%, 80%, 100% { transform: translateY(0); } 40% { transform: translateY(-6px); } }
|
66 |
|
67 |
-
.custom-radio:checked+span {
|
68 |
-
background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 100%);
|
69 |
-
color: white;
|
70 |
-
border-color: var(--primary);
|
71 |
-
}
|
72 |
|
73 |
-
/* Styles
|
74 |
.alert-message { display: flex; align-items: flex-start; padding: 1rem; border-radius: 0.5rem; border-width: 1px; border-style: solid; }
|
75 |
.alert-message i { margin-right: 0.75rem; font-size: 1.25rem; margin-top: 0.125rem; flex-shrink: 0; }
|
76 |
.alert-message div p:first-child { font-weight: 500; }
|
@@ -103,19 +102,19 @@
|
|
103 |
.image-preview-item:hover .remove-image { opacity: 1; }
|
104 |
.remove-image:hover { background-color: rgba(0, 0, 0, 0.8); transform: scale(1.1); }
|
105 |
|
106 |
-
/* Style Prose
|
107 |
-
.prose { white-space: pre-wrap; word-wrap: break-word; overflow-wrap: break-word; color: #2d3748; line-height: 1.7; font-size: 0.95rem;
|
108 |
-
@media (min-width: 640px) { .prose { font-size: 1rem; } }
|
109 |
.prose h1, .prose h2, .prose h3, .prose h4 { color: var(--primary-dark); margin-top: 1.5em; margin-bottom: 0.5em; font-weight: 600; }
|
110 |
.prose p { margin-bottom: 1em; }
|
111 |
.prose ul, .prose ol { padding-left: 1.5em; margin-bottom: 1em; }
|
112 |
.prose blockquote { border-left: 4px solid var(--primary); padding-left: 1em; font-style: italic; color: var(--secondary); margin: 1em 0; }
|
113 |
-
.prose code { background-color: #edf2f7;
|
114 |
-
.prose pre { background-color: #1a202c;
|
115 |
.prose pre code { background-color: transparent; padding: 0; border-radius: 0; font-size: 0.875em; }
|
116 |
|
117 |
/* Loader */
|
118 |
-
.loader { display: inline-block; position: relative; width: 64px; height: 16px;
|
119 |
.loader div { position: absolute; top: 6px; width: 10px; height: 10px; border-radius: 50%; background: var(--primary); animation-timing-function: cubic-bezier(0, 1, 1, 0); }
|
120 |
.loader div:nth-child(1) { left: 6px; animation: loader1 0.6s infinite; }
|
121 |
.loader div:nth-child(2) { left: 6px; animation: loader2 0.6s infinite; }
|
@@ -150,36 +149,32 @@
|
|
150 |
|
151 |
<body class="min-h-screen bg-gradient-to-br from-blue-50 via-white to-blue-50 text-gray-800">
|
152 |
<nav class="glassmorphism sticky top-0 z-50 border-b border-blue-100">
|
153 |
-
|
154 |
-
<div class="container mx-auto px-4 sm:px-6 py-3 sm:py-4"> <!-- Ajustement padding nav -->
|
155 |
<div class="flex items-center justify-between">
|
156 |
<div class="flex items-center space-x-3 sm:space-x-4">
|
157 |
<div class="bg-gradient-to-r from-blue-600 to-blue-800 rounded-lg p-2 shadow-lg transform hover:scale-110 transition-transform duration-300">
|
158 |
-
<i class="fas fa-robot text-white text-lg sm:text-xl"></i>
|
159 |
</div>
|
160 |
-
<h1 class="text-xl sm:text-2xl font-bold gradient-text">Mariam AI</h1>
|
161 |
</div>
|
162 |
-
<div class="text-xs sm:text-sm text-blue-900 font-medium bg-blue-50 py-1 px-3 sm:px-4 rounded-full shadow-sm hidden sm:block">Assistant Français</div>
|
163 |
-
<div class="text-xs text-blue-900 font-medium bg-blue-50 py-1 px-3 rounded-full shadow-sm sm:hidden">Assistant</div>
|
164 |
</div>
|
165 |
</div>
|
166 |
</nav>
|
167 |
|
168 |
-
|
169 |
-
<main class="container mx-auto px-4 sm:px-6 py-8 sm:py-12"> <!-- Ajustement padding main -->
|
170 |
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 sm:gap-8">
|
171 |
<!-- Section Travail Argumentatif -->
|
172 |
<div class="card-hover glassmorphism rounded-2xl overflow-hidden scale-in">
|
173 |
-
|
174 |
-
<div class="p-6 sm:p-8"> <!-- Ajustement padding carte -->
|
175 |
<div class="flex items-center space-x-3 sm:space-x-4 mb-6 sm:mb-8">
|
176 |
<div class="bg-blue-100 rounded-lg p-2 sm:p-3 transform rotate-3">
|
177 |
<i class="fas fa-pen-fancy text-blue-600 text-lg sm:text-xl"></i>
|
178 |
</div>
|
179 |
<h2 class="text-xl sm:text-2xl font-bold text-gray-800">Travail Argumentatif</h2>
|
180 |
</div>
|
181 |
-
|
182 |
-
<form id="francais-form" class="space-y-6 sm:space-y-8"> <!-- Ajustement espacement -->
|
183 |
<div class="space-y-2">
|
184 |
<label for="sujet-francais" class="block text-sm font-medium text-gray-700 flex items-center">
|
185 |
<i class="fas fa-book-open mr-2 text-blue-500"></i>Sujet <span class="text-red-500 ml-1">*</span>
|
@@ -189,14 +184,13 @@
|
|
189 |
class="w-full px-3 py-2 sm:px-4 sm:py-3 rounded-xl border-2 border-gray-200 focus:border-blue-500 focus:outline-none transition-all duration-200 resize-none text-base"
|
190 |
placeholder="Entrez votre sujet ici..." required></textarea>
|
191 |
</div>
|
192 |
-
<div class="text-xs text-gray-400 text-right" id="character-count">
|
193 |
</div>
|
194 |
|
195 |
<div class="space-y-3">
|
196 |
<label class="block text-sm font-medium text-gray-700 flex items-center">
|
197 |
<i class="fas fa-tasks mr-2 text-blue-500"></i>Type d'argumentation
|
198 |
</label>
|
199 |
-
<!-- Grid s'adapte déjà bien (2 cols par défaut, 4 sur sm+) -->
|
200 |
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4">
|
201 |
<label class="relative">
|
202 |
<input type="radio" name="choix" value="Etaye" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer" checked>
|
@@ -239,7 +233,7 @@
|
|
239 |
<span class="text-sm">Utiliser DeepThink</span>
|
240 |
<div class="deepthink-tooltip">
|
241 |
<i class="fas fa-info-circle text-gray-400 ml-1"></i>
|
242 |
-
<span class="tooltip-text">Modèle avancé (Pro). Plus lent, meilleure qualité. Limité: 1/jour.</span>
|
243 |
</div>
|
244 |
</label>
|
245 |
<span id="deepthink-status" class="text-xs text-gray-500 ml-2"></span>
|
@@ -253,8 +247,7 @@
|
|
253 |
</div>
|
254 |
</button>
|
255 |
</form>
|
256 |
-
|
257 |
-
<div id="francais-output" class="mt-6 sm:mt-8 p-4 sm:p-6 bg-blue-50 rounded-xl prose max-w-none shadow-inner min-h-[150px]"> <!-- Ajustement padding et min-height -->
|
258 |
<!-- Le contenu généré sera inséré ici -->
|
259 |
</div>
|
260 |
</div>
|
@@ -262,8 +255,7 @@
|
|
262 |
|
263 |
<!-- Section Étude de texte -->
|
264 |
<div class="card-hover glassmorphism rounded-2xl overflow-hidden scale-in" style="animation-delay: 0.1s;">
|
265 |
-
|
266 |
-
<div class="p-6 sm:p-8"> <!-- Ajustement padding carte -->
|
267 |
<div class="flex items-center space-x-3 sm:space-x-4 mb-6 sm:mb-8">
|
268 |
<div class="bg-blue-100 rounded-lg p-2 sm:p-3 transform -rotate-3">
|
269 |
<i class="fas fa-file-alt text-blue-600 text-lg sm:text-xl"></i>
|
@@ -297,8 +289,7 @@
|
|
297 |
</div>
|
298 |
</button>
|
299 |
</form>
|
300 |
-
|
301 |
-
<div id="etude-texte-output" class="mt-6 sm:mt-8 p-4 sm:p-6 bg-blue-50 rounded-xl prose max-w-none shadow-inner min-h-[150px]"> <!-- Ajustement padding et min-height -->
|
302 |
<!-- Le contenu analysé sera inséré ici -->
|
303 |
</div>
|
304 |
</div>
|
@@ -452,10 +443,10 @@
|
|
452 |
return;
|
453 |
}
|
454 |
|
455 |
-
sauvegardes.forEach((sauvegarde) => {
|
456 |
const date = new Date(sauvegarde.date);
|
457 |
-
const formattedDate = date.toLocaleDateString('fr-FR', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });
|
458 |
-
const displayTitle = (sauvegarde.titre || "Sans titre").length > 40 ? sauvegarde.titre.substring(0, 37) + '...' : (sauvegarde.titre || "Sans titre");
|
459 |
|
460 |
const sauvegardeDiv = document.createElement('div');
|
461 |
sauvegardeDiv.dataset.originalDate = sauvegarde.date;
|
@@ -490,7 +481,7 @@
|
|
490 |
sauvegardeDiv.querySelector('.copy-btn').addEventListener('click', (e) => {
|
491 |
e.stopPropagation();
|
492 |
navigator.clipboard.writeText(sauvegarde.contenu || '').then(() => {
|
493 |
-
const icon = e.currentTarget.querySelector('i'); icon.className = 'fas fa-check text-green-500 text-xs sm:text-sm'; setTimeout(() => { icon.className = 'fas fa-copy text-xs sm:text-sm'; }, 1500);
|
494 |
}).catch(err => { console.error('Copy error:', err); displayNotification("Erreur copie", "error"); });
|
495 |
});
|
496 |
|
@@ -548,7 +539,7 @@
|
|
548 |
e.preventDefault();
|
549 |
const originalButtonContent = submitButton.innerHTML;
|
550 |
submitButton.disabled = true;
|
551 |
-
submitButton.innerHTML = `<div class="flex items-center justify-center"><div class="loader"><div></div><div></div><div></div><div></div></div><span class="ml-2 text-sm sm:text-base">Génération...</span></div>`;
|
552 |
|
553 |
const sujetValue = sujetTextarea.value.trim();
|
554 |
const isDeepThinkChecked = deepThinkCheckbox.checked;
|
@@ -564,10 +555,10 @@
|
|
564 |
const lastUsedDateStr = localStorage.getItem(DEEPTHINK_STORAGE_KEY);
|
565 |
const todayStr = new Date().toISOString().split('T')[0];
|
566 |
if (lastUsedDateStr === todayStr) {
|
567 |
-
output.innerHTML = `<div class="alert-message alert-warning"><i class="fas fa-exclamation-triangle"></i><div><p>Limite atteinte</p><p>DeepThink déjà utilisé.</p></div></div>`;
|
568 |
checkDeepThinkAvailability(); submitButton.disabled = false; submitButton.innerHTML = originalButtonContent; return;
|
569 |
}
|
570 |
-
} catch(e) { /* Proceed without check
|
571 |
}
|
572 |
output.innerHTML = `<div class="flex justify-center items-center p-6"><div class="loader"><div></div><div></div><div></div><div></div></div></div>`;
|
573 |
|
@@ -579,8 +570,8 @@
|
|
579 |
|
580 |
try { output.innerHTML = marked.parse(result.output || ''); } catch (e) { output.innerHTML = "Erreur d'affichage."; console.error(e); }
|
581 |
|
582 |
-
const titreSauvegarde = sujetValue.substring(0, 40) + (sujetValue.length > 40 ? '...' : '');
|
583 |
-
const deepThinkSuffix = isDeepThinkChecked ? ' [DT]' : '';
|
584 |
sauvegarderReponse(titreSauvegarde + deepThinkSuffix, result.output);
|
585 |
|
586 |
if (isDeepThinkChecked) {
|
@@ -605,7 +596,7 @@
|
|
605 |
e.preventDefault();
|
606 |
const originalButtonContent = submitButton.innerHTML;
|
607 |
submitButton.disabled = true;
|
608 |
-
submitButton.innerHTML = `<div class="flex items-center justify-center"><div class="loader"><div></div><div></div><div></div><div></div></div><span class="ml-2 text-sm sm:text-base">Analyse...</span></div>`;
|
609 |
|
610 |
if (uploadedFiles.size === 0) {
|
611 |
output.innerHTML = `<div class="alert-message alert-warning"><i class="fas fa-exclamation-triangle"></i><div><p>Aucune image</p><p>Ajoutez au moins une image.</p></div></div>`;
|
@@ -621,7 +612,7 @@
|
|
621 |
|
622 |
try { output.innerHTML = marked.parse(result.output || ''); } catch (e) { output.innerHTML = "Erreur d'affichage."; console.error(e); }
|
623 |
|
624 |
-
const titre = `Analyse img ${new Date().toLocaleDateString('fr-FR', { month: 'short', day: 'numeric' })}`;
|
625 |
sauvegarderReponse(titre, result.output);
|
626 |
} catch (error) {
|
627 |
console.error("Erreur soumission (img):", error);
|
@@ -641,7 +632,7 @@
|
|
641 |
}
|
642 |
function enhanceTextareaFocus() {
|
643 |
const textarea = document.getElementById('sujet-francais'); const counter = document.getElementById('character-count'); if(!textarea || !counter) return;
|
644 |
-
textarea.addEventListener('input', () => { const length = textarea.value.length; counter.textContent = `${length}c`; textarea.classList.remove('border-red-500'); });
|
645 |
}
|
646 |
function enhanceRadioButtons() {
|
647 |
document.querySelectorAll('input[type="radio"] + span').forEach(label => {
|
@@ -669,6 +660,35 @@
|
|
669 |
checkDeepThinkAvailability();
|
670 |
afficherSauvegardes();
|
671 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
672 |
// Welcome Message
|
673 |
try {
|
674 |
const showWelcome = sessionStorage.getItem('welcomeShown') !== 'true';
|
@@ -679,7 +699,7 @@
|
|
679 |
const welcomeMsg = welcomeContainer.firstElementChild;
|
680 |
setTimeout(() => { welcomeMsg.classList.remove('opacity-0', 'translate-y-4'); }, 500);
|
681 |
welcomeMsg.querySelector('.close-welcome').addEventListener('click', () => closeWelcomeMessage(welcomeMsg));
|
682 |
-
setTimeout(() => { if (document.body.contains(welcomeMsg)) closeWelcomeMessage(welcomeMsg); }, 6000);
|
683 |
sessionStorage.setItem('welcomeShown', 'true');
|
684 |
}
|
685 |
} catch(e) { console.warn("SessionStorage (Welcome):", e); }
|
|
|
7 |
<title>Mariam AI - Assistant Français Intelligent</title>
|
8 |
<script src="https://cdn.tailwindcss.com"></script>
|
9 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
|
|
|
10 |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
11 |
<style>
|
12 |
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap');
|
|
|
28 |
font-family: 'Plus Jakarta Sans', sans-serif;
|
29 |
background-color: #fafafa;
|
30 |
scroll-behavior: smooth;
|
31 |
+
-webkit-tap-highlight-color: transparent;
|
32 |
+
/* MODIFICATION: Empêcher la sélection de texte par défaut */
|
33 |
+
-webkit-user-select: none; /* Safari */
|
34 |
+
-moz-user-select: none; /* Firefox */
|
35 |
+
-ms-user-select: none; /* IE/Edge */
|
36 |
+
user-select: none; /* Standard */
|
37 |
}
|
38 |
|
39 |
+
/* MODIFICATION: Réactiver la sélection pour les champs modifiables */
|
40 |
+
input, textarea {
|
41 |
+
-webkit-user-select: text; /* Safari */
|
42 |
+
-moz-user-select: text; /* Firefox */
|
43 |
+
-ms-user-select: text; /* IE/Edge */
|
44 |
+
user-select: text; /* Standard */
|
45 |
+
}
|
46 |
+
/* Optionnel: Si vous voulez autoriser la sélection dans les zones de sortie */
|
47 |
+
/* #francais-output, #etude-texte-output, .backup-content {
|
48 |
+
-webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text;
|
49 |
+
} */
|
50 |
+
|
51 |
+
|
52 |
.glassmorphism {
|
53 |
background: rgba(255, 255, 255, 0.95);
|
54 |
backdrop-filter: blur(10px);
|
55 |
+
-webkit-backdrop-filter: blur(10px);
|
56 |
border: 1px solid rgba(255, 255, 255, 0.3);
|
57 |
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.07);
|
58 |
}
|
59 |
|
60 |
+
.card-hover { transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); }
|
61 |
+
.card-hover:hover { transform: translateY(-4px); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.08); }
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
+
.gradient-text { background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 100%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; text-fill-color: transparent; }
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
|
65 |
+
.loading-dot { animation: bounce 1.4s infinite; }
|
|
|
|
|
66 |
.loading-dot:nth-child(2) { animation-delay: 0.2s; }
|
67 |
.loading-dot:nth-child(3) { animation-delay: 0.4s; }
|
68 |
@keyframes bounce { 0%, 80%, 100% { transform: translateY(0); } 40% { transform: translateY(-6px); } }
|
69 |
|
70 |
+
.custom-radio:checked+span { background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 100%); color: white; border-color: var(--primary); }
|
|
|
|
|
|
|
|
|
71 |
|
72 |
+
/* Styles alertes */
|
73 |
.alert-message { display: flex; align-items: flex-start; padding: 1rem; border-radius: 0.5rem; border-width: 1px; border-style: solid; }
|
74 |
.alert-message i { margin-right: 0.75rem; font-size: 1.25rem; margin-top: 0.125rem; flex-shrink: 0; }
|
75 |
.alert-message div p:first-child { font-weight: 500; }
|
|
|
102 |
.image-preview-item:hover .remove-image { opacity: 1; }
|
103 |
.remove-image:hover { background-color: rgba(0, 0, 0, 0.8); transform: scale(1.1); }
|
104 |
|
105 |
+
/* Style Prose */
|
106 |
+
.prose { white-space: pre-wrap; word-wrap: break-word; overflow-wrap: break-word; color: #2d3748; line-height: 1.7; font-size: 0.95rem; }
|
107 |
+
@media (min-width: 640px) { .prose { font-size: 1rem; } }
|
108 |
.prose h1, .prose h2, .prose h3, .prose h4 { color: var(--primary-dark); margin-top: 1.5em; margin-bottom: 0.5em; font-weight: 600; }
|
109 |
.prose p { margin-bottom: 1em; }
|
110 |
.prose ul, .prose ol { padding-left: 1.5em; margin-bottom: 1em; }
|
111 |
.prose blockquote { border-left: 4px solid var(--primary); padding-left: 1em; font-style: italic; color: var(--secondary); margin: 1em 0; }
|
112 |
+
.prose code { background-color: #edf2f7; padding: 0.2em 0.4em; border-radius: 0.25rem; font-size: 0.9em; }
|
113 |
+
.prose pre { background-color: #1a202c; color: #e2e8f0; padding: 1em; border-radius: 0.375rem; overflow-x: auto; }
|
114 |
.prose pre code { background-color: transparent; padding: 0; border-radius: 0; font-size: 0.875em; }
|
115 |
|
116 |
/* Loader */
|
117 |
+
.loader { display: inline-block; position: relative; width: 64px; height: 16px; }
|
118 |
.loader div { position: absolute; top: 6px; width: 10px; height: 10px; border-radius: 50%; background: var(--primary); animation-timing-function: cubic-bezier(0, 1, 1, 0); }
|
119 |
.loader div:nth-child(1) { left: 6px; animation: loader1 0.6s infinite; }
|
120 |
.loader div:nth-child(2) { left: 6px; animation: loader2 0.6s infinite; }
|
|
|
149 |
|
150 |
<body class="min-h-screen bg-gradient-to-br from-blue-50 via-white to-blue-50 text-gray-800">
|
151 |
<nav class="glassmorphism sticky top-0 z-50 border-b border-blue-100">
|
152 |
+
<div class="container mx-auto px-4 sm:px-6 py-3 sm:py-4">
|
|
|
153 |
<div class="flex items-center justify-between">
|
154 |
<div class="flex items-center space-x-3 sm:space-x-4">
|
155 |
<div class="bg-gradient-to-r from-blue-600 to-blue-800 rounded-lg p-2 shadow-lg transform hover:scale-110 transition-transform duration-300">
|
156 |
+
<i class="fas fa-robot text-white text-lg sm:text-xl"></i>
|
157 |
</div>
|
158 |
+
<h1 class="text-xl sm:text-2xl font-bold gradient-text">Mariam AI</h1>
|
159 |
</div>
|
160 |
+
<div class="text-xs sm:text-sm text-blue-900 font-medium bg-blue-50 py-1 px-3 sm:px-4 rounded-full shadow-sm hidden sm:block">Assistant Français</div>
|
161 |
+
<div class="text-xs text-blue-900 font-medium bg-blue-50 py-1 px-3 rounded-full shadow-sm sm:hidden">Assistant</div>
|
162 |
</div>
|
163 |
</div>
|
164 |
</nav>
|
165 |
|
166 |
+
<main class="container mx-auto px-4 sm:px-6 py-8 sm:py-12">
|
|
|
167 |
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 sm:gap-8">
|
168 |
<!-- Section Travail Argumentatif -->
|
169 |
<div class="card-hover glassmorphism rounded-2xl overflow-hidden scale-in">
|
170 |
+
<div class="p-6 sm:p-8">
|
|
|
171 |
<div class="flex items-center space-x-3 sm:space-x-4 mb-6 sm:mb-8">
|
172 |
<div class="bg-blue-100 rounded-lg p-2 sm:p-3 transform rotate-3">
|
173 |
<i class="fas fa-pen-fancy text-blue-600 text-lg sm:text-xl"></i>
|
174 |
</div>
|
175 |
<h2 class="text-xl sm:text-2xl font-bold text-gray-800">Travail Argumentatif</h2>
|
176 |
</div>
|
177 |
+
<form id="francais-form" class="space-y-6 sm:space-y-8">
|
|
|
178 |
<div class="space-y-2">
|
179 |
<label for="sujet-francais" class="block text-sm font-medium text-gray-700 flex items-center">
|
180 |
<i class="fas fa-book-open mr-2 text-blue-500"></i>Sujet <span class="text-red-500 ml-1">*</span>
|
|
|
184 |
class="w-full px-3 py-2 sm:px-4 sm:py-3 rounded-xl border-2 border-gray-200 focus:border-blue-500 focus:outline-none transition-all duration-200 resize-none text-base"
|
185 |
placeholder="Entrez votre sujet ici..." required></textarea>
|
186 |
</div>
|
187 |
+
<div class="text-xs text-gray-400 text-right" id="character-count">0c</div>
|
188 |
</div>
|
189 |
|
190 |
<div class="space-y-3">
|
191 |
<label class="block text-sm font-medium text-gray-700 flex items-center">
|
192 |
<i class="fas fa-tasks mr-2 text-blue-500"></i>Type d'argumentation
|
193 |
</label>
|
|
|
194 |
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4">
|
195 |
<label class="relative">
|
196 |
<input type="radio" name="choix" value="Etaye" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer" checked>
|
|
|
233 |
<span class="text-sm">Utiliser DeepThink</span>
|
234 |
<div class="deepthink-tooltip">
|
235 |
<i class="fas fa-info-circle text-gray-400 ml-1"></i>
|
236 |
+
<span class="tooltip-text">Modèle avancé (Gemini Pro). Plus lent, meilleure qualité. Limité: 1/jour.</span>
|
237 |
</div>
|
238 |
</label>
|
239 |
<span id="deepthink-status" class="text-xs text-gray-500 ml-2"></span>
|
|
|
247 |
</div>
|
248 |
</button>
|
249 |
</form>
|
250 |
+
<div id="francais-output" class="mt-6 sm:mt-8 p-4 sm:p-6 bg-blue-50 rounded-xl prose max-w-none shadow-inner min-h-[150px]">
|
|
|
251 |
<!-- Le contenu généré sera inséré ici -->
|
252 |
</div>
|
253 |
</div>
|
|
|
255 |
|
256 |
<!-- Section Étude de texte -->
|
257 |
<div class="card-hover glassmorphism rounded-2xl overflow-hidden scale-in" style="animation-delay: 0.1s;">
|
258 |
+
<div class="p-6 sm:p-8">
|
|
|
259 |
<div class="flex items-center space-x-3 sm:space-x-4 mb-6 sm:mb-8">
|
260 |
<div class="bg-blue-100 rounded-lg p-2 sm:p-3 transform -rotate-3">
|
261 |
<i class="fas fa-file-alt text-blue-600 text-lg sm:text-xl"></i>
|
|
|
289 |
</div>
|
290 |
</button>
|
291 |
</form>
|
292 |
+
<div id="etude-texte-output" class="mt-6 sm:mt-8 p-4 sm:p-6 bg-blue-50 rounded-xl prose max-w-none shadow-inner min-h-[150px]">
|
|
|
293 |
<!-- Le contenu analysé sera inséré ici -->
|
294 |
</div>
|
295 |
</div>
|
|
|
443 |
return;
|
444 |
}
|
445 |
|
446 |
+
sauvegardes.forEach((sauvegarde) => {
|
447 |
const date = new Date(sauvegarde.date);
|
448 |
+
const formattedDate = date.toLocaleDateString('fr-FR', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });
|
449 |
+
const displayTitle = (sauvegarde.titre || "Sans titre").length > 40 ? sauvegarde.titre.substring(0, 37) + '...' : (sauvegarde.titre || "Sans titre");
|
450 |
|
451 |
const sauvegardeDiv = document.createElement('div');
|
452 |
sauvegardeDiv.dataset.originalDate = sauvegarde.date;
|
|
|
481 |
sauvegardeDiv.querySelector('.copy-btn').addEventListener('click', (e) => {
|
482 |
e.stopPropagation();
|
483 |
navigator.clipboard.writeText(sauvegarde.contenu || '').then(() => {
|
484 |
+
const icon = e.currentTarget.querySelector('i'); icon.className = 'fas fa-check text-green-500 text-xs sm:text-sm'; setTimeout(() => { icon.className = 'fas fa-copy text-xs sm:text-sm'; }, 1500);
|
485 |
}).catch(err => { console.error('Copy error:', err); displayNotification("Erreur copie", "error"); });
|
486 |
});
|
487 |
|
|
|
539 |
e.preventDefault();
|
540 |
const originalButtonContent = submitButton.innerHTML;
|
541 |
submitButton.disabled = true;
|
542 |
+
submitButton.innerHTML = `<div class="flex items-center justify-center"><div class="loader"><div></div><div></div><div></div><div></div></div><span class="ml-2 text-sm sm:text-base">Génération...</span></div>`;
|
543 |
|
544 |
const sujetValue = sujetTextarea.value.trim();
|
545 |
const isDeepThinkChecked = deepThinkCheckbox.checked;
|
|
|
555 |
const lastUsedDateStr = localStorage.getItem(DEEPTHINK_STORAGE_KEY);
|
556 |
const todayStr = new Date().toISOString().split('T')[0];
|
557 |
if (lastUsedDateStr === todayStr) {
|
558 |
+
output.innerHTML = `<div class="alert-message alert-warning"><i class="fas fa-exclamation-triangle"></i><div><p>Limite atteinte</p><p>DeepThink déjà utilisé.</p></div></div>`;
|
559 |
checkDeepThinkAvailability(); submitButton.disabled = false; submitButton.innerHTML = originalButtonContent; return;
|
560 |
}
|
561 |
+
} catch(e) { /* Proceed without check */ }
|
562 |
}
|
563 |
output.innerHTML = `<div class="flex justify-center items-center p-6"><div class="loader"><div></div><div></div><div></div><div></div></div></div>`;
|
564 |
|
|
|
570 |
|
571 |
try { output.innerHTML = marked.parse(result.output || ''); } catch (e) { output.innerHTML = "Erreur d'affichage."; console.error(e); }
|
572 |
|
573 |
+
const titreSauvegarde = sujetValue.substring(0, 40) + (sujetValue.length > 40 ? '...' : '');
|
574 |
+
const deepThinkSuffix = isDeepThinkChecked ? ' [DT]' : '';
|
575 |
sauvegarderReponse(titreSauvegarde + deepThinkSuffix, result.output);
|
576 |
|
577 |
if (isDeepThinkChecked) {
|
|
|
596 |
e.preventDefault();
|
597 |
const originalButtonContent = submitButton.innerHTML;
|
598 |
submitButton.disabled = true;
|
599 |
+
submitButton.innerHTML = `<div class="flex items-center justify-center"><div class="loader"><div></div><div></div><div></div><div></div></div><span class="ml-2 text-sm sm:text-base">Analyse...</span></div>`;
|
600 |
|
601 |
if (uploadedFiles.size === 0) {
|
602 |
output.innerHTML = `<div class="alert-message alert-warning"><i class="fas fa-exclamation-triangle"></i><div><p>Aucune image</p><p>Ajoutez au moins une image.</p></div></div>`;
|
|
|
612 |
|
613 |
try { output.innerHTML = marked.parse(result.output || ''); } catch (e) { output.innerHTML = "Erreur d'affichage."; console.error(e); }
|
614 |
|
615 |
+
const titre = `Analyse img ${new Date().toLocaleDateString('fr-FR', { month: 'short', day: 'numeric' })}`;
|
616 |
sauvegarderReponse(titre, result.output);
|
617 |
} catch (error) {
|
618 |
console.error("Erreur soumission (img):", error);
|
|
|
632 |
}
|
633 |
function enhanceTextareaFocus() {
|
634 |
const textarea = document.getElementById('sujet-francais'); const counter = document.getElementById('character-count'); if(!textarea || !counter) return;
|
635 |
+
textarea.addEventListener('input', () => { const length = textarea.value.length; counter.textContent = `${length}c`; textarea.classList.remove('border-red-500'); });
|
636 |
}
|
637 |
function enhanceRadioButtons() {
|
638 |
document.querySelectorAll('input[type="radio"] + span').forEach(label => {
|
|
|
660 |
checkDeepThinkAvailability();
|
661 |
afficherSauvegardes();
|
662 |
|
663 |
+
// MODIFICATION: Empêcher le menu contextuel (clic droit)
|
664 |
+
document.addEventListener('contextmenu', function(event) {
|
665 |
+
// Optionnel: Autoriser le clic droit sur les inputs/textareas
|
666 |
+
// if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
|
667 |
+
// return;
|
668 |
+
// }
|
669 |
+
event.preventDefault();
|
670 |
+
});
|
671 |
+
|
672 |
+
// MODIFICATION: Empêcher le début de sélection (complément CSS)
|
673 |
+
document.addEventListener('selectstart', function(event) {
|
674 |
+
// Autoriser la sélection dans les inputs et textareas
|
675 |
+
if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
|
676 |
+
return;
|
677 |
+
}
|
678 |
+
// Optionnel: Autoriser la sélection dans les zones de sortie générées
|
679 |
+
// const outputIds = ['francais-output', 'etude-texte-output'];
|
680 |
+
// let parent = event.target.closest('.prose'); // Check if selection starts within a prose element
|
681 |
+
// if (parent && outputIds.includes(parent.id)) {
|
682 |
+
// return;
|
683 |
+
// }
|
684 |
+
// Optionnel: Autoriser la sélection dans les sauvegardes affichées
|
685 |
+
// if (event.target.closest('.backup-content')) {
|
686 |
+
// return;
|
687 |
+
// }
|
688 |
+
|
689 |
+
event.preventDefault();
|
690 |
+
});
|
691 |
+
|
692 |
// Welcome Message
|
693 |
try {
|
694 |
const showWelcome = sessionStorage.getItem('welcomeShown') !== 'true';
|
|
|
699 |
const welcomeMsg = welcomeContainer.firstElementChild;
|
700 |
setTimeout(() => { welcomeMsg.classList.remove('opacity-0', 'translate-y-4'); }, 500);
|
701 |
welcomeMsg.querySelector('.close-welcome').addEventListener('click', () => closeWelcomeMessage(welcomeMsg));
|
702 |
+
setTimeout(() => { if (document.body.contains(welcomeMsg)) closeWelcomeMessage(welcomeMsg); }, 6000);
|
703 |
sessionStorage.setItem('welcomeShown', 'true');
|
704 |
}
|
705 |
} catch(e) { console.warn("SessionStorage (Welcome):", e); }
|