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 |
