diff options
Diffstat (limited to 'public')
-rw-r--r-- | public/css/body.css | 8 | ||||
-rw-r--r-- | public/js/main.js | 57 | ||||
-rw-r--r-- | public/js/modif_page.js | 78 | ||||
-rw-r--r-- | public/js/tinymce.js | 28 |
4 files changed, 140 insertions, 31 deletions
diff --git a/public/css/body.css b/public/css/body.css index 140655b..b728d05 100644 --- a/public/css/body.css +++ b/public/css/body.css | |||
@@ -49,12 +49,20 @@ main | |||
49 | { | 49 | { |
50 | display: none; | 50 | display: none; |
51 | } | 51 | } |
52 | section | ||
53 | { | ||
54 | margin: 10px 0; | ||
55 | } | ||
52 | section > h3 | 56 | section > h3 |
53 | { | 57 | { |
54 | padding: 15px; | 58 | padding: 15px; |
55 | margin: 0; | 59 | margin: 0; |
56 | text-align: center; | 60 | text-align: center; |
57 | } | 61 | } |
62 | section .fetch_articles | ||
63 | { | ||
64 | margin-left: 15px; | ||
65 | } | ||
58 | .login_form | 66 | .login_form |
59 | { | 67 | { |
60 | background-color: white; | 68 | background-color: white; |
diff --git a/public/js/main.js b/public/js/main.js index d2f8876..59a9331 100644 --- a/public/js/main.js +++ b/public/js/main.js | |||
@@ -36,15 +36,10 @@ function toastNotify(message){ | |||
36 | setTimeout(function(){ toast.className = toast.className.replace('show', ''); }, 5000); | 36 | setTimeout(function(){ toast.className = toast.className.replace('show', ''); }, 5000); |
37 | } | 37 | } |
38 | 38 | ||
39 | |||
40 | // exécuté à la fin du chargement de la page | 39 | // exécuté à la fin du chargement de la page |
41 | document.addEventListener('DOMContentLoaded', () => { | 40 | document.addEventListener('DOMContentLoaded', () => { |
42 | 41 | ||
43 | // détection des dates et conversion à l'heure locale | 42 | insertLocalDates(); |
44 | document.querySelectorAll('.local_date').forEach(function(element){ | ||
45 | const utc_date = element.getAttribute('date-utc'); // forme: 2025-10-10T12:17:00+00:00 | ||
46 | element.innerText = toFormatedLocalDate(utc_date); | ||
47 | }); | ||
48 | 43 | ||
49 | // ouvrir/fermer les sous-menus avec écran tactile | 44 | // ouvrir/fermer les sous-menus avec écran tactile |
50 | document.querySelectorAll('.sub-menu-toggle').forEach(button => { | 45 | document.querySelectorAll('.sub-menu-toggle').forEach(button => { |
@@ -85,6 +80,48 @@ document.addEventListener('DOMContentLoaded', () => { | |||
85 | }); | 80 | }); |
86 | 81 | ||
87 | 82 | ||
83 | function fetchArticles(bloc_id){ | ||
84 | const parent = document.getElementById(bloc_id); | ||
85 | |||
86 | const block_type = parent.getAttribute('block-type'); | ||
87 | let last_article = ''; | ||
88 | if(block_type === 'post_block'){ | ||
89 | // pas parfait, suppose que les positions sont correctes | ||
90 | last_article = parent.querySelectorAll('article').length - 1; | ||
91 | } | ||
92 | else if(block_type === 'news_block'){ | ||
93 | // date_time du dernier article affiché (heure UTC), date vide si bloc vide | ||
94 | const news_elements = parent.querySelector('.section_child').querySelectorAll('article'); | ||
95 | last_article = news_elements.length !== 0 ? news_elements[news_elements.length - 1].querySelector('.local_date').getAttribute('date-utc') : ''; | ||
96 | } | ||
97 | else{ | ||
98 | console.log("Erreur, le type de bloc n'est pas reconnu"); | ||
99 | return; | ||
100 | } | ||
101 | |||
102 | fetch('index.php?fetch=next_articles&id=' + bloc_id + '&last_article=' + last_article) // méthode GET par défaut | ||
103 | .then(response => response.json()) | ||
104 | .then(data => { | ||
105 | if(data.success){ | ||
106 | // insérer les articles | ||
107 | parent.querySelector('.section_child').innerHTML += data.html; | ||
108 | insertLocalDates(); | ||
109 | |||
110 | // cacher le bouton | ||
111 | parent.querySelector('.fetch_articles').querySelector('button').className = data.truncated ? '' : 'hidden'; | ||
112 | |||
113 | console.log("Articles insérés dans le bloc"); | ||
114 | } | ||
115 | else{ | ||
116 | console.log("Erreur côté serveur à la récupération d'articles"); | ||
117 | } | ||
118 | }) | ||
119 | .catch(error => { | ||
120 | console.error('Erreur:', error); | ||
121 | }); | ||
122 | } | ||
123 | |||
124 | |||
88 | // complète les fonctions dans tinymce.js | 125 | // complète les fonctions dans tinymce.js |
89 | function switchPositions(article_id, direction) | 126 | function switchPositions(article_id, direction) |
90 | { | 127 | { |
@@ -239,6 +276,14 @@ function submitDate(id_date) | |||
239 | } | 276 | } |
240 | } | 277 | } |
241 | 278 | ||
279 | function insertLocalDates(){ | ||
280 | // détection des dates et conversion à l'heure locale | ||
281 | document.querySelectorAll('.local_date').forEach(function(element){ | ||
282 | const utc_date = element.getAttribute('date-utc'); // forme: 2025-10-10T12:17:00+00:00 | ||
283 | element.innerText = toFormatedLocalDate(utc_date); | ||
284 | }); | ||
285 | } | ||
286 | |||
242 | function toFormatedLocalDate(utc_string_date){ // forme: 2025-07-17T13:54:00.000Z ou 2025-02-04T00:24 | 287 | function toFormatedLocalDate(utc_string_date){ // forme: 2025-07-17T13:54:00.000Z ou 2025-02-04T00:24 |
243 | const date = new Date(utc_string_date); | 288 | const date = new Date(utc_string_date); |
244 | 289 | ||
diff --git a/public/js/modif_page.js b/public/js/modif_page.js index bf269ee..15f3598 100644 --- a/public/js/modif_page.js +++ b/public/js/modif_page.js | |||
@@ -1,5 +1,8 @@ | |||
1 | /* -- mode modification d'une page -- */ | 1 | /* -- mode modification d'une page -- */ |
2 | 2 | ||
3 | // beaucoup de fonctions similaires | ||
4 | // à factoriser avec le pattern stratégie? | ||
5 | |||
3 | // même fonction que dans new_page.js | 6 | // même fonction que dans new_page.js |
4 | function makePageNamePath(){ | 7 | function makePageNamePath(){ |
5 | document.getElementById("page_name_path").value = document.getElementById("page_name").value | 8 | document.getElementById("page_name_path").value = document.getElementById("page_name").value |
@@ -92,7 +95,7 @@ function changeDescription(node_data_id){ | |||
92 | toastNotify("la nouvelle description de la page est: " + data.description); | 95 | toastNotify("la nouvelle description de la page est: " + data.description); |
93 | } | 96 | } |
94 | else{ | 97 | else{ |
95 | console.error('Erreur à la modification de la description de la page.'); | 98 | console.error('Erreur côté serveur à la modification de la description de la page.'); |
96 | } | 99 | } |
97 | }) | 100 | }) |
98 | .catch(error => { | 101 | .catch(error => { |
@@ -119,7 +122,7 @@ function renamePageBloc(bloc_id){ | |||
119 | toastNotify('Le bloc a été renommé: ' + data.title); | 122 | toastNotify('Le bloc a été renommé: ' + data.title); |
120 | } | 123 | } |
121 | else{ | 124 | else{ |
122 | console.error('Erreur au renommage du titre.'); | 125 | console.error('Erreur côté serveur au renommage du titre.'); |
123 | } | 126 | } |
124 | }) | 127 | }) |
125 | .catch(error => { | 128 | .catch(error => { |
@@ -168,7 +171,7 @@ function switchBlocsPositions(bloc_id, direction) { | |||
168 | } | 171 | } |
169 | else { | 172 | else { |
170 | 173 | ||
171 | console.error('Échec de l\'inversion'); | 174 | console.error("Échec de l'inversion côté serveur"); |
172 | } | 175 | } |
173 | }) | 176 | }) |
174 | .catch(error => { | 177 | .catch(error => { |
@@ -187,17 +190,21 @@ function articlesOrderSelect(bloc_id){ | |||
187 | .then(response => response.json()) | 190 | .then(response => response.json()) |
188 | .then(data => { | 191 | .then(data => { |
189 | if(data.success){ | 192 | if(data.success){ |
190 | // inverser l'ordre des articles!! | 193 | // inversion des articles |
191 | const parent = document.getElementById(bloc_id).querySelector(".section_child"); | 194 | /*const parent = document.getElementById(bloc_id).querySelector(".section_child"); |
192 | const articles = Array.from(parent.querySelectorAll("article")); | 195 | const articles = Array.from(parent.querySelectorAll("article")); |
193 | articles.reverse().forEach(article => { | 196 | articles.reverse().forEach(article => { |
194 | parent.appendChild(article); // déplace dans le DOM, ne copie pas | 197 | parent.appendChild(article); // déplace dans le DOM, ne copie pas |
195 | }); | 198 | });*/ |
199 | |||
200 | // Ã cause de la pagination, au lieu d'inverser, on remplace les articles par les 1er dans le nouveau sens | ||
201 | document.getElementById(bloc_id).querySelector('.section_child').innerHTML = ''; | ||
202 | fetchArticles(bloc_id); | ||
196 | 203 | ||
197 | console.log('ordre ' + articles_order_select); | 204 | console.log('ordre ' + articles_order_select); |
198 | } | 205 | } |
199 | else{ | 206 | else{ |
200 | console.log("Erreur au changement de l'ordre d'affichage côté serveur"); | 207 | console.log("Erreur côté serveur au changement de l'ordre d'affichage"); |
201 | } | 208 | } |
202 | }) | 209 | }) |
203 | .catch(error => { | 210 | .catch(error => { |
@@ -219,10 +226,10 @@ function changePresentation(bloc_id){ | |||
219 | document.getElementById(bloc_id).className = presentation; | 226 | document.getElementById(bloc_id).className = presentation; |
220 | document.getElementById(bloc_id).querySelector(".section_child").style.gridTemplateColumns = presentation === 'grid' ? 'repeat(auto-fit, minmax(' + data.cols_min_width + 'px, 1fr))' : ''; | 227 | document.getElementById(bloc_id).querySelector(".section_child").style.gridTemplateColumns = presentation === 'grid' ? 'repeat(auto-fit, minmax(' + data.cols_min_width + 'px, 1fr))' : ''; |
221 | document.getElementById('cols_min_width_edit_' + bloc_id).className = presentation === 'grid' ? '' : 'hidden'; | 228 | document.getElementById('cols_min_width_edit_' + bloc_id).className = presentation === 'grid' ? '' : 'hidden'; |
222 | console.log('changement de présentation'); | 229 | console.log('Changement de présentation'); |
223 | } | 230 | } |
224 | else{ | 231 | else{ |
225 | console.log('Erreur au changement de présentation côté serveur'); | 232 | console.log('Erreur côté serveur au changement de présentation'); |
226 | } | 233 | } |
227 | }) | 234 | }) |
228 | .catch(error => { | 235 | .catch(error => { |
@@ -230,6 +237,7 @@ function changePresentation(bloc_id){ | |||
230 | }); | 237 | }); |
231 | } | 238 | } |
232 | 239 | ||
240 | // ressemble à changePaginationLimit | ||
233 | function changeColsMinWidth(bloc_id){ | 241 | function changeColsMinWidth(bloc_id){ |
234 | const cols_min_width_input = document.getElementById('cols_min_width_select_' + bloc_id); | 242 | const cols_min_width_input = document.getElementById('cols_min_width_select_' + bloc_id); |
235 | 243 | ||
@@ -250,10 +258,58 @@ function changeColsMinWidth(bloc_id){ | |||
250 | if(data.success){ | 258 | if(data.success){ |
251 | document.getElementById(bloc_id).className = 'grid'; | 259 | document.getElementById(bloc_id).className = 'grid'; |
252 | document.getElementById(bloc_id).querySelector(".section_child").style.gridTemplateColumns = 'repeat(auto-fit, minmax(' + data.cols_min_width + 'px, 1fr))'; | 260 | document.getElementById(bloc_id).querySelector(".section_child").style.gridTemplateColumns = 'repeat(auto-fit, minmax(' + data.cols_min_width + 'px, 1fr))'; |
253 | console.log('changement de la largeur minimum en mode grille'); | 261 | console.log('Changement de la largeur minimum en mode grille'); |
262 | } | ||
263 | else{ | ||
264 | console.log('Erreur côté serveur au changement du nb de colonnes en mode grille'); | ||
265 | } | ||
266 | }) | ||
267 | .catch(error => { | ||
268 | console.error('Erreur:', error); | ||
269 | }); | ||
270 | } | ||
271 | |||
272 | // ressemble à changeColsMinWidth | ||
273 | function changePaginationLimit(bloc_id){ | ||
274 | const pagination_limit_input = document.getElementById('pagination_limit_' + bloc_id); | ||
275 | |||
276 | if(pagination_limit_input.value > 30){ | ||
277 | pagination_limit_input.value = 30; | ||
278 | } | ||
279 | else if(pagination_limit_input.value < 0){ | ||
280 | pagination_limit_input.value = 0; // fait joli dans la BDD, les valeurs négatives ont le même effet que 0 | ||
281 | } | ||
282 | |||
283 | fetch('index.php?bloc_edit=change_pagination_limit', { | ||
284 | method: 'POST', | ||
285 | headers: { 'Content-Type': 'application/json' }, | ||
286 | body: JSON.stringify({ id: bloc_id, pagination_limit: pagination_limit_input.value }) | ||
287 | }) | ||
288 | .then(response => response.json()) | ||
289 | .then(data => { | ||
290 | if(data.success){ | ||
291 | const parent = document.getElementById(bloc_id).querySelector('.section_child'); | ||
292 | const articles_list = parent.querySelectorAll('article'); | ||
293 | |||
294 | if(data.new_limit > data.old_limit || data.new_limit <= 0){ // si 0, fetchArticles va TOUT chercher! | ||
295 | parent.innerHTML = ''; // pas opti, mais améliorer ça serait très compliqué | ||
296 | fetchArticles(bloc_id); | ||
297 | } | ||
298 | else if(data.new_limit < articles_list.length){ | ||
299 | // retirer les articles | ||
300 | const articles_array = Array.from(articles_list).slice(0, data.new_limit); | ||
301 | parent.innerHTML = ''; | ||
302 | for(let i = 0; i < articles_array.length; i++){ | ||
303 | parent.appendChild(articles_array[i]); | ||
304 | } | ||
305 | // remettre le bouton "Articles suivants" | ||
306 | document.getElementById(bloc_id).querySelector('.fetch_articles').querySelector('button').className = ''; | ||
307 | } | ||
308 | |||
309 | console.log("Changement du nombre d'articles affichés simultanément dans ce bloc"); | ||
254 | } | 310 | } |
255 | else{ | 311 | else{ |
256 | console.log('Erreur au changement du nb de colonnes en mode grille côté serveur'); | 312 | console.log("Erreur côté serveur au changement du nb d'éléments affichés par la pagination"); |
257 | } | 313 | } |
258 | }) | 314 | }) |
259 | .catch(error => { | 315 | .catch(error => { |
diff --git a/public/js/tinymce.js b/public/js/tinymce.js index 97ecad8..d2f9c46 100644 --- a/public/js/tinymce.js +++ b/public/js/tinymce.js | |||
@@ -1,5 +1,5 @@ | |||
1 | // code à réorganiser | 1 | // code à réorganiser |
2 | // seule certaines fonctions ont leur place dans Editor, d'autres servent à manipuler les articles d'une autre manière (déplacer, supprimer...) | 2 | // seules certaines fonctions ont leur place dans Editor, d'autres servent à manipuler les articles d'une autre manière (déplacer, supprimer...) |
3 | // => encapsuler Editor dans une classe Article (comme la balise) qui existe même quand l'éditeur est fermé | 3 | // => encapsuler Editor dans une classe Article (comme la balise) qui existe même quand l'éditeur est fermé |
4 | 4 | ||
5 | 5 | ||
@@ -292,7 +292,7 @@ class Editor | |||
292 | } | 292 | } |
293 | 293 | ||
294 | submit(clone = null){ | 294 | submit(clone = null){ |
295 | var content; | 295 | let content; |
296 | const params = new URL(document.location).searchParams; // "search" = ? et paramètres, searchParams = objet avec des getters | 296 | const params = new URL(document.location).searchParams; // "search" = ? et paramètres, searchParams = objet avec des getters |
297 | // Ã comparer avec: new URLSearchParams(window.location.search); | 297 | // Ã comparer avec: new URLSearchParams(window.location.search); |
298 | // c'est pareil ou pas? | 298 | // c'est pareil ou pas? |
@@ -302,7 +302,7 @@ class Editor | |||
302 | const prefixes = ['t', 'p', 'i', 'd']; | 302 | const prefixes = ['t', 'p', 'i', 'd']; |
303 | const allElemsWithId = document.querySelectorAll('.data'); | 303 | const allElemsWithId = document.querySelectorAll('.data'); |
304 | content = {}; | 304 | content = {}; |
305 | var id_from_builder; | 305 | let id_from_builder; |
306 | 306 | ||
307 | allElemsWithId.forEach(element => { | 307 | allElemsWithId.forEach(element => { |
308 | const first_letter = element.id.charAt(0).toLowerCase(); | 308 | const first_letter = element.id.charAt(0).toLowerCase(); |
@@ -394,14 +394,14 @@ class Editor | |||
394 | // restera ici jusqu'Ã ce que la gestion des balises soient faite ailleurs | 394 | // restera ici jusqu'Ã ce que la gestion des balises soient faite ailleurs |
395 | function makeNewArticleButtons(id, article_id, clone, placement = 'last') | 395 | function makeNewArticleButtons(id, article_id, clone, placement = 'last') |
396 | { | 396 | { |
397 | var share_btn = document.querySelector(`.share.hidden`); // combinaison de deux classes | 397 | let share_btn = document.querySelector(`.share.hidden`); // combinaison de deux classes |
398 | var new_btn = document.getElementById(`new-${id}`); | 398 | let new_btn = document.getElementById(`new-${id}`); |
399 | var edit_btn = document.getElementById(`edit-${id}`); | 399 | let edit_btn = document.getElementById(`edit-${id}`); |
400 | var pos_up_btn = document.getElementById(`position_up-${id}`); | 400 | let pos_up_btn = document.getElementById(`position_up-${id}`); |
401 | var pos_down_btn = document.getElementById(`position_down-${id}`); | 401 | let pos_down_btn = document.getElementById(`position_down-${id}`); |
402 | var delete_btn = document.getElementById(`delete-${id}`); | 402 | let delete_btn = document.getElementById(`delete-${id}`); |
403 | var cancel_btn = document.getElementById(`cancel-${id}`); | 403 | let cancel_btn = document.getElementById(`cancel-${id}`); |
404 | var submit_btn = document.getElementById(`submit-${id}`); | 404 | let submit_btn = document.getElementById(`submit-${id}`); |
405 | 405 | ||
406 | share_btn.classList.remove('hidden'); | 406 | share_btn.classList.remove('hidden'); |
407 | new_btn.classList.add('hidden'); | 407 | new_btn.classList.add('hidden'); |
@@ -412,8 +412,8 @@ function makeNewArticleButtons(id, article_id, clone, placement = 'last') | |||
412 | //cancel_btn.classList.add('hidden'); | 412 | //cancel_btn.classList.add('hidden'); |
413 | //submit_btn.classList.add('hidden'); | 413 | //submit_btn.classList.add('hidden'); |
414 | 414 | ||
415 | var article = document.getElementById(id); | 415 | let article = document.getElementById(id); |
416 | var article_elem_parent = findParentByTagName(article, 'article'); | 416 | let article_elem_parent = findParentByTagName(article, 'article'); |
417 | 417 | ||
418 | share_btn.setAttribute('onclick', "copyInClipBoard('" + window.location.href + article_id + "')"); // # de l'ancre ajouté au clic sur le lien ouvrant l'éditeur | 418 | share_btn.setAttribute('onclick', "copyInClipBoard('" + window.location.href + article_id + "')"); // # de l'ancre ajouté au clic sur le lien ouvrant l'éditeur |
419 | article.id = article_id; | 419 | article.id = article_id; |
@@ -430,7 +430,7 @@ function makeNewArticleButtons(id, article_id, clone, placement = 'last') | |||
430 | submit_btn.id = 'submit-' + article_id; | 430 | submit_btn.id = 'submit-' + article_id; |
431 | submit_btn.querySelector('button').setAttribute('onclick', "submitArticle('" + article_id + "')"); | 431 | submit_btn.querySelector('button').setAttribute('onclick', "submitArticle('" + article_id + "')"); |
432 | 432 | ||
433 | var section_child = article_elem_parent.parentNode.querySelector('.section_child'); // renommer section_child | 433 | let section_child = article_elem_parent.parentNode.querySelector('.section_child'); // renommer section_child |
434 | 434 | ||
435 | // parentNode vise la balise section | 435 | // parentNode vise la balise section |
436 | article_elem_parent.parentNode.replaceChild(clone.cloneNode(true), article_elem_parent); // clone du squelette pour le garder intact | 436 | article_elem_parent.parentNode.replaceChild(clone.cloneNode(true), article_elem_parent); // clone du squelette pour le garder intact |