OUAREDAEK commited on
Commit
d3bef47
·
verified ·
1 Parent(s): 5906a4b

Upload templates/index-old3.html with huggingface_hub

Browse files
Files changed (1) hide show
  1. templates/index-old3.html +2633 -0
templates/index-old3.html ADDED
@@ -0,0 +1,2633 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Dashboard Réflexif – ReflAgent</title>
7
+
8
+ <style>
9
+ /* ================= STYLES DE BASE ================= */
10
+ body {
11
+ font-family: 'Segoe UI', Arial, sans-serif;
12
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
13
+ margin: 0;
14
+ padding: 20px;
15
+ color: #333;
16
+ }
17
+
18
+ h2, h3, h4 {
19
+ color: #1976D2;
20
+ margin-top: 0;
21
+ }
22
+
23
+ h2 {
24
+ background: linear-gradient(90deg, #1976D2, #2196F3);
25
+ -webkit-background-clip: text;
26
+ -webkit-text-fill-color: transparent;
27
+ padding: 10px 0;
28
+ border-bottom: 2px solid #e3f2fd;
29
+ margin-bottom: 25px;
30
+ }
31
+
32
+ h3 {
33
+ background: #e3f2fd;
34
+ padding: 12px 15px;
35
+ border-radius: 8px;
36
+ margin: 25px 0 15px;
37
+ display: flex;
38
+ align-items: center;
39
+ gap: 10px;
40
+ }
41
+
42
+ h3::before {
43
+ content: '';
44
+ display: inline-block;
45
+ width: 6px;
46
+ height: 24px;
47
+ background: #1976D2;
48
+ border-radius: 3px;
49
+ }
50
+
51
+ #reflection {
52
+ background: white;
53
+ padding: 30px;
54
+ border-radius: 20px;
55
+ max-width: 1400px;
56
+ margin: auto;
57
+ box-shadow: 0 10px 40px rgba(0,0,0,0.08);
58
+ border: 1px solid #e0e0e0;
59
+ }
60
+
61
+ /* ================= SYSTEME D'ONGLETS ================= */
62
+ .tabs-container {
63
+ margin-bottom: 30px;
64
+ }
65
+
66
+ .tabs {
67
+ display: flex;
68
+ background: #f8f9fa;
69
+ border-radius: 12px;
70
+ padding: 5px;
71
+ margin-bottom: 20px;
72
+ border: 1px solid #e0e0e0;
73
+ }
74
+
75
+ .tab-btn {
76
+ flex: 1;
77
+ padding: 15px 20px;
78
+ border: none;
79
+ background: transparent;
80
+ color: #666;
81
+ font-weight: 600;
82
+ font-size: 16px;
83
+ cursor: pointer;
84
+ border-radius: 8px;
85
+ transition: all 0.3s ease;
86
+ display: flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ gap: 10px;
90
+ }
91
+
92
+ .tab-btn:hover {
93
+ background: rgba(25, 118, 210, 0.1);
94
+ color: #1976D2;
95
+ }
96
+
97
+ .tab-btn.active {
98
+ background: #1976D2;
99
+ color: white;
100
+ box-shadow: 0 3px 8px rgba(25, 118, 210, 0.2);
101
+ }
102
+
103
+ .tab-content {
104
+ display: none;
105
+ animation: fadeIn 0.5s ease;
106
+ }
107
+
108
+ .tab-content.active {
109
+ display: block;
110
+ }
111
+
112
+ /* ================= NAVIGATION ================= */
113
+ .nav {
114
+ display: flex;
115
+ justify-content: space-between;
116
+ align-items: center;
117
+ margin-bottom: 30px;
118
+ background: linear-gradient(90deg, #e3f2fd, #f3e5f5);
119
+ padding: 15px 25px;
120
+ border-radius: 12px;
121
+ border: 1px solid #bbdefb;
122
+ }
123
+
124
+ #scenarioTitle {
125
+ font-size: 1.4em;
126
+ color: #333;
127
+ text-align: center;
128
+ flex-grow: 1;
129
+ margin: 0 20px;
130
+ }
131
+
132
+ button {
133
+ background: linear-gradient(135deg, #1976D2, #2196F3);
134
+ color: white;
135
+ border: none;
136
+ padding: 12px 25px;
137
+ border-radius: 10px;
138
+ cursor: pointer;
139
+ font-weight: 600;
140
+ font-size: 15px;
141
+ transition: all 0.3s ease;
142
+ box-shadow: 0 3px 8px rgba(25, 118, 210, 0.2);
143
+ display: flex;
144
+ align-items: center;
145
+ gap: 8px;
146
+ }
147
+
148
+ button:hover:not(:disabled) {
149
+ transform: translateY(-2px);
150
+ box-shadow: 0 5px 15px rgba(25, 118, 210, 0.3);
151
+ }
152
+
153
+ button:active:not(:disabled) {
154
+ transform: translateY(0);
155
+ }
156
+
157
+ button:disabled {
158
+ opacity: 0.5;
159
+ cursor: not-allowed;
160
+ background: #b0bec5;
161
+ }
162
+
163
+ /* ================= BOUTON LECTURE CROISÉE ================= */
164
+ #crossReadersBtn {
165
+ background: linear-gradient(135deg, #43A047, #4CAF50) !important;
166
+ color: white;
167
+ border: none;
168
+ padding: 12px 25px;
169
+ border-radius: 10px;
170
+ cursor: pointer;
171
+ font-weight: 600;
172
+ font-size: 15px;
173
+ transition: all 0.3s ease;
174
+ box-shadow: 0 3px 8px rgba(67, 160, 71, 0.2);
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: center;
178
+ gap: 8px;
179
+ width: 100%;
180
+ }
181
+
182
+ #crossReadersBtn:hover:not(:disabled) {
183
+ transform: translateY(-2px);
184
+ box-shadow: 0 5px 15px rgba(67, 160, 71, 0.3);
185
+ background: linear-gradient(135deg, #388E3C, #43A047) !important;
186
+ }
187
+
188
+ #crossReadersBtn:active:not(:disabled) {
189
+ transform: translateY(0);
190
+ }
191
+
192
+ #crossReadersBtn:disabled {
193
+ opacity: 0.5;
194
+ cursor: not-allowed;
195
+ background: #b0bec5 !important;
196
+ }
197
+
198
+ /* ================= ONGLET 1: ÉVALUATEUR GDPR ================= */
199
+ #tab-evaluator .evaluator-info {
200
+ background: linear-gradient(135deg, #fff3e0, #ffe0b2);
201
+ padding: 25px;
202
+ border-radius: 15px;
203
+ border-left: 6px solid #ff9800;
204
+ margin: 20px 0;
205
+ }
206
+
207
+ #tab-evaluator .evaluator-info h4 {
208
+ color: #ff9800;
209
+ margin-top: 0;
210
+ margin-bottom: 20px;
211
+ display: flex;
212
+ align-items: center;
213
+ gap: 10px;
214
+ font-size: 20px;
215
+ }
216
+
217
+ .evaluator-field {
218
+ margin-bottom: 20px;
219
+ background: white;
220
+ padding: 20px;
221
+ border-radius: 10px;
222
+ border: 1px solid #FFE0B2;
223
+ }
224
+
225
+ .evaluator-field label {
226
+ display: block;
227
+ margin-bottom: 12px;
228
+ color: #333;
229
+ font-weight: 600;
230
+ font-size: 15px;
231
+ }
232
+
233
+ .evaluator-field input[type="text"],
234
+ .evaluator-field select {
235
+ width: 100%;
236
+ padding: 14px 18px;
237
+ border: 2px solid #e0e0e0;
238
+ border-radius: 8px;
239
+ font-size: 15px;
240
+ transition: all 0.3s;
241
+ box-sizing: border-box;
242
+ background: white;
243
+ }
244
+
245
+ .evaluator-field input[type="text"]:focus,
246
+ .evaluator-field select:focus {
247
+ outline: none;
248
+ border-color: #1976D2;
249
+ box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);
250
+ }
251
+
252
+ .evaluator-field input:disabled,
253
+ .evaluator-field select:disabled {
254
+ background: #f5f5f5;
255
+ color: #999;
256
+ cursor: not-allowed;
257
+ }
258
+
259
+ .evaluator-field small {
260
+ display: block;
261
+ margin-top: 8px;
262
+ color: #666;
263
+ font-size: 13px;
264
+ font-style: italic;
265
+ }
266
+
267
+ /* Style pour les boutons radio GDPR */
268
+ .gdpr-options {
269
+ display: flex;
270
+ gap: 30px;
271
+ margin-top: 10px;
272
+ flex-wrap: wrap;
273
+ }
274
+
275
+ .gdpr-option {
276
+ display: flex;
277
+ align-items: center;
278
+ gap: 10px;
279
+ cursor: pointer;
280
+ padding: 12px 20px;
281
+ border-radius: 8px;
282
+ background: white;
283
+ border: 2px solid #e0e0e0;
284
+ transition: all 0.3s;
285
+ flex: 1;
286
+ min-width: 250px;
287
+ }
288
+
289
+ .gdpr-option:hover {
290
+ border-color: #1976D2;
291
+ background: #f0f7ff;
292
+ }
293
+
294
+ .gdpr-option input[type="radio"] {
295
+ width: 20px;
296
+ height: 20px;
297
+ cursor: pointer;
298
+ }
299
+
300
+ .gdpr-option span {
301
+ font-size: 15px;
302
+ font-weight: 500;
303
+ color: #333;
304
+ }
305
+
306
+ #anonymousMessage {
307
+ background: #E3F2FD;
308
+ padding: 18px;
309
+ border-radius: 10px;
310
+ margin-top: 20px;
311
+ border-left: 4px solid #1976D2;
312
+ animation: fadeIn 0.5s ease;
313
+ }
314
+
315
+ #anonymousMessage p {
316
+ margin: 0;
317
+ color: #1976D2;
318
+ font-size: 14px;
319
+ line-height: 1.5;
320
+ }
321
+
322
+ /* ================= ONGLET 2: DASHBOARD ÉTUDIANT COMPACT ================= */
323
+ #tab-dashboard .manifest-item {
324
+ background: linear-gradient(135deg, #f9fbe7, #f0f4c3);
325
+ padding: 15px;
326
+ border-radius: 12px;
327
+ border-left: 6px solid #cddc39;
328
+ margin: 15px 0;
329
+ box-shadow: 0 3px 10px rgba(0,0,0,0.05);
330
+ font-size: 14px;
331
+ }
332
+
333
+ .manifest-item b {
334
+ color: #689f38;
335
+ }
336
+
337
+ /* ================= COMPÉTENCES COMPACTES ================= */
338
+ #competence-bars {
339
+ background: white;
340
+ padding: 15px;
341
+ border-radius: 12px;
342
+ border: 1px solid #e0e0e0;
343
+ margin: 15px 0;
344
+ }
345
+
346
+ .compact-competences-grid {
347
+ display: grid;
348
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
349
+ gap: 12px;
350
+ margin: 10px 0;
351
+ }
352
+
353
+ .compact-competence-item {
354
+ padding: 10px;
355
+ background: #f8f9fa;
356
+ border-radius: 8px;
357
+ border-left: 4px solid #1976D2;
358
+ transition: transform 0.2s;
359
+ }
360
+
361
+ .compact-competence-item:hover {
362
+ transform: translateY(-2px);
363
+ background: #e3f2fd;
364
+ }
365
+
366
+ .compact-competence-label {
367
+ font-size: 12px;
368
+ font-weight: 600;
369
+ color: #333;
370
+ margin-bottom: 8px;
371
+ display: flex;
372
+ justify-content: space-between;
373
+ }
374
+
375
+ .compact-competence-bar {
376
+ height: 10px;
377
+ background: #e0e0e0;
378
+ border-radius: 5px;
379
+ overflow: hidden;
380
+ margin: 5px 0;
381
+ }
382
+
383
+ .compact-competence-fill {
384
+ height: 100%;
385
+ border-radius: 5px;
386
+ color: white;
387
+ font-size: 9px;
388
+ text-align: right;
389
+ padding-right: 5px;
390
+ line-height: 10px;
391
+ font-weight: bold;
392
+ transition: width 0.5s ease;
393
+ }
394
+
395
+ /* ================= LÉGENDE RADAR COMPACTE ================= */
396
+ .compact-radar-legend {
397
+ display: flex;
398
+ justify-content: center;
399
+ gap: 15px;
400
+ margin: 15px 0;
401
+ flex-wrap: wrap;
402
+ padding: 10px;
403
+ background: white;
404
+ border-radius: 8px;
405
+ border: 1px solid #e0e0e0;
406
+ }
407
+
408
+ .compact-legend-item {
409
+ display: flex;
410
+ align-items: center;
411
+ gap: 8px;
412
+ padding: 6px 10px;
413
+ background: #f8f9fa;
414
+ border-radius: 6px;
415
+ font-size: 12px;
416
+ }
417
+
418
+ .compact-legend-color {
419
+ width: 16px;
420
+ height: 16px;
421
+ border-radius: 4px;
422
+ border: 2px solid white;
423
+ }
424
+
425
+ .compact-legend-low { background: linear-gradient(135deg, #e53935, #f44336); }
426
+ .compact-legend-medium { background: linear-gradient(135deg, #fb8c00, #ff9800); }
427
+ .compact-legend-high { background: linear-gradient(135deg, #43a047, #4caf50); }
428
+
429
+ /* ================= RADAR COMPACT ================= */
430
+ #radar-container {
431
+ background: white;
432
+ padding: 15px;
433
+ border-radius: 12px;
434
+ border: 1px solid #e0e0e0;
435
+ margin: 15px 0;
436
+ }
437
+
438
+ #radar {
439
+ max-width: 100%;
440
+ height: auto;
441
+ }
442
+
443
+ /* ================= MESSAGE BOT RADAR COMPACT ================= */
444
+ .compact-radar-bot-message {
445
+ background: linear-gradient(135deg, #E3F2FD, #BBDEFB);
446
+ padding: 15px;
447
+ border-radius: 10px;
448
+ border-left: 4px solid #1976D2;
449
+ margin: 15px 0;
450
+ }
451
+
452
+ .compact-radar-bot-header {
453
+ display: flex;
454
+ align-items: center;
455
+ gap: 10px;
456
+ margin-bottom: 10px;
457
+ }
458
+
459
+ .compact-radar-bot-icon {
460
+ font-size: 20px;
461
+ background: #1976D2;
462
+ color: white;
463
+ width: 40px;
464
+ height: 40px;
465
+ border-radius: 50%;
466
+ display: flex;
467
+ align-items: center;
468
+ justify-content: center;
469
+ }
470
+
471
+ .compact-radar-bot-title {
472
+ font-size: 16px;
473
+ font-weight: 600;
474
+ color: #1976D2;
475
+ margin: 0;
476
+ }
477
+
478
+ .compact-radar-bot-content {
479
+ font-size: 14px;
480
+ line-height: 1.5;
481
+ color: #333;
482
+ margin: 0;
483
+ }
484
+
485
+ .compact-radar-bot-insights {
486
+ background: white;
487
+ padding: 10px;
488
+ border-radius: 8px;
489
+ margin-top: 10px;
490
+ border: 1px solid #E3F2FD;
491
+ }
492
+
493
+ .compact-radar-insight-item {
494
+ display: flex;
495
+ align-items: center;
496
+ gap: 8px;
497
+ margin-bottom: 6px;
498
+ padding: 6px 10px;
499
+ border-radius: 6px;
500
+ background: #F5F5F5;
501
+ font-size: 12px;
502
+ }
503
+
504
+ /* ================= GRILLE DES MÉTRIQUES RADAR COMPACTE ================= */
505
+ .compact-radar-metrics-grid {
506
+ display: grid;
507
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
508
+ gap: 12px;
509
+ margin: 15px 0;
510
+ }
511
+
512
+ .compact-metric-card {
513
+ background: white;
514
+ border-radius: 10px;
515
+ padding: 15px;
516
+ box-shadow: 0 3px 8px rgba(0,0,0,0.08);
517
+ border-left: 4px solid #1976D2;
518
+ transition: transform 0.3s;
519
+ text-align: center;
520
+ }
521
+
522
+ .compact-metric-card:hover {
523
+ transform: translateY(-3px);
524
+ box-shadow: 0 5px 15px rgba(0,0,0,0.12);
525
+ }
526
+
527
+ .compact-metric-icon {
528
+ font-size: 24px;
529
+ margin-bottom: 8px;
530
+ }
531
+
532
+ .compact-metric-name {
533
+ font-weight: 600;
534
+ color: #333;
535
+ margin-bottom: 5px;
536
+ font-size: 14px;
537
+ }
538
+
539
+ .compact-metric-value {
540
+ font-size: 20px;
541
+ font-weight: bold;
542
+ color: #1976D2;
543
+ margin: 5px 0;
544
+ }
545
+
546
+ .compact-metric-value.high { color: #43A047; }
547
+ .compact-metric-value.medium { color: #FB8C00; }
548
+ .compact-metric-value.low { color: #E53935; }
549
+
550
+ .compact-metric-description {
551
+ font-size: 11px;
552
+ color: #666;
553
+ margin-top: 5px;
554
+ line-height: 1.3;
555
+ }
556
+
557
+ /* ================= HEATMAP COMPACT ================= */
558
+ .compact-heatmap-and-indicators {
559
+ background: white;
560
+ padding: 15px;
561
+ border-radius: 12px;
562
+ border: 1px solid #e0e0e0;
563
+ margin: 15px 0;
564
+ }
565
+
566
+ .compact-heatmap-analysis {
567
+ margin-bottom: 15px;
568
+ }
569
+
570
+ .compact-analysis-controls {
571
+ display: flex;
572
+ align-items: center;
573
+ gap: 10px;
574
+ margin-bottom: 15px;
575
+ padding: 10px;
576
+ background: #f8f9fa;
577
+ border-radius: 8px;
578
+ }
579
+
580
+ .compact-analysis-controls label {
581
+ font-weight: 600;
582
+ color: #1976D2;
583
+ font-size: 14px;
584
+ }
585
+
586
+ .compact-analysis-controls select {
587
+ padding: 8px 12px;
588
+ border-radius: 6px;
589
+ border: 2px solid #1976D2;
590
+ background: white;
591
+ color: #333;
592
+ font-weight: 500;
593
+ cursor: pointer;
594
+ flex-grow: 1;
595
+ font-size: 14px;
596
+ }
597
+
598
+ #heatmap {
599
+ max-width: 100%;
600
+ height: auto;
601
+ border-radius: 8px;
602
+ }
603
+
604
+ /* ================= LÉGENDE HEATMAP COMPACTE ================= */
605
+ .compact-enriched-legend {
606
+ background: white;
607
+ padding: 15px;
608
+ border-radius: 10px;
609
+ border: 1px solid #e0e0e0;
610
+ margin: 15px 0;
611
+ }
612
+
613
+ .compact-legend-section h5 {
614
+ color: #1976D2;
615
+ margin-bottom: 10px;
616
+ font-size: 14px;
617
+ display: flex;
618
+ align-items: center;
619
+ gap: 6px;
620
+ }
621
+
622
+ .compact-legend-grid {
623
+ display: grid;
624
+ grid-template-columns: repeat(3, 1fr);
625
+ gap: 8px;
626
+ }
627
+
628
+ .compact-legend-item-small {
629
+ display: flex;
630
+ align-items: center;
631
+ gap: 6px;
632
+ font-size: 11px;
633
+ }
634
+
635
+ .compact-legend-color-small {
636
+ width: 16px;
637
+ height: 16px;
638
+ border-radius: 4px;
639
+ border: 2px solid white;
640
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
641
+ }
642
+
643
+ /* ================= INDICATEURS DE PERSÉVÉRANCE COMPACTS ================= */
644
+ .compact-persistence-analysis {
645
+ background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
646
+ padding: 15px;
647
+ border-radius: 10px;
648
+ border-left: 4px solid #1976D2;
649
+ margin: 15px 0;
650
+ }
651
+
652
+ .compact-persistence-indicators {
653
+ display: flex;
654
+ flex-direction: column;
655
+ gap: 8px;
656
+ margin-bottom: 10px;
657
+ }
658
+
659
+ .compact-indicator {
660
+ display: flex;
661
+ align-items: center;
662
+ gap: 8px;
663
+ padding: 8px 10px;
664
+ background: white;
665
+ border-radius: 6px;
666
+ font-size: 12px;
667
+ border-left: 3px solid #1976D2;
668
+ }
669
+
670
+ .compact-indicator-dot {
671
+ width: 10px;
672
+ height: 10px;
673
+ border-radius: 50%;
674
+ }
675
+
676
+ .compact-persistence-text {
677
+ font-size: 12px;
678
+ line-height: 1.4;
679
+ }
680
+
681
+ .compact-persistence-text > div {
682
+ margin-bottom: 6px;
683
+ padding: 8px;
684
+ background: white;
685
+ border-radius: 6px;
686
+ border-left: 3px solid #1976D2;
687
+ }
688
+
689
+ /* ================= ONGLET 3: MESSAGE RÉFLEXIF ET ÉVALUATION ================= */
690
+ #tab-evaluation #reflagent {
691
+ background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
692
+ padding: 25px;
693
+ border-radius: 15px;
694
+ border-left: 8px solid #43a047;
695
+ margin: 25px 0;
696
+ font-size: 16px;
697
+ line-height: 1.6;
698
+ position: relative;
699
+ overflow: hidden;
700
+ min-height: 100px;
701
+ display: flex;
702
+ align-items: center;
703
+ }
704
+
705
+ #tab-evaluation #reflagent::before {
706
+ content: '🤖';
707
+ position: absolute;
708
+ top: 15px;
709
+ right: 15px;
710
+ font-size: 40px;
711
+ opacity: 0.2;
712
+ }
713
+
714
+ /* ================= MÉTRIQUES DE CONFIANCE ================= */
715
+ #tab-evaluation hr {
716
+ border: none;
717
+ height: 2px;
718
+ background: linear-gradient(90deg, #1976D2, transparent);
719
+ margin: 40px 0;
720
+ }
721
+
722
+ .trust-item {
723
+ margin-bottom: 20px;
724
+ padding: 15px;
725
+ background: #f8f9fa;
726
+ border-radius: 12px;
727
+ transition: transform 0.3s;
728
+ }
729
+
730
+ .trust-item:hover {
731
+ transform: translateX(5px);
732
+ background: #f1f3f4;
733
+ }
734
+
735
+ .trust-item b {
736
+ display: block;
737
+ margin-bottom: 10px;
738
+ color: #1976D2;
739
+ font-size: 15px;
740
+ }
741
+
742
+ .stars {
743
+ display: flex;
744
+ gap: 8px;
745
+ margin: 10px 0;
746
+ }
747
+
748
+ .stars span {
749
+ font-size: 32px;
750
+ cursor: pointer;
751
+ color: #e0e0e0;
752
+ transition: all 0.2s;
753
+ text-shadow: none;
754
+ }
755
+
756
+ .stars span.active {
757
+ color: #ffd54f;
758
+ text-shadow: 0 2px 4px rgba(255, 213, 79, 0.3);
759
+ }
760
+
761
+ .stars span:hover {
762
+ transform: scale(1.2);
763
+ }
764
+
765
+ .stars span.inactive {
766
+ color: #e0e0e0;
767
+ text-shadow: none;
768
+ }
769
+
770
+ .stars span.inactive:hover {
771
+ color: #ffd54f;
772
+ }
773
+
774
+ /* ================= CHAMP COMMENTAIRE ================= */
775
+ textarea {
776
+ width: 100%;
777
+ min-height: 120px;
778
+ border-radius: 12px;
779
+ padding: 15px;
780
+ border: 2px solid #e0e0e0;
781
+ font-family: inherit;
782
+ font-size: 14px;
783
+ resize: vertical;
784
+ transition: all 0.3s;
785
+ margin-bottom: 20px;
786
+ }
787
+
788
+ textarea:focus {
789
+ outline: none;
790
+ border-color: #1976D2;
791
+ box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);
792
+ }
793
+
794
+ /* ================= BARRE DE CONFIANCE ================= */
795
+ #trustBar {
796
+ height: 100%;
797
+ border-radius: 10px;
798
+ color: white;
799
+ font-size: 14px;
800
+ text-align: center;
801
+ line-height: 24px;
802
+ font-weight: bold;
803
+ transition: width 0.5s ease, background 0.5s ease;
804
+ position: relative;
805
+ overflow: hidden;
806
+ width: 0%;
807
+ background: #e0e0e0;
808
+ }
809
+
810
+ #trustBar::after {
811
+ content: '';
812
+ position: absolute;
813
+ top: 0;
814
+ left: 0;
815
+ right: 0;
816
+ bottom: 0;
817
+ background: linear-gradient(90deg,
818
+ transparent,
819
+ rgba(255,255,255,0.4),
820
+ transparent
821
+ );
822
+ animation: shimmer 2s infinite;
823
+ }
824
+
825
+ @keyframes shimmer {
826
+ 0% { transform: translateX(-100%); }
827
+ 100% { transform: translateX(100%); }
828
+ }
829
+
830
+ /* ================= MESSAGES ================= */
831
+ #saveTrustMsg {
832
+ padding: 10px 15px;
833
+ border-radius: 8px;
834
+ margin: 10px 0;
835
+ font-weight: 500;
836
+ text-align: center;
837
+ transition: all 0.3s;
838
+ min-height: 50px;
839
+ display: flex;
840
+ align-items: center;
841
+ justify-content: center;
842
+ }
843
+
844
+ /* ================= STATISTIQUES ================= */
845
+ .stats-grid {
846
+ display: grid;
847
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
848
+ gap: 15px;
849
+ margin: 20px 0;
850
+ }
851
+
852
+ .stat-item {
853
+ background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
854
+ padding: 15px;
855
+ border-radius: 10px;
856
+ text-align: center;
857
+ transition: transform 0.3s;
858
+ }
859
+
860
+ .stat-item:hover {
861
+ transform: translateY(-3px);
862
+ box-shadow: 0 5px 15px rgba(0,0,0,0.1);
863
+ }
864
+
865
+ .stat-value {
866
+ font-size: 28px;
867
+ font-weight: bold;
868
+ color: #1976D2;
869
+ margin: 10px 0;
870
+ }
871
+
872
+ .stat-label {
873
+ font-size: 13px;
874
+ color: #666;
875
+ font-weight: 500;
876
+ }
877
+
878
+ /* ================= ANIMATIONS ================= */
879
+ @keyframes fadeIn {
880
+ from { opacity: 0; transform: translateY(20px); }
881
+ to { opacity: 1; transform: translateY(0); }
882
+ }
883
+
884
+ @keyframes slideIn {
885
+ from { transform: translateX(100%); opacity: 0; }
886
+ to { transform: translateX(0); opacity: 1; }
887
+ }
888
+
889
+ @keyframes slideOut {
890
+ from { transform: translateX(0); opacity: 1; }
891
+ to { transform: translateX(100%); opacity: 0; }
892
+ }
893
+
894
+ @keyframes pulse {
895
+ 0% { transform: scale(1); }
896
+ 50% { transform: scale(1.05); }
897
+ 100% { transform: scale(1); }
898
+ }
899
+
900
+ /* ================= RESPONSIVE ================= */
901
+ @media (max-width: 1200px) {
902
+ #reflection {
903
+ padding: 20px;
904
+ }
905
+
906
+ .tabs {
907
+ flex-direction: column;
908
+ }
909
+
910
+ .tab-btn {
911
+ width: 100%;
912
+ }
913
+ }
914
+
915
+ @media (max-width: 768px) {
916
+ body {
917
+ padding: 10px;
918
+ }
919
+
920
+ .nav {
921
+ flex-direction: column;
922
+ gap: 15px;
923
+ text-align: center;
924
+ }
925
+
926
+ #scenarioTitle {
927
+ margin: 10px 0;
928
+ font-size: 1.2em;
929
+ }
930
+
931
+ button {
932
+ width: 100%;
933
+ justify-content: center;
934
+ }
935
+
936
+ .gdpr-options {
937
+ flex-direction: column;
938
+ gap: 10px;
939
+ }
940
+
941
+ .gdpr-option {
942
+ min-width: 100%;
943
+ }
944
+
945
+ .compact-competences-grid {
946
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
947
+ }
948
+
949
+ .compact-radar-metrics-grid {
950
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
951
+ }
952
+
953
+ .compact-radar-legend {
954
+ flex-direction: column;
955
+ align-items: center;
956
+ gap: 8px;
957
+ }
958
+
959
+ .compact-legend-grid {
960
+ grid-template-columns: repeat(2, 1fr);
961
+ }
962
+
963
+ .compact-analysis-controls {
964
+ flex-direction: column;
965
+ align-items: stretch;
966
+ }
967
+
968
+ .compact-persistence-indicators {
969
+ flex-direction: column;
970
+ }
971
+ }
972
+
973
+ /* ================= PROGRESS BAR CONTAINER ================= */
974
+ .progress-container {
975
+ width: 100%;
976
+ background: #f5f5f5;
977
+ border-radius: 12px;
978
+ height: 24px;
979
+ margin: 8px 0 20px;
980
+ overflow: hidden;
981
+ box-shadow: inset 0 2px 5px rgba(0,0,0,0.1);
982
+ }
983
+
984
+ /* ================= TOOLTIPS ================= */
985
+ .tooltip {
986
+ position: absolute;
987
+ background: rgba(25, 118, 210, 0.95);
988
+ color: white;
989
+ padding: 12px 18px;
990
+ border-radius: 10px;
991
+ font-size: 14px;
992
+ pointer-events: none;
993
+ opacity: 0;
994
+ transition: opacity 0.3s;
995
+ z-index: 1000;
996
+ max-width: 300px;
997
+ box-shadow: 0 6px 20px rgba(0,0,0,0.2);
998
+ border: 2px solid white;
999
+ backdrop-filter: blur(5px);
1000
+ }
1001
+
1002
+ .tooltip::after {
1003
+ content: '';
1004
+ position: absolute;
1005
+ top: 100%;
1006
+ left: 50%;
1007
+ margin-left: -10px;
1008
+ border-width: 10px;
1009
+ border-style: solid;
1010
+ border-color: rgba(25, 118, 210, 0.95) transparent transparent transparent;
1011
+ }
1012
+
1013
+ /* ================= SCROLLBAR ================= */
1014
+ ::-webkit-scrollbar {
1015
+ width: 10px;
1016
+ }
1017
+
1018
+ ::-webkit-scrollbar-track {
1019
+ background: #f1f1f1;
1020
+ border-radius: 5px;
1021
+ }
1022
+
1023
+ ::-webkit-scrollbar-thumb {
1024
+ background: linear-gradient(135deg, #1976D2, #2196F3);
1025
+ border-radius: 5px;
1026
+ }
1027
+
1028
+ ::-webkit-scrollbar-thumb:hover {
1029
+ background: linear-gradient(135deg, #1565c0, #1976D2);
1030
+ }
1031
+
1032
+ /* ================= LOADING ================= */
1033
+ .loading {
1034
+ display: inline-block;
1035
+ width: 20px;
1036
+ height: 20px;
1037
+ border: 3px solid #f3f3f3;
1038
+ border-top: 3px solid #1976D2;
1039
+ border-radius: 50%;
1040
+ animation: spin 1s linear infinite;
1041
+ }
1042
+
1043
+ @keyframes spin {
1044
+ 0% { transform: rotate(0deg); }
1045
+ 100% { transform: rotate(360deg); }
1046
+ }
1047
+
1048
+ /* ================= NOTIFICATIONS ================= */
1049
+ .notification {
1050
+ position: fixed;
1051
+ top: 20px;
1052
+ right: 20px;
1053
+ background: white;
1054
+ padding: 18px;
1055
+ border-radius: 12px;
1056
+ box-shadow: 0 8px 25px rgba(0,0,0,0.15);
1057
+ border-left: 6px solid #1976D2;
1058
+ z-index: 10000;
1059
+ max-width: 320px;
1060
+ animation: slideIn 0.4s ease-out;
1061
+ display: flex;
1062
+ align-items: flex-start;
1063
+ gap: 12px;
1064
+ }
1065
+
1066
+ .notification-icon {
1067
+ font-size: 28px;
1068
+ flex-shrink: 0;
1069
+ }
1070
+
1071
+ .notification-content {
1072
+ flex-grow: 1;
1073
+ }
1074
+
1075
+ .notification-title {
1076
+ font-weight: bold;
1077
+ color: #1976D2;
1078
+ margin-bottom: 5px;
1079
+ font-size: 15px;
1080
+ }
1081
+
1082
+ .notification-message {
1083
+ color: #555;
1084
+ font-size: 13px;
1085
+ line-height: 1.4;
1086
+ }
1087
+
1088
+ .notification-close {
1089
+ background: none;
1090
+ border: none;
1091
+ color: #999;
1092
+ cursor: pointer;
1093
+ padding: 0;
1094
+ font-size: 20px;
1095
+ line-height: 1;
1096
+ }
1097
+ </style>
1098
+ </head>
1099
+
1100
+ <body>
1101
+
1102
+ <div id="reflection">
1103
+
1104
+ <!-- NAVIGATION SCÉNARIOS -->
1105
+ <div class="nav">
1106
+ <button id="prevScenario">⬅️ Scénario précédent</button>
1107
+ <h3 id="scenarioTitle">Chargement...</h3>
1108
+ <button id="nextScenario">Scénario suivant ➡️</button>
1109
+ </div>
1110
+
1111
+ <!-- SYSTEME D'ONGLETS -->
1112
+ <div class="tabs-container">
1113
+ <div class="tabs">
1114
+ <button class="tab-btn active" data-tab="tab-evaluator">
1115
+ <span>👤</span> Évaluateur (RGPD)
1116
+ </button>
1117
+ <button class="tab-btn" data-tab="tab-dashboard">
1118
+ <span>📊</span> Dashboard Étudiant
1119
+ </button>
1120
+ <button class="tab-btn" data-tab="tab-evaluation">
1121
+ <span>🤖</span> Message Réflexif & Évaluation
1122
+ </button>
1123
+ </div>
1124
+
1125
+ <!-- ONGLET 1: INFORMATIONS ÉVALUATEUR GDPR -->
1126
+ <div id="tab-evaluator" class="tab-content active">
1127
+ <h3>👤 Informations de l'évaluateur (RGPD)</h3>
1128
+
1129
+ <div class="evaluator-info">
1130
+ <!-- Consentement RGPD -->
1131
+ <div class="evaluator-field">
1132
+ <label for="gdprConsent">
1133
+ <strong><span style="color: #1976D2; margin-right: 5px;">🔒</span> Consentement RGPD <span style="color: #e53935;">*</span></strong>
1134
+ </label>
1135
+ <div class="gdpr-options">
1136
+ <label class="gdpr-option">
1137
+ <input type="radio" name="gdprConsent" value="accept" id="gdprAccept" required>
1138
+ <span>J'accepte de partager mes informations pour l'évaluation</span>
1139
+ </label>
1140
+ <label class="gdpr-option">
1141
+ <input type="radio" name="gdprConsent" value="decline" id="gdprDecline">
1142
+ <span>Je préfère rester anonyme</span>
1143
+ </label>
1144
+ </div>
1145
+ <small>Veuillez accepter le consentement RGPD pour pouvoir remplir les champs d'identification</small>
1146
+ </div>
1147
+
1148
+ <!-- Champs conditionnels (masqués par défaut) -->
1149
+ <div id="evaluatorFields" style="display: none;">
1150
+ <!-- Nom et prénom -->
1151
+ <div class="evaluator-field">
1152
+ <label for="evaluatorName">
1153
+ <strong><span style="color: #1976D2; margin-right: 5px;">📝</span> Nom et prénom <span style="color: #e53935;">*</span></strong>
1154
+ </label>
1155
+ <input type="text"
1156
+ id="evaluatorName"
1157
+ placeholder="Ex: Dupont Jean ou Marie Curie"
1158
+ maxlength="100"
1159
+ disabled>
1160
+ <small>Veuillez saisir votre nom et prénom</small>
1161
+ </div>
1162
+
1163
+ <!-- Rôle -->
1164
+ <div class="evaluator-field">
1165
+ <label for="evaluatorRole"><strong><span style="color: #1976D2; margin-right: 5px;">👔</span> Rôle principal <span style="color: #e53935;">*</span></strong></label>
1166
+ <select id="evaluatorRole" disabled>
1167
+ <option value="">Sélectionnez votre rôle...</option>
1168
+ <option value="enseignant">Enseignant / Formateur</option>
1169
+ <option value="chercheur">Chercheur / Scientifique</option>
1170
+ <option value="expert_pedago">Expert pédagogique</option>
1171
+ <option value="etudiant_avance">Étudiant avancé / Doctorant</option>
1172
+ <option value="conseiller">Conseiller pédagogique</option>
1173
+ <option value="responsable">Responsable de formation</option>
1174
+ <option value="autre">Autre professionnel de l'éducation</option>
1175
+ </select>
1176
+ <small>Sélectionnez votre rôle principal dans le domaine éducatif</small>
1177
+ </div>
1178
+
1179
+ <!-- Niveau d'expertise en réflexivité -->
1180
+ <div class="evaluator-field">
1181
+ <label for="expertiseLevel"><strong><span style="color: #1976D2; margin-right: 5px;">🎓</span> Niveau d'expertise en réflexivité <span style="color: #e53935;">*</span></strong></label>
1182
+ <select id="expertiseLevel" disabled>
1183
+ <option value="">Sélectionnez votre niveau...</option>
1184
+ <option value="debutant">Débutant - Je découvre la réflexivité</option>
1185
+ <option value="intermediaire">Intermédiaire - J'utilise régulièrement des outils réflexifs</option>
1186
+ <option value="avance">Avancé - Je conçois des dispositifs réflexifs</option>
1187
+ <option value="expert">Expert - Je forme à la réflexivité pédagogique</option>
1188
+ <option value="chercheur_reflex">Chercheur en réflexivité</option>
1189
+ </select>
1190
+ <small>Indiquez votre niveau de maîtrise des concepts et outils de réflexivité</small>
1191
+ </div>
1192
+
1193
+ <!-- Niveau de maîtrise des messages réflexifs -->
1194
+ <div class="evaluator-field">
1195
+ <label for="messageMastery"><strong><span style="color: #1976D2; margin-right: 5px;">💬</span> Niveau de maîtrise des messages réflexifs <span style="color: #e53935;">*</span></strong></label>
1196
+ <select id="messageMastery" disabled>
1197
+ <option value="">Sélectionnez votre niveau...</option>
1198
+ <option value="novice">Novice - Je commence à analyser des messages réflexifs</option>
1199
+ <option value="intermediaire_msg">Intermédiaire - J'évalue régulièrement des feedbacks réflexifs</option>
1200
+ <option value="avance_msg">Avancé - Je rédige des messages réflexifs pour autrui</option>
1201
+ <option value="expert_msg">Expert - Je forme à la conception de messages réflexifs</option>
1202
+ </select>
1203
+ <small>Indiquez votre expérience avec l'analyse et la création de messages réflexifs</small>
1204
+ </div>
1205
+ </div>
1206
+
1207
+ <!-- Message pour utilisateurs anonymes -->
1208
+ <div id="anonymousMessage" style="display: none;">
1209
+ <p>
1210
+ <strong><span style="margin-right: 5px;">🕵️</span> Évaluation anonyme :</strong> Vos évaluations seront enregistrées sans information personnelle.
1211
+ Seules vos réponses aux métriques de confiance seront conservées.
1212
+ </p>
1213
+ </div>
1214
+
1215
+ <!-- Boutons d'action -->
1216
+ <div style="display: flex; gap: 10px; margin-top: 20px;">
1217
+ <button onclick="fillSampleEvaluator()" type="button" style="background: #666; flex: 1;" id="fillExampleBtn">
1218
+ <span style="margin-right: 5px;">📋</span> Remplir exemple
1219
+ </button>
1220
+ <button onclick="clearEvaluatorFields()" type="button" style="background: #9e9e9e; flex: 1;" id="clearFieldsBtn">
1221
+ <span style="margin-right: 5px;">🗑️</span> Effacer
1222
+ </button>
1223
+ </div>
1224
+ </div>
1225
+ </div>
1226
+
1227
+ <!-- ONGLET 2: DASHBOARD ÉTUDIANT COMPACT -->
1228
+ <div id="tab-dashboard" class="tab-content">
1229
+ <h3>📝 Manifeste étudiant</h3>
1230
+ <div id="manifest-list">
1231
+ <div class="manifest-item">
1232
+ <em>Chargement des données...</em>
1233
+ </div>
1234
+ </div>
1235
+
1236
+ <h3>📊 Progression par compétence</h3>
1237
+ <div id="competence-bars">
1238
+ <div id="compact-competences">
1239
+ <em>Chargement des compétences...</em>
1240
+ </div>
1241
+ </div>
1242
+
1243
+ <!-- LÉGENDE RADAR COMPACTE -->
1244
+ <div class="compact-radar-legend">
1245
+ <div class="compact-legend-item">
1246
+ <div class="compact-legend-color compact-legend-low"></div>
1247
+ <span>Faible (0-50%)</span>
1248
+ </div>
1249
+ <div class="compact-legend-item">
1250
+ <div class="compact-legend-color compact-legend-medium"></div>
1251
+ <span>Moyen (50-70%)</span>
1252
+ </div>
1253
+ <div class="compact-legend-item">
1254
+ <div class="compact-legend-color compact-legend-high"></div>
1255
+ <span>Élevé (70-100%)</span>
1256
+ </div>
1257
+ </div>
1258
+
1259
+ <h3>🕸️ Radar – Learning Analytics</h3>
1260
+
1261
+ <!-- Grille des métriques radar compacte -->
1262
+ <div class="compact-radar-metrics-grid" id="compact-radar-metrics-grid">
1263
+ <!-- Les métriques seront ajoutées dynamiquement -->
1264
+ </div>
1265
+
1266
+ <!-- Container Radar et Bot Message -->
1267
+ <div id="radar-container">
1268
+ <div style="display: flex; gap: 20px; flex-wrap: wrap;">
1269
+ <!-- Message Bot Radar Compact -->
1270
+ <div class="compact-radar-bot-message" style="flex: 1; min-width: 300px;">
1271
+ <div class="compact-radar-bot-header">
1272
+ <div class="compact-radar-bot-icon">🎯</div>
1273
+ <h4 class="compact-radar-bot-title">Analyse de Profil</h4>
1274
+ </div>
1275
+ <p class="compact-radar-bot-content" id="compact-radar-bot-content">Analyse en cours...</p>
1276
+ <div class="compact-radar-bot-insights">
1277
+ <div id="compact-radar-bot-insights">
1278
+ <!-- Les insights seront ajoutés dynamiquement -->
1279
+ </div>
1280
+ </div>
1281
+ </div>
1282
+
1283
+ <!-- Canvas Radar Compact -->
1284
+ <div style="flex: 1; min-width: 300px; text-align: center;">
1285
+ <canvas id="radar" width="500" height="500" style="max-width: 100%; height: auto;"></canvas>
1286
+ </div>
1287
+ </div>
1288
+ </div>
1289
+
1290
+ <!-- HEATMAP COMPACTE -->
1291
+ <div class="compact-heatmap-and-indicators">
1292
+ <h3>🔥 Heatmap d'activité - Analyse de Persévérance</h3>
1293
+
1294
+ <div class="compact-heatmap-analysis">
1295
+ <div class="compact-analysis-controls">
1296
+ <label for="persistenceMode">Mode d'analyse :</label>
1297
+ <select id="persistenceMode" onchange="changePersistenceAnalysis()">
1298
+ <option value="regularity">📊 Régularité du travail</option>
1299
+ <option value="effortPattern">🔄 Schéma d'effort</option>
1300
+ <option value="deadline">⏰ Gestion des échéances</option>
1301
+ <option value="combined">🎯 Vue combinée</option>
1302
+ </select>
1303
+ </div>
1304
+
1305
+ <!-- Canvas pour le heatmap -->
1306
+ <canvas id="heatmap" width="800" height="250" style="max-width: 100%; height: auto;"></canvas>
1307
+ </div>
1308
+
1309
+ <!-- Légende des niveaux d'activité compacte -->
1310
+ <div class="compact-enriched-legend">
1311
+ <div class="compact-legend-section">
1312
+ <h5>📈 Niveaux d'activité</h5>
1313
+ <div class="compact-legend-grid">
1314
+ <div class="compact-legend-item-small">
1315
+ <div class="compact-legend-color-small" style="background:#EBEDF0;"></div>
1316
+ <span>Aucune activité</span>
1317
+ </div>
1318
+ <div class="compact-legend-item-small">
1319
+ <div class="compact-legend-color-small" style="background:#C6E48B;"></div>
1320
+ <span>Faible activité</span>
1321
+ </div>
1322
+ <div class="compact-legend-item-small">
1323
+ <div class="compact-legend-color-small" style="background:#7BC96F;"></div>
1324
+ <span>Activité modérée</span>
1325
+ </div>
1326
+ <div class="compact-legend-item-small">
1327
+ <div class="compact-legend-color-small" style="background:#239A3B;"></div>
1328
+ <span>Activité élevée</span>
1329
+ </div>
1330
+ <div class="compact-legend-item-small">
1331
+ <div class="compact-legend-color-small" style="background:#196127;"></div>
1332
+ <span>Activité intense</span>
1333
+ </div>
1334
+ </div>
1335
+ </div>
1336
+ </div>
1337
+
1338
+ <!-- Analyse de persévérance compacte -->
1339
+ <div class="compact-persistence-analysis" id="compact-persistenceAnalysis">
1340
+ <h5>🎯 Indicateurs de Persévérance</h5>
1341
+ <div class="compact-persistence-indicators">
1342
+ <div class="compact-indicator">
1343
+ <span class="compact-indicator-dot" style="background:#FF6B6B;"></span>
1344
+ <span>Régularité : <strong id="compact-regularityScore">-</strong></span>
1345
+ </div>
1346
+ <div class="compact-indicator">
1347
+ <span class="compact-indicator-dot" style="background:#4ECDC4;"></span>
1348
+ <span>Schéma d'effort : <strong id="compact-effortPattern">-</strong></span>
1349
+ </div>
1350
+ <div class="compact-indicator">
1351
+ <span class="compact-indicator-dot" style="background:#FFD166;"></span>
1352
+ <span>Gestion échéances : <strong id="compact-deadlineScore">-</strong></span>
1353
+ </div>
1354
+ </div>
1355
+
1356
+ <div class="compact-persistence-text" style="margin-top: 10px;">
1357
+ <div><strong>Persévérance et gestion des efforts :</strong> <span id="compact-regularityText">Analyse en cours...</span></div>
1358
+ <div><strong>Schéma d'effort :</strong> <span id="compact-patternText">Analyse en cours...</span></div>
1359
+ </div>
1360
+ </div>
1361
+ </div>
1362
+ </div>
1363
+
1364
+ <!-- ONGLET 3: MESSAGE RÉFLEXIF ET ÉVALUATION -->
1365
+ <div id="tab-evaluation" class="tab-content">
1366
+ <h3>🤖 ReflAgent – Analyse & accompagnement</h3>
1367
+ <div id="reflagent">
1368
+ <em>Le message d'analyse apparaîtra ici après chargement...</em>
1369
+ </div>
1370
+
1371
+ <hr>
1372
+
1373
+ <h3>🧑‍⚖️ Volet Expert – Métriques de Confiance</h3>
1374
+ <p style="color: #666; margin-bottom: 20px; font-style: italic;">
1375
+ Évaluez votre confiance dans l'analyse de ReflAgent pour ce scénario :
1376
+ </p>
1377
+
1378
+ <!-- MÉTRIQUES TRADUITES EN FRANÇAIS -->
1379
+ <div class="trust-item">
1380
+ <b>Authenticité Réflexive (AR)</b>
1381
+ <div class="stars" data-metric="AR">
1382
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1383
+ </div>
1384
+ <small style="color: #666; display: block; margin-top: 5px;">
1385
+ L'analyse reflète-t-elle fidèlement la situation réelle de l'étudiant ?
1386
+ </small>
1387
+ </div>
1388
+
1389
+ <div class="trust-item">
1390
+ <b>Alignement Empathique (AE)</b>
1391
+ <div class="stars" data-metric="AE">
1392
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1393
+ </div>
1394
+ <small style="color: #666; display: block; margin-top: 5px;">
1395
+ L'agent comprend-il les émotions, motivations et difficultés de l'étudiant ?
1396
+ </small>
1397
+ </div>
1398
+
1399
+ <div class="trust-item">
1400
+ <b>Encouragement Sensible au Risque (ESR)</b>
1401
+ <div class="stars" data-metric="ESR">
1402
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1403
+ </div>
1404
+ <small style="color: #666; display: block; margin-top: 5px;">
1405
+ Les encouragements tiennent-ils compte des risques et difficultés identifiés ?
1406
+ </small>
1407
+ </div>
1408
+
1409
+ <div class="trust-item">
1410
+ <b>Support aux Défis Mentaux (SDM)</b>
1411
+ <div class="stars" data-metric="SDM">
1412
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1413
+ </div>
1414
+ <small style="color: #666; display: block; margin-top: 5px;">
1415
+ L'agent aide-t-il l'étudiant à développer sa pensée critique et ses compétences cognitives ?
1416
+ </small>
1417
+ </div>
1418
+
1419
+ <div class="trust-item">
1420
+ <b>Support Métacognitif (SM)</b>
1421
+ <div class="stars" data-metric="SM">
1422
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1423
+ </div>
1424
+ <small style="color: #666; display: block; margin-top: 5px;">
1425
+ L'agent aide-t-il l'étudiant à réfléchir sur ses propres stratégies d'apprentissage ?
1426
+ </small>
1427
+ </div>
1428
+
1429
+ <h4>💬 Commentaire expert</h4>
1430
+ <textarea id="trustComment" placeholder="Ajoutez vos observations, suggestions ou critiques concernant l'analyse de ReflAgent..."></textarea>
1431
+
1432
+ <div style="display: flex; justify-content: space-between; align-items: center; margin: 25px 0;">
1433
+ <div style="flex-grow: 1; margin-right: 20px;">
1434
+ <h4 style="margin-bottom: 10px;">🔒 Indice global de confiance</h4>
1435
+ <div class="progress-container">
1436
+ <div class="fill" id="trustBar">0%</div>
1437
+ </div>
1438
+ <div style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 12px; color: #666;">
1439
+ <span>Faible confiance</span>
1440
+ <span>Confidence moyenne</span>
1441
+ <span>Forte confiance</span>
1442
+ </div>
1443
+ </div>
1444
+ <div style="display: flex; flex-direction: column; gap: 10px; align-items: flex-end;">
1445
+ <button id="saveTrustBtn" style="height: fit-content; width: 100%;">💾 Sauvegarder l'évaluation</button>
1446
+ <button id="crossReadersBtn" style="height: fit-content; width: 100%; background: linear-gradient(135deg, #43A047, #4CAF50);">
1447
+ 📊 Lecture croisée
1448
+ </button>
1449
+ </div>
1450
+ </div>
1451
+
1452
+ <div id="saveTrustMsg"></div>
1453
+
1454
+ <!-- Statistiques rapides -->
1455
+ <div class="stats-grid">
1456
+ <div class="stat-item">
1457
+ <div class="stat-label">Scénario actuel</div>
1458
+ <div class="stat-value" id="currentScenarioNum">-</div>
1459
+ </div>
1460
+ <div class="stat-item">
1461
+ <div class="stat-label">Confiance moyenne</div>
1462
+ <div class="stat-value" id="avgTrustScore">0%</div>
1463
+ </div>
1464
+ <div class="stat-item">
1465
+ <div class="stat-label">Niveau de risque</div>
1466
+ <div class="stat-value" id="riskLevel">-</div>
1467
+ </div>
1468
+ <div class="stat-item">
1469
+ <div class="stat-label">Activité moyenne</div>
1470
+ <div class="stat-value" id="avgActivity">-</div>
1471
+ </div>
1472
+ </div>
1473
+ </div>
1474
+ </div>
1475
+ </div>
1476
+
1477
+ <!-- Script principal -->
1478
+ <script>
1479
+ // ================= VARIABLES =================
1480
+ let scenarios = [];
1481
+ let currentScenarioIndex = 0;
1482
+ let radarMetrics = [];
1483
+
1484
+ // Métriques de radar par défaut (sans abréviations)
1485
+ const DEFAULT_RADAR_METRICS = [
1486
+ { label: "Démarrage des activités", value: 85 },
1487
+ { label: "Connaissances validées", value: 72 },
1488
+ { label: "Niveau moyen de compétence", value: 68 },
1489
+ { label: "Taux d'erreur (inversé)", value: 35 },
1490
+ { label: "Achèvement des activités", value: 74 },
1491
+ { label: "Interactions avec les ressources", value: 80 },
1492
+ { label: "Domaines de compétence", value: 78 }
1493
+ ];
1494
+
1495
+ // Noms des métriques traduits en français
1496
+ const trustMetrics = {
1497
+ "AR": 0, // Authenticité Réflexive
1498
+ "AE": 0, // Alignement Empathique
1499
+ "ESR": 0, // Encouragement Sensible au Risque
1500
+ "SDM": 0, // Support aux Défis Mentaux
1501
+ "SM": 0 // Support Métacognitif
1502
+ };
1503
+
1504
+ const trustWeights = {
1505
+ "AR": 0.30,
1506
+ "AE": 0.20,
1507
+ "ESR": 0.20,
1508
+ "SDM": 0.10,
1509
+ "SM": 0.20
1510
+ };
1511
+
1512
+ // ================= INIT =================
1513
+ document.addEventListener("DOMContentLoaded", () => {
1514
+ console.log("✅ DOM chargé, initialisation...");
1515
+ loadScenarios();
1516
+ initTrustStars();
1517
+ initTrustSave();
1518
+ initTabs();
1519
+ initGDPR();
1520
+
1521
+ // Initialiser la barre de confiance à 0%
1522
+ updateTrustBar();
1523
+ });
1524
+
1525
+ // ================= SYSTEME D'ONGLETS =================
1526
+ function initTabs() {
1527
+ const tabBtns = document.querySelectorAll('.tab-btn');
1528
+ const tabContents = document.querySelectorAll('.tab-content');
1529
+
1530
+ tabBtns.forEach(btn => {
1531
+ btn.addEventListener('click', () => {
1532
+ const tabId = btn.getAttribute('data-tab');
1533
+
1534
+ // Retirer la classe active de tous les boutons et contenus
1535
+ tabBtns.forEach(b => b.classList.remove('active'));
1536
+ tabContents.forEach(c => c.classList.remove('active'));
1537
+
1538
+ // Ajouter la classe active au bouton et au contenu correspondant
1539
+ btn.classList.add('active');
1540
+ document.getElementById(tabId).classList.add('active');
1541
+ });
1542
+ });
1543
+ }
1544
+
1545
+ // ================= GDPR =================
1546
+ function initGDPR() {
1547
+ const gdprAccept = document.getElementById('gdprAccept');
1548
+ const gdprDecline = document.getElementById('gdprDecline');
1549
+ const evaluatorFields = document.getElementById('evaluatorFields');
1550
+ const anonymousMessage = document.getElementById('anonymousMessage');
1551
+
1552
+ // Activer/désactiver les champs selon le choix GDPR
1553
+ function updateGDPRFields() {
1554
+ if (gdprAccept.checked) {
1555
+ // Afficher les champs et les activer
1556
+ evaluatorFields.style.display = 'block';
1557
+ anonymousMessage.style.display = 'none';
1558
+
1559
+ // Activer les champs
1560
+ document.getElementById('evaluatorName').disabled = false;
1561
+ document.getElementById('evaluatorRole').disabled = false;
1562
+ document.getElementById('expertiseLevel').disabled = false;
1563
+ document.getElementById('messageMastery').disabled = false;
1564
+ } else if (gdprDecline.checked) {
1565
+ // Cacher les champs et afficher le message anonyme
1566
+ evaluatorFields.style.display = 'none';
1567
+ anonymousMessage.style.display = 'block';
1568
+
1569
+ // Désactiver et vider les champs
1570
+ document.getElementById('evaluatorName').disabled = true;
1571
+ document.getElementById('evaluatorName').value = '';
1572
+ document.getElementById('evaluatorRole').disabled = true;
1573
+ document.getElementById('evaluatorRole').value = '';
1574
+ document.getElementById('expertiseLevel').disabled = true;
1575
+ document.getElementById('expertiseLevel').value = '';
1576
+ document.getElementById('messageMastery').disabled = true;
1577
+ document.getElementById('messageMastery').value = '';
1578
+ }
1579
+ }
1580
+
1581
+ // Écouter les changements
1582
+ gdprAccept.addEventListener('change', updateGDPRFields);
1583
+ gdprDecline.addEventListener('change', updateGDPRFields);
1584
+
1585
+ // Initialiser
1586
+ updateGDPRFields();
1587
+ }
1588
+
1589
+ // ================= CHARGEMENT JSON =================
1590
+ function loadScenarios() {
1591
+ console.log("Chargement des scénarios...");
1592
+ fetch("/static/scenarios.json")
1593
+ .then(r => {
1594
+ if (!r.ok) throw new Error("Erreur de chargement du fichier JSON");
1595
+ return r.json();
1596
+ })
1597
+ .then(data => {
1598
+ console.log("Scénarios chargés:", data.scenarios.length);
1599
+ scenarios = data.scenarios;
1600
+ loadScenario(0);
1601
+ })
1602
+ .catch(error => {
1603
+ console.error("Erreur:", error);
1604
+ document.getElementById("manifest-list").innerHTML =
1605
+ `<div class="manifest-item" style="background:#FFEBEE;color:#C62828;">
1606
+ Erreur de chargement des scénarios. Vérifiez que le fichier scenarios.json existe.
1607
+ </div>`;
1608
+ });
1609
+ }
1610
+
1611
+ // ================= CHARGER SCÉNARIO =================
1612
+ function loadScenario(index) {
1613
+ console.log("Chargement scénario", index);
1614
+ if (index < 0 || index >= scenarios.length) return;
1615
+ currentScenarioIndex = index;
1616
+ const s = scenarios[index];
1617
+
1618
+ // Mettre à jour le titre
1619
+ const titleElement = document.getElementById("scenarioTitle");
1620
+ titleElement.textContent = `Scénario ${s.id} – ${s.title}`;
1621
+
1622
+ // Mettre à jour le manifeste
1623
+ document.getElementById("manifest-list").innerHTML = `
1624
+ <div class="manifest-item">
1625
+ <b>Type de Manifest :</b> ${s.manifest.type}<br>
1626
+ <b>Manifeste (écrit par l'étudiant) :</b> ${s.manifest.manifeste}<br>
1627
+ <b>Description du Profil :</b> ${s.manifest.description}
1628
+ </div>`;
1629
+
1630
+ // Mettre à jour les compétences compactes
1631
+ updateCompactCompetences(s.competences);
1632
+
1633
+ // Mettre à jour le radar avec les nouvelles métriques
1634
+ if (s.radar && s.radar.length > 0) {
1635
+ radarMetrics = s.radar;
1636
+ } else {
1637
+ // Utiliser les métriques par défaut avec variation pour chaque scénario
1638
+ radarMetrics = DEFAULT_RADAR_METRICS.map(metric => {
1639
+ // Variation de ±15% selon l'index du scénario pour rendre les données plus réalistes
1640
+ const variation = (index % 7) * 5 - 15; // -15 à +15
1641
+ const newValue = Math.max(10, Math.min(95, metric.value + variation));
1642
+ return {
1643
+ label: metric.label,
1644
+ value: newValue
1645
+ };
1646
+ });
1647
+ }
1648
+
1649
+ // Mettre à jour la grille des métriques radar compacte
1650
+ updateCompactRadarMetricsGrid();
1651
+
1652
+ // Mettre à jour le graphique radar
1653
+ drawRadar();
1654
+
1655
+ // Mettre à jour le message bot radar compact
1656
+ updateCompactRadarBotMessage(s);
1657
+
1658
+ // Mettre à jour la heatmap enrichie compacte
1659
+ drawCompactEnrichedHeatmap(s);
1660
+
1661
+ // Mettre à jour le message ReflAgent
1662
+ document.getElementById("reflagent").textContent = s.reflAgent;
1663
+
1664
+ // Mettre à jour les boutons de navigation
1665
+ updateNavButtons();
1666
+
1667
+ // Mettre à jour les statistiques
1668
+ updateStats();
1669
+ }
1670
+
1671
+ // ================= FONCTIONS POUR LA VERSION COMPACTE =================
1672
+
1673
+ // Mettre à jour les compétences compactes
1674
+ function updateCompactCompetences(competences) {
1675
+ const container = document.getElementById("compact-competences");
1676
+ if (!container) return;
1677
+
1678
+ container.innerHTML = '';
1679
+
1680
+ competences.forEach(comp => {
1681
+ // Déterminer la couleur selon la valeur
1682
+ let color;
1683
+ if (comp.value < 50) color = '#E53935';
1684
+ else if (comp.value < 70) color = '#FB8C00';
1685
+ else color = '#43A047';
1686
+
1687
+ // Créer l'élément de compétence
1688
+ const compItem = document.createElement('div');
1689
+ compItem.className = 'compact-competence-item';
1690
+ compItem.innerHTML = `
1691
+ <div class="compact-competence-label">
1692
+ <span>${comp.label}</span>
1693
+ <span>${comp.value}%</span>
1694
+ </div>
1695
+ <div class="compact-competence-bar">
1696
+ <div class="compact-competence-fill" style="width: ${comp.value}%; background: ${color};">
1697
+ ${comp.value >= 10 ? comp.value + '%' : ''}
1698
+ </div>
1699
+ </div>
1700
+ `;
1701
+
1702
+ container.appendChild(compItem);
1703
+ });
1704
+ }
1705
+
1706
+ // Mettre à jour la grille des métriques radar compacte
1707
+ function updateCompactRadarMetricsGrid() {
1708
+ const grid = document.getElementById("compact-radar-metrics-grid");
1709
+ if (!grid) return;
1710
+
1711
+ grid.innerHTML = '';
1712
+
1713
+ radarMetrics.forEach(metric => {
1714
+ // Déterminer la classe de couleur selon la valeur
1715
+ let colorClass = "";
1716
+ if (metric.value >= 70) colorClass = "high";
1717
+ else if (metric.value >= 40) colorClass = "medium";
1718
+ else colorClass = "low";
1719
+
1720
+ // Déterminer l'icône selon le type de métrique
1721
+ let icon = "📊";
1722
+ if (metric.label.includes("Démarrage")) icon = "🚀";
1723
+ else if (metric.label.includes("Connaissances")) icon = "🎓";
1724
+ else if (metric.label.includes("Niveau moyen")) icon = "📈";
1725
+ else if (metric.label.includes("Taux d'erreur")) icon = "🎯";
1726
+ else if (metric.label.includes("Achèvement")) icon = "🏁";
1727
+ else if (metric.label.includes("Interactions")) icon = "📚";
1728
+ else if (metric.label.includes("Domaines")) icon = "🔧";
1729
+
1730
+ // Déterminer la description
1731
+ let description = "";
1732
+ if (metric.label.includes("Démarrage")) description = "Rapidité d'initiation";
1733
+ else if (metric.label.includes("Connaissances")) description = "Acquis démontrés";
1734
+ else if (metric.label.includes("Niveau moyen")) description = "Moyenne des compétences";
1735
+ else if (metric.label.includes("Taux d'erreur")) description = "Précision et attention";
1736
+ else if (metric.label.includes("Achèvement")) description = "Terminaison des tâches";
1737
+ else if (metric.label.includes("Interactions")) description = "Utilisation supports";
1738
+ else if (metric.label.includes("Domaines")) description = "Étendue couverte";
1739
+
1740
+ const metricCard = document.createElement("div");
1741
+ metricCard.className = "compact-metric-card";
1742
+ metricCard.innerHTML = `
1743
+ <div class="compact-metric-icon">${icon}</div>
1744
+ <div class="compact-metric-name">${metric.label}</div>
1745
+ <div class="compact-metric-value ${colorClass}">${metric.value}%</div>
1746
+ <div class="compact-metric-description">${description}</div>
1747
+ `;
1748
+
1749
+ grid.appendChild(metricCard);
1750
+ });
1751
+ }
1752
+
1753
+ // Mettre à jour le message bot radar compact
1754
+ function updateCompactRadarBotMessage(scenario) {
1755
+ const radarBotContent = document.getElementById("compact-radar-bot-content");
1756
+ const radarBotInsights = document.getElementById("compact-radar-bot-insights");
1757
+
1758
+ if (!radarBotContent || !radarBotInsights) return;
1759
+
1760
+ // Messages pour chaque profil basé sur le titre du scénario
1761
+ const profileMessages = {
1762
+ "Étudiant engagé": {
1763
+ title: "Étudiant Engagé et Motivé",
1764
+ message: "🎯 Ton engagement est impressionnant ! Tu démontres une forte volonté d'apprendre.",
1765
+ insights: [
1766
+ { icon: "🔥", text: "Motivation élevée" },
1767
+ { icon: "🎯", text: "Objectifs bien définis" },
1768
+ { icon: "📚", text: "Implication active" }
1769
+ ]
1770
+ },
1771
+ "Étudiant actif mais inefficace": {
1772
+ title: "Actif mais Peu Efficace",
1773
+ message: "📊 Tu es très actif mais ton taux d'erreur est élevé. Concentre-toi sur une compétence à la fois.",
1774
+ insights: [
1775
+ { icon: "⚡", text: "Activité élevée" },
1776
+ { icon: "⚠️", text: "Erreurs fréquentes" },
1777
+ { icon: "🎯", text: "Focus nécessaire" }
1778
+ ]
1779
+ },
1780
+ "Étudiant orienté vers le succès": {
1781
+ title: "Orientation Réussite",
1782
+ message: "🏆 Tu vises l'excellence avec détermination. Ta rigueur est exemplaire.",
1783
+ insights: [
1784
+ { icon: "⭐", text: "Excellence visée" },
1785
+ { icon: "🎯", text: "Objectifs ambitieux" },
1786
+ { icon: "📈", text: "Performance supérieure" }
1787
+ ]
1788
+ },
1789
+ "Étudiant motivé": {
1790
+ title: "Nouvellement Motivé",
1791
+ message: "🚀 Ta motivation est un excellent point de départ ! Progresse étape par étape.",
1792
+ insights: [
1793
+ { icon: "🌟", text: "Motivation récente" },
1794
+ { icon: "🧱", text: "Construction des bases" },
1795
+ { icon: "📖", text: "Curiosité ouverte" }
1796
+ ]
1797
+ },
1798
+ "Étudiant surmotivé": {
1799
+ title: "Surmotivé - Attention",
1800
+ message: "💥 Ton niveau d'investissement est exceptionnel, attention au risque de surmenage.",
1801
+ insights: [
1802
+ { icon: "⚡", text: "Investissement maximal" },
1803
+ { icon: "⚠️", text: "Risque de burnout" },
1804
+ { icon: "⚖️", text: "Équilibre nécessaire" }
1805
+ ]
1806
+ },
1807
+ "Étudiant stratégique": {
1808
+ title: "Stratégique et Efficient",
1809
+ message: "♟️ Tu abordes l'apprentissage avec intelligence et planification.",
1810
+ insights: [
1811
+ { icon: "🧠", text: "Approche réfléchie" },
1812
+ { icon: "🎯", text: "Optimisation efforts" },
1813
+ { icon: "📊", text: "Analyse des retours" }
1814
+ ]
1815
+ }
1816
+ };
1817
+
1818
+ // Récupérer le message pour le profil ou utiliser un message par défaut
1819
+ const profileMessage = profileMessages[scenario.title] || {
1820
+ title: "Profil d'Apprentissage",
1821
+ message: "Analyse de votre profil d'apprentissage en cours...",
1822
+ insights: [
1823
+ { icon: "📊", text: "Évaluation indicateurs" },
1824
+ { icon: "🎯", text: "Forces et améliorations" },
1825
+ { icon: "🚀", text: "Recommandations" }
1826
+ ]
1827
+ };
1828
+
1829
+ // Mettre à jour l'interface
1830
+ radarBotContent.innerHTML = `<strong>${profileMessage.title}</strong><br>${profileMessage.message}`;
1831
+
1832
+ // Mettre à jour les insights
1833
+ radarBotInsights.innerHTML = '';
1834
+ profileMessage.insights.forEach(insight => {
1835
+ const insightElement = document.createElement('div');
1836
+ insightElement.className = 'compact-radar-insight-item';
1837
+ insightElement.innerHTML = `
1838
+ <div class="radar-insight-icon">${insight.icon}</div>
1839
+ <div class="radar-insight-text">${insight.text}</div>
1840
+ `;
1841
+ radarBotInsights.appendChild(insightElement);
1842
+ });
1843
+ }
1844
+
1845
+ // Dessiner la heatmap enrichie compacte
1846
+ function drawCompactEnrichedHeatmap(scenario) {
1847
+ const canvas = document.getElementById("heatmap");
1848
+ if (!canvas) return;
1849
+
1850
+ const ctx = canvas.getContext("2d");
1851
+ const cellSize = 15;
1852
+ const padding = 1;
1853
+ const days = ["L", "M", "M", "J", "V", "S", "D"];
1854
+ const weeks = 4;
1855
+ const totalDays = weeks * 7;
1856
+
1857
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
1858
+
1859
+ // Titre enrichi
1860
+ const scenarioTitles = {
1861
+ 1: {
1862
+ title: "Engagé mais désorganisé",
1863
+ emoji: "😅",
1864
+ pattern: "Effort concentré avant échéances"
1865
+ },
1866
+ 2: {
1867
+ title: "Actif mais peu efficace",
1868
+ emoji: "😰",
1869
+ pattern: "Démarrage lent, accélération tardive"
1870
+ },
1871
+ 3: {
1872
+ title: "Autonome et stratégique",
1873
+ emoji: "😊",
1874
+ pattern: "Travail régulier et équilibré"
1875
+ }
1876
+ };
1877
+
1878
+ const scenarioInfo = scenarioTitles[scenario.id] || {
1879
+ title: "Votre activité",
1880
+ emoji: "📊",
1881
+ pattern: "Schéma à analyser"
1882
+ };
1883
+
1884
+ ctx.font = "bold 14px Arial";
1885
+ ctx.fillStyle = "#1976D2";
1886
+ ctx.textAlign = "center";
1887
+ ctx.fillText(`${scenarioInfo.emoji} ${scenarioInfo.title}`, canvas.width / 2, 20);
1888
+
1889
+ ctx.font = "12px Arial";
1890
+ ctx.fillStyle = "#666";
1891
+ ctx.fillText(`${scenarioInfo.pattern}`, canvas.width / 2, 40);
1892
+
1893
+ // Générer les données d'activité selon le scénario
1894
+ const activityData = generateCompactPersistenceData(scenario.id, totalDays);
1895
+
1896
+ // Dessiner la heatmap
1897
+ const colors = ["#EBEDF0", "#C6E48B", "#7BC96F", "#239A3B", "#196127"];
1898
+
1899
+ for (let day = 0; day < totalDays; day++) {
1900
+ const week = Math.floor(day / 7);
1901
+ const weekday = day % 7;
1902
+
1903
+ const x = 30 + week * (cellSize * 7 + padding * 7) + weekday * (cellSize + padding);
1904
+ const y = 60 + weekday * (cellSize + padding);
1905
+
1906
+ const intensity = activityData[day];
1907
+
1908
+ // Dessiner la cellule
1909
+ ctx.fillStyle = colors[intensity];
1910
+ ctx.fillRect(x, y, cellSize, cellSize);
1911
+
1912
+ // Bordure avec indication des échéances (vendredi = jour important)
1913
+ if (weekday === 4) { // Vendredi
1914
+ ctx.strokeStyle = "#FF6B6B";
1915
+ ctx.lineWidth = 1.5;
1916
+ } else {
1917
+ ctx.strokeStyle = intensity > 0 ? "#239A3B" : "#eee";
1918
+ ctx.lineWidth = 0.5;
1919
+ }
1920
+ ctx.strokeRect(x, y, cellSize, cellSize);
1921
+ }
1922
+
1923
+ // Analyser et afficher les métriques de persévérance compactes
1924
+ analyzeCompactPersistenceMetrics(activityData, scenario.id);
1925
+ }
1926
+
1927
+ // Générer des données de persévérance compactes
1928
+ function generateCompactPersistenceData(scenarioId, totalDays) {
1929
+ const data = new Array(totalDays).fill(0);
1930
+
1931
+ switch(scenarioId) {
1932
+ case 1: // Scénario désorganisé - Effort concentré avant échéances
1933
+ for (let i = 0; i < totalDays; i++) {
1934
+ const weekday = i % 7;
1935
+ if (weekday === 3 || weekday === 4) { // Jeudi et vendredi
1936
+ data[i] = Math.floor(Math.random() * 2) + 3; // 3-4
1937
+ } else if (weekday === 5 || weekday === 6) { // Weekend
1938
+ data[i] = Math.floor(Math.random() * 2); // 0-1
1939
+ } else {
1940
+ data[i] = Math.floor(Math.random() * 2) + 1; // 1-2
1941
+ }
1942
+ }
1943
+ break;
1944
+
1945
+ case 2: // Scénario peu efficace - Démarrage lent, accélération tardive
1946
+ for (let i = 0; i < totalDays; i++) {
1947
+ const progress = i / totalDays;
1948
+ if (progress < 0.3) {
1949
+ data[i] = Math.floor(Math.random() * 2); // 0-1
1950
+ } else if (progress > 0.7) {
1951
+ data[i] = Math.floor(Math.random() * 2) + 3; // 3-4
1952
+ } else {
1953
+ data[i] = Math.floor(Math.random() * 2) + 1; // 1-2
1954
+ }
1955
+ }
1956
+ break;
1957
+
1958
+ case 3: // Scénario stratégique - Travail régulier
1959
+ for (let i = 0; i < totalDays; i++) {
1960
+ const weekday = i % 7;
1961
+ if (weekday === 5 || weekday === 6) { // Weekend léger
1962
+ data[i] = Math.floor(Math.random() * 2); // 0-1
1963
+ } else {
1964
+ data[i] = Math.floor(Math.random() * 2) + 2; // 2-3
1965
+ }
1966
+ }
1967
+ break;
1968
+
1969
+ default:
1970
+ for (let i = 0; i < totalDays; i++) {
1971
+ data[i] = Math.floor(Math.random() * 5); // 0-4 aléatoire
1972
+ }
1973
+ }
1974
+
1975
+ return data;
1976
+ }
1977
+
1978
+ // Analyser les métriques de persévérance compactes
1979
+ function analyzeCompactPersistenceMetrics(activityData, scenarioId) {
1980
+ const totalDays = activityData.length;
1981
+
1982
+ // 1. Calculer la régularité (écart-type)
1983
+ const avgActivity = activityData.reduce((a, b) => a + b, 0) / totalDays;
1984
+ const variance = activityData.reduce((a, b) => a + Math.pow(b - avgActivity, 2), 0) / totalDays;
1985
+ const stdDev = Math.sqrt(variance);
1986
+ const regularity = Math.max(0, 100 - stdDev * 25);
1987
+
1988
+ // 2. Identifier le schéma d'effort
1989
+ let pattern = "Régulier";
1990
+ let patternDescription = "Effort équilibré toute la semaine";
1991
+
1992
+ // Analyser la distribution
1993
+ const weeklyPatterns = [];
1994
+ for (let w = 0; w < 4; w++) {
1995
+ const weekData = activityData.slice(w * 7, Math.min((w + 1) * 7, totalDays));
1996
+ if (weekData.length < 5) continue;
1997
+
1998
+ const weekAvg = weekData.reduce((a, b) => a + b, 0) / weekData.length;
1999
+
2000
+ if (weekData[4] > weekAvg * 1.5 && weekData[3] > weekAvg * 1.3) {
2001
+ pattern = "Effort concentré";
2002
+ patternDescription = "Pic d'activité jeudi/vendredi";
2003
+ } else if (weekData[0] < weekAvg * 0.7 && weekData[4] > weekAvg * 1.2) {
2004
+ pattern = "Accélération progressive";
2005
+ patternDescription = "Démarrage lent, fin forte";
2006
+ }
2007
+ }
2008
+
2009
+ // 3. Calculer la gestion des échéances
2010
+ const deadlineDays = activityData.filter((_, index) => index % 7 === 3 || index % 7 === 4);
2011
+ const nonDeadlineDays = activityData.filter((_, index) => index % 7 !== 3 && index % 7 !== 4);
2012
+
2013
+ let deadlineScore = 50;
2014
+ if (deadlineDays.length > 0 && nonDeadlineDays.length > 0) {
2015
+ const deadlineAvg = deadlineDays.reduce((a, b) => a + b, 0) / deadlineDays.length;
2016
+ const nonDeadlineAvg = nonDeadlineDays.reduce((a, b) => a + b, 0) / nonDeadlineDays.length;
2017
+ deadlineScore = Math.min(100, Math.max(0, (deadlineAvg / 4) * 100));
2018
+ }
2019
+
2020
+ // Mettre à jour l'interface compacte
2021
+ document.getElementById("compact-regularityScore").textContent = Math.round(regularity) + "%";
2022
+ document.getElementById("compact-effortPattern").textContent = pattern;
2023
+ document.getElementById("compact-deadlineScore").textContent = Math.round(deadlineScore) + "%";
2024
+
2025
+ // Mettre à jour l'analyse textuelle compacte
2026
+ document.getElementById("compact-regularityText").textContent =
2027
+ regularity > 75 ? "Excellente régularité" :
2028
+ regularity > 60 ? "Bonne régularité" :
2029
+ regularity > 40 ? "Régularité moyenne" :
2030
+ "Faible régularité";
2031
+
2032
+ document.getElementById("compact-patternText").textContent = patternDescription;
2033
+ }
2034
+
2035
+ // ================= RADAR =================
2036
+ function drawRadar() {
2037
+ const canvas = document.getElementById("radar");
2038
+ if (!canvas) {
2039
+ console.error("Canvas radar non trouvé!");
2040
+ return;
2041
+ }
2042
+
2043
+ const ctx = canvas.getContext("2d");
2044
+ const cx = canvas.width / 2;
2045
+ const cy = canvas.height / 2;
2046
+ const radius = 200;
2047
+ const n = radarMetrics.length;
2048
+
2049
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
2050
+
2051
+ // Dessiner le radar
2052
+ for (let i = 1; i <= 5; i++) {
2053
+ ctx.beginPath();
2054
+ ctx.arc(cx, cy, (radius / 5) * i, 0, 2 * Math.PI);
2055
+ ctx.strokeStyle = "#e0e0e0";
2056
+ ctx.stroke();
2057
+ }
2058
+
2059
+ // Dessiner les axes
2060
+ radarMetrics.forEach((m, i) => {
2061
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2062
+
2063
+ ctx.beginPath();
2064
+ ctx.moveTo(cx, cy);
2065
+ ctx.lineTo(cx + radius * Math.cos(angle), cy + radius * Math.sin(angle));
2066
+ ctx.strokeStyle = "#b0bec5";
2067
+ ctx.stroke();
2068
+
2069
+ // Labels
2070
+ const tx = cx + (radius + 25) * Math.cos(angle);
2071
+ const ty = cy + (radius + 25) * Math.sin(angle);
2072
+
2073
+ ctx.font = "10px Arial";
2074
+ ctx.fillStyle = "#000";
2075
+ ctx.textAlign = angle > Math.PI / 2 || angle < -Math.PI / 2 ? "right" : "left";
2076
+ ctx.textBaseline = "middle";
2077
+ ctx.fillText(`${m.label.split(' ')[0]}`, tx, ty);
2078
+ });
2079
+
2080
+ // Dessiner le polygone
2081
+ ctx.beginPath();
2082
+ radarMetrics.forEach((m, i) => {
2083
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2084
+ const r = radius * (m.value / 100);
2085
+ const x = cx + r * Math.cos(angle);
2086
+ const y = cy + r * Math.sin(angle);
2087
+ i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
2088
+ });
2089
+ ctx.closePath();
2090
+
2091
+ ctx.fillStyle = "rgba(25,118,210,0.25)";
2092
+ ctx.fill();
2093
+ ctx.strokeStyle = "#1976D2";
2094
+ ctx.lineWidth = 2;
2095
+ ctx.stroke();
2096
+
2097
+ // Dessiner les points
2098
+ radarMetrics.forEach((m, i) => {
2099
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2100
+ const r = radius * (m.value / 100);
2101
+ const x = cx + r * Math.cos(angle);
2102
+ const y = cy + r * Math.sin(angle);
2103
+
2104
+ ctx.beginPath();
2105
+ ctx.arc(x, y, 4, 0, 2 * Math.PI);
2106
+ ctx.fillStyle = "#1976D2";
2107
+ ctx.fill();
2108
+ });
2109
+ }
2110
+
2111
+ // ================= NAVIGATION =================
2112
+ document.getElementById("prevScenario").onclick = () =>
2113
+ loadScenario(currentScenarioIndex - 1);
2114
+
2115
+ document.getElementById("nextScenario").onclick = () =>
2116
+ loadScenario(currentScenarioIndex + 1);
2117
+
2118
+ function updateNavButtons() {
2119
+ document.getElementById("prevScenario").disabled =
2120
+ currentScenarioIndex === 0;
2121
+ document.getElementById("nextScenario").disabled =
2122
+ currentScenarioIndex === scenarios.length - 1;
2123
+ }
2124
+
2125
+ // ================= BOUTON LECTURE CROISÉE =================
2126
+ document.getElementById('crossReadersBtn').onclick = () => {
2127
+ console.log('Navigation vers la page de lecture croisée...');
2128
+
2129
+ // Animation de transition
2130
+ const reflectionDiv = document.getElementById('reflection');
2131
+ if (reflectionDiv) {
2132
+ reflectionDiv.style.opacity = '0.7';
2133
+ reflectionDiv.style.transition = 'opacity 0.3s ease';
2134
+ }
2135
+
2136
+ // Redirection
2137
+ setTimeout(() => {
2138
+ window.location.href = 'cross_reading/cross_readers.html';
2139
+ }, 300);
2140
+ };
2141
+
2142
+ // ================= MÉTRIQUES DE CONFIANCE =================
2143
+ function initTrustStars(){
2144
+ console.log("Initialisation des étoiles...");
2145
+
2146
+ // Réinitialiser toutes les métriques
2147
+ for (const key in trustMetrics) {
2148
+ trustMetrics[key] = 0;
2149
+ }
2150
+
2151
+ let starsCreated = 0;
2152
+
2153
+ document.querySelectorAll(".stars").forEach(div => {
2154
+ const metric = div.dataset.metric;
2155
+ console.log(`Création des étoiles pour: ${metric}`);
2156
+
2157
+ // Vérifier que la métrique existe
2158
+ if (!trustMetrics.hasOwnProperty(metric)) {
2159
+ console.error(`Métrique inconnue: ${metric}`);
2160
+ return;
2161
+ }
2162
+
2163
+ // Vider le conteneur
2164
+ div.innerHTML = '';
2165
+
2166
+ // Créer 5 étoiles
2167
+ for (let i = 1; i <= 5; i++) {
2168
+ const star = document.createElement("span");
2169
+ star.textContent = "★";
2170
+ star.classList.add("inactive");
2171
+ star.style.cursor = "pointer";
2172
+ star.title = `${i} étoile${i > 1 ? 's' : ''}`;
2173
+
2174
+ // Stocker la valeur dans un attribut data
2175
+ star.dataset.value = i;
2176
+
2177
+ star.onclick = function() {
2178
+ const value = parseInt(this.dataset.value);
2179
+ console.log(`Clic sur ${metric}: ${value} étoiles`);
2180
+
2181
+ // Mettre à jour la valeur de la métrique
2182
+ trustMetrics[metric] = value;
2183
+
2184
+ // Mettre à jour l'affichage des étoiles dans ce groupe
2185
+ const allStarsInGroup = this.parentElement.children;
2186
+ for (let j = 0; j < allStarsInGroup.length; j++) {
2187
+ const starElem = allStarsInGroup[j];
2188
+ const starValue = parseInt(starElem.dataset.value);
2189
+
2190
+ if (starValue <= value) {
2191
+ starElem.classList.remove("inactive");
2192
+ starElem.classList.add("active");
2193
+ } else {
2194
+ starElem.classList.add("inactive");
2195
+ starElem.classList.remove("active");
2196
+ }
2197
+ }
2198
+
2199
+ // Mettre à jour la barre de progression
2200
+ updateTrustBar();
2201
+ };
2202
+
2203
+ div.appendChild(star);
2204
+ starsCreated++;
2205
+ }
2206
+ });
2207
+
2208
+ console.log(`${starsCreated} étoiles créées pour ${Object.keys(trustMetrics).length} métriques`);
2209
+ console.log("Métriques initialisées:", trustMetrics);
2210
+ }
2211
+
2212
+ function updateTrustBar(){
2213
+ console.log("=== MISE À JOUR BARRE DE CONFIANCE ===");
2214
+
2215
+ let scoreTotal = 0;
2216
+ let scoreMaxPossible = 0;
2217
+ let details = [];
2218
+
2219
+ // Calcul détaillé
2220
+ for (const metric in trustMetrics) {
2221
+ const valeur = trustMetrics[metric];
2222
+ const poids = trustWeights[metric];
2223
+ const contribution = valeur * poids;
2224
+ const maxContribution = 5 * poids;
2225
+
2226
+ scoreTotal += contribution;
2227
+ scoreMaxPossible += maxContribution;
2228
+
2229
+ details.push({
2230
+ métrique: metric,
2231
+ valeur: valeur,
2232
+ poids: poids,
2233
+ contribution: contribution.toFixed(2),
2234
+ max: maxContribution.toFixed(2)
2235
+ });
2236
+ }
2237
+
2238
+ console.log("Détails du calcul:");
2239
+ details.forEach(d => {
2240
+ console.log(`${d.métrique}: ${d.valeur}/5 × ${d.poids} = ${d.contribution} / ${d.max}`);
2241
+ });
2242
+
2243
+ console.log(`Total: ${scoreTotal.toFixed(2)} / ${scoreMaxPossible.toFixed(2)}`);
2244
+
2245
+ // Calcul du pourcentage
2246
+ let pourcentage = 0;
2247
+ if (scoreMaxPossible > 0) {
2248
+ pourcentage = Math.round((scoreTotal / scoreMaxPossible) * 100);
2249
+ }
2250
+
2251
+ console.log(`Pourcentage calculé: ${pourcentage}%`);
2252
+
2253
+ // Mettre à jour la barre de progression
2254
+ const barre = document.getElementById("trustBar");
2255
+ if (barre) {
2256
+ barre.style.width = pourcentage + "%";
2257
+ barre.textContent = pourcentage + "%";
2258
+
2259
+ // Changer la couleur selon le niveau
2260
+ if (pourcentage < 40) {
2261
+ barre.style.background = "#E53935"; // Rouge - Faible
2262
+ barre.title = `Faible confiance (${pourcentage}%)`;
2263
+ } else if (pourcentage < 70) {
2264
+ barre.style.background = "#FB8C00"; // Orange - Moyen
2265
+ barre.title = `Confiance moyenne (${pourcentage}%)`;
2266
+ } else {
2267
+ barre.style.background = "#43A047"; // Vert - Fort
2268
+ barre.title = `Forte confiance (${pourcentage}%)`;
2269
+ }
2270
+
2271
+ console.log(`Barre mise à jour: ${pourcentage}% (width: ${pourcentage}%)`);
2272
+ } else {
2273
+ console.error("Élément #trustBar non trouvé!");
2274
+ }
2275
+
2276
+ // Mettre à jour la statistique de confiance moyenne
2277
+ const avgTrustElem = document.getElementById("avgTrustScore");
2278
+ if (avgTrustElem) {
2279
+ avgTrustElem.textContent = pourcentage + "%";
2280
+ console.log(`Statistique moyenne mise à jour: ${pourcentage}%`);
2281
+ }
2282
+
2283
+ // Afficher un résumé dans la console
2284
+ console.log("=== RÉSUMÉ FINAL ===");
2285
+ console.log(`Indice global de confiance: ${pourcentage}%`);
2286
+ console.log("Valeurs des métriques:", JSON.stringify(trustMetrics, null, 2));
2287
+ console.log("====================");
2288
+
2289
+ return pourcentage;
2290
+ }
2291
+
2292
+ function initTrustSave(){
2293
+ const saveBtn = document.getElementById("saveTrustBtn");
2294
+ if (!saveBtn) {
2295
+ console.error("Bouton de sauvegarde non trouvé!");
2296
+ return;
2297
+ }
2298
+
2299
+ saveBtn.onclick = () => {
2300
+ console.log("=== DÉBUT SAUVEGARDE ===");
2301
+
2302
+ // Récupérer les informations GDPR
2303
+ const gdprAccept = document.getElementById('gdprAccept').checked;
2304
+ const gdprDecline = document.getElementById('gdprDecline').checked;
2305
+
2306
+ // Récupérer les informations conditionnelles
2307
+ let evaluatorName = "";
2308
+ let evaluatorRole = "";
2309
+ let expertiseLevel = "";
2310
+ let messageMastery = "";
2311
+
2312
+ if (gdprAccept) {
2313
+ evaluatorName = document.getElementById("evaluatorName").value.trim();
2314
+ evaluatorRole = document.getElementById("evaluatorRole").value;
2315
+ expertiseLevel = document.getElementById("expertiseLevel").value;
2316
+ messageMastery = document.getElementById("messageMastery").value;
2317
+ }
2318
+
2319
+ const comment = document.getElementById("trustComment").value;
2320
+ const msgDiv = document.getElementById("saveTrustMsg");
2321
+
2322
+ // Validation : consentement GDPR obligatoire
2323
+ if (!gdprAccept && !gdprDecline) {
2324
+ const message = "❌ Veuillez sélectionner une option de consentement RGPD.";
2325
+ console.error(message);
2326
+
2327
+ if (msgDiv) {
2328
+ msgDiv.textContent = message;
2329
+ msgDiv.style.background = "#FFEBEE";
2330
+ msgDiv.style.color = "#C62828";
2331
+ }
2332
+ return;
2333
+ }
2334
+
2335
+ // Validation : si GDPR accepté, vérifier les champs obligatoires
2336
+ if (gdprAccept) {
2337
+ if (!evaluatorName) {
2338
+ const message = "❌ Veuillez saisir votre nom et prénom.";
2339
+ console.error(message);
2340
+
2341
+ if (msgDiv) {
2342
+ msgDiv.textContent = message;
2343
+ msgDiv.style.background = "#FFEBEE";
2344
+ msgDiv.style.color = "#C62828";
2345
+ }
2346
+
2347
+ const nameField = document.getElementById("evaluatorName");
2348
+ nameField.style.borderColor = "#E53935";
2349
+ nameField.style.boxShadow = "0 0 0 3px rgba(229, 57, 53, 0.1)";
2350
+ nameField.focus();
2351
+
2352
+ setTimeout(() => {
2353
+ nameField.style.borderColor = "#e0e0e0";
2354
+ nameField.style.boxShadow = "none";
2355
+ }, 3000);
2356
+
2357
+ return;
2358
+ }
2359
+
2360
+ if (!evaluatorRole) {
2361
+ const message = "❌ Veuillez sélectionner votre rôle.";
2362
+ console.error(message);
2363
+
2364
+ if (msgDiv) {
2365
+ msgDiv.textContent = message;
2366
+ msgDiv.style.background = "#FFEBEE";
2367
+ msgDiv.style.color = "#C62828";
2368
+ }
2369
+ return;
2370
+ }
2371
+
2372
+ if (!expertiseLevel) {
2373
+ const message = "❌ Veuillez sélectionner votre niveau d'expertise en réflexivité.";
2374
+ console.error(message);
2375
+
2376
+ if (msgDiv) {
2377
+ msgDiv.textContent = message;
2378
+ msgDiv.style.background = "#FFEBEE";
2379
+ msgDiv.style.color = "#C62828";
2380
+ }
2381
+ return;
2382
+ }
2383
+
2384
+ if (!messageMastery) {
2385
+ const message = "❌ Veuillez sélectionner votre niveau de maîtrise des messages réflexifs.";
2386
+ console.error(message);
2387
+
2388
+ if (msgDiv) {
2389
+ msgDiv.textContent = message;
2390
+ msgDiv.style.background = "#FFEBEE";
2391
+ msgDiv.style.color = "#C62828";
2392
+ }
2393
+ return;
2394
+ }
2395
+ }
2396
+
2397
+ // Vérifier si au moins une évaluation
2398
+ let hasEvaluation = false;
2399
+ for (const metric in trustMetrics) {
2400
+ if (trustMetrics[metric] > 0) {
2401
+ hasEvaluation = true;
2402
+ break;
2403
+ }
2404
+ }
2405
+
2406
+ if (!hasEvaluation) {
2407
+ const message = "⚠️ Veuillez évaluer au moins une métrique avant de sauvegarder.";
2408
+ console.warn(message);
2409
+
2410
+ if (msgDiv) {
2411
+ msgDiv.textContent = message;
2412
+ msgDiv.style.background = "#FFF3E0";
2413
+ msgDiv.style.color = "#EF6C00";
2414
+ }
2415
+ return;
2416
+ }
2417
+
2418
+ // Calculer l'indice de confiance
2419
+ const trustScore = updateTrustBar(); // Cette fonction retourne le pourcentage
2420
+
2421
+ console.log(`Indice calculé pour sauvegarde: ${trustScore}%`);
2422
+
2423
+ // Préparer les données
2424
+ const data = {
2425
+ scenario_id: scenarios[currentScenarioIndex].id,
2426
+ scenario_title: scenarios[currentScenarioIndex].title,
2427
+ trust_metrics: {...trustMetrics},
2428
+ trust_score: trustScore,
2429
+ gdpr_consent: gdprAccept ? "accept" : "decline",
2430
+ evaluator_name: gdprAccept ? evaluatorName : null,
2431
+ evaluator_role: gdprAccept ? evaluatorRole : null,
2432
+ expertise_level: gdprAccept ? expertiseLevel : null,
2433
+ message_mastery: gdprAccept ? messageMastery : null,
2434
+ comment: comment || null,
2435
+ timestamp: new Date().toISOString(),
2436
+ trust_weights: {...trustWeights}
2437
+ };
2438
+
2439
+ console.log("Données à envoyer:", JSON.stringify(data, null, 2));
2440
+
2441
+ // Envoyer au serveur
2442
+ fetch("/save_trust", {
2443
+ method: "POST",
2444
+ headers: { "Content-Type": "application/json" },
2445
+ body: JSON.stringify(data)
2446
+ })
2447
+ .then(res => {
2448
+ if (!res.ok) throw new Error(`Erreur HTTP ${res.status}: ${res.statusText}`);
2449
+ return res.json();
2450
+ })
2451
+ .then(responseData => {
2452
+ console.log("✅ Réponse du serveur:", responseData);
2453
+
2454
+ if (msgDiv) {
2455
+ const nameDisplay = gdprAccept ? evaluatorName : "Évaluateur anonyme";
2456
+ msgDiv.innerHTML = `
2457
+ <div style="display: flex; align-items: center; gap: 10px;">
2458
+ <div style="font-size: 24px;">✅</div>
2459
+ <div>
2460
+ <strong>Évaluation sauvegardée avec succès !</strong><br>
2461
+ <small>Merci ${nameDisplay} pour votre contribution.</small><br>
2462
+ <small><em>Indice global: ${trustScore}%</em></small>
2463
+ </div>
2464
+ </div>
2465
+ `;
2466
+ msgDiv.style.background = "#E8F5E9";
2467
+ msgDiv.style.color = "#2E7D32";
2468
+ msgDiv.style.padding = "15px";
2469
+ }
2470
+
2471
+ // Réinitialiser après succès (optionnel)
2472
+ setTimeout(() => {
2473
+ resetTrustEvaluation();
2474
+ }, 3000);
2475
+ })
2476
+ .catch(error => {
2477
+ console.error("❌ Erreur de sauvegarde:", error);
2478
+ if (msgDiv) {
2479
+ msgDiv.textContent = `❌ Erreur: ${error.message}`;
2480
+ msgDiv.style.background = "#FFEBEE";
2481
+ msgDiv.style.color = "#C62828";
2482
+ }
2483
+ });
2484
+ };
2485
+
2486
+ console.log("✅ Bouton de sauvegarde initialisé");
2487
+ }
2488
+
2489
+ // Fonction pour réinitialiser l'évaluation
2490
+ function resetTrustEvaluation() {
2491
+ console.log("Réinitialisation de l'évaluation...");
2492
+
2493
+ // Réinitialiser les métriques
2494
+ for (const key in trustMetrics) {
2495
+ trustMetrics[key] = 0;
2496
+ }
2497
+
2498
+ // Réinitialiser les étoiles
2499
+ document.querySelectorAll(".stars").forEach(div => {
2500
+ Array.from(div.children).forEach(star => {
2501
+ star.classList.add("inactive");
2502
+ star.classList.remove("active");
2503
+ });
2504
+ });
2505
+
2506
+ // Réinitialiser la barre
2507
+ updateTrustBar();
2508
+
2509
+ // Vider le commentaire
2510
+ document.getElementById("trustComment").value = "";
2511
+
2512
+ console.log("Évaluation réinitialisée");
2513
+ }
2514
+
2515
+ // ================= FONCTIONS UTILITAIRES =================
2516
+
2517
+ // Mettre à jour les statistiques
2518
+ function updateStats() {
2519
+ if (!scenarios || scenarios.length === 0) return;
2520
+
2521
+ const currentScenario = scenarios[currentScenarioIndex];
2522
+
2523
+ document.getElementById("currentScenarioNum").textContent = currentScenario.id;
2524
+
2525
+ // Niveau de risque
2526
+ const risk = currentScenario.risk || 50;
2527
+ let riskLevel = "Moyen";
2528
+ let riskColor = "#FB8C00";
2529
+
2530
+ if (risk < 40) {
2531
+ riskLevel = "Faible";
2532
+ riskColor = "#43A047";
2533
+ } else if (risk > 70) {
2534
+ riskLevel = "Élevé";
2535
+ riskColor = "#E53935";
2536
+ }
2537
+
2538
+ document.getElementById("riskLevel").textContent = riskLevel;
2539
+ document.getElementById("riskLevel").style.color = riskColor;
2540
+
2541
+ // Activité moyenne à partir des données radar
2542
+ if (currentScenario.radar && currentScenario.radar.length > 0) {
2543
+ const avgRadar = currentScenario.radar.reduce((sum, item) => sum + item.value, 0) / currentScenario.radar.length;
2544
+ document.getElementById("avgActivity").textContent = Math.round(avgRadar) + "%";
2545
+ }
2546
+ }
2547
+
2548
+ // Fonction pour remplir un exemple d'évaluateur
2549
+ function fillSampleEvaluator() {
2550
+ // Sélectionner l'option GDPR "accept"
2551
+ document.getElementById('gdprAccept').checked = true;
2552
+ document.getElementById('gdprDecline').checked = false;
2553
+
2554
+ // Mettre à jour les champs
2555
+ initGDPR();
2556
+
2557
+ // Remplir les champs
2558
+ document.getElementById("evaluatorName").value = "Martin Sophie";
2559
+ document.getElementById("evaluatorRole").value = "enseignant";
2560
+ document.getElementById("expertiseLevel").value = "avance";
2561
+ document.getElementById("messageMastery").value = "intermediaire_msg";
2562
+
2563
+ showNotification("Exemple", "Champs d'évaluateur remplis avec un exemple", "info");
2564
+ }
2565
+
2566
+ // Fonction pour effacer les champs évaluateur
2567
+ function clearEvaluatorFields() {
2568
+ // Sélectionner l'option GDPR "decline" par défaut
2569
+ document.getElementById('gdprDecline').checked = true;
2570
+ document.getElementById('gdprAccept').checked = false;
2571
+
2572
+ // Mettre à jour les champs
2573
+ initGDPR();
2574
+
2575
+ showNotification("Champs effacés", "Les informations d'évaluateur ont été effacées", "info");
2576
+ }
2577
+
2578
+ // Fonction pour afficher une notification
2579
+ function showNotification(title, message, type = "info") {
2580
+ console.log(`[${type}] ${title}: ${message}`);
2581
+
2582
+ const msgDiv = document.getElementById("saveTrustMsg");
2583
+ if (msgDiv) {
2584
+ msgDiv.textContent = `${title}: ${message}`;
2585
+ msgDiv.style.background = type === "success" ? "#E8F5E9" :
2586
+ type === "error" ? "#FFEBEE" : "#E3F2FD";
2587
+ msgDiv.style.color = type === "success" ? "#2E7D32" :
2588
+ type === "error" ? "#C62828" : "#1565C0";
2589
+ }
2590
+ }
2591
+
2592
+ // Changer le mode d'analyse de persévérance
2593
+ function changePersistenceAnalysis() {
2594
+ const mode = document.getElementById("persistenceMode").value;
2595
+ const currentScenario = scenarios[currentScenarioIndex];
2596
+
2597
+ // Redessiner la heatmap avec le mode sélectionné
2598
+ drawCompactEnrichedHeatmap(currentScenario);
2599
+
2600
+ // Ajouter une annotation selon le mode
2601
+ const canvas = document.getElementById("heatmap");
2602
+ const ctx = canvas.getContext("2d");
2603
+
2604
+ ctx.font = "12px Arial";
2605
+ ctx.fillStyle = "#1976D2";
2606
+ ctx.textAlign = "center";
2607
+
2608
+ switch(mode) {
2609
+ case "regularity":
2610
+ ctx.fillText("📊 Analyse de la régularité", canvas.width / 2, canvas.height - 10);
2611
+ break;
2612
+ case "effortPattern":
2613
+ ctx.fillText("🔄 Schéma d'effort", canvas.width / 2, canvas.height - 10);
2614
+ break;
2615
+ case "deadline":
2616
+ ctx.fillText("⏰ Gestion des échéances", canvas.width / 2, canvas.height - 10);
2617
+ break;
2618
+ case "combined":
2619
+ ctx.fillText("🎯 Vue combinée", canvas.width / 2, canvas.height - 10);
2620
+ break;
2621
+ }
2622
+ }
2623
+
2624
+ // Exposer les fonctions globales
2625
+ window.changePersistenceAnalysis = changePersistenceAnalysis;
2626
+ window.updateStats = updateStats;
2627
+ window.showNotification = showNotification;
2628
+ window.fillSampleEvaluator = fillSampleEvaluator;
2629
+ window.clearEvaluatorFields = clearEvaluatorFields;
2630
+ </script>
2631
+
2632
+ </body>
2633
+ </html>