gtkh commited on
Commit
3c1d38c
·
verified ·
1 Parent(s): 0371a26

parfait, tu peux classer les tâche dans l'ordre en fonction de l'heure à quelle doivent être faite - Follow Up Deployment

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +484 -19
  3. prompts.txt +5 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Agenda
3
- emoji: 🐢
4
- colorFrom: red
5
- colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: agenda
3
+ emoji: 🐳
4
+ colorFrom: gray
5
+ colorTo: pink
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,484 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </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>Agenda</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
9
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
10
+ <style>
11
+ @keyframes fadeIn {
12
+ from { opacity: 0; }
13
+ to { opacity: 1; }
14
+ }
15
+ @keyframes slideInLeft {
16
+ from { transform: translateX(-100%); }
17
+ to { transform: translateX(0); }
18
+ }
19
+ .modal-backdrop {
20
+ position: fixed;
21
+ inset: 0;
22
+ background-color: rgba(0, 0, 0, 0.5);
23
+ animation: fadeIn 0.2s ease-out forwards;
24
+ }
25
+ .slide-in {
26
+ animation: slideInLeft 0.3s ease-out forwards;
27
+ }
28
+ .agenda-event:hover {
29
+ transform: translateY(-2px);
30
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
31
+ }
32
+ .day-header {
33
+ background: linear-gradient(to bottom, #1e3a8a, #1e40af);
34
+ color: white;
35
+ }
36
+ .day-header-today {
37
+ background: linear-gradient(to bottom, #3b82f6, #2563eb);
38
+ }
39
+ .agenda-event {
40
+ transition: all 0.2s ease;
41
+ }
42
+ .week-navigation {
43
+ background: linear-gradient(to right, #1e3a8a, #1e40af);
44
+ }
45
+ .time-display {
46
+ backdrop-filter: blur(2px);
47
+ }
48
+
49
+ /* Responsive adjustments */
50
+ @media (max-width: 1024px) {
51
+ #agenda-grid {
52
+ min-width: 100%;
53
+ display: flex;
54
+ flex-direction: column;
55
+ border-top: none;
56
+ }
57
+ #agenda-grid > div {
58
+ border-bottom: 1px solid #374151;
59
+ min-height: 60px;
60
+ }
61
+ .day-body {
62
+ min-height: auto;
63
+ padding: 0.5rem;
64
+ }
65
+ .agenda-event {
66
+ margin: 0.25rem 0;
67
+ aspect-ratio: auto;
68
+ }
69
+ }
70
+
71
+ @media (min-width: 1025px) {
72
+ #agenda-grid {
73
+ min-width: 80rem;
74
+ display: grid;
75
+ grid-template-columns: repeat(7, minmax(11rem, 1fr));
76
+ border-top: 1px solid #374151;
77
+ }
78
+ .day-body {
79
+ min-height: 100vh;
80
+ padding: 0.5rem;
81
+ border-right: 1px solid #e5e7eb;
82
+ display: flex;
83
+ flex-direction: column;
84
+ gap: 0.5rem;
85
+ }
86
+ .day-body:last-child {
87
+ border-right: none;
88
+ }
89
+ .agenda-event {
90
+ aspect-ratio: auto;
91
+ min-height: 5rem;
92
+ }
93
+ }
94
+ </style>
95
+ </head>
96
+ <body class="font-sans">
97
+ <!-- Agenda Panel -->
98
+ <div id="agendaPanel" class="fixed inset-0 z-50 hidden overflow-hidden">
99
+ <div class="modal-backdrop"></div>
100
+ <div class="fixed inset-y-0 left-0 bg-white shadow-2xl slide-in flex flex-col w-full sm:w-4/5 xl:w-2/3">
101
+ <!-- Header -->
102
+ <div class="flex items-center justify-between week-navigation px-6 py-4">
103
+ <h2 class="text-white text-2xl sm:text-3xl font-bold tracking-tight">Mon Agenda</h2>
104
+ <button id="closeAgenda" class="text-white hover:bg-blue-700 rounded-full p-1 transition-colors">
105
+ <span class="material-icons text-2xl">close</span>
106
+ </button>
107
+ </div>
108
+
109
+ <!-- Week Navigation -->
110
+ <div class="flex items-center justify-between px-4 py-3 bg-blue-800">
111
+ <button id="agenda-prev" class="text-white hover:bg-blue-700 rounded-full p-2 transition-colors">
112
+ <span class="material-icons">chevron_left</span>
113
+ </button>
114
+ <h3 id="agenda-date" class="flex-1 text-center text-white text-lg sm:text-xl font-medium"></h3>
115
+ <button id="agenda-next" class="text-white hover:bg-blue-700 rounded-full p-2 transition-colors">
116
+ <span class="material-icons">chevron_right</span>
117
+ </button>
118
+ </div>
119
+
120
+ <!-- Agenda Grid -->
121
+ <div id="agenda-scroll" class="relative flex-1 overflow-y-auto bg-gray-100">
122
+ <div id="agenda-grid" class="min-h-full bg-white"></div>
123
+
124
+ <!-- Add Event Button -->
125
+ <button id="agenda-add" class="fixed bottom-6 right-6 w-12 h-12 sm:w-14 sm:h-14 rounded-full bg-blue-600 hover:bg-blue-700 text-white flex items-center justify-center shadow-xl transition-all hover:scale-110">
126
+ <span class="material-icons text-3xl">add</span>
127
+ </button>
128
+ </div>
129
+ </div>
130
+ </div>
131
+
132
+ <!-- Event Modal -->
133
+ <div id="agendaEventModal" class="fixed inset-0 z-50 hidden">
134
+ <div class="modal-backdrop"></div>
135
+ <div class="fixed inset-0 flex items-center justify-center p-4 sm:p-6">
136
+ <div class="bg-white rounded-xl shadow-2xl w-full max-w-lg overflow-hidden">
137
+ <!-- Modal Header -->
138
+ <div class="bg-blue-600 px-6 py-4">
139
+ <h3 id="agendaModalTitle" class="text-lg font-semibold text-white">Nouvel événement</h3>
140
+ </div>
141
+
142
+ <!-- Modal Content -->
143
+ <div class="p-6 space-y-5">
144
+ <div>
145
+ <label class="block text-sm font-medium text-gray-700 mb-1">Titre</label>
146
+ <input id="agenda-event-title" type="text" class="w-full border-gray-300 rounded-lg px-3 py-2 border focus:ring-blue-500 focus:border-blue-500 transition-all">
147
+ </div>
148
+
149
+ <div>
150
+ <label class="block text-sm font-medium text-gray-700 mb-1">Date</label>
151
+ <input id="agenda-event-date" type="date" class="w-full border-gray-300 rounded-lg px-3 py-2 border focus:ring-blue-500 focus:border-blue-500 transition-all">
152
+ </div>
153
+
154
+ <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
155
+ <div>
156
+ <label class="block text-sm font-medium text-gray-700 mb-1">Début</label>
157
+ <input id="agenda-event-start" type="time" class="w-full border-gray-300 rounded-lg px-3 py-2 border focus:ring-blue-500 focus:border-blue-500 transition-all">
158
+ </div>
159
+ <div>
160
+ <label class="block text-sm font-medium text-gray-700 mb-1">Fin</label>
161
+ <input id="agenda-event-end" type="time" class="w-full border-gray-300 rounded-lg px-3 py-2 border focus:ring-blue-500 focus:border-blue-500 transition-all">
162
+ </div>
163
+ </div>
164
+
165
+ <div>
166
+ <label class="block text-sm font-medium text-gray-700 mb-1">Description</label>
167
+ <textarea id="agenda-event-desc" rows="3" class="w-full border-gray-300 rounded-lg px-3 py-2 border focus:ring-blue-500 focus:border-blue-500 transition-all"></textarea>
168
+ </div>
169
+
170
+ <div>
171
+ <label class="block text-sm font-medium text-gray-700 mb-2">Couleur</label>
172
+ <div id="agenda-color-picker" class="flex flex-wrap gap-2"></div>
173
+ </div>
174
+ </div>
175
+
176
+ <!-- Modal Footer -->
177
+ <div class="bg-gray-50 px-6 py-4 flex justify-end space-x-3">
178
+ <button id="cancelAgendaEvent" class="px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-100 transition-colors">
179
+ Annuler
180
+ </button>
181
+ <button id="deleteAgendaEvent" class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors hidden">
182
+ Supprimer
183
+ </button>
184
+ <button id="saveAgendaEvent" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
185
+ Enregistrer
186
+ </button>
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </div>
191
+
192
+ <script>
193
+ let agendaWeekStart = '';
194
+ let agendaEditingId = null;
195
+ const agendaColors = ['#60a5fa', '#34d399', '#f87171', '#a78bfa', '#fbbf24', '#f472b6', '#38bdf8'];
196
+ let agendaSelectedColor = agendaColors[0];
197
+
198
+ // Attach initAgenda to the global window object so it is accessible when the
199
+ // sidebar button callback tries to invoke it. This avoids "initAgenda is not
200
+ // defined" errors that can happen if the function is not evaluated in the
201
+ // global scope when the page is embedded inside the Apps Script iframe.
202
+ window.initAgenda = function() {
203
+ const today = new Date();
204
+ agendaWeekStart = formatDateISO(getWeekStart(today));
205
+ buildAgendaGrid();
206
+ updateAgendaDate();
207
+ loadAgenda();
208
+
209
+ // Event listeners
210
+ document.getElementById('agenda-prev').onclick = () => changeAgendaDate(-1);
211
+ document.getElementById('agenda-next').onclick = () => changeAgendaDate(1);
212
+ document.getElementById('agenda-add').onclick = () => openAgendaModal(false, {
213
+ date: agendaWeekStart,
214
+ start: '08:00',
215
+ end: '09:00'
216
+ });
217
+ document.getElementById('cancelAgendaEvent').onclick = () => document.getElementById('agendaEventModal').classList.add('hidden');
218
+ document.getElementById('saveAgendaEvent').onclick = saveAgendaEvent;
219
+ document.getElementById('deleteAgendaEvent').onclick = deleteAgendaEvent;
220
+
221
+ // Color picker setup
222
+ const picker = document.getElementById('agenda-color-picker');
223
+ picker.innerHTML = '';
224
+ agendaColors.forEach(c => {
225
+ const s = document.createElement('button');
226
+ s.className = 'w-8 h-8 rounded-full border-2 border-white cursor-pointer shadow hover:scale-110 transition-transform';
227
+ s.style.backgroundColor = c;
228
+ s.dataset.color = c;
229
+ s.title = c;
230
+ s.addEventListener('click', () => {
231
+ agendaSelectedColor = c;
232
+ updateColorPicker();
233
+ });
234
+ picker.appendChild(s);
235
+ });
236
+ updateColorPicker();
237
+ };
238
+
239
+ function buildAgendaGrid() {
240
+ const grid = document.getElementById('agenda-grid');
241
+ grid.innerHTML = '';
242
+ const dates = getWeekDates(agendaWeekStart);
243
+ const todayFmt = formatDateISO(new Date());
244
+
245
+ dates.forEach(d => {
246
+ const col = document.createElement('div');
247
+ col.className = 'border-l border-r border-gray-200 flex flex-col h-full';
248
+
249
+ // Day header
250
+ const head = document.createElement('div');
251
+ head.className = `day-header sticky top-0 text-center py-2 sm:py-3 border-b border-gray-200 z-10 ${
252
+ d === todayFmt ? 'day-header-today' : ''
253
+ }`;
254
+
255
+ const dt = new Date(d);
256
+ const dayName = dt.toLocaleDateString('fr-FR', { weekday: 'long' }).substring(0,3).toUpperCase();
257
+ const dayNum = dt.getDate();
258
+
259
+ head.innerHTML = `
260
+ <div class="text-sm font-medium tracking-wider">${dayName}</div>
261
+ <div class="text-xl font-bold mt-1">${dayNum}</div>
262
+ `;
263
+ col.appendChild(head);
264
+
265
+ // Day body
266
+ const body = document.createElement('div');
267
+ body.className = 'day-body bg-white flex-1';
268
+ body.dataset.date = d;
269
+ col.appendChild(body);
270
+
271
+ grid.appendChild(col);
272
+ });
273
+ }
274
+
275
+ function updateAgendaDate() {
276
+ const start = new Date(agendaWeekStart);
277
+ const end = new Date(start);
278
+ end.setDate(start.getDate() + 6);
279
+
280
+ const startStr = start.toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit' });
281
+ const endStr = end.toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric' });
282
+
283
+ document.getElementById('agenda-date').textContent = `Semaine du ${startStr} au ${endStr}`;
284
+ }
285
+
286
+ function changeAgendaDate(delta) {
287
+ const d = new Date(agendaWeekStart);
288
+ d.setDate(d.getDate() + delta * 7);
289
+ agendaWeekStart = formatDateISO(d);
290
+ buildAgendaGrid();
291
+ updateAgendaDate();
292
+ loadAgenda();
293
+ }
294
+
295
+ function loadAgenda() {
296
+ const start = agendaWeekStart;
297
+ const end = formatDateISO(addDays(start, 6));
298
+ google.script.run.withSuccessHandler(renderAgenda).getAgendaRange(start, end);
299
+ }
300
+
301
+ function renderAgenda(list) {
302
+ if (!Array.isArray(list)) list = [];
303
+ const grid = document.getElementById('agenda-grid');
304
+ if (!grid) return;
305
+
306
+ grid.querySelectorAll('.agenda-event').forEach(e => e.remove());
307
+
308
+ // Sort events by start time
309
+ list.sort((a, b) => {
310
+ const timeA = a.start || '00:00';
311
+ const timeB = b.start || '00:00';
312
+ return timeA.localeCompare(timeB);
313
+ });
314
+
315
+ list.forEach(ev => {
316
+ const container = grid.querySelector(`.day-body[data-date="${ev.date}"]`);
317
+ if (!container) return;
318
+
319
+ const div = document.createElement('div');
320
+ div.className = 'agenda-event rounded-lg shadow-md p-3 mb-2 text-sm relative overflow-hidden hover:z-10 border border-white/50';
321
+ div.style.backgroundColor = ev.color || agendaColors[0];
322
+ div.style.minHeight = '5rem';
323
+
324
+ const title = document.createElement('div');
325
+ title.className = 'font-bold mb-1 truncate';
326
+ title.textContent = ev.title || 'Sans titre';
327
+ div.appendChild(title);
328
+
329
+ const desc = document.createElement('div');
330
+ desc.className = 'text-sm line-clamp-2 mb-4';
331
+ desc.textContent = ev.description || '';
332
+ div.appendChild(desc);
333
+
334
+ const time = document.createElement('div');
335
+ time.className = 'time-display absolute bottom-2 right-2 text-xs px-2 py-1 rounded';
336
+ time.textContent = `${ev.start} - ${ev.end}`;
337
+ time.style.backgroundColor = `${ev.color || agendaColors[0]}CC`;
338
+ div.appendChild(time);
339
+
340
+ div.onclick = () => openAgendaModal(true, ev);
341
+ container.appendChild(div);
342
+ });
343
+
344
+ // Check if today is visible and scroll to it
345
+ const today = formatDateISO(new Date());
346
+ const todayColumn = grid.querySelector(`.day-body[data-date="${today}"]`);
347
+ if (todayColumn) {
348
+ grid.scrollTo({
349
+ top: 0,
350
+ behavior: 'smooth'
351
+ });
352
+ }
353
+ }
354
+
355
+ function openAgendaModal(isEdit, data) {
356
+ agendaEditingId = isEdit ? data.row : null;
357
+ document.getElementById('agendaModalTitle').textContent = isEdit ? 'Modifier l\'événement' : 'Nouvel événement';
358
+ document.getElementById('agenda-event-title').value = data.title || '';
359
+ document.getElementById('agenda-event-date').value = data.date || agendaWeekStart;
360
+ document.getElementById('agenda-event-start').value = data.start || '08:00';
361
+ document.getElementById('agenda-event-end').value = data.end || '09:00';
362
+ document.getElementById('agenda-event-desc').value = data.description || '';
363
+ agendaSelectedColor = data.color || agendaColors[0];
364
+ updateColorPicker();
365
+ document.getElementById('deleteAgendaEvent').classList.toggle('hidden', !isEdit);
366
+ document.getElementById('agendaEventModal').classList.remove('hidden');
367
+ }
368
+
369
+ function saveAgendaEvent() {
370
+ const obj = {
371
+ row: agendaEditingId,
372
+ date: document.getElementById('agenda-event-date').value,
373
+ title: document.getElementById('agenda-event-title').value.trim(),
374
+ start: document.getElementById('agenda-event-start').value,
375
+ end: document.getElementById('agenda-event-end').value,
376
+ description: document.getElementById('agenda-event-desc').value.trim(),
377
+ color: agendaSelectedColor
378
+ };
379
+
380
+ // Validate required fields
381
+ if (!obj.title) {
382
+ alert('Veuillez entrer un titre pour l\'événement');
383
+ return;
384
+ }
385
+
386
+ const afterSave = () => {
387
+ document.getElementById('agendaEventModal').classList.add('hidden');
388
+ const start = formatDateISO(getWeekStart(obj.date));
389
+ if (start !== agendaWeekStart) {
390
+ agendaWeekStart = start;
391
+ buildAgendaGrid();
392
+ updateAgendaDate();
393
+ }
394
+ loadAgenda();
395
+ };
396
+
397
+ const runner = google.script.run.withSuccessHandler(afterSave);
398
+ if (agendaEditingId) runner.updateAgendaItem(obj);
399
+ else runner.createAgendaItem(obj);
400
+ }
401
+
402
+ function deleteAgendaEvent() {
403
+ if (!agendaEditingId) return;
404
+ if (!confirm('Voulez-vous vraiment supprimer cet événement ? Cette action est irréversible.')) return;
405
+ google.script.run.withSuccessHandler(() => {
406
+ document.getElementById('agendaEventModal').classList.add('hidden');
407
+ loadAgenda();
408
+ }).deleteAgendaItem(agendaEditingId);
409
+ }
410
+
411
+ function updateColorPicker() {
412
+ document.querySelectorAll('#agenda-color-picker button').forEach(s => {
413
+ const active = s.dataset.color === agendaSelectedColor;
414
+ s.classList.toggle('ring-2', active);
415
+ s.classList.toggle('ring-offset-2', active);
416
+ s.classList.toggle('ring-blue-500', active);
417
+ s.classList.toggle('scale-110', active);
418
+ });
419
+ }
420
+
421
+ function formatDateISO(d) {
422
+ if (d === undefined || d === null || d === '') return '';
423
+ let dt;
424
+ if (d instanceof Date) {
425
+ dt = d;
426
+ } else if (typeof d === 'number') {
427
+ dt = new Date(Math.round((d - 25569) * 86400000));
428
+ } else {
429
+ dt = new Date(d);
430
+ }
431
+ if (isNaN(dt)) return '';
432
+ const y = dt.getFullYear();
433
+ const m = String(dt.getMonth() + 1).padStart(2, '0');
434
+ const day = String(dt.getDate()).padStart(2, '0');
435
+ return `${y}-${m}-${day}`;
436
+ }
437
+
438
+ function getWeekStart(date) {
439
+ const d = new Date(date);
440
+ const day = d.getDay();
441
+ const diff = day === 0 ? -6 : (day === 1 ? 0 : 1 - day);
442
+ d.setDate(d.getDate() + diff);
443
+ d.setHours(0, 0, 0, 0);
444
+ return d;
445
+ }
446
+
447
+ function getWeekDates(start) {
448
+ const dates = [];
449
+ const d = new Date(start);
450
+ // Lundi (0) à Dimanche (+6)
451
+ for (let i = 0; i < 7; i++) {
452
+ dates.push(formatDateISO(addDays(d, i)));
453
+ }
454
+ return dates;
455
+ }
456
+
457
+ function addDays(date, n) {
458
+ const d = new Date(date);
459
+ d.setDate(d.getDate() + n);
460
+ return d;
461
+ }
462
+
463
+ // Setup open/close handlers when the sidebar button is clicked
464
+ (function() {
465
+ const openBtn = document.getElementById('sidebar-agenda');
466
+ if (openBtn) {
467
+ openBtn.addEventListener('click', () => {
468
+ activateSidebarButton('sidebar-agenda');
469
+ if (typeof window.initAgenda === 'function') window.initAgenda();
470
+ document.getElementById('agendaPanel').classList.remove('hidden');
471
+ });
472
+ }
473
+
474
+ document.getElementById('closeAgenda').addEventListener('click', () => {
475
+ document.getElementById('agendaPanel').classList.add('hidden');
476
+ });
477
+
478
+ document.getElementById('agendaPanel').addEventListener('click', e => {
479
+ if (e.target.id === 'agendaPanel') e.target.classList.add('hidden');
480
+ });
481
+ })();
482
+ </script>
483
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=gtkh/agenda" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
484
+ </html>
prompts.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Can you improve the visual appearance of my application while ensuring its compatibility with my server-side data : <!-- Agenda.html --> <style> #agendaPanel .slide-in { animation: slideInLeft 0.3s forwards; } #agendaPanel > div { max-width: 100rem; width:100%; } #agendaPanel h2 { font-size: 1.875rem; } #agenda-grid { /* enlarge columns so event cards are wider */ min-width: 84rem; display: grid; grid-template-columns: repeat(7, minmax(12rem, 1fr)); border-top: 1px solid #374151; height: 100%; } #agenda-grid > div { height: 100%; } .day-body { position: relative; flex: 1 1 auto; min-height: 15rem; display: flex; flex-direction: column; align-items: stretch; padding: 0.25rem; /* remove useless horizontal grid lines */ background-image: none; } .agenda-event { position: relative; margin: 0.75rem 0; background-color: #60a5fa; border-radius: 0.25rem; padding: 0.75rem; padding-bottom: 1.5rem; font-size: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); cursor: pointer; aspect-ratio: 1 / 1; display: flex; flex-direction: column; overflow: hidden; border: 2px solid rgba(0,0,0,0.4); } .agenda-event-title { font-weight: bold; margin-bottom: 0.25rem; text-align: center; } .agenda-event-desc { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; } .agenda-time { position: absolute; bottom: 0.25rem; right: 0.25rem; background-color: rgba(30, 64, 175, 0.8); color: #fff; font-size: 0.875rem; padding: 0.125rem 0.5rem; border-radius: 0.25rem; } </style> <div id="agendaPanel" class="fixed inset-0 z-50 hidden"> <div class="modal-backdrop"></div> <div class="fixed inset-y-0 left-0 bg-white shadow-xl slide-in flex flex-col"> <div class="flex items-center justify-between bg-blue-600 px-6 py-4"> <h2 class="text-white text-3xl">Agenda</h2> <button id="closeAgenda" class="text-white text-2xl"> <span class="material-icons">close</span> </button> </div> <div class="flex-1 overflow-auto"> <div class="h-full flex flex-col bg-gray-900 text-gray-100"> <div class="flex items-center justify-between px-4 py-2 bg-gray-800"> <button id="agenda-prev" class="text-white"><span class="material-icons">chevron_left</span></button> <h3 id="agenda-date" class="flex-1 text-center text-lg font-medium"></h3> <button id="agenda-next" class="text-white"><span class="material-icons">chevron_right</span></button> </div> <div id="agenda-scroll" class="relative flex-1 overflow-y-auto"> <div id="agenda-grid"></div> <button id="agenda-add" class="absolute bottom-4 right-4 w-10 h-10 rounded-full bg-blue-600 text-white flex items-center justify-center shadow-lg"><span class="material-icons">add</span></button> </div> </div> </div> </div> </div> <div id="agendaEventModal" class="fixed inset-0 z-50 hidden"> <div class="modal-backdrop"></div> <div class="fixed inset-0 flex items-center justify-center p-4"> <div class="bg-white rounded-lg shadow-xl w-full max-w-md p-6"> <h3 id="agendaModalTitle" class="text-lg font-medium mb-4">Nouvel événement</h3> <div class="space-y-4"> <div><label class="block text-sm">Titre</label><input id="agenda-event-title" type="text" class="w-full border rounded px-2 py-1"></div> <div><label class="block text-sm">Date</label><input id="agenda-event-date" type="date" class="w-full border rounded px-2 py-1"></div> <div class="grid grid-cols-2 gap-4"> <div><label class="block text-sm">Début</label><input id="agenda-event-start" type="time" class="w-full border rounded px-2 py-1"></div> <div><label class="block text-sm">Fin</label><input id="agenda-event-end" type="time" class="w-full border rounded px-2 py-1"></div> </div> <div><label class="block text-sm">Description</label><textarea id="agenda-event-desc" rows="3" class="w-full border rounded px-2 py-1"></textarea></div> <div> <label class="block text-sm mb-1">Couleur</label> <div id="agenda-color-picker" class="flex space-x-2"></div> </div> </div> <div class="mt-6 flex justify-end space-x-2"> <button id="cancelAgendaEvent" class="px-4 py-2 border rounded">Annuler</button> <button id="deleteAgendaEvent" class="px-4 py-2 bg-red-600 text-white rounded hidden">Supprimer l'événement</button> <button id="saveAgendaEvent" class="px-4 py-2 bg-blue-600 text-white rounded">Enregistrer</button> </div> </div> </div> </div> <script> let agendaWeekStart = ''; let agendaEditingId = null; const agendaColors = ['#60a5fa','#34d399','#f87171','#a78bfa','#fbbf24','#f472b6','#38bdf8']; let agendaSelectedColor = agendaColors[0]; // Attach initAgenda to the global window object so it is accessible when the // sidebar button callback tries to invoke it. This avoids "initAgenda is not // defined" errors that can happen if the function is not evaluated in the // global scope when the page is embedded inside the Apps Script iframe. window.initAgenda = function(){ agendaWeekStart = formatDateISO(getWeekStart(new Date())); buildAgendaGrid(); updateAgendaDate(); loadAgenda(); document.getElementById('agenda-prev').onclick = () => changeAgendaDate(-1); document.getElementById('agenda-next').onclick = () => changeAgendaDate(1); document.getElementById('agenda-add').onclick = () => openAgendaModal(false,{date:agendaWeekStart,start:'08:00',end:'09:00'}); document.getElementById('cancelAgendaEvent').onclick = () => document.getElementById('agendaEventModal').classList.add('hidden'); document.getElementById('saveAgendaEvent').onclick = saveAgendaEvent; document.getElementById('deleteAgendaEvent').onclick = deleteAgendaEvent; const picker=document.getElementById('agenda-color-picker'); picker.innerHTML=''; agendaColors.forEach(c=>{ const s=document.createElement('span'); s.className='w-6 h-6 rounded-full border cursor-pointer'; s.style.backgroundColor=c; s.dataset.color=c; s.addEventListener('click',()=>{agendaSelectedColor=c;updateColorPicker();}); picker.appendChild(s); }); }; function buildAgendaGrid(){ const grid=document.getElementById('agenda-grid'); grid.innerHTML=''; const dates=getWeekDates(agendaWeekStart); dates.forEach(d=>{ const col=document.createElement('div'); col.className='border-l border-r border-gray-700 flex flex-col'; const head=document.createElement('div'); head.className='sticky top-0 bg-gray-800 text-center py-1 border-b border-gray-700 border-l border-r'; const dt=new Date(d); head.textContent=dt.toLocaleDateString('fr-FR',{weekday:'long',day:'2-digit',month:'2-digit'}); col.appendChild(head); const body=document.createElement('div'); body.className='day-body'; body.dataset.date=d; col.appendChild(body); grid.appendChild(col); }); } function updateAgendaDate(){ const start=new Date(agendaWeekStart); const end=new Date(start); end.setDate(start.getDate()+6); const startStr=start.toLocaleDateString('fr-FR',{day:'2-digit',month:'2-digit'}); const endStr=end.toLocaleDateString('fr-FR',{day:'2-digit',month:'2-digit',year:'numeric'}); document.getElementById('agenda-date').textContent=`Semaine du ${startStr} au ${endStr}`; } function changeAgendaDate(delta){ const d=new Date(agendaWeekStart); d.setDate(d.getDate()+delta*7); agendaWeekStart=formatDateISO(d); buildAgendaGrid(); updateAgendaDate(); loadAgenda(); } function loadAgenda(){ const start=agendaWeekStart; const end=formatDateISO(addDays(start,6)); google.script.run.withSuccessHandler(renderAgenda).getAgendaRange(start,end); } function renderAgenda(list){ if(!Array.isArray(list)) list = []; const grid=document.getElementById('agenda-grid'); if(!grid) return; grid.querySelectorAll('.agenda-event').forEach(e=>e.remove()); list.forEach(ev=>{ const container=grid.querySelector(`.day-body[data-date="${ev.date}"]`); if(!container) return; const div=document.createElement('div'); div.className='agenda-event text-sm'; div.style.backgroundColor = ev.color || agendaColors[0]; const time=document.createElement('span'); time.className='agenda-time'; time.textContent=`${ev.start} à ${ev.end}`; div.appendChild(time); const title=document.createElement('div'); title.className='agenda-event-title'; title.textContent=ev.title; div.appendChild(title); const desc=document.createElement('div'); desc.className='agenda-event-desc'; desc.textContent=ev.description||''; div.appendChild(desc); div.onclick=()=>openAgendaModal(true,ev); container.prepend(div); }); } function openAgendaModal(isEdit,data){ agendaEditingId=isEdit?data.row:null; document.getElementById('agendaModalTitle').textContent=isEdit?'Modifier l\u00e9v\u00e9nement':'Nouvel \u00e9v\u00e9nement'; document.getElementById('agenda-event-title').value=data.title||''; document.getElementById('agenda-event-date').value=data.date||agendaWeekStart; document.getElementById('agenda-event-start').value=data.start||''; document.getElementById('agenda-event-end').value=data.end||''; document.getElementById('agenda-event-desc').value=data.description||''; agendaSelectedColor=data.color||agendaColors[0]; updateColorPicker(); document.getElementById('deleteAgendaEvent').classList.toggle('hidden',!isEdit); document.getElementById('agendaEventModal').classList.remove('hidden'); } function saveAgendaEvent(){ const obj={ row: agendaEditingId, date: document.getElementById('agenda-event-date').value, title: document.getElementById('agenda-event-title').value.trim(), start: document.getElementById('agenda-event-start').value, end: document.getElementById('agenda-event-end').value, description: document.getElementById('agenda-event-desc').value.trim(), color: agendaSelectedColor }; const afterSave=()=>{ document.getElementById('agendaEventModal').classList.add('hidden'); const start=formatDateISO(getWeekStart(obj.date)); if(start!==agendaWeekStart){ agendaWeekStart=start; buildAgendaGrid(); updateAgendaDate(); } loadAgenda(); }; const runner=google.script.run.withSuccessHandler(afterSave); if(agendaEditingId) runner.updateAgendaItem(obj); else runner.createAgendaItem(obj); } function deleteAgendaEvent(){ if(!agendaEditingId) return; if(!confirm('Supprimer cet événement ?')) return; google.script.run.withSuccessHandler(()=>{document.getElementById('agendaEventModal').classList.add('hidden');loadAgenda();}).deleteAgendaItem(agendaEditingId); } function updateColorPicker(){ document.querySelectorAll('#agenda-color-picker span').forEach(s=>{ const active = s.dataset.color===agendaSelectedColor; s.classList.toggle('ring',active); s.classList.toggle('ring-2',active); s.classList.toggle('ring-offset-2',active); }); } function formatDateISO(d){ if(d===undefined||d===null||d==='') return ''; let dt; if(d instanceof Date){ dt=d; }else if(typeof d==='number'){ dt=new Date(Math.round((d-25569)*86400000)); }else{ dt=new Date(d); } if(isNaN(dt)) return ''; const y=dt.getFullYear(); const m=String(dt.getMonth()+1).padStart(2,'0'); const day=String(dt.getDate()).padStart(2,'0'); return `${y}-${m}-${day}`; } function getWeekStart(date){ const d=new Date(date); const day=d.getDay(); const diff=day===0?-6:1-day; d.setDate(d.getDate()+diff); d.setHours(0,0,0,0); return d; } function getWeekDates(start){ const dates=[]; const d=new Date(start); for(let i=0;i<7;i++){ dates.push(formatDateISO(addDays(d,i))); } return dates; } function addDays(date,n){ const d=new Date(date); d.setDate(d.getDate()+n); return d; } // Setup open/close handlers when the sidebar button is clicked (function(){ const openBtn = document.getElementById('sidebar-agenda'); if(openBtn){ openBtn.addEventListener('click', () => { activateSidebarButton('sidebar-agenda'); if(typeof window.initAgenda === 'function') window.initAgenda(); document.getElementById('agendaPanel').classList.remove('hidden'); }); } document.getElementById('closeAgenda').addEventListener('click', () => { document.getElementById('agendaPanel').classList.add('hidden'); }); document.getElementById('agendaPanel').addEventListener('click', e => { if(e.target.id === 'agendaPanel') e.target.classList.add('hidden'); }); })(); </script>
2
+ les dimension ne sont pas bon revois la mise ne page
3
+ Je veux le calendrier soit afficher en colonne du lundi au dimanche
4
+ Non je veux les calendrier soit afficher en forme de colonne par en liste
5
+ parfait, tu peux classer les tâche dans l'ordre en fonction de l'heure à quelle doivent être faite