Upload index.html
Browse files- templates/index.html +98 -177
templates/index.html
CHANGED
@@ -2,163 +2,96 @@
|
|
2 |
<html lang="fr">
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
5 |
-
<
|
6 |
-
|
7 |
-
<script src="https://cdn.tailwindcss.com"></script>
|
8 |
-
|
|
|
9 |
<style>
|
10 |
-
|
11 |
-
|
12 |
-
.custom-prose h1, .custom-prose h2, .custom-prose h3 {
|
13 |
-
font-family: 'Playfair Display', serif;
|
14 |
-
margin-top: 2em;
|
15 |
-
margin-bottom: 1em;
|
16 |
-
line-height: 1.3;
|
17 |
-
}
|
18 |
-
|
19 |
-
.custom-prose p {
|
20 |
-
margin-bottom: 1.5em;
|
21 |
-
line-height: 1.8;
|
22 |
-
}
|
23 |
-
|
24 |
-
.custom-prose ul, .custom-prose ol {
|
25 |
-
margin-top: 1em;
|
26 |
-
margin-bottom: 1em;
|
27 |
-
padding-left: 1.5em;
|
28 |
-
}
|
29 |
-
|
30 |
-
.custom-prose li {
|
31 |
-
margin-bottom: 0.5em;
|
32 |
-
}
|
33 |
-
|
34 |
-
.markdown-table table {
|
35 |
-
width: 100%;
|
36 |
-
border-collapse: separate;
|
37 |
-
border-spacing: 0;
|
38 |
-
margin: 2em 0;
|
39 |
-
background: white;
|
40 |
-
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
41 |
-
}
|
42 |
-
|
43 |
-
.markdown-table th {
|
44 |
-
background: #1a365d;
|
45 |
-
color: white;
|
46 |
-
font-weight: 600;
|
47 |
-
padding: 1rem;
|
48 |
-
text-align: left;
|
49 |
-
}
|
50 |
-
|
51 |
-
.markdown-table td {
|
52 |
-
padding: 1rem;
|
53 |
-
border-bottom: 1px solid #e2e8f0;
|
54 |
-
}
|
55 |
-
|
56 |
-
.markdown-table tr:hover {
|
57 |
-
background: #f8fafc;
|
58 |
-
}
|
59 |
-
|
60 |
.spinner {
|
61 |
border: 4px solid rgba(0, 0, 0, 0.1);
|
62 |
width: 3rem;
|
63 |
height: 3rem;
|
64 |
border-radius: 50%;
|
65 |
-
border-left-color: #
|
66 |
animation: spin 1s linear infinite;
|
67 |
}
|
68 |
-
|
69 |
@keyframes spin {
|
70 |
to { transform: rotate(360deg); }
|
71 |
}
|
72 |
-
|
73 |
-
.
|
74 |
-
|
75 |
-
|
|
|
76 |
}
|
77 |
-
|
78 |
-
.
|
79 |
-
|
80 |
-
|
81 |
-
|
|
|
|
|
|
|
|
|
82 |
}
|
83 |
</style>
|
84 |
</head>
|
85 |
-
<body class="bg-
|
86 |
-
<div class="max-w-
|
87 |
-
<!-- En-tête -->
|
88 |
-
<header class="text-center
|
89 |
-
<h1 class="
|
90 |
-
<p class="text-xl text-gray-600">
|
91 |
</header>
|
92 |
|
93 |
-
<div class="bg-white rounded-
|
94 |
-
<!--
|
95 |
-
<form id="uploadForm" class="
|
96 |
-
<
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
<div class="text-sm text-gray-600">
|
106 |
-
<label for="imageInput" class="relative cursor-pointer bg-white rounded-md font-medium text-blue-600 hover:text-blue-500 focus-within:outline-none">
|
107 |
-
<span>Télécharger un fichier</span>
|
108 |
-
<input id="imageInput" name="image" type="file" class="sr-only" accept="image/*" required>
|
109 |
-
</label>
|
110 |
-
</div>
|
111 |
-
<p class="text-xs text-gray-500">PNG, JPG jusqu'à 10MB</p>
|
112 |
-
</div>
|
113 |
-
</div>
|
114 |
-
</div>
|
115 |
-
|
116 |
-
<!-- Prévisualisation -->
|
117 |
-
<div id="previewContainer" class="hidden">
|
118 |
-
<p class="text-gray-700 font-medium mb-3">Aperçu du document :</p>
|
119 |
-
<div class="relative rounded-lg overflow-hidden bg-gray-100">
|
120 |
-
<img id="previewImage" src="#" alt="Aperçu" class="w-full max-h-80 object-contain">
|
121 |
-
</div>
|
122 |
</div>
|
123 |
-
|
124 |
-
|
125 |
-
Lancer l'analyse
|
126 |
</button>
|
127 |
</form>
|
128 |
|
129 |
<!-- Indicateur de chargement -->
|
130 |
-
<div id="loading" class="hidden">
|
131 |
-
<div class="
|
132 |
-
|
133 |
-
<div class="spinner mx-auto mb-4"></div>
|
134 |
-
<p class="text-gray-700 font-medium">Analyse en cours...</p>
|
135 |
-
</div>
|
136 |
-
</div>
|
137 |
</div>
|
138 |
|
139 |
-
<!--
|
140 |
-
<
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
</
|
149 |
-
|
150 |
-
|
151 |
-
<!--
|
152 |
-
<
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
<div id="tableauContent" class="hidden markdown-table prose prose-lg max-w-none">
|
157 |
-
</div>
|
158 |
</div>
|
159 |
</div>
|
160 |
</div>
|
161 |
|
|
|
162 |
<script>
|
163 |
const uploadForm = document.getElementById('uploadForm');
|
164 |
const imageInput = document.getElementById('imageInput');
|
@@ -166,20 +99,12 @@
|
|
166 |
const previewImage = document.getElementById('previewImage');
|
167 |
const loadingIndicator = document.getElementById('loading');
|
168 |
const resultDiv = document.getElementById('result');
|
169 |
-
const
|
170 |
-
const
|
171 |
-
const dissertationContent = document.getElementById('dissertationContent');
|
172 |
const tableauContent = document.getElementById('tableauContent');
|
|
|
173 |
|
174 |
-
//
|
175 |
-
marked.setOptions({
|
176 |
-
breaks: true,
|
177 |
-
gfm: true,
|
178 |
-
headerIds: true,
|
179 |
-
langPrefix: 'language-',
|
180 |
-
});
|
181 |
-
|
182 |
-
// Prévisualisation
|
183 |
imageInput.addEventListener('change', function() {
|
184 |
const file = this.files[0];
|
185 |
if (file) {
|
@@ -194,27 +119,16 @@
|
|
194 |
}
|
195 |
});
|
196 |
|
197 |
-
// Gestion
|
198 |
-
dissertationTab.addEventListener('click', function() {
|
199 |
-
dissertationTab.classList.add('text-blue-600', 'border-b-2', 'border-blue-600');
|
200 |
-
tableauTab.classList.remove('text-blue-600', 'border-b-2', 'border-blue-600');
|
201 |
-
dissertationContent.classList.remove('hidden');
|
202 |
-
tableauContent.classList.add('hidden');
|
203 |
-
});
|
204 |
-
|
205 |
-
tableauTab.addEventListener('click', function() {
|
206 |
-
tableauTab.classList.add('text-blue-600', 'border-b-2', 'border-blue-600');
|
207 |
-
dissertationTab.classList.remove('text-blue-600', 'border-b-2', 'border-blue-600');
|
208 |
-
tableauContent.classList.remove('hidden');
|
209 |
-
dissertationContent.classList.add('hidden');
|
210 |
-
});
|
211 |
-
|
212 |
-
// Soumission du formulaire
|
213 |
uploadForm.addEventListener('submit', function(e) {
|
214 |
e.preventDefault();
|
|
|
|
|
215 |
loadingIndicator.classList.remove('hidden');
|
216 |
resultDiv.classList.add('hidden');
|
217 |
-
|
|
|
|
|
218 |
const formData = new FormData(uploadForm);
|
219 |
|
220 |
fetch('/analyze', {
|
@@ -225,32 +139,39 @@
|
|
225 |
.then(data => {
|
226 |
loadingIndicator.classList.add('hidden');
|
227 |
if (data.error) {
|
228 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
}
|
230 |
-
|
231 |
-
dissertationContent.innerHTML = marked.parse(data.dissertation);
|
232 |
-
tableauContent.innerHTML = marked.parse(data.tableau);
|
233 |
-
|
234 |
-
resultDiv.classList.remove('hidden');
|
235 |
-
// Afficher l'onglet dissertation par défaut
|
236 |
-
dissertationTab.click();
|
237 |
-
|
238 |
-
// Scroll vers les résultats
|
239 |
-
resultDiv.scrollIntoView({ behavior: 'smooth' });
|
240 |
})
|
241 |
.catch(error => {
|
242 |
loadingIndicator.classList.add('hidden');
|
243 |
-
|
|
|
244 |
});
|
245 |
});
|
246 |
|
247 |
-
//
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
|
|
|
|
|
|
|
|
|
|
253 |
});
|
254 |
</script>
|
255 |
</body>
|
256 |
-
</html>
|
|
|
2 |
<html lang="fr">
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
5 |
+
<title>Mariam AI - Section Commentaire Composé</title>
|
6 |
+
<!-- Intégration de Tailwind CSS avec le plugin Typography -->
|
7 |
+
<script src="https://cdn.tailwindcss.com?plugins=typography"></script>
|
8 |
+
<!-- Intégration de Marked.js pour la conversion Markdown -->
|
9 |
+
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
10 |
<style>
|
11 |
+
/* Spinner personnalisé */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
.spinner {
|
13 |
border: 4px solid rgba(0, 0, 0, 0.1);
|
14 |
width: 3rem;
|
15 |
height: 3rem;
|
16 |
border-radius: 50%;
|
17 |
+
border-left-color: #4f46e5;
|
18 |
animation: spin 1s linear infinite;
|
19 |
}
|
|
|
20 |
@keyframes spin {
|
21 |
to { transform: rotate(360deg); }
|
22 |
}
|
23 |
+
/* Style personnalisé pour les tableaux générés en Markdown */
|
24 |
+
.prose table {
|
25 |
+
width: 100%;
|
26 |
+
max-width: 100%;
|
27 |
+
border-collapse: collapse;
|
28 |
}
|
29 |
+
.prose th,
|
30 |
+
.prose td {
|
31 |
+
border: 1px solid #e5e7eb;
|
32 |
+
padding: 0.75rem;
|
33 |
+
text-align: left;
|
34 |
+
}
|
35 |
+
.prose th {
|
36 |
+
background-color: #f3f4f6;
|
37 |
+
font-weight: 600;
|
38 |
}
|
39 |
</style>
|
40 |
</head>
|
41 |
+
<body class="bg-gray-100">
|
42 |
+
<div class="max-w-3xl mx-auto p-4">
|
43 |
+
<!-- En-tête de l'application -->
|
44 |
+
<header class="mb-8 text-center">
|
45 |
+
<h1 class="text-4xl font-extrabold text-gray-800">Mariam AI</h1>
|
46 |
+
<p class="text-xl text-gray-600">Section Commentaire Composé</p>
|
47 |
</header>
|
48 |
|
49 |
+
<div class="bg-white rounded-lg shadow-lg p-6">
|
50 |
+
<!-- Formulaire d'upload et prévisualisation -->
|
51 |
+
<form id="uploadForm" enctype="multipart/form-data" class="mb-6">
|
52 |
+
<label for="imageInput" class="block text-lg font-medium text-gray-700 mb-2">
|
53 |
+
Sélectionnez une image :
|
54 |
+
</label>
|
55 |
+
<input type="file" name="image" id="imageInput" accept="image/*" required
|
56 |
+
class="block w-full border border-gray-300 rounded-md p-2 mb-4 focus:ring focus:ring-blue-300">
|
57 |
+
<!-- Prévisualisation de l'image -->
|
58 |
+
<div id="previewContainer" class="mb-4 hidden">
|
59 |
+
<p class="text-gray-700 font-medium mb-2">Prévisualisation :</p>
|
60 |
+
<img id="previewImage" src="#" alt="Prévisualisation" class="w-full max-h-64 object-contain rounded-lg shadow-md">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
</div>
|
62 |
+
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition-colors">
|
63 |
+
Analyser
|
|
|
64 |
</button>
|
65 |
</form>
|
66 |
|
67 |
<!-- Indicateur de chargement -->
|
68 |
+
<div id="loading" class="flex flex-col items-center space-y-2 mb-6 hidden">
|
69 |
+
<div class="spinner"></div>
|
70 |
+
<span class="text-gray-700 font-medium">Analyse en cours...</span>
|
|
|
|
|
|
|
|
|
71 |
</div>
|
72 |
|
73 |
+
<!-- Bouton pour afficher/masquer le tableau d'analyse -->
|
74 |
+
<button id="toggleButton" class="hidden bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-4 rounded w-full mb-4 transition-colors">
|
75 |
+
Afficher le Tableau
|
76 |
+
</button>
|
77 |
+
|
78 |
+
<!-- Zone de résultats -->
|
79 |
+
<div id="result" class="hidden">
|
80 |
+
<!-- Section Dissertation -->
|
81 |
+
<section class="mb-8">
|
82 |
+
<h2 class="text-2xl font-semibold text-gray-800 mb-4">Dissertation</h2>
|
83 |
+
<div id="dissertationContent" class="prose prose-sm sm:prose lg:prose-xl bg-gray-50 border border-gray-200 rounded p-6 text-gray-800 overflow-x-auto"></div>
|
84 |
+
</section>
|
85 |
+
<!-- Section Tableau d'analyse -->
|
86 |
+
<section id="tableauSection" class="hidden">
|
87 |
+
<h2 class="text-2xl font-semibold text-gray-800 mb-4">Tableau d'analyse</h2>
|
88 |
+
<div id="tableauContent" class="prose prose-sm sm:prose lg:prose-xl bg-gray-50 border border-gray-200 rounded p-6 text-gray-800 overflow-x-auto"></div>
|
89 |
+
</section>
|
|
|
|
|
90 |
</div>
|
91 |
</div>
|
92 |
</div>
|
93 |
|
94 |
+
<!-- Script JavaScript -->
|
95 |
<script>
|
96 |
const uploadForm = document.getElementById('uploadForm');
|
97 |
const imageInput = document.getElementById('imageInput');
|
|
|
99 |
const previewImage = document.getElementById('previewImage');
|
100 |
const loadingIndicator = document.getElementById('loading');
|
101 |
const resultDiv = document.getElementById('result');
|
102 |
+
const toggleButton = document.getElementById('toggleButton');
|
103 |
+
const tableauSection = document.getElementById('tableauSection');
|
|
|
104 |
const tableauContent = document.getElementById('tableauContent');
|
105 |
+
const dissertationContent = document.getElementById('dissertationContent');
|
106 |
|
107 |
+
// Prévisualisation de l'image sélectionnée
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
imageInput.addEventListener('change', function() {
|
109 |
const file = this.files[0];
|
110 |
if (file) {
|
|
|
119 |
}
|
120 |
});
|
121 |
|
122 |
+
// Gestion de la soumission du formulaire
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
uploadForm.addEventListener('submit', function(e) {
|
124 |
e.preventDefault();
|
125 |
+
|
126 |
+
// Afficher le chargement et masquer les résultats
|
127 |
loadingIndicator.classList.remove('hidden');
|
128 |
resultDiv.classList.add('hidden');
|
129 |
+
toggleButton.classList.add('hidden');
|
130 |
+
tableauSection.classList.add('hidden');
|
131 |
+
|
132 |
const formData = new FormData(uploadForm);
|
133 |
|
134 |
fetch('/analyze', {
|
|
|
139 |
.then(data => {
|
140 |
loadingIndicator.classList.add('hidden');
|
141 |
if (data.error) {
|
142 |
+
alert("Erreur : " + data.error);
|
143 |
+
} else {
|
144 |
+
// Convertir le Markdown en HTML via Marked.js
|
145 |
+
dissertationContent.innerHTML = marked.parse(data.dissertation);
|
146 |
+
tableauContent.innerHTML = marked.parse(data.tableau);
|
147 |
+
|
148 |
+
// Afficher la zone de résultats et le bouton de basculement
|
149 |
+
resultDiv.classList.remove('hidden');
|
150 |
+
toggleButton.classList.remove('hidden');
|
151 |
+
// Masquer le tableau par défaut
|
152 |
+
tableauSection.classList.add('hidden');
|
153 |
+
toggleButton.textContent = 'Afficher le Tableau';
|
154 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
})
|
156 |
.catch(error => {
|
157 |
loadingIndicator.classList.add('hidden');
|
158 |
+
console.error(error);
|
159 |
+
alert("Une erreur est survenue lors de l'analyse.");
|
160 |
});
|
161 |
});
|
162 |
|
163 |
+
// Gestion du bouton d'affichage/masquage du tableau
|
164 |
+
toggleButton.addEventListener('click', function() {
|
165 |
+
if (tableauSection.classList.contains('hidden')) {
|
166 |
+
tableauSection.classList.remove('hidden');
|
167 |
+
toggleButton.textContent = 'Masquer le Tableau';
|
168 |
+
// Défilement automatique vers le tableau
|
169 |
+
tableauSection.scrollIntoView({ behavior: 'smooth' });
|
170 |
+
} else {
|
171 |
+
tableauSection.classList.add('hidden');
|
172 |
+
toggleButton.textContent = 'Afficher le Tableau';
|
173 |
+
}
|
174 |
});
|
175 |
</script>
|
176 |
</body>
|
177 |
+
</html>
|