diff options
-rw-r--r-- | public/css/calendar.css | 4 | ||||
-rw-r--r-- | public/index.php (renamed from public/index.html) | 8 | ||||
-rw-r--r-- | public/js/calendar.js | 277 | ||||
-rw-r--r-- | public/js/calendar_admin.js | 331 | ||||
-rw-r--r-- | src/post-ajax.php | 4 |
5 files changed, 355 insertions, 269 deletions
diff --git a/public/css/calendar.css b/public/css/calendar.css index 035118a..b762a89 100644 --- a/public/css/calendar.css +++ b/public/css/calendar.css | |||
@@ -1,3 +1,7 @@ | |||
1 | .event{ | ||
2 | border: 2px double; | ||
3 | border-radius: 5px; | ||
4 | } | ||
1 | #calendar_zone{ | 5 | #calendar_zone{ |
2 | display: flex; | 6 | display: flex; |
3 | max-width: 1000px; | 7 | max-width: 1000px; |
diff --git a/public/index.html b/public/index.php index bdd7f67..abcef90 100644 --- a/public/index.html +++ b/public/index.php | |||
@@ -1,3 +1,7 @@ | |||
1 | <?php | ||
2 | session_start(); | ||
3 | $_SESSION['admin'] = false; | ||
4 | ?> | ||
1 | <!DOCTYPE html> | 5 | <!DOCTYPE html> |
2 | <html lang="fr"> | 6 | <html lang="fr"> |
3 | <head> | 7 | <head> |
@@ -11,7 +15,9 @@ | |||
11 | <script src='js/fullcalendar/packages/list/index.global.min.js'></script> | 15 | <script src='js/fullcalendar/packages/list/index.global.min.js'></script> |
12 | <script src='js/fullcalendar/packages/interaction/index.global.min.js'></script> | 16 | <script src='js/fullcalendar/packages/interaction/index.global.min.js'></script> |
13 | <script src='js/fullcalendar/packages/core/locales/fr.global.min.js'></script> | 17 | <script src='js/fullcalendar/packages/core/locales/fr.global.min.js'></script> |
14 | <script src="js/calendar.js"></script> | 18 | <?php |
19 | echo (isset($_SESSION['admin']) && $_SESSION['admin'] === true) ? '<script src="js/calendar_admin.js"></script>' . "\n" : '<script src="js/calendar.js"></script>' . "\n"; | ||
20 | ?> | ||
15 | </head> | 21 | </head> |
16 | 22 | ||
17 | <body> | 23 | <body> |
diff --git a/public/js/calendar.js b/public/js/calendar.js index 154cdfd..fb26e80 100644 --- a/public/js/calendar.js +++ b/public/js/calendar.js | |||
@@ -1,19 +1,3 @@ | |||
1 | /* // à utiliser plus tard? | ||
2 | const current_view = calendar.view; | ||
3 | switch(current_view.type){ | ||
4 | case 'dayGridMonth': | ||
5 | console.log('mois'); | ||
6 | break; | ||
7 | case 'timeGridWeek': | ||
8 | console.log('semaine'); | ||
9 | break; | ||
10 | case 'timeGridDay': | ||
11 | console.log('jour'); | ||
12 | break; | ||
13 | default: | ||
14 | console.log('erreur'); | ||
15 | }*/ | ||
16 | |||
17 | document.addEventListener('DOMContentLoaded', function(){ | 1 | document.addEventListener('DOMContentLoaded', function(){ |
18 | const calendarEl = document.getElementById('calendar'); | 2 | const calendarEl = document.getElementById('calendar'); |
19 | let selected_start_string = null; | 3 | let selected_start_string = null; |
@@ -50,90 +34,13 @@ document.addEventListener('DOMContentLoaded', function(){ | |||
50 | nowIndicator: true, // barre rouge pour maintenant | 34 | nowIndicator: true, // barre rouge pour maintenant |
51 | 35 | ||
52 | select: function(info){ | 36 | select: function(info){ |
53 | const aside = document.querySelector('aside'); | 37 | selected_start_string = info.startStr; // variable "globale" |
54 | let checked = ''; | ||
55 | let input = 'datetime-local'; | ||
56 | |||
57 | // on veut des chaines de la forme 2025-05-20T07:05 | ||
58 | // il faut retirer les secondes et le fuseau horaire du format ISO, c'est chiant | ||
59 | // on enverra par contre une chaine ISO au serveur pour avoir un enregistrement correct | ||
60 | |||
61 | let start_value; | ||
62 | let end_value; | ||
63 | const end = new Date(info.endStr); | ||
64 | |||
65 | console.log(info.startStr); | ||
66 | console.log(info.endStr); | ||
67 | |||
68 | if(calendar.view.type == 'dayGridMonth'){ | ||
69 | start_value = info.startStr + 'T10:00'; | ||
70 | end.setDate(end.getDate() - 1); // jour de fin modifié pour ne pas faire bizarre pour l'utilisateur | ||
71 | end.setHours(11); | ||
72 | end_value = end.toISOString().split('T')[0] + 'T11:00'; | ||
73 | } | ||
74 | else if(calendar.view.type == 'timeGridWeek' || calendar.view.type == 'timeGridDay'){ | ||
75 | const start_array = info.startStr.split("T"); | ||
76 | const end_array = info.endStr.split("T"); | ||
77 | |||
78 | // clic sur la ligne "Journée", = 'dayGridMonth' | ||
79 | if(start_array.length == 1){ | ||
80 | checked = 'checked'; | ||
81 | input = 'date'; | ||
82 | start_value = info.startStr; | ||
83 | end.setDate(end.getDate() - 1); | ||
84 | end_value = end.toISOString().split('T')[0]; | ||
85 | } | ||
86 | else if(start_array.length == 2){ | ||
87 | start_value = start_array[0] + "T" + start_array[1].substr(0,5); // format 2025-06-12T10:00 | ||
88 | end_value = end_array[0] + "T" + end_array[1].substr(0,5); | ||
89 | } | ||
90 | else{ | ||
91 | console.log('pas censé se produire'); | ||
92 | return; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | selected_start_string = start_value; // variable "globale" | ||
97 | |||
98 | const aside_content = `<div class="form_event"> | ||
99 | <div class="event_title_box"> | ||
100 | <h2>Nouvel évènement</h2> | ||
101 | </div> | ||
102 | <div class=""> | ||
103 | <label for="event_title">Nom</label> | ||
104 | <input type="text" id="event_title"> | ||
105 | </div> | ||
106 | <div class=""> | ||
107 | <label for="event_description">Description</label> | ||
108 | <textarea id="event_description" cols="27"></textarea> | ||
109 | </div> | ||
110 | <div class=""> | ||
111 | <input type="checkbox" id="event_all_day" class="event_all_day" ` + checked + `> | ||
112 | <label for="event_all_day">Journée entière</label> | ||
113 | </div> | ||
114 | <div class=""> | ||
115 | <label for="event_start">Début</label> | ||
116 | <input type="` + input + `" id="event_start" value="` + start_value + `"> | ||
117 | </div> | ||
118 | <div class=""> | ||
119 | <label for="event_end">Fin</label> | ||
120 | <input type="` + input + `" id="event_end" value="` + end_value + `"> | ||
121 | </div> | ||
122 | <div class=""> | ||
123 | <label for="event_color">Couleur</label> | ||
124 | <input type="color" id="event_color" value="#3788D8"> | ||
125 | </div> | ||
126 | <button class="submit_new_event">Enregistrer</button> | ||
127 | <button class="event_close_button">Annuler</button> | ||
128 | </div>`; | ||
129 | aside.innerHTML = aside_content; | ||
130 | calendar.updateSize(); | ||
131 | }, | 38 | }, |
132 | //unselect: function(event, view){}, | 39 | //unselect: function(event, view){}, |
40 | |||
133 | eventClick: function(info){ | 41 | eventClick: function(info){ |
134 | const aside = document.querySelector('aside'); | 42 | const aside = document.querySelector('aside'); |
135 | const checked = info.event.allDay ? 'checked' : ''; | 43 | const checked = info.event.allDay ? 'checked' : ''; |
136 | const input = info.event.allDay ? 'date' : 'datetime-local'; | ||
137 | 44 | ||
138 | // change des objets Date en chaînes compatibles avec les input | 45 | // change des objets Date en chaînes compatibles avec les input |
139 | function formatDate(date){ | 46 | function formatDate(date){ |
@@ -148,38 +55,14 @@ document.addEventListener('DOMContentLoaded', function(){ | |||
148 | const formated_start = formatDate(info.event.start); | 55 | const formated_start = formatDate(info.event.start); |
149 | const formated_end = formatDate(info.event.allDay ? getEndMinusOneDay(info.event.end) : info.event.end, info.event.allDay); | 56 | const formated_end = formatDate(info.event.allDay ? getEndMinusOneDay(info.event.end) : info.event.end, info.event.allDay); |
150 | 57 | ||
151 | const aside_content = `<div class="form_event"> | 58 | const aside_content = `<div class="event" style="border-color: ` + info.event.backgroundColor +`;"> |
152 | <div class="event_title_box"> | 59 | <h3>` + info.event.title + `</h3> |
153 | <h2>Modifier un évènement</h2> | 60 | <p><i>` + info.event.extendedProps.description + `</i></p> |
154 | </div> | 61 | <p>Journée entière: ` + (checked ? 'oui' : 'non') + `</p> |
155 | <div class=""> | 62 | <p>Début: ` + formated_start + `</p> |
156 | <label for="event_title">Nom</label> | 63 | <p>Fin: ` + formated_end + `</p> |
157 | <input type="text" id="event_title" value="` + info.event.title + `"> | 64 | </div>`; |
158 | <input type="hidden" id="event_id" value="` + info.event.id + `"> | 65 | |
159 | </div> | ||
160 | <div class=""> | ||
161 | <label for="event_description">Description</label> | ||
162 | <textarea id="event_description" cols="27">` + info.event.extendedProps.description + `</textarea> | ||
163 | </div> | ||
164 | <div class=""> | ||
165 | <input type="checkbox" id="event_all_day" class="event_all_day" ` + checked + `> | ||
166 | <label for="event_all_day">Journée entière</label> | ||
167 | </div> | ||
168 | <div class=""> | ||
169 | <label for="event_start">Début</label> | ||
170 | <input type="` + input + `" id="event_start" value="` + formated_start + `"> | ||
171 | </div> | ||
172 | <div class=""> | ||
173 | <label for="event_end">Fin</label> | ||
174 | <input type="` + input + `" id="event_end" value="` + formated_end + `"> | ||
175 | </div> | ||
176 | <div class=""> | ||
177 | <label for="event_color">Couleur</label> | ||
178 | <input type="color" id="event_color" value="` + info.event.backgroundColor + `"> | ||
179 | </div> | ||
180 | <button class="submit_update_event">Modifier</button> | ||
181 | <button class="event_close_button">Annuler</button> | ||
182 | </div>`; | ||
183 | aside.innerHTML = aside_content; | 66 | aside.innerHTML = aside_content; |
184 | calendar.updateSize(); | 67 | calendar.updateSize(); |
185 | }, | 68 | }, |
@@ -198,137 +81,6 @@ document.addEventListener('DOMContentLoaded', function(){ | |||
198 | calendar.updateSize(); | 81 | calendar.updateSize(); |
199 | } | 82 | } |
200 | 83 | ||
201 | function submitEvent(new_event){ | ||
202 | const event_title = document.getElementById('event_title').value; | ||
203 | const event_description = document.getElementById('event_description').value; | ||
204 | const event_all_day = document.getElementById('event_all_day').checked; | ||
205 | let event_start = document.getElementById('event_start').value; | ||
206 | let event_end = document.getElementById('event_end').value; | ||
207 | const event_color = document.getElementById('event_color').value; // #3788d8 par défaut | ||
208 | const event_id = new_event ? '' : document.getElementById('event_id').value; | ||
209 | |||
210 | if(event_title.length !== 0 && event_start.length !== 0 && event_end.length !== 0 && event_color.length !== 0 | ||
211 | && (new_event || event_id.length !== 0)) | ||
212 | { | ||
213 | if(event_all_day){ | ||
214 | // on remet le jour de fin exclu | ||
215 | const tmp_object = new Date(event_end); | ||
216 | tmp_object.setDate(tmp_object.getDate() + 1); | ||
217 | event_end = tmp_object.toISOString().split('T')[0]; | ||
218 | } | ||
219 | else{ | ||
220 | event_start = new Date(event_start).toISOString(); | ||
221 | event_end = new Date(event_end).toISOString(); | ||
222 | } | ||
223 | console.log(event_end); | ||
224 | |||
225 | if(event_start > event_end || (!event_all_day && event_start == event_end)){ | ||
226 | return; | ||
227 | } | ||
228 | |||
229 | // création | ||
230 | if(new_event){ | ||
231 | const event = { | ||
232 | title: event_title, | ||
233 | description: event_description, | ||
234 | allDay: event_all_day, | ||
235 | start: event_start, | ||
236 | end: event_end, | ||
237 | color: event_color | ||
238 | }; | ||
239 | |||
240 | fetch('../src/post-ajax.php', { | ||
241 | method: 'POST', | ||
242 | headers: { | ||
243 | 'Content-Type': 'application/json', | ||
244 | }, | ||
245 | body: JSON.stringify(event), | ||
246 | }) | ||
247 | .then(response => response.json()) | ||
248 | .then(data => { | ||
249 | if(data.success){ | ||
250 | event.id = data.id; | ||
251 | calendar.addEvent(event); | ||
252 | hideModal(); | ||
253 | } | ||
254 | }) | ||
255 | .catch((error) => { | ||
256 | console.error('Error:', error); | ||
257 | }); | ||
258 | |||
259 | } | ||
260 | // modification | ||
261 | else{ | ||
262 | const event = calendar.getEventById(event_id); | ||
263 | |||
264 | if(event){ | ||
265 | const event_copy = { | ||
266 | id: parseInt(event.id), | ||
267 | description: event_description, | ||
268 | title: event_title, | ||
269 | allDay: event_all_day, | ||
270 | start: event_start, | ||
271 | end: event_end, | ||
272 | color: event_color | ||
273 | }; | ||
274 | |||
275 | fetch('../src/post-ajax.php', { | ||
276 | method: 'POST', | ||
277 | headers: { | ||
278 | 'Content-Type': 'application/json', | ||
279 | }, | ||
280 | body: JSON.stringify(event_copy), | ||
281 | }) | ||
282 | .then(response => response.json()) | ||
283 | .then(data => { | ||
284 | if(data.success){ | ||
285 | event.setProp('title', event_title); | ||
286 | event.setExtendedProp('description', event_description); | ||
287 | event.setAllDay(event_all_day); | ||
288 | event.setStart(event_start); | ||
289 | event.setEnd(event_end); | ||
290 | event.setProp('color', event_color); | ||
291 | hideModal(); | ||
292 | } | ||
293 | }) | ||
294 | .catch((error) => { | ||
295 | console.error('Error:', error); | ||
296 | }); | ||
297 | } | ||
298 | else{ | ||
299 | console.log("Événement non trouvé !"); | ||
300 | } | ||
301 | } | ||
302 | } | ||
303 | else{ | ||
304 | // notif input vide | ||
305 | console.log('erreur: input vide'); | ||
306 | } | ||
307 | } | ||
308 | |||
309 | function checkAllDay(){ | ||
310 | const event_start_input = document.getElementById('event_start'); | ||
311 | const event_end_input = document.getElementById('event_end'); | ||
312 | |||
313 | const start = event_start_input.value; | ||
314 | const end = event_end_input.value; | ||
315 | |||
316 | if(document.getElementById('event_all_day').checked){ | ||
317 | event_start_input.type = 'date'; | ||
318 | event_end_input.type = 'date'; | ||
319 | |||
320 | event_start_input.value = start.split('T')[0]; | ||
321 | event_end_input.value = end.split('T')[0]; | ||
322 | } | ||
323 | else{ | ||
324 | event_start_input.type = 'datetime-local'; | ||
325 | event_end_input.type = 'datetime-local'; | ||
326 | |||
327 | event_start_input.value = start + 'T10:00'; | ||
328 | event_end_input.value = end + 'T11:00'; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | document.addEventListener('keydown', function(event){ | 84 | document.addEventListener('keydown', function(event){ |
333 | if(event.key === 'Escape') { | 85 | if(event.key === 'Escape') { |
334 | hideModal(); | 86 | hideModal(); |
@@ -340,15 +92,6 @@ document.addEventListener('DOMContentLoaded', function(){ | |||
340 | if(event.target.classList.contains('event_close_button')){ | 92 | if(event.target.classList.contains('event_close_button')){ |
341 | hideModal(); | 93 | hideModal(); |
342 | } | 94 | } |
343 | else if(event.target.classList.contains('event_all_day')){ | ||
344 | checkAllDay(); | ||
345 | } | ||
346 | else if(event.target.classList.contains('submit_new_event')){ | ||
347 | submitEvent(true); | ||
348 | } | ||
349 | else if(event.target.classList.contains('submit_update_event')){ | ||
350 | submitEvent(false); | ||
351 | } | ||
352 | }); | 95 | }); |
353 | 96 | ||
354 | calendar.render(); | 97 | calendar.render(); |
diff --git a/public/js/calendar_admin.js b/public/js/calendar_admin.js new file mode 100644 index 0000000..253d127 --- /dev/null +++ b/public/js/calendar_admin.js | |||
@@ -0,0 +1,331 @@ | |||
1 | document.addEventListener('DOMContentLoaded', function(){ | ||
2 | const calendarEl = document.getElementById('calendar'); | ||
3 | let selected_start_string = null; | ||
4 | |||
5 | const calendar = new FullCalendar.Calendar(calendarEl,{ | ||
6 | editable: true, | ||
7 | locale: 'fr', | ||
8 | initialView: 'dayGridMonth', | ||
9 | headerToolbar:{ | ||
10 | left: 'prev,next today', | ||
11 | center: 'title', | ||
12 | right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' | ||
13 | //right: 'dayGridMonth,timeGridWeek' | ||
14 | }, | ||
15 | slotMinWidth: 70, | ||
16 | defaultAllDay: false, | ||
17 | |||
18 | // numéros de semaine | ||
19 | //weekNumbers: true, | ||
20 | //weekText: 's', | ||
21 | |||
22 | // vue mois | ||
23 | contentHeight: 600, // après initialisation: calendar.setOption('contentHeight', 650); | ||
24 | //aspectRatio: 1.5, // après initialisation: calendar.setOption('aspectRatio', 1.8); | ||
25 | // pour recalculer la taille au redimensionnement du parent, exécuter: calendar.updateSize() | ||
26 | stickyHeaderDates: true, // garder les en-tête de colonnes lors du scroll | ||
27 | fixedWeekCount: false, // avec false, affiche 4, 5 ou 6 semaines selon le mois | ||
28 | selectable: true, // sélection de jours multiples | ||
29 | navLinks: true, // numéros de jour et de semaines clicables | ||
30 | |||
31 | // vue semaine | ||
32 | slotEventOverlap: true, // superposition (limitée) de deux évènements simultanés | ||
33 | allDayContent: 'Journée', // texte dans la case "toute la journée" | ||
34 | nowIndicator: true, // barre rouge pour maintenant | ||
35 | |||
36 | select: function(info){ | ||
37 | selected_start_string = info.startStr; // variable "globale" | ||
38 | const aside = document.querySelector('aside'); | ||
39 | let checked = ''; | ||
40 | let input = 'datetime-local'; | ||
41 | |||
42 | // on veut des chaines de la forme 2025-05-20T07:05 | ||
43 | // il faut retirer les secondes et le fuseau horaire du format ISO, c'est chiant | ||
44 | // on enverra par contre une chaine ISO au serveur pour avoir un enregistrement correct | ||
45 | |||
46 | let start_value; | ||
47 | let end_value; | ||
48 | const end = new Date(info.endStr); | ||
49 | |||
50 | if(calendar.view.type == 'dayGridMonth'){ | ||
51 | start_value = info.startStr + 'T10:00'; | ||
52 | end.setDate(end.getDate() - 1); // jour de fin modifié pour ne pas faire bizarre pour l'utilisateur | ||
53 | end.setHours(11); | ||
54 | end_value = end.toISOString().split('T')[0] + 'T11:00'; | ||
55 | } | ||
56 | else if(calendar.view.type == 'timeGridWeek' || calendar.view.type == 'timeGridDay'){ | ||
57 | const start_array = info.startStr.split("T"); | ||
58 | const end_array = info.endStr.split("T"); | ||
59 | |||
60 | // clic sur la ligne "Journée", = 'dayGridMonth' | ||
61 | if(start_array.length == 1){ | ||
62 | checked = 'checked'; | ||
63 | input = 'date'; | ||
64 | start_value = info.startStr; | ||
65 | end.setDate(end.getDate() - 1); | ||
66 | end_value = end.toISOString().split('T')[0]; | ||
67 | } | ||
68 | else if(start_array.length == 2){ | ||
69 | start_value = start_array[0] + "T" + start_array[1].substr(0,5); // format 2025-06-12T10:00 | ||
70 | end_value = end_array[0] + "T" + end_array[1].substr(0,5); | ||
71 | } | ||
72 | } | ||
73 | |||
74 | const aside_content = `<div class="form_event"> | ||
75 | <div class="event_title_box"> | ||
76 | <h2>Nouvel évènement</h2> | ||
77 | </div> | ||
78 | <div class=""> | ||
79 | <label for="event_title">Nom</label> | ||
80 | <input type="text" id="event_title"> | ||
81 | </div> | ||
82 | <div class=""> | ||
83 | <label for="event_description">Description</label> | ||
84 | <textarea id="event_description" cols="27"></textarea> | ||
85 | </div> | ||
86 | <div class=""> | ||
87 | <input type="checkbox" id="event_all_day" class="event_all_day" ` + checked + `> | ||
88 | <label for="event_all_day">Journée entière</label> | ||
89 | </div> | ||
90 | <div class=""> | ||
91 | <label for="event_start">Début</label> | ||
92 | <input type="` + input + `" id="event_start" value="` + start_value + `"> | ||
93 | </div> | ||
94 | <div class=""> | ||
95 | <label for="event_end">Fin</label> | ||
96 | <input type="` + input + `" id="event_end" value="` + end_value + `"> | ||
97 | </div> | ||
98 | <div class=""> | ||
99 | <label for="event_color">Couleur</label> | ||
100 | <input type="color" id="event_color" value="#3788D8"> | ||
101 | </div> | ||
102 | <button class="submit_new_event">Enregistrer</button> | ||
103 | <button class="event_close_button">Annuler</button> | ||
104 | </div>`; | ||
105 | aside.innerHTML = aside_content; | ||
106 | calendar.updateSize(); | ||
107 | }, | ||
108 | //unselect: function(event, view){}, | ||
109 | eventClick: function(info){ | ||
110 | const aside = document.querySelector('aside'); | ||
111 | const checked = info.event.allDay ? 'checked' : ''; | ||
112 | const input = info.event.allDay ? 'date' : 'datetime-local'; | ||
113 | |||
114 | // change des objets Date en chaînes compatibles avec les input | ||
115 | function formatDate(date){ | ||
116 | return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0') | ||
117 | + (info.event.allDay ? '' : 'T' + date.getHours().toString().padStart(2, '0') + ':' + date.getMinutes().toString().padStart(2, '0')); | ||
118 | } | ||
119 | function getEndMinusOneDay(date){ | ||
120 | date.setDate(date.getDate() - 1); // jour de fin modifié pour ne pas faire bizarre pour l'utilisateur | ||
121 | return date; | ||
122 | } | ||
123 | |||
124 | const formated_start = formatDate(info.event.start); | ||
125 | const formated_end = formatDate(info.event.allDay ? getEndMinusOneDay(info.event.end) : info.event.end, info.event.allDay); | ||
126 | |||
127 | const aside_content = `<div class="form_event"> | ||
128 | <div class="event_title_box"> | ||
129 | <h2>Modifier un évènement</h2> | ||
130 | </div> | ||
131 | <div class=""> | ||
132 | <label for="event_title">Nom</label> | ||
133 | <input type="text" id="event_title" value="` + info.event.title + `"> | ||
134 | <input type="hidden" id="event_id" value="` + info.event.id + `"> | ||
135 | </div> | ||
136 | <div class=""> | ||
137 | <label for="event_description">Description</label> | ||
138 | <textarea id="event_description" cols="27">` + info.event.extendedProps.description + `</textarea> | ||
139 | </div> | ||
140 | <div class=""> | ||
141 | <input type="checkbox" id="event_all_day" class="event_all_day" ` + checked + `> | ||
142 | <label for="event_all_day">Journée entière</label> | ||
143 | </div> | ||
144 | <div class=""> | ||
145 | <label for="event_start">Début</label> | ||
146 | <input type="` + input + `" id="event_start" value="` + formated_start + `"> | ||
147 | </div> | ||
148 | <div class=""> | ||
149 | <label for="event_end">Fin</label> | ||
150 | <input type="` + input + `" id="event_end" value="` + formated_end + `"> | ||
151 | </div> | ||
152 | <div class=""> | ||
153 | <label for="event_color">Couleur</label> | ||
154 | <input type="color" id="event_color" value="` + info.event.backgroundColor + `"> | ||
155 | </div> | ||
156 | <button class="submit_update_event">Modifier</button> | ||
157 | <button class="event_close_button">Annuler</button> | ||
158 | </div>`; | ||
159 | aside.innerHTML = aside_content; | ||
160 | calendar.updateSize(); | ||
161 | }, | ||
162 | viewDidMount: function(info){ // déclenché lorsque qu'une nouvelle vue est chargée (mois, semaine...) | ||
163 | if(selected_start_string){ | ||
164 | calendar.gotoDate(new Date(selected_start_string)); | ||
165 | } | ||
166 | }, | ||
167 | //datesSet: function(info){}, // déclenché lorsque des dates affichées sont chargées (= comme viewDidMount + changement de date) | ||
168 | events: '../src/load-events.php' // fichier PHP qui retourne les événements | ||
169 | }); | ||
170 | |||
171 | function hideModal(){ | ||
172 | const aside = document.querySelector('aside'); | ||
173 | aside.innerHTML = ''; | ||
174 | calendar.updateSize(); | ||
175 | } | ||
176 | |||
177 | function submitEvent(new_event){ | ||
178 | const event_title = document.getElementById('event_title').value; | ||
179 | const event_description = document.getElementById('event_description').value; | ||
180 | const event_all_day = document.getElementById('event_all_day').checked; | ||
181 | let event_start = document.getElementById('event_start').value; | ||
182 | let event_end = document.getElementById('event_end').value; | ||
183 | const event_color = document.getElementById('event_color').value; // #3788d8 par défaut | ||
184 | const event_id = new_event ? '' : document.getElementById('event_id').value; | ||
185 | |||
186 | if(event_title.length !== 0 && event_start.length !== 0 && event_end.length !== 0 && event_color.length !== 0 | ||
187 | && (new_event || event_id.length !== 0)) | ||
188 | { | ||
189 | if(event_all_day){ | ||
190 | // on remet le jour de fin exclu | ||
191 | const tmp_object = new Date(event_end); | ||
192 | tmp_object.setDate(tmp_object.getDate() + 1); | ||
193 | event_end = tmp_object.toISOString().split('T')[0]; | ||
194 | } | ||
195 | else{ | ||
196 | event_start = new Date(event_start).toISOString(); | ||
197 | event_end = new Date(event_end).toISOString(); | ||
198 | } | ||
199 | console.log(event_end); | ||
200 | |||
201 | if(event_start > event_end || (!event_all_day && event_start == event_end)){ | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | // création | ||
206 | if(new_event){ | ||
207 | const event = { | ||
208 | title: event_title, | ||
209 | description: event_description, | ||
210 | allDay: event_all_day, | ||
211 | start: event_start, | ||
212 | end: event_end, | ||
213 | color: event_color | ||
214 | }; | ||
215 | |||
216 | fetch('../src/post-ajax.php', { | ||
217 | method: 'POST', | ||
218 | headers: { | ||
219 | 'Content-Type': 'application/json', | ||
220 | }, | ||
221 | body: JSON.stringify(event), | ||
222 | }) | ||
223 | .then(response => response.json()) | ||
224 | .then(data => { | ||
225 | if(data.success){ | ||
226 | event.id = data.id; | ||
227 | calendar.addEvent(event); | ||
228 | hideModal(); | ||
229 | } | ||
230 | }) | ||
231 | .catch((error) => { | ||
232 | console.error('Error:', error); | ||
233 | }); | ||
234 | |||
235 | } | ||
236 | // modification | ||
237 | else{ | ||
238 | const event = calendar.getEventById(event_id); | ||
239 | |||
240 | if(event){ | ||
241 | const event_copy = { | ||
242 | id: parseInt(event.id), | ||
243 | description: event_description, | ||
244 | title: event_title, | ||
245 | allDay: event_all_day, | ||
246 | start: event_start, | ||
247 | end: event_end, | ||
248 | color: event_color | ||
249 | }; | ||
250 | |||
251 | fetch('../src/post-ajax.php', { | ||
252 | method: 'POST', | ||
253 | headers: { | ||
254 | 'Content-Type': 'application/json', | ||
255 | }, | ||
256 | body: JSON.stringify(event_copy), | ||
257 | }) | ||
258 | .then(response => response.json()) | ||
259 | .then(data => { | ||
260 | if(data.success){ | ||
261 | event.setProp('title', event_title); | ||
262 | event.setExtendedProp('description', event_description); | ||
263 | event.setAllDay(event_all_day); | ||
264 | event.setStart(event_start); | ||
265 | event.setEnd(event_end); | ||
266 | event.setProp('color', event_color); | ||
267 | hideModal(); | ||
268 | } | ||
269 | }) | ||
270 | .catch((error) => { | ||
271 | console.error('Error:', error); | ||
272 | }); | ||
273 | } | ||
274 | else{ | ||
275 | console.log("Événement non trouvé !"); | ||
276 | } | ||
277 | } | ||
278 | } | ||
279 | else{ | ||
280 | // notif input vide | ||
281 | console.log('erreur: input vide'); | ||
282 | } | ||
283 | } | ||
284 | |||
285 | function checkAllDay(){ | ||
286 | const event_start_input = document.getElementById('event_start'); | ||
287 | const event_end_input = document.getElementById('event_end'); | ||
288 | |||
289 | const start = event_start_input.value; | ||
290 | const end = event_end_input.value; | ||
291 | |||
292 | if(document.getElementById('event_all_day').checked){ | ||
293 | event_start_input.type = 'date'; | ||
294 | event_end_input.type = 'date'; | ||
295 | |||
296 | event_start_input.value = start.split('T')[0]; | ||
297 | event_end_input.value = end.split('T')[0]; | ||
298 | } | ||
299 | else{ | ||
300 | event_start_input.type = 'datetime-local'; | ||
301 | event_end_input.type = 'datetime-local'; | ||
302 | |||
303 | event_start_input.value = start + 'T10:00'; | ||
304 | event_end_input.value = end + 'T11:00'; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | document.addEventListener('keydown', function(event){ | ||
309 | if(event.key === 'Escape') { | ||
310 | hideModal(); | ||
311 | } | ||
312 | }); | ||
313 | |||
314 | // technique de la délégation d'événements pour utiliser un bouton ajouté dynamiquement | ||
315 | document.addEventListener('click', function(event){ | ||
316 | if(event.target.classList.contains('event_close_button')){ | ||
317 | hideModal(); | ||
318 | } | ||
319 | else if(event.target.classList.contains('event_all_day')){ | ||
320 | checkAllDay(); | ||
321 | } | ||
322 | else if(event.target.classList.contains('submit_new_event')){ | ||
323 | submitEvent(true); | ||
324 | } | ||
325 | else if(event.target.classList.contains('submit_update_event')){ | ||
326 | submitEvent(false); | ||
327 | } | ||
328 | }); | ||
329 | |||
330 | calendar.render(); | ||
331 | }); \ No newline at end of file | ||
diff --git a/src/post-ajax.php b/src/post-ajax.php index df5a01a..bedfed5 100644 --- a/src/post-ajax.php +++ b/src/post-ajax.php | |||
@@ -1,5 +1,7 @@ | |||
1 | <?php | 1 | <?php |
2 | if($_SERVER['REQUEST_METHOD'] === 'POST'){ // && $_SESSION['admin'] === true | 2 | session_start(); |
3 | |||
4 | if(isset($_SESSION['admin']) && $_SESSION['admin'] === true && $_SERVER['REQUEST_METHOD'] === 'POST'){ // && $_SESSION['admin'] === true | ||
3 | if($_SERVER['CONTENT_TYPE'] === 'application/json'){ | 5 | if($_SERVER['CONTENT_TYPE'] === 'application/json'){ |
4 | $data = file_get_contents('php://input'); | 6 | $data = file_get_contents('php://input'); |
5 | $json = json_decode($data, true); | 7 | $json = json_decode($data, true); |