Docfile commited on
Commit
0ddde91
·
verified ·
1 Parent(s): de339e9

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +265 -93
templates/index.html CHANGED
@@ -1,118 +1,290 @@
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>Générateur Fiche Évaluation Gym</title>
7
- <style>
8
- body { font-family: sans-serif; margin: 20px; }
9
- label { display: block; margin-top: 10px; font-weight: bold; }
10
- input[type=text], input[type=number] { width: 95%; padding: 8px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px; }
11
- .element-row { display: flex; align-items: center; margin-bottom: 10px; border: 1px solid #eee; padding: 10px; border-radius: 5px;}
12
- .element-row input { margin-right: 10px; }
13
- .element-row input[name="new_element_name"] { flex-grow: 3; } /* More space for name */
14
- .element-row input[name="new_element_categorie"] { flex-grow: 1; }
15
- .element-row input[name="new_element_points"] { flex-grow: 1; }
16
- button { padding: 10px 15px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; margin-top: 5px; }
17
- button:hover { background-color: #0056b3; }
18
- .remove-btn { background-color: #dc3545; margin-left: 10px; }
19
- .remove-btn:hover { background-color: #c82333; }
20
- #elements-container { margin-top: 15px; padding-top: 10px; border-top: 1px dashed #ccc; }
21
- fieldset { border: 1px solid #ddd; padding: 15px; margin-bottom: 20px; border-radius: 5px; }
22
- legend { font-weight: bold; padding: 0 10px; }
23
- .format-options label { display: inline-block; margin-right: 15px; font-weight: normal;}
24
- .format-options input[type=radio] { margin-right: 5px; }
25
- </style>
 
 
 
 
26
  </head>
27
- <body>
 
 
 
 
 
 
 
28
 
29
- <h1>Générateur de Fiche d'Évaluation Gymnastique</h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
- <form method="post">
 
 
 
 
 
 
32
 
33
- <fieldset>
34
- <legend>Informations Générales</legend>
35
- <label for="centre_examen">Centre d'examen:</label>
36
- <input type="text" id="centre_examen" name="centre_examen" value="Centre d'examen">
37
-
38
- <label for="type_examen">Type d'examen:</label>
39
- <input type="text" id="type_examen" name="type_examen" value="Bac Général">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- <label for="serie">Série:</label>
42
- <input type="text" id="serie" name="serie" value="Série">
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
- <label for="etablissement">Établissement:</label>
45
- <input type="text" id="etablissement" name="etablissement" value="Établissement">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
- <label for="session">Session:</label>
48
- <input type="number" id="session" name="session" value="2025">
 
 
 
 
 
 
 
 
 
49
 
50
- <label for="nom_candidat">Nom du Candidat:</label>
51
- <input type="text" id="nom_candidat" name="nom_candidat" value="Nom Prénom">
52
- </fieldset>
53
 
54
- <fieldset>
55
- <legend>Éléments Techniques</legend>
56
- <div id="elements-container">
57
- <!-- Element rows will be added here by JavaScript -->
58
- <div class="element-row">
59
- <input type="text" name="new_element_name" placeholder="Nom de l'élément" required>
60
- <input type="text" name="new_element_categorie" placeholder="Catégorie (A, B...)" required>
61
- <input type="number" step="0.1" name="new_element_points" placeholder="Points max" required>
62
- <button type="button" class="remove-btn" onclick="removeElement(this)">Supprimer</button>
63
- </div>
 
 
 
 
 
 
 
64
  </div>
65
- <button type="button" id="add-element-btn">Ajouter un élément</button>
66
- </fieldset>
67
-
68
- <fieldset>
69
- <legend>Format de Sortie</legend>
70
- <div class="format-options">
71
- <label>
72
- <input type="radio" name="format" value="docx" checked> DOCX
73
- </label>
74
- <label>
75
- <input type="radio" name="format" value="pdf"> PDF (Nécessite ConvertAPI)
76
- </label>
77
  </div>
78
- </fieldset>
 
 
 
 
 
 
 
 
 
 
 
79
 
80
- <button type="submit">Générer le Document</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
- </form>
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- <script>
85
- const container = document.getElementById('elements-container');
86
- const addButton = document.getElementById('add-element-btn');
 
 
 
 
87
 
88
- function createEmptyElementRow() {
89
- const newRow = document.createElement('div');
90
- newRow.classList.add('element-row');
91
- newRow.innerHTML = `
92
- <input type="text" name="new_element_name" placeholder="Nom de l'élément" required>
93
- <input type="text" name="new_element_categorie" placeholder="Catégorie (A, B...)" required>
94
- <input type="number" step="0.1" name="new_element_points" placeholder="Points max" required>
95
- <button type="button" class="remove-btn" onclick="removeElement(this)">Supprimer</button>
96
- `;
97
- container.appendChild(newRow);
98
  }
99
 
100
- function removeElement(button) {
101
- // Prevent removing the last row if you want at least one always present
102
- if (container.children.length > 1) {
103
- button.parentElement.remove();
104
- } else {
105
- alert("Vous devez avoir au moins un élément.");
106
- }
107
  }
 
108
 
109
- addButton.addEventListener('click', createEmptyElementRow);
110
-
111
- // Optional: Add a few empty rows initially if needed
112
- // createEmptyElementRow();
113
- // createEmptyElementRow();
114
-
115
- </script>
116
 
 
117
  </body>
118
  </html>
 
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>Générateur d'évaluation gymnique - Mariam Eps</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <!-- AlpineJS not strictly needed for this functionality, but keep if used elsewhere -->
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/3.13.0/cdn.min.js" defer></script>
10
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
11
+ <style>
12
+ @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap');
13
+ body {
14
+ font-family: 'Montserrat', sans-serif;
15
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
16
+ }
17
+ .card-shadow { box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); }
18
+ .input-focus-effect { transition: all 0.3s ease; }
19
+ .input-focus-effect:focus { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(45, 85, 255, 0.2); }
20
+ .btn-hover-effect { transition: all 0.3s ease; }
21
+ .btn-hover-effect:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(45, 85, 255, 0.2); }
22
+ .element-card { transition: all 0.3s ease; }
23
+ .element-card:hover { transform: translateY(-3px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); }
24
+ .navbar-shadow { box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); }
25
+ textarea.element-name { resize: vertical; min-height: 60px; }
26
+ /* Style for remove button */
27
+ .remove-btn { background-color: #ef4444; color: white; transition: background-color 0.3s ease; }
28
+ .remove-btn:hover { background-color: #dc2626; }
29
+ </style>
30
  </head>
31
+ <body class="min-h-screen">
32
+ <!-- Loader -->
33
+ <div id="loader" class="hidden fixed inset-0 bg-gray-900 bg-opacity-50 flex items-center justify-center z-[100]">
34
+ <div class="flex flex-col items-center">
35
+ <div class="animate-spin rounded-full h-16 w-16 border-t-4 border-blue-500"></div>
36
+ <p class="mt-4 text-white text-lg">Génération en cours...</p>
37
+ </div>
38
+ </div>
39
 
40
+ <!-- Barre de navigation -->
41
+ <header class="bg-indigo-700 text-white navbar-shadow fixed w-full top-0 z-50">
42
+ <!-- Navbar content unchanged -->
43
+ <div class="container mx-auto px-4 py-3 flex justify-between items-center">
44
+ <div class="flex items-center">
45
+ <span class="font-bold text-xl tracking-wider">Mariam Eps</span>
46
+ </div>
47
+ <div>
48
+ <nav class="hidden md:flex space-x-6">
49
+ <a href="#" class="hover:text-indigo-200 transition-colors duration-200 font-medium">Accueil</a>
50
+ <a href="#" class="hover:text-indigo-200 transition-colors duration-200 font-medium">Évaluations</a>
51
+ <a href="#" class="hover:text-indigo-200 transition-colors duration-200 font-medium">Ressources</a>
52
+ <a href="#" class="hover:text-indigo-200 transition-colors duration-200 font-medium">Contact</a>
53
+ </nav>
54
+ <button class="md:hidden focus:outline-none">
55
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
56
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
57
+ </svg>
58
+ </button>
59
+ </div>
60
+ </div>
61
+ </header>
62
 
63
+ <!-- Contenu principal -->
64
+ <div class="pt-20 pb-8"> <!-- Increased pt slightly for fixed navbar -->
65
+ <div class="container max-w-4xl mx-auto px-4 mt-8">
66
+ <div class="mb-8 text-center animate__animated animate__fadeInDown">
67
+ <h1 class="text-3xl md:text-4xl font-bold text-indigo-700 mb-2">Générateur d'évaluation gymnique</h1>
68
+ <p class="text-gray-600 max-w-2xl mx-auto">Créez facilement des documents d'évaluation personnalisés pour vos examens de gymnastique</p>
69
+ </div>
70
 
71
+ <form method="POST" action="/eps" class="space-y-8 animate__animated animate__fadeIn"> <!-- Added action="/eps" -->
72
+ <!-- Card principale -->
73
+ <div class="bg-white rounded-xl card-shadow p-6 md:p-8">
74
+ <!-- Informations générales -->
75
+ <div class="mb-8">
76
+ <h2 class="text-xl font-semibold text-indigo-600 mb-4 flex items-center">
77
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z" clip-rule="evenodd" /></svg>
78
+ Informations générales
79
+ </h2>
80
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
81
+ <div>
82
+ <label for="centre_examen" class="block text-sm font-medium text-gray-700 mb-1">Centre d'examen</label>
83
+ <input type="text" id="centre_examen" name="centre_examen" value="Centre d'examen" class="w-full px-4 py-2 bg-gray-50 border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
84
+ </div>
85
+ <div>
86
+ <label for="type_examen" class="block text-sm font-medium text-gray-700 mb-1">Type d'examen</label>
87
+ <input type="text" id="type_examen" name="type_examen" value="Bac Général" class="w-full px-4 py-2 bg-gray-50 border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
88
+ </div>
89
+ <div>
90
+ <label for="serie" class="block text-sm font-medium text-gray-700 mb-1">Série</label>
91
+ <input type="text" id="serie" name="serie" value="Série" class="w-full px-4 py-2 bg-gray-50 border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
92
+ </div>
93
+ <div>
94
+ <label for="etablissement" class="block text-sm font-medium text-gray-700 mb-1">Établissement</label>
95
+ <input type="text" id="etablissement" name="etablissement" value="Établissement" class="w-full px-4 py-2 bg-gray-50 border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
96
+ </div>
97
+ <div>
98
+ <label for="session" class="block text-sm font-medium text-gray-700 mb-1">Session</label>
99
+ <input type="text" id="session" name="session" value="2025" class="w-full px-4 py-2 bg-gray-50 border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
100
+ </div>
101
+ <div>
102
+ <label for="nom_candidat" class="block text-sm font-medium text-gray-700 mb-1">Nom du candidat</label>
103
+ <input type="text" id="nom_candidat" name="nom_candidat" value="Candidat" class="w-full px-4 py-2 bg-gray-50 border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
104
+ </div>
105
+ </div>
106
+ </div>
107
 
108
+ <!-- Choix du format de téléchargement -->
109
+ <div class="mb-6">
110
+ <label class="block text-sm font-medium text-gray-700 mb-1">Choisissez le format de téléchargement :</label>
111
+ <div class="flex items-center space-x-4">
112
+ <label class="inline-flex items-center cursor-pointer">
113
+ <input type="radio" name="format" value="docx" checked class="form-radio text-indigo-600 focus:ring-indigo-500">
114
+ <span class="ml-2 text-gray-700">DOCX</span>
115
+ </label>
116
+ <label class="inline-flex items-center cursor-pointer">
117
+ <input type="radio" name="format" value="pdf" class="form-radio text-indigo-600 focus:ring-indigo-500">
118
+ <span class="ml-2 text-gray-700">PDF</span>
119
+ </label>
120
+ </div>
121
+ </div>
122
 
123
+ <!-- Éléments techniques -->
124
+ <div>
125
+ <h2 class="text-xl font-semibold text-indigo-600 mb-4 flex items-center">
126
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor"><path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z" /><path fill-rule="evenodd" d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm3 4a1 1 0 000 2h.01a1 1 0 100-2H7zm3 0a1 1 0 000 2h3a1 1 0 100-2h-3zm-3 4a1 1 0 100 2h.01a1 1 0 100-2H7zm3 0a1 1 0 100 2h3a1 1 0 100-2h-3z" clip-rule="evenodd" /></svg>
127
+ Éléments techniques
128
+ </h2>
129
+ <div id="elements_container" class="space-y-4">
130
+ <!-- Initial Element Row -->
131
+ <div class="p-5 bg-gray-50 border border-gray-200 rounded-lg element-card relative">
132
+ <div class="grid grid-cols-1 gap-2">
133
+ <div>
134
+ <label class="block text-sm font-medium text-gray-700 mb-1">Nom de l'élément</label>
135
+ <textarea name="new_element_name" placeholder="Ex : Saut groupé" required
136
+ class="element-name w-full px-4 py-2 bg-white border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"></textarea>
137
+ </div>
138
+ <div class="grid grid-cols-2 gap-2">
139
+ <div>
140
+ <label class="block text-sm font-medium text-gray-700 mb-1">Catégorie</label>
141
+ <input type="text" name="new_element_categorie" placeholder="Ex : A" required
142
+ class="w-full px-4 py-2 bg-white border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
143
+ </div>
144
+ <div>
145
+ <label class="block text-sm font-medium text-gray-700 mb-1">Points</label>
146
+ <input type="text" inputmode="decimal" pattern="^\d*([.,])?\d*$" name="new_element_points" placeholder="Ex : 1.5" required
147
+ class="w-full px-4 py-2 bg-white border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
148
+ </div>
149
+ </div>
150
+ </div>
151
+ <!-- Add Remove Button Here -->
152
+ <button type="button" onclick="removeElement(this)" title="Supprimer cet élément"
153
+ class="remove-btn absolute top-2 right-2 p-1.5 rounded-full btn-hover-effect">
154
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
155
+ <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
156
+ </svg>
157
+ </button>
158
+ </div>
159
+ <!-- More elements added dynamically here -->
160
+ </div>
161
+ <div class="flex justify-center mt-6">
162
+ <button type="button" onclick="addElement()" id="add-element-btn"
163
+ class="inline-flex items-center px-4 py-2 bg-indigo-100 text-indigo-700 rounded-lg btn-hover-effect focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
164
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
165
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
166
+ </svg>
167
+ Ajouter un autre élément
168
+ </button>
169
+ </div>
170
+ </div>
171
+ </div>
172
 
173
+ <!-- Bouton de génération -->
174
+ <div class="animate__animated animate__fadeInUp">
175
+ <button type="submit"
176
+ class="w-full py-3 px-6 bg-gradient-to-r from-indigo-600 to-blue-500 text-white font-medium rounded-lg btn-hover-effect flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
177
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" /></svg>
178
+ Générer le document
179
+ </button>
180
+ </div>
181
+ </form>
182
+ </div>
183
+ </div>
184
 
185
+ <script>
186
+ const container = document.getElementById("elements_container");
187
+ const addButton = document.getElementById('add-element-btn');
188
 
189
+ // --- MODIFIED: Function to add element WITH remove button ---
190
+ function addElement() {
191
+ const div = document.createElement("div");
192
+ // Added 'relative' class for positioning the remove button
193
+ div.className = "p-5 bg-gray-50 border border-gray-200 rounded-lg element-card relative animate__animated animate__fadeIn";
194
+ div.innerHTML = `
195
+ <div class="grid grid-cols-1 gap-2">
196
+ <div>
197
+ <label class="block text-sm font-medium text-gray-700 mb-1">Nom de l'élément</label>
198
+ <textarea name="new_element_name" placeholder="Ex : Saut groupé" required
199
+ class="element-name w-full px-4 py-2 bg-white border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"></textarea>
200
+ </div>
201
+ <div class="grid grid-cols-2 gap-2">
202
+ <div>
203
+ <label class="block text-sm font-medium text-gray-700 mb-1">Catégorie</label>
204
+ <input type="text" name="new_element_categorie" placeholder="Ex : A" required
205
+ class="w-full px-4 py-2 bg-white border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
206
  </div>
207
+ <div>
208
+ <label class="block text-sm font-medium text-gray-700 mb-1">Points</label>
209
+ <input type="text" inputmode="decimal" pattern="^\\d*([.,])?\\d*$" name="new_element_points" placeholder="Ex : 1.5" required
210
+ class="w-full px-4 py-2 bg-white border border-gray-200 rounded-lg input-focus-effect focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
 
 
 
 
 
 
 
 
211
  </div>
212
+ </div>
213
+ </div>
214
+ <!-- Remove Button Added -->
215
+ <button type="button" onclick="removeElement(this)" title="Supprimer cet élément"
216
+ class="remove-btn absolute top-2 right-2 p-1.5 rounded-full btn-hover-effect">
217
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
218
+ <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
219
+ </svg>
220
+ </button>
221
+ `;
222
+ container.appendChild(div);
223
+ }
224
 
225
+ // --- NEW: Function to remove element ---
226
+ function removeElement(button) {
227
+ // Check if it's the last element before removing
228
+ if (container.children.length > 1) {
229
+ const elementCard = button.closest('.element-card'); // Find the parent card div
230
+ if (elementCard) {
231
+ // Optional: Add fade out animation before removing
232
+ elementCard.classList.add('animate__animated', 'animate__fadeOut');
233
+ elementCard.addEventListener('animationend', () => {
234
+ elementCard.remove();
235
+ });
236
+ }
237
+ } else {
238
+ alert("Vous devez conserver au moins un élément technique.");
239
+ }
240
+ }
241
 
242
+ // Replace commas with dots in "Points" fields
243
+ container.addEventListener('input', function(event) {
244
+ if (event.target && event.target.name === 'new_element_points') {
245
+ // Allow only numbers and one dot/comma, then replace comma with dot
246
+ event.target.value = event.target.value.replace(/[^0-9.,]/g, '').replace(/,/g, '.');
247
+ // Ensure only one dot
248
+ const parts = event.target.value.split('.');
249
+ if (parts.length > 2) {
250
+ event.target.value = parts[0] + '.' + parts.slice(1).join('');
251
+ }
252
+ }
253
+ });
254
 
255
+ // Show loader on form submission
256
+ document.querySelector('form').addEventListener('submit', function(e) {
257
+ // Basic validation: check if required fields in elements are filled
258
+ let allValid = true;
259
+ const elementNames = document.querySelectorAll('textarea[name="new_element_name"]');
260
+ const elementCats = document.querySelectorAll('input[name="new_element_categorie"]');
261
+ const elementPoints = document.querySelectorAll('input[name="new_element_points"]');
262
 
263
+ for (let i = 0; i < elementNames.length; i++) {
264
+ if (!elementNames[i].value.trim() || !elementCats[i].value.trim() || !elementPoints[i].value.trim()) {
265
+ allValid = false;
266
+ // Optional: highlight the invalid row
267
+ elementNames[i].closest('.element-card').style.border = '1px solid red';
268
+ } else {
269
+ elementNames[i].closest('.element-card').style.border = '1px solid #e5e7eb'; // Reset border
270
+ }
 
 
271
  }
272
 
273
+ if (!allValid) {
274
+ e.preventDefault(); // Stop submission
275
+ alert("Veuillez remplir tous les champs pour chaque élément technique.");
276
+ } else {
277
+ document.getElementById('loader').classList.remove('hidden');
 
 
278
  }
279
+ });
280
 
281
+ // Optional: Remove validation error border on input
282
+ container.addEventListener('input', function(event) {
283
+ if (event.target && (event.target.name === 'new_element_name' || event.target.name === 'new_element_categorie' || event.target.name === 'new_element_points')) {
284
+ event.target.closest('.element-card').style.border = '1px solid #e5e7eb';
285
+ }
286
+ });
 
287
 
288
+ </script>
289
  </body>
290
  </html>