diff options
author | polo <ordipolo@gmx.fr> | 2025-06-24 01:04:35 +0200 |
---|---|---|
committer | polo <ordipolo@gmx.fr> | 2025-06-24 01:04:35 +0200 |
commit | f007bac3b9172711dc0fcca1306270ab99dbd8a4 (patch) | |
tree | 7a34c7da793ed212af1e3ae5d879e6c587e3d8bb | |
parent | 8ee3440f204dfc6532a49a05719ba37a8c4df359 (diff) | |
download | fullcalendar-master.zip |
-rw-r--r-- | public/css/calendar.css | 24 | ||||
-rw-r--r-- | public/index.php | 8 | ||||
-rw-r--r-- | public/js/calendar.js | 21 | ||||
-rw-r--r-- | src/controller/calendar.php | 133 |
4 files changed, 121 insertions, 65 deletions
diff --git a/public/css/calendar.css b/public/css/calendar.css index 5dfb343..b24fe5b 100644 --- a/public/css/calendar.css +++ b/public/css/calendar.css | |||
@@ -2,13 +2,15 @@ | |||
2 | border: 2px double; | 2 | border: 2px double; |
3 | border-radius: 5px; | 3 | border-radius: 5px; |
4 | width: max-content; | 4 | width: max-content; |
5 | padding: 5px; | ||
5 | } | 6 | } |
6 | #calendar_zone{ | 7 | #calendar_zone{ |
7 | display: flex; | 8 | display: flex; |
8 | max-width: 1000px; | 9 | max-width: 1170px; |
10 | gap: 5px; | ||
9 | } | 11 | } |
10 | #calendar{ | 12 | #calendar{ |
11 | width: -moz-available; | 13 | width: 1165px; |
12 | } | 14 | } |
13 | .event_title_box{ | 15 | .event_title_box{ |
14 | display: flex; | 16 | display: flex; |
@@ -46,4 +48,20 @@ td .fc-timegrid-axis{ | |||
46 | color: white; | 48 | color: white; |
47 | background-color: #00679e; | 49 | background-color: #00679e; |
48 | border-radius: 5px; | 50 | border-radius: 5px; |
49 | } \ No newline at end of file | 51 | } |
52 | |||
53 | @media screen and (max-width: 900px){ | ||
54 | #calendar_zone{ | ||
55 | padding: 0; | ||
56 | } | ||
57 | .fc-toolbar-title{ | ||
58 | font-size: large !important; | ||
59 | } | ||
60 | } | ||
61 | @media screen and (max-width: 650px){ | ||
62 | .fc-toolbar-chunk{ | ||
63 | font-size: smaller; | ||
64 | } | ||
65 | } | ||
66 | @media screen and (max-width: 550px){ | ||
67 | } | ||
diff --git a/public/index.php b/public/index.php index 99220e8..540e8ab 100644 --- a/public/index.php +++ b/public/index.php | |||
@@ -8,6 +8,7 @@ require '../src/controller/calendar.php'; | |||
8 | <head> | 8 | <head> |
9 | <meta charset="utf-8" /> | 9 | <meta charset="utf-8" /> |
10 | <title>fullcalendar</title> | 10 | <title>fullcalendar</title> |
11 | <meta name="viewport" content="width=device-width"> | ||
11 | <link rel="stylesheet" href="css/calendar.css"> | 12 | <link rel="stylesheet" href="css/calendar.css"> |
12 | <!-- <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/fullcalendar/main.min.css' /> --> | 13 | <!-- <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/fullcalendar/main.min.css' /> --> |
13 | <script src='js/fullcalendar/packages/core/index.global.min.js'></script> | 14 | <script src='js/fullcalendar/packages/core/index.global.min.js'></script> |
@@ -17,7 +18,12 @@ require '../src/controller/calendar.php'; | |||
17 | <script src='js/fullcalendar/packages/interaction/index.global.min.js'></script> | 18 | <script src='js/fullcalendar/packages/interaction/index.global.min.js'></script> |
18 | <script src='js/fullcalendar/packages/core/locales/fr.global.min.js'></script> | 19 | <script src='js/fullcalendar/packages/core/locales/fr.global.min.js'></script> |
19 | <?php | 20 | <?php |
20 | echo (isset($_SESSION['admin']) && $_SESSION['admin'] === true) ? '<script src="js/calendar_admin.js"></script>' . "\n" : '<script src="js/calendar.js"></script>' . "\n"; | 21 | if($_SESSION['admin'] === true){ |
22 | echo '<script src="js/calendar_admin.js"></script>' . "\n"; | ||
23 | } | ||
24 | else{ | ||
25 | echo '<script src="js/calendar.js"></script>' . "\n"; | ||
26 | } | ||
21 | ?> | 27 | ?> |
22 | </head> | 28 | </head> |
23 | 29 | ||
diff --git a/public/js/calendar.js b/public/js/calendar.js index 2193272..a092632 100644 --- a/public/js/calendar.js +++ b/public/js/calendar.js | |||
@@ -62,19 +62,24 @@ document.addEventListener('DOMContentLoaded', function(){ | |||
62 | const start = formatDate(info.event.start); | 62 | const start = formatDate(info.event.start); |
63 | const start_date = start.split('T')[0]; | 63 | const start_date = start.split('T')[0]; |
64 | const start_hour = (info.event.allDay ? '' : '<br>à ' + start.split('T')[1]).replace(":", "h"); | 64 | const start_hour = (info.event.allDay ? '' : '<br>à ' + start.split('T')[1]).replace(":", "h"); |
65 | const formated_start = 'le ' + start_date.split('-')[2] + '/' + start_date.split('-')[1] + '/' + start_date.split('-')[0] + start_hour; | 65 | const formated_start = start_date.split('-')[2] + '/' + start_date.split('-')[1] + '/' + start_date.split('-')[0] + start_hour; |
66 | const end = formatDate(info.event.allDay ? minusOneDay(info.event.end) : info.event.end, info.event.allDay); | 66 | const end = formatDate(info.event.allDay ? minusOneDay(info.event.end) : info.event.end, info.event.allDay); |
67 | const end_date = end.split('T')[0]; | 67 | const end_date = end.split('T')[0]; |
68 | const end_hour = (info.event.allDay ? '' : '<br>à ' + end.split('T')[1]).replace(":", "h"); | 68 | const end_hour = (info.event.allDay ? '' : '<br>à ' + end.split('T')[1]).replace(":", "h"); |
69 | const formated_end = 'le ' + end_date.split('-')[2] + '/' + end_date.split('-')[1] + '/' + end_date.split('-')[0] + end_hour; | 69 | const formated_end = end_date.split('-')[2] + '/' + end_date.split('-')[1] + '/' + end_date.split('-')[0] + end_hour; |
70 | 70 | ||
71 | const aside_content = `<div class="event" style="border-color: ` + info.event.backgroundColor +`;"> | 71 | let aside_content = `<div class="event" style="border-color: ` + info.event.backgroundColor +`;"> |
72 | <h3>` + info.event.title + `</h3> | 72 | <h3>` + info.event.title + `</h3> |
73 | <p><i>` + info.event.extendedProps.description + `</i></p> | 73 | <p><i>` + info.event.extendedProps.description + `</i></p>`; |
74 | <p>Journée entière: <br>` + (checked ? 'oui' : 'non') + `</p> | 74 | if(checked && (formated_start === formated_end)){ // affichage simplifié évènement d'un jour |
75 | <p>Début: <br>` + formated_start + `</p> | 75 | aside_content = aside_content + `<p>le ` + formated_start + `</p> |
76 | <p>Fin: <br> ` + formated_end + `</p> | ||
77 | </div>`; | 76 | </div>`; |
77 | } | ||
78 | else{ | ||
79 | aside_content = aside_content + `<p>du ` + formated_start + `</p> | ||
80 | <p>au ` + formated_end + `</p> | ||
81 | </div>`; | ||
82 | } | ||
78 | 83 | ||
79 | aside.innerHTML = aside_content; | 84 | aside.innerHTML = aside_content; |
80 | calendar.updateSize(); | 85 | calendar.updateSize(); |
diff --git a/src/controller/calendar.php b/src/controller/calendar.php index ab2832e..c15141a 100644 --- a/src/controller/calendar.php +++ b/src/controller/calendar.php | |||
@@ -1,12 +1,31 @@ | |||
1 | <?php | 1 | <?php |
2 | // src/controller/calendar.php | 2 | // src/controller/calendar.php |
3 | 3 | ||
4 | function cleanInput(array $data): array | ||
5 | { | ||
6 | $data['title'] = htmlspecialchars($data['title']); | ||
7 | $data['description'] = htmlspecialchars($data['description']); | ||
8 | try{ | ||
9 | $data['start'] = new Datetime($data['start']); | ||
10 | $data['end'] = new Datetime($data['end']); | ||
11 | } | ||
12 | catch(Exception $e){ | ||
13 | throw new InvalidArgumentException('Bad date input'); | ||
14 | } | ||
15 | $data['allDay'] = filter_var($data['allDay'] ?? null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); | ||
16 | if(!is_bool($data['allDay'])){ | ||
17 | throw new InvalidArgumentException('Bad checkbox input'); | ||
18 | } | ||
19 | $data['color'] = isset($data['color']) ? htmlspecialchars($data['color']) : null; | ||
20 | return $data; | ||
21 | } | ||
22 | |||
4 | // chargement des évènements à la création du calendrier | 23 | // chargement des évènements à la création du calendrier |
5 | // et au changement de dates affichées (boutons flèches mais pas changement de vue) | 24 | // et au changement de dates affichées (boutons flèches mais pas changement de vue) |
6 | if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['action'] === 'get_events' | 25 | if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['action'] === 'get_events' |
7 | && isset($_GET['start']) && isset($_GET['end']) && empty($_POST)) | 26 | && isset($_GET['start']) && isset($_GET['end']) && empty($_POST)) |
8 | { | 27 | { |
9 | // bornes début et fin du calendrier affiché à l'heure locale | 28 | // bornes début et fin du calendrier affiché à l'heure locale |
10 | // noter que la vue "planning" est similaire à la vue "semaine" | 29 | // noter que la vue "planning" est similaire à la vue "semaine" |
11 | $start = new DateTime($_GET['start']); | 30 | $start = new DateTime($_GET['start']); |
12 | $end = new DateTime($_GET['end']); | 31 | $end = new DateTime($_GET['end']); |
@@ -26,42 +45,33 @@ if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['acti | |||
26 | 45 | ||
27 | $events = [ | 46 | $events = [ |
28 | [ | 47 | [ |
29 | 'id' => 1, | 48 | 'id' => 1, |
30 | 'title' => 'Évènement1', | 49 | 'title' => 'Évènement1', |
31 | 'start' => '2025-06-03T05:00:00Z', // Z indique que l'heure est en UTC | 50 | 'description' => 'blablabla', |
32 | 'end' => '2025-06-03T09:00:00Z', | 51 | 'start' => '2025-06-03T05:00:00Z', // Z indique que l'heure est en UTC |
33 | 'allDay' => false, | 52 | 'end' => '2025-06-03T09:00:00Z', |
34 | 'color' => '#ffa500', // couleur hexa, éviter les couleurs CSS qui ne fonctionnent pas dans value="" en HTML | 53 | 'allDay' => false, |
35 | //'url' => 'https://dev.nageurs-bigoudens.fr', // comportement: https://fullcalendar.io/docs/eventClick | 54 | 'color' => '#ffa500', // couleur hexa, éviter les couleurs CSS qui ne fonctionnent pas dans value="" en HTML |
36 | 'description' => 'blablabla', | 55 | //'url' => 'https://dev.nageurs-bigoudens.fr', // comportement: https://fullcalendar.io/docs/eventClick |
37 | ], | 56 | ], |
38 | [ | 57 | [ |
39 | 'id' => 2, | 58 | 'id' => 2, |
40 | 'title' => 'Évènement2', | 59 | 'title' => 'Évènement2', |
41 | 'start' => '2025-06-06T08:00:00Z', | 60 | 'description' => 'truc machin', |
42 | 'end' => '2025-06-07T08:00:00Z', | 61 | 'start' => '2025-06-06T08:00:00Z', |
43 | 'allDay' => false, | 62 | 'end' => '2025-06-07T08:00:00Z', |
44 | 'color' => '#e01b24', | 63 | 'allDay' => false, |
45 | 'description' => 'truc machin', | 64 | 'color' => '#e01b24', |
46 | ], | 65 | ], |
47 | [ | 66 | [ |
48 | 'id' => 3, | 67 | 'id' => 3, |
49 | 'title' => 'Évènement3', | 68 | 'title' => 'Évènement3', |
50 | 'start' => '2025-06-08', | 69 | 'description' => 'ça va chier', |
51 | 'end' => '2025-06-09', | 70 | 'start' => '2025-06-08', |
52 | 'allDay' => true, // pas d'heure | 71 | 'end' => '2025-06-09', |
53 | 'color' => '#008000', | 72 | 'allDay' => true, // pas d'heure |
54 | 'description' => 'ça va chier', | 73 | 'color' => '#008000', |
55 | ], | 74 | ], |
56 | // provoque une erreur, si allDay la fin ne peut être égale au début | ||
57 | /*[ | ||
58 | 'id' => 4, | ||
59 | 'title' => 'Évènement4', | ||
60 | 'start' => '2025-06-09', | ||
61 | 'end' => '2025-06-09', | ||
62 | 'allDay' => true, | ||
63 | 'color' => '#1a5fb4', | ||
64 | ],*/ | ||
65 | ]; | 75 | ]; |
66 | 76 | ||
67 | header('Content-Type: application/json'); | 77 | header('Content-Type: application/json'); |
@@ -71,29 +81,46 @@ if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['acti | |||
71 | 81 | ||
72 | // actions sur le calendrier | 82 | // actions sur le calendrier |
73 | elseif(isset($_SESSION['admin']) && $_SESSION['admin'] === true | 83 | elseif(isset($_SESSION['admin']) && $_SESSION['admin'] === true |
74 | && $_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['CONTENT_TYPE'] === 'application/json') | 84 | && $_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['CONTENT_TYPE'] === 'application/json') |
75 | { | 85 | { |
76 | $data = file_get_contents('php://input'); | 86 | $data = file_get_contents('php://input'); |
77 | $json = json_decode($data, true); | 87 | $json = json_decode($data, true); |
78 | 88 | ||
79 | if($_GET['action'] === 'new_event'){ | 89 | if($_GET['action'] === 'new_event'){ |
80 | // BDD | 90 | try{ |
81 | //print_r($json);die; | 91 | $json = cleanInput($json); |
82 | $id = 7; // généré par la BDD | ||
83 | echo json_encode(['success' => true, 'id' => $id]); | ||
84 | } | 92 | } |
85 | elseif($_GET['action'] === 'update_event'){ | 93 | catch(InvalidArgumentException $e){ |
86 | // BDD | 94 | echo json_encode(['success' => false, 'error' => $e->getMessage()]); |
87 | //print_r($json);die; | 95 | http_response_code(400); |
88 | echo json_encode(['success' => true]); | 96 | die; |
89 | } | 97 | } |
90 | elseif($_GET['action'] === 'remove_event'){ | 98 | //print_r($json);die; |
91 | // BDD | 99 | |
92 | //echo $json['id']; die; | 100 | $id = 7; // généré par la BDD |
93 | echo json_encode(['success' => true]); | 101 | echo json_encode(['success' => true, 'id' => $id]); |
102 | } | ||
103 | elseif($_GET['action'] === 'update_event'){ | ||
104 | try{ | ||
105 | $json = cleanInput($json); | ||
94 | } | 106 | } |
95 | else{ | 107 | catch(InvalidArgumentException $e){ |
96 | echo json_encode(['success' => false]); | 108 | echo json_encode(['success' => false, 'error' => $e->getMessage()]); |
109 | http_response_code(400); | ||
110 | die; | ||
97 | } | 111 | } |
98 | die; | 112 | //print_r($json);die; |
99 | } \ No newline at end of file | 113 | |
114 | echo json_encode(['success' => true]); | ||
115 | } | ||
116 | elseif($_GET['action'] === 'remove_event'){ | ||
117 | $json['id'] = (int)$json['id']; | ||
118 | //echo $json['id']; die; | ||
119 | |||
120 | echo json_encode(['success' => true]); | ||
121 | } | ||
122 | else{ | ||
123 | echo json_encode(['success' => false]); | ||
124 | } | ||
125 | die; | ||
126 | } | ||