Docfile commited on
Commit
811a2c3
·
verified ·
1 Parent(s): b79d861

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +114 -98
templates/index.html CHANGED
@@ -4,181 +4,197 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Mariam AI - Analyse d'Image</title>
7
- <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/3.3.2/tailwind.min.css" rel="stylesheet">
8
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js"></script>
9
- <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
10
  <style>
11
- /* Animation de loader */
12
  .loader {
13
  width: 48px;
14
  height: 48px;
15
- border: 5px solid #e5e7eb;
16
- border-top-color: #4f46e5;
17
  border-radius: 50%;
18
- animation: spin 1s linear infinite;
 
 
19
  }
20
 
21
- @keyframes spin {
22
- to {
23
- transform: rotate(360deg);
24
- }
25
  }
26
 
27
- /* Animation de fade-in */
28
  .fade-in {
29
- animation: fadeIn 0.5s ease-in-out;
30
  }
31
 
32
  @keyframes fadeIn {
33
- from {
34
- opacity: 0;
35
- }
36
- to {
37
- opacity: 1;
38
- }
 
 
 
 
 
 
39
  }
40
- </style>
41
- </head>
42
- <body class="bg-gray-50 text-gray-800 min-h-screen flex flex-col">
43
 
44
- <!-- Header -->
45
- <header class="bg-white shadow-md">
46
- <div class="max-w-7xl mx-auto px-4 py-6">
47
- <h1 class="text-4xl font-extrabold text-indigo-600">Mariam AI</h1>
48
- <p class="mt-2 text-sm text-gray-500">Un assistant intelligent pour l'analyse d'image et la rédaction de dissertations.</p>
49
- </div>
50
- </header>
51
 
52
- <!-- Main Content -->
53
- <main class="flex-1 flex items-center justify-center px-4 py-8">
54
- <div class="bg-white shadow-lg rounded-lg w-full max-w-3xl p-8 space-y-8">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
 
 
56
  <!-- Upload Section -->
57
- <div>
58
- <h2 class="text-2xl font-semibold text-gray-900">Téléversez votre image</h2>
59
- <p class="text-sm text-gray-500">Glissez et déposez une image ou cliquez pour choisir un fichier à analyser.</p>
60
- <form id="uploadForm" class="space-y-4 mt-4">
61
- <div class="upload-zone border-2 border-dashed border-indigo-500 rounded-lg p-6 text-center transition hover:bg-indigo-50">
62
- <input type="file" id="imageInput" accept="image/*" required class="hidden" onchange="handleImageUpload()">
63
  <label for="imageInput" class="cursor-pointer">
64
- <svg xmlns="http://www.w3.org/2000/svg" class="mx-auto h-12 w-12 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
65
- <path stroke-linecap="round" stroke-linejoin="round" d="M4 16l4-4a3 3 0 014 0l4 4m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
66
- </svg>
67
- <span id="fileName" class="block mt-2 text-sm text-gray-600">Cliquez ou glissez une image ici</span>
 
 
 
 
 
68
  </label>
69
  </div>
70
 
71
  <!-- Image Preview -->
72
- <div id="imagePreviewContainer" class="hidden mt-4 text-center">
73
- <h3 class="text-lg font-semibold text-gray-800 mb-2">Aperçu de l'image :</h3>
74
- <img id="imagePreview" src="" alt="Aperçu de l'image" class="mx-auto max-w-xs rounded-lg shadow">
75
  </div>
76
 
77
- <div class="text-center">
78
- <button type="submit" class="w-full sm:w-auto px-6 py-3 bg-indigo-600 text-white font-medium rounded-md hover:bg-indigo-700 transition">
 
79
  Analyser l'image
80
  </button>
81
  </div>
82
  </form>
83
  </div>
84
 
85
- <!-- Loading Indicator -->
86
- <div id="loading" class="hidden text-center space-y-4">
87
- <div class="loader mx-auto"></div>
88
- <p class="text-gray-500">Analyse en cours, veuillez patienter...</p>
 
 
89
  </div>
90
 
91
  <!-- Results Section -->
92
- <div id="results" class="hidden space-y-6 fade-in">
93
- <!-- Dissertation -->
94
- <div class="bg-gray-50 rounded-lg p-6 shadow">
95
- <h2 class="text-xl font-bold text-gray-800">Dissertation</h2>
96
- <div id="dissertationResult" class="prose prose-indigo max-w-none mt-4"></div>
97
- </div>
98
  <!-- Tableau Button -->
99
- <div class="text-center">
100
- <button id="showTableau" class="px-6 py-3 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition">
 
101
  Voir le tableau d'analyse
102
  </button>
103
  </div>
 
 
 
 
 
 
 
104
  </div>
105
- </div>
106
- </main>
107
 
108
  <script>
109
  let tableauContent = '';
110
 
111
- // Met à jour le nom du fichier téléversé et affiche un aperçu de l'image
112
- function handleImageUpload() {
113
  const input = document.getElementById('imageInput');
114
- const fileName = document.getElementById('fileName');
115
- const previewContainer = document.getElementById('imagePreviewContainer');
116
  const imagePreview = document.getElementById('imagePreview');
 
117
 
118
- if (input.files.length > 0) {
119
  const file = input.files[0];
120
  fileName.textContent = file.name;
121
 
122
- // Vérifie si le fichier est une image et génère l'aperçu
123
- if (file.type.startsWith('image/')) {
124
- const reader = new FileReader();
125
- reader.onload = (e) => {
126
- imagePreview.src = e.target.result;
127
- previewContainer.classList.remove('hidden');
128
- };
129
- reader.readAsDataURL(file);
130
- } else {
131
- previewContainer.classList.add('hidden');
132
- imagePreview.src = '';
133
- Swal.fire('Erreur', 'Veuillez téléverser un fichier image valide.', 'error');
134
- }
135
  } else {
136
- previewContainer.classList.add('hidden');
137
- imagePreview.src = '';
138
  fileName.textContent = 'Cliquez ou glissez une image ici';
 
139
  }
140
  }
141
 
142
- // Affiche le tableau dans une popup
143
- document.getElementById('showTableau').addEventListener('click', () => {
144
- Swal.fire({
145
- title: 'Tableau d\'analyse',
146
- html: marked.parse(tableauContent),
147
- width: '80%',
148
- customClass: {
149
- htmlContainer: 'prose prose-indigo max-w-none'
150
- }
151
- });
152
- });
153
-
154
- // Gestion du formulaire de téléversement
155
  document.getElementById('uploadForm').addEventListener('submit', async (e) => {
156
  e.preventDefault();
 
157
  const loading = document.getElementById('loading');
158
  const results = document.getElementById('results');
159
  const dissertationResult = document.getElementById('dissertationResult');
 
160
  const formData = new FormData();
161
  formData.append('image', document.getElementById('imageInput').files[0]);
162
-
163
  loading.classList.remove('hidden');
164
  results.classList.add('hidden');
165
-
166
  try {
167
  const response = await fetch('/analyze', {
168
  method: 'POST',
169
  body: formData
170
  });
171
-
172
  const data = await response.json();
 
173
  if (response.ok) {
174
  tableauContent = data.tableau;
175
  dissertationResult.innerHTML = marked.parse(data.dissertation);
176
  results.classList.remove('hidden');
 
177
  } else {
178
- Swal.fire('Erreur', data.error, 'error');
 
 
 
 
179
  }
180
  } catch (error) {
181
- Swal.fire('Erreur', 'Une erreur est survenue lors de l\'analyse.', 'error');
 
 
 
 
182
  } finally {
183
  loading.classList.add('hidden');
184
  }
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Mariam AI - Analyse d'Image</title>
7
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
8
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js"></script>
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.7.32/sweetalert2.all.min.js"></script>
10
  <style>
 
11
  .loader {
12
  width: 48px;
13
  height: 48px;
14
+ border: 5px solid #FFF;
15
+ border-bottom-color: #6366F1;
16
  border-radius: 50%;
17
+ display: inline-block;
18
+ box-sizing: border-box;
19
+ animation: rotation 1s linear infinite;
20
  }
21
 
22
+ @keyframes rotation {
23
+ 0% { transform: rotate(0deg); }
24
+ 100% { transform: rotate(360deg); }
 
25
  }
26
 
 
27
  .fade-in {
28
+ animation: fadeIn 0.5s ease-in;
29
  }
30
 
31
  @keyframes fadeIn {
32
+ 0% { opacity: 0; }
33
+ 100% { opacity: 1; }
34
+ }
35
+
36
+ .upload-zone {
37
+ border: 2px dashed #6366F1;
38
+ transition: all 0.3s ease;
39
+ }
40
+
41
+ .upload-zone:hover {
42
+ border-color: #4F46E5;
43
+ background-color: #EEF2FF;
44
  }
 
 
 
45
 
46
+ .preview-container {
47
+ margin-top: 1rem;
48
+ display: none; /* Par défaut, masqué */
49
+ }
 
 
 
50
 
51
+ .preview-container img {
52
+ max-width: 100%;
53
+ max-height: 300px;
54
+ border-radius: 8px;
55
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
56
+ }
57
+ </style>
58
+ </head>
59
+ <body class="bg-gray-50">
60
+ <div class="min-h-screen">
61
+ <!-- Header -->
62
+ <header class="bg-white shadow-sm">
63
+ <div class="max-w-7xl mx-auto px-4 py-4 sm:px-6 lg:px-8">
64
+ <h1 class="text-3xl font-bold text-indigo-600">Mariam AI</h1>
65
+ <p class="mt-1 text-sm text-gray-500">Assistant pour commentaire composé.</p>
66
+ </div>
67
+ </header>
68
 
69
+ <!-- Main content -->
70
+ <main class="max-w-7xl mx-auto px-4 py-8 sm:px-6 lg:px-8">
71
  <!-- Upload Section -->
72
+ <div class="bg-white rounded-lg shadow p-6 mb-8">
73
+ <form id="uploadForm" class="space-y-6">
74
+ <div class="upload-zone rounded-lg p-8 text-center">
75
+ <input type="file" id="imageInput" accept="image/*" required
76
+ class="hidden" onchange="updatePreview()">
 
77
  <label for="imageInput" class="cursor-pointer">
78
+ <div class="space-y-2">
79
+ <svg class="mx-auto h-12 w-12 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
80
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
81
+ d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
82
+ </svg>
83
+ <div id="fileName" class="text-sm text-gray-500">
84
+ Cliquez ou glissez une image ici
85
+ </div>
86
+ </div>
87
  </label>
88
  </div>
89
 
90
  <!-- Image Preview -->
91
+ <div class="preview-container text-center" id="previewContainer">
92
+ <p class="text-gray-500 text-sm mb-2">Prévisualisation de l'image :</p>
93
+ <img id="imagePreview" alt="Prévisualisation de l'image">
94
  </div>
95
 
96
+ <div class="flex justify-center">
97
+ <button type="submit"
98
+ class="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors duration-200">
99
  Analyser l'image
100
  </button>
101
  </div>
102
  </form>
103
  </div>
104
 
105
+ <!-- Loading indicator -->
106
+ <div id="loading" class="hidden">
107
+ <div class="flex flex-col items-center justify-center space-y-4">
108
+ <span class="loader"></span>
109
+ <p class="text-gray-500">Analyse en cours, veuillez patienter...</p>
110
+ </div>
111
  </div>
112
 
113
  <!-- Results Section -->
114
+ <div id="results" class="space-y-8 hidden">
 
 
 
 
 
115
  <!-- Tableau Button -->
116
+ <div class="flex justify-center">
117
+ <button id="showTableau"
118
+ class="px-6 py-3 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition-colors duration-200">
119
  Voir le tableau d'analyse
120
  </button>
121
  </div>
122
+
123
+ <!-- Dissertation -->
124
+ <div class="bg-white rounded-lg shadow p-6">
125
+ <h2 class="text-2xl font-bold text-gray-900 mb-4">Dissertation</h2>
126
+ <div id="dissertationResult" class="prose max-w-none markdown-content">
127
+ </div>
128
+ </div>
129
  </div>
130
+ </main>
131
+ </div>
132
 
133
  <script>
134
  let tableauContent = '';
135
 
136
+ function updatePreview() {
 
137
  const input = document.getElementById('imageInput');
138
+ const previewContainer = document.getElementById('previewContainer');
 
139
  const imagePreview = document.getElementById('imagePreview');
140
+ const fileName = document.getElementById('fileName');
141
 
142
+ if (input.files && input.files[0]) {
143
  const file = input.files[0];
144
  fileName.textContent = file.name;
145
 
146
+ // Prévisualisation de l'image
147
+ const reader = new FileReader();
148
+ reader.onload = (e) => {
149
+ imagePreview.src = e.target.result;
150
+ previewContainer.style.display = 'block'; // Afficher la prévisualisation
151
+ };
152
+ reader.readAsDataURL(file);
 
 
 
 
 
 
153
  } else {
 
 
154
  fileName.textContent = 'Cliquez ou glissez une image ici';
155
+ previewContainer.style.display = 'none'; // Cacher la prévisualisation
156
  }
157
  }
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  document.getElementById('uploadForm').addEventListener('submit', async (e) => {
160
  e.preventDefault();
161
+
162
  const loading = document.getElementById('loading');
163
  const results = document.getElementById('results');
164
  const dissertationResult = document.getElementById('dissertationResult');
165
+
166
  const formData = new FormData();
167
  formData.append('image', document.getElementById('imageInput').files[0]);
168
+
169
  loading.classList.remove('hidden');
170
  results.classList.add('hidden');
171
+
172
  try {
173
  const response = await fetch('/analyze', {
174
  method: 'POST',
175
  body: formData
176
  });
177
+
178
  const data = await response.json();
179
+
180
  if (response.ok) {
181
  tableauContent = data.tableau;
182
  dissertationResult.innerHTML = marked.parse(data.dissertation);
183
  results.classList.remove('hidden');
184
+ results.classList.add('fade-in');
185
  } else {
186
+ Swal.fire({
187
+ icon: 'error',
188
+ title: 'Erreur',
189
+ text: data.error
190
+ });
191
  }
192
  } catch (error) {
193
+ Swal.fire({
194
+ icon: 'error',
195
+ title: 'Erreur',
196
+ text: 'Une erreur est survenue lors de l\'analyse'
197
+ });
198
  } finally {
199
  loading.classList.add('hidden');
200
  }