Update templates/index.html
Browse files- templates/index.html +151 -8
templates/index.html
CHANGED
|
@@ -41,6 +41,89 @@
|
|
| 41 |
border-radius: 0.25rem;
|
| 42 |
font-family: ui-monospace, monospace;
|
| 43 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
@keyframes fadeIn {
|
| 45 |
from { opacity: 0; }
|
| 46 |
to { opacity: 1; }
|
|
@@ -48,6 +131,14 @@
|
|
| 48 |
.animate-fade-in {
|
| 49 |
animation: fadeIn 1s ease-out;
|
| 50 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
</style>
|
| 52 |
</head>
|
| 53 |
<body class="bg-gray-50 min-h-screen">
|
|
@@ -65,9 +156,10 @@
|
|
| 65 |
<!-- Main Content -->
|
| 66 |
<div class="grid md:grid-cols-2 gap-8">
|
| 67 |
<!-- Upload Section -->
|
| 68 |
-
<div class="bg-white rounded-xl shadow-lg p-6">
|
| 69 |
<h2 class="text-2xl font-semibold text-primary mb-4">📷 Téléchargement d'images</h2>
|
| 70 |
<div
|
|
|
|
| 71 |
class="upload-zone border-2 border-dashed border-primary rounded-lg p-8 text-center cursor-pointer hover:bg-gray-50 transition-colors"
|
| 72 |
onclick="document.getElementById('image-upload').click()">
|
| 73 |
<input type="file" id="image-upload" multiple accept="image/*" class="hidden">
|
|
@@ -82,7 +174,11 @@
|
|
| 82 |
</div>
|
| 83 |
|
| 84 |
<!-- Bouton de soumission (seulement) -->
|
| 85 |
-
<div class="bg-white rounded-xl shadow-lg p-6 flex flex-col justify-center">
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
<button id="submit-btn" class="w-full mt-6 bg-primary hover:bg-primary-dark text-white font-bold py-3 px-6 rounded-lg transition-all transform hover:-translate-y-1 hover:shadow-lg disabled:opacity-50 disabled:cursor-not-allowed">
|
| 87 |
🚀 Soumettre
|
| 88 |
</button>
|
|
@@ -90,7 +186,7 @@
|
|
| 90 |
</div>
|
| 91 |
|
| 92 |
<!-- Résultats -->
|
| 93 |
-
<div id="results" class="mt-12 bg-white rounded-xl shadow-lg p-6 hidden">
|
| 94 |
<h2 class="text-2xl font-semibold text-primary mb-4">📝 Résultat de l'analyse</h2>
|
| 95 |
<div id="analysis-result" class="markdown-content prose max-w-none"></div>
|
| 96 |
</div>
|
|
@@ -109,12 +205,44 @@
|
|
| 109 |
const submitBtn = document.getElementById('submit-btn');
|
| 110 |
const resultsSection = document.getElementById('results');
|
| 111 |
const analysisResult = document.getElementById('analysis-result');
|
|
|
|
| 112 |
|
| 113 |
let uploadedFiles = [];
|
| 114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
imageUpload.addEventListener('change', handleFileSelect);
|
| 116 |
submitBtn.addEventListener('click', handleSubmit);
|
| 117 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
function handleFileSelect(event) {
|
| 119 |
uploadedFiles = Array.from(event.target.files);
|
| 120 |
updatePreview();
|
|
@@ -126,12 +254,13 @@
|
|
| 126 |
const preview = document.createElement('div');
|
| 127 |
preview.className = 'relative';
|
| 128 |
preview.innerHTML = `
|
| 129 |
-
<img src="${URL.createObjectURL(file)}" alt="Preview" class="w-full h-32 object-cover rounded-lg">
|
| 130 |
-
<button onclick="removeImage(${index})" class="absolute top-2 right-2 bg-red-500 text-white rounded-full p-1 hover:bg-red-600">
|
| 131 |
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 132 |
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
| 133 |
</svg>
|
| 134 |
</button>
|
|
|
|
| 135 |
`;
|
| 136 |
previewContainer.appendChild(preview);
|
| 137 |
});
|
|
@@ -168,9 +297,23 @@
|
|
| 168 |
throw new Error(data.error);
|
| 169 |
}
|
| 170 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
resultsSection.classList.remove('hidden');
|
| 172 |
-
analysisResult.innerHTML = marked.parse(
|
| 173 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
} catch (error) {
|
| 175 |
alert('Erreur lors de l\'analyse: ' + error.message);
|
| 176 |
} finally {
|
|
@@ -183,4 +326,4 @@
|
|
| 183 |
});
|
| 184 |
</script>
|
| 185 |
</body>
|
| 186 |
-
</html>
|
|
|
|
| 41 |
border-radius: 0.25rem;
|
| 42 |
font-family: ui-monospace, monospace;
|
| 43 |
}
|
| 44 |
+
/* Amélioration pour les paragraphes et espaces */
|
| 45 |
+
.markdown-content p {
|
| 46 |
+
margin-bottom: 1rem;
|
| 47 |
+
line-height: 1.7;
|
| 48 |
+
white-space: pre-line;
|
| 49 |
+
}
|
| 50 |
+
/* Styles pour les titres */
|
| 51 |
+
.markdown-content h1 {
|
| 52 |
+
font-size: 1.8rem;
|
| 53 |
+
font-weight: bold;
|
| 54 |
+
margin-top: 1.5rem;
|
| 55 |
+
margin-bottom: 1rem;
|
| 56 |
+
padding-bottom: 0.5rem;
|
| 57 |
+
border-bottom: 1px solid #e2e8f0;
|
| 58 |
+
color: #2d3748;
|
| 59 |
+
}
|
| 60 |
+
.markdown-content h2 {
|
| 61 |
+
font-size: 1.5rem;
|
| 62 |
+
font-weight: bold;
|
| 63 |
+
margin-top: 1.25rem;
|
| 64 |
+
margin-bottom: 0.75rem;
|
| 65 |
+
color: #2d3748;
|
| 66 |
+
}
|
| 67 |
+
.markdown-content h3 {
|
| 68 |
+
font-size: 1.25rem;
|
| 69 |
+
font-weight: bold;
|
| 70 |
+
margin-top: 1rem;
|
| 71 |
+
margin-bottom: 0.5rem;
|
| 72 |
+
color: #2d3748;
|
| 73 |
+
}
|
| 74 |
+
/* Styles pour les listes */
|
| 75 |
+
.markdown-content ul, .markdown-content ol {
|
| 76 |
+
margin-left: 1.5rem;
|
| 77 |
+
margin-bottom: 1rem;
|
| 78 |
+
padding-left: 1rem;
|
| 79 |
+
}
|
| 80 |
+
.markdown-content li {
|
| 81 |
+
margin-bottom: 0.5rem;
|
| 82 |
+
}
|
| 83 |
+
.markdown-content ul {
|
| 84 |
+
list-style-type: disc;
|
| 85 |
+
}
|
| 86 |
+
.markdown-content ol {
|
| 87 |
+
list-style-type: decimal;
|
| 88 |
+
}
|
| 89 |
+
/* Styles pour les citations */
|
| 90 |
+
.markdown-content blockquote {
|
| 91 |
+
border-left: 4px solid #4CAF50;
|
| 92 |
+
padding: 0.5rem 1rem;
|
| 93 |
+
margin: 1rem 0;
|
| 94 |
+
background-color: #f8f9fa;
|
| 95 |
+
font-style: italic;
|
| 96 |
+
color: #4a5568;
|
| 97 |
+
}
|
| 98 |
+
/* Styles pour les tableaux */
|
| 99 |
+
.markdown-content table {
|
| 100 |
+
border-collapse: collapse;
|
| 101 |
+
width: 100%;
|
| 102 |
+
margin: 1rem 0;
|
| 103 |
+
}
|
| 104 |
+
.markdown-content th,
|
| 105 |
+
.markdown-content td {
|
| 106 |
+
padding: 0.5rem;
|
| 107 |
+
border: 1px solid #e2e8f0;
|
| 108 |
+
}
|
| 109 |
+
.markdown-content th {
|
| 110 |
+
background-color: #f8f9fa;
|
| 111 |
+
font-weight: bold;
|
| 112 |
+
}
|
| 113 |
+
/* Styles pour les séparateurs */
|
| 114 |
+
.markdown-content hr {
|
| 115 |
+
margin: 1.5rem 0;
|
| 116 |
+
border: 0;
|
| 117 |
+
border-top: 1px solid #e2e8f0;
|
| 118 |
+
}
|
| 119 |
+
/* Style pour les liens */
|
| 120 |
+
.markdown-content a {
|
| 121 |
+
color: #4CAF50;
|
| 122 |
+
text-decoration: underline;
|
| 123 |
+
}
|
| 124 |
+
.markdown-content a:hover {
|
| 125 |
+
text-decoration: none;
|
| 126 |
+
}
|
| 127 |
@keyframes fadeIn {
|
| 128 |
from { opacity: 0; }
|
| 129 |
to { opacity: 1; }
|
|
|
|
| 131 |
.animate-fade-in {
|
| 132 |
animation: fadeIn 1s ease-out;
|
| 133 |
}
|
| 134 |
+
/* Style pour le conteneur des résultats */
|
| 135 |
+
#results {
|
| 136 |
+
transition: all 0.3s ease;
|
| 137 |
+
}
|
| 138 |
+
/* Ombres plus marquées pour les cartes */
|
| 139 |
+
.card-shadow {
|
| 140 |
+
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.1);
|
| 141 |
+
}
|
| 142 |
</style>
|
| 143 |
</head>
|
| 144 |
<body class="bg-gray-50 min-h-screen">
|
|
|
|
| 156 |
<!-- Main Content -->
|
| 157 |
<div class="grid md:grid-cols-2 gap-8">
|
| 158 |
<!-- Upload Section -->
|
| 159 |
+
<div class="bg-white rounded-xl shadow-lg p-6 card-shadow">
|
| 160 |
<h2 class="text-2xl font-semibold text-primary mb-4">📷 Téléchargement d'images</h2>
|
| 161 |
<div
|
| 162 |
+
id="upload-zone"
|
| 163 |
class="upload-zone border-2 border-dashed border-primary rounded-lg p-8 text-center cursor-pointer hover:bg-gray-50 transition-colors"
|
| 164 |
onclick="document.getElementById('image-upload').click()">
|
| 165 |
<input type="file" id="image-upload" multiple accept="image/*" class="hidden">
|
|
|
|
| 174 |
</div>
|
| 175 |
|
| 176 |
<!-- Bouton de soumission (seulement) -->
|
| 177 |
+
<div class="bg-white rounded-xl shadow-lg p-6 flex flex-col justify-center card-shadow">
|
| 178 |
+
<h2 class="text-2xl font-semibold text-primary mb-4">🧠 Analyse Philosophique</h2>
|
| 179 |
+
<p class="text-gray-600 mb-6">
|
| 180 |
+
Cette analyse vous fournira une réflexion philosophique approfondie basée sur le(s) document(s) téléchargé(s).
|
| 181 |
+
</p>
|
| 182 |
<button id="submit-btn" class="w-full mt-6 bg-primary hover:bg-primary-dark text-white font-bold py-3 px-6 rounded-lg transition-all transform hover:-translate-y-1 hover:shadow-lg disabled:opacity-50 disabled:cursor-not-allowed">
|
| 183 |
🚀 Soumettre
|
| 184 |
</button>
|
|
|
|
| 186 |
</div>
|
| 187 |
|
| 188 |
<!-- Résultats -->
|
| 189 |
+
<div id="results" class="mt-12 bg-white rounded-xl shadow-lg p-6 hidden animate-fade-in card-shadow">
|
| 190 |
<h2 class="text-2xl font-semibold text-primary mb-4">📝 Résultat de l'analyse</h2>
|
| 191 |
<div id="analysis-result" class="markdown-content prose max-w-none"></div>
|
| 192 |
</div>
|
|
|
|
| 205 |
const submitBtn = document.getElementById('submit-btn');
|
| 206 |
const resultsSection = document.getElementById('results');
|
| 207 |
const analysisResult = document.getElementById('analysis-result');
|
| 208 |
+
const uploadZone = document.getElementById('upload-zone');
|
| 209 |
|
| 210 |
let uploadedFiles = [];
|
| 211 |
|
| 212 |
+
// Configuration de marked pour mieux gérer les espaces et retours à la ligne
|
| 213 |
+
marked.setOptions({
|
| 214 |
+
breaks: true, // Convertit les retours à la ligne en <br>
|
| 215 |
+
gfm: true, // GitHub Flavored Markdown
|
| 216 |
+
headerIds: true, // Ajoute des IDs aux en-têtes
|
| 217 |
+
mangle: false, // Pas de mangling des caractères spéciaux
|
| 218 |
+
smartLists: true, // Meilleur rendu des listes
|
| 219 |
+
smartypants: true, // Transforme les quotes, tirets etc.
|
| 220 |
+
xhtml: true // Utilise la syntaxe XHTML
|
| 221 |
+
});
|
| 222 |
+
|
| 223 |
imageUpload.addEventListener('change', handleFileSelect);
|
| 224 |
submitBtn.addEventListener('click', handleSubmit);
|
| 225 |
|
| 226 |
+
// Support pour le drag and drop
|
| 227 |
+
uploadZone.addEventListener('dragover', (e) => {
|
| 228 |
+
e.preventDefault();
|
| 229 |
+
uploadZone.classList.add('bg-gray-50');
|
| 230 |
+
});
|
| 231 |
+
|
| 232 |
+
uploadZone.addEventListener('dragleave', () => {
|
| 233 |
+
uploadZone.classList.remove('bg-gray-50');
|
| 234 |
+
});
|
| 235 |
+
|
| 236 |
+
uploadZone.addEventListener('drop', (e) => {
|
| 237 |
+
e.preventDefault();
|
| 238 |
+
uploadZone.classList.remove('bg-gray-50');
|
| 239 |
+
const files = Array.from(e.dataTransfer.files).filter(file => file.type.startsWith('image/'));
|
| 240 |
+
if (files.length > 0) {
|
| 241 |
+
uploadedFiles = files;
|
| 242 |
+
updatePreview();
|
| 243 |
+
}
|
| 244 |
+
});
|
| 245 |
+
|
| 246 |
function handleFileSelect(event) {
|
| 247 |
uploadedFiles = Array.from(event.target.files);
|
| 248 |
updatePreview();
|
|
|
|
| 254 |
const preview = document.createElement('div');
|
| 255 |
preview.className = 'relative';
|
| 256 |
preview.innerHTML = `
|
| 257 |
+
<img src="${URL.createObjectURL(file)}" alt="Preview" class="w-full h-32 object-cover rounded-lg shadow-md">
|
| 258 |
+
<button onclick="removeImage(${index})" class="absolute top-2 right-2 bg-red-500 text-white rounded-full p-1 hover:bg-red-600 shadow-sm transition-all transform hover:scale-110">
|
| 259 |
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 260 |
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
| 261 |
</svg>
|
| 262 |
</button>
|
| 263 |
+
<div class="mt-1 text-sm text-gray-600 truncate">${file.name}</div>
|
| 264 |
`;
|
| 265 |
previewContainer.appendChild(preview);
|
| 266 |
});
|
|
|
|
| 297 |
throw new Error(data.error);
|
| 298 |
}
|
| 299 |
|
| 300 |
+
// Préparation des données Markdown pour un meilleur rendu
|
| 301 |
+
let markdownContent = data.result;
|
| 302 |
+
|
| 303 |
+
// Assurer que les doubles retours à la ligne sont bien rendus
|
| 304 |
+
markdownContent = markdownContent.replace(/\n\n/g, '\n \n');
|
| 305 |
+
|
| 306 |
+
// Préserver les espaces multiples
|
| 307 |
+
markdownContent = markdownContent.replace(/ +/g, match => ' '.repeat(match.length));
|
| 308 |
+
|
| 309 |
resultsSection.classList.remove('hidden');
|
| 310 |
+
analysisResult.innerHTML = marked.parse(markdownContent);
|
| 311 |
+
|
| 312 |
+
// Animation douce pour le scroll
|
| 313 |
+
resultsSection.scrollIntoView({
|
| 314 |
+
behavior: 'smooth',
|
| 315 |
+
block: 'start'
|
| 316 |
+
});
|
| 317 |
} catch (error) {
|
| 318 |
alert('Erreur lors de l\'analyse: ' + error.message);
|
| 319 |
} finally {
|
|
|
|
| 326 |
});
|
| 327 |
</script>
|
| 328 |
</body>
|
| 329 |
+
</html>
|