From 0ac8f8d12f117e458271c961b303d3c47f4ead9d Mon Sep 17 00:00:00 2001 From: polo Date: Tue, 28 Oct 2025 10:11:08 +0100 Subject: =?UTF-8?q?classes=20Input=20plus=20adaptables,=20s=C3=A9paration?= =?UTF-8?q?=20des=20r=C3=B4les?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/css/foot.css | 26 ++++-- public/css/head.css | 70 ++++++++++------ public/js/Input.js | 132 +++++++++++++++++++------------ src/controller/HeadFootController.php | 3 +- src/controller/ImageUploadController.php | 4 +- src/view/HeaderBuilder.php | 17 +++- src/view/templates/footer.php | 2 +- src/view/templates/header.php | 18 +++-- 8 files changed, 174 insertions(+), 98 deletions(-) diff --git a/public/css/foot.css b/public/css/foot.css index 38284e3..ed65666 100644 --- a/public/css/foot.css +++ b/public/css/foot.css @@ -79,16 +79,16 @@ footer .data > div margin: 0 3px; }*/ -#footer_logo_img +#footer_logo_content { max-width: 288px; min-width: 150px; } -@media screen and (max-width: 1000px) +@media screen and (max-width: 800px) { - .footer .contact + footer .contact { - width: 70px; + font-size: smaller; } } @@ -119,10 +119,6 @@ footer .data > div color: black; text-decoration: none; } -.empty_admin_zone -{ - height: 70px; -} .logged_in { /*height: 70px;*/ @@ -149,6 +145,20 @@ footer .data > div background-color: yellow; border-radius: 4px; } +@media screen and (max-width: 550px){ + .logged_in, .logged_in button + { + font-size: 96%; + } + .admin_buttons_zone + { + margin: 3px; + } +} +.empty_admin_zone +{ + height: 93px; /* 40 => 1 ligne, 70/64 => 2 lignes, 93/83 => 3 lignes */ +} .modif_mode { background-color: #ffae1a; /* orange clair soupe de poisson */ diff --git a/public/css/head.css b/public/css/head.css index dab81a8..c178d3a 100644 --- a/public/css/head.css +++ b/public/css/head.css @@ -21,33 +21,24 @@ header { max-height: 24px; } - +.header_additional_inputs +{ + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + align-items: center; + margin-top: 10px; +} .header_content { - padding: 20px 0; + margin-top: 10px; + padding-bottom: 20px; display: grid; grid-template-columns: 1fr 1fr 1fr; align-items: end; } /*.header_left_col {}*/ -@media screen and (max-width: 1000px){ - .header_content{ - padding: 18px 0; - } -} -@media screen and (max-width: 450px){ - .header_content - { - /*grid-template-columns: 1fr 2fr 1fr;*/ - display: block; - padding: 18px; - } - #header_logo - { - display: none; - } -} .header_center_col { @@ -73,7 +64,7 @@ header h2 header img { vertical-align: bottom; /* supprime espace sous l'image */ - max-width: 150px; + max-width: 180px; max-height: 100px; } header a @@ -83,13 +74,46 @@ header a } /*.header_right_col {}*/ -#header_social img +#header_social +{ + display: flex; + justify-content: center; +} +#header_social_content img { width: 28px; - background-color: rgba(255, 255, 255, 0.7); + background-color: #ffffffb3; border-radius: 50%; } -#header_social img:hover + +#header_social_content img:hover { background-color: yellow; +} +#header_social_input +{ + background-color: #ffffff7f; + border-radius: 10px; + padding: 5px; +} + +@media screen and (max-width: 1000px){ + .header_content{ + padding: 15px 0; + } + header img + { + max-width: 160px; + } +} +@media screen and (max-width: 500px){ + .header_content + { + display: block; + padding: 10px; + } + #header_logo + { + display: none; + } } \ No newline at end of file diff --git a/public/js/Input.js b/public/js/Input.js index 0b6912b..9a131c8 100644 --- a/public/js/Input.js +++ b/public/js/Input.js @@ -1,96 +1,126 @@ -class Input{ - constructor(name){ +class InputToggler{ + constructor(name, options = {}){ this.name = name; - /*const name_array = name.split('_'); - this.node = name_array[0]; - this.what = name_array[1];*/ this.parent = document.getElementById(name); + + // ids alternatifs optionnels + this.content_elem = this.parent.querySelector(options.content_selector || `#${name}_content`); + this.input_elem = this.parent.querySelector(options.input_selector || `#${name}_input`); + this.open_elem = this.parent.querySelector(options.open_selector || `#${name}_open`); + this.submit_elem = this.parent.querySelector(options.submit_selector || `#${name}_submit`); + this.cancel_elem = this.parent.querySelector(options.cancel_selector || `#${name}_cancel`); + + // balises à ne pas gérer (fonctionne mais inutilisé pour l'instant) + this.ignored_tags = { + has_content: options.has_content !== false, // => true sauf si le paramètre vaut false + has_input: options.has_input !== false, + has_open_button: options.has_open_button !== false, + has_submit_button: options.has_submit_button !== false, + has_cancel_button: options.has_cancel_button !== false + } } open(){ - this.parent.querySelector('#' + this.name + '_content').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_input').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_open').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_submit').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_cancel').classList.remove('hidden'); + this.toggleVisibility(true); } close(){ - this.parent.querySelector('#' + this.name + '_content').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_input').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_open').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_submit').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_cancel').classList.add('hidden'); + this.toggleVisibility(false); + } + toggleVisibility(show_input = false){ + // avec && si la partie de gauche est "false", on traite la partie de droite + // ?. est l'opérateur de chainage optionnel + this.ignored_tags.has_content && this.content_elem.classList.toggle('hidden', show_input); + this.ignored_tags.has_input && this.input_elem.classList.toggle('hidden', !show_input); + this.ignored_tags.has_open_button && this.open_elem.classList.toggle('hidden', show_input); + this.ignored_tags.has_submit_button && this.submit_elem.classList.toggle('hidden', !show_input); + this.ignored_tags.has_cancel_button && this.cancel_elem.classList.toggle('hidden', !show_input); } cancel(){ this.close(); } } -class InputFile extends Input{ +class InputText extends InputToggler{ + constructor(name, options = {}){ + super(name, options); + this.fetch_endpoint = options.endpoint || 'index.php'; + this.fetch_key = options.fetch_key || 'head_foot_text'; + } submit(){ - const file = this.parent.querySelector('#' + this.name + '_input').files[0]; - if(!file){ - console.error("Erreur: aucun fichier sélectionné."); - toastNotify("Erreur: aucun fichier sélectionné."); - return; - } - const form_data = new FormData(); - form_data.append('file', file); - - fetch('index.php?head_foot_image=' + this.name, { - method: 'POST', // apparemment il faudrait utiliser PUT - body: form_data + fetch(this.fetch_endpoint + '?' + this.fetch_key + '=' + this.name, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({new_text: this.input_elem.value}) }) .then(response => response.json()) .then(data => { if(data.success){ - // cas particuliers - if(this.name === 'head_favicon'){ - const link = document.querySelector('link[rel="icon"]'); - link.type = data.mime_type; - link.href = data.location; - } - else if(this.name === 'header_background'){ - document.querySelector('header').style.backgroundImage = "url('" + data.location + "')"; - } - - this.parent.querySelector('#' + this.name + '_content').src = data.location; + this.content_elem.innerHTML = this.input_elem.value; this.close(); } else{ - console.error("Erreur: le serveur n'a pas enregistré l'image'."); + console.error("Erreur: le serveur n'a pas enregistré le nouveau texte."); } }) .catch(error => { console.error('Erreur:', error); }); } + cancel(){ + this.input_elem.value = this.content_elem.innerHTML; + super.cancel(); + } } -class InputText extends Input{ +class InputFile extends InputToggler{ + constructor(name, options = {}){ + super(name, options); + this.fetch_endpoint = options.endpoint || 'index.php'; + this.fetch_key = options.fetch_key || 'head_foot_image'; + } submit(){ - const new_text = this.parent.querySelector('#' + this.name + '_input').value; + const file = this.input_elem.files[0]; + if(!file){ + console.error("Erreur: aucun fichier sélectionné."); + toastNotify("Erreur: aucun fichier sélectionné."); + return; + } + const form_data = new FormData(); + form_data.append('file', file); - fetch('index.php?head_foot_text=' + this.name, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({new_text: new_text}) + fetch(this.fetch_endpoint + '?' + this.fetch_key + '=' + this.name, { + method: 'POST', // apparemment il faudrait utiliser PUT + body: form_data }) .then(response => response.json()) .then(data => { if(data.success){ - this.parent.querySelector('#' + this.name + '_content').innerHTML = new_text; + this.onSuccess(data); this.close(); } else{ - console.error("Erreur: le serveur n'a pas enregistré le nouveau texte."); + console.error("Erreur: le serveur n'a pas enregistré l'image'."); } }) .catch(error => { console.error('Erreur:', error); }); } - cancel(){ // surcharge - this.parent.querySelector('#' + this.name + '_input').value = this.parent.querySelector('#' + this.name + '_content').innerHTML; - this.close(); + onSuccess(data){ + this.content_elem.src = data.location; } +} + +class InputFileFavicon extends InputFile{ + onSuccess(data){ + const link = document.querySelector('link[rel="icon"]'); + link.type = data.mime_type; + link.href = data.location; + super.onSuccess(data); + } +} +class InputFileHeaderBackground extends InputFile{ + onSuccess(data){ + document.querySelector('header').style.backgroundImage = `url('${data.location}')`; + super.onSuccess(data); + } } \ No newline at end of file diff --git a/src/controller/HeadFootController.php b/src/controller/HeadFootController.php index a739df8..5945c87 100644 --- a/src/controller/HeadFootController.php +++ b/src/controller/HeadFootController.php @@ -5,7 +5,6 @@ declare(strict_types=1); use App\Entity\NodeDataAsset; use App\Entity\Asset; -use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManager; class HeadFootController @@ -38,7 +37,7 @@ class HeadFootController } else{ if(!is_dir(Asset::USER_PATH)){ - mkdir(Asset::USER_PATH, 0755, true); + mkdir(Asset::USER_PATH, 0777, true); } /* -- téléchargement -- */ diff --git a/src/controller/ImageUploadController.php b/src/controller/ImageUploadController.php index 5e80ba5..b085e11 100644 --- a/src/controller/ImageUploadController.php +++ b/src/controller/ImageUploadController.php @@ -66,10 +66,10 @@ class ImageUploadController // Vérifier si les répertoires existent, sinon les créer if(!is_dir($dest)){ - mkdir($dest, 0700, true); + mkdir($dest, 0777, true); } if(!is_dir($dest_mini)){ - mkdir($dest_mini, 0700, true); + mkdir($dest_mini, 0777, true); } $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'tif']; diff --git a/src/view/HeaderBuilder.php b/src/view/HeaderBuilder.php index ae9a888..7e3c363 100644 --- a/src/view/HeaderBuilder.php +++ b/src/view/HeaderBuilder.php @@ -43,6 +43,7 @@ class HeaderBuilder extends AbstractBuilder } // réseaux sociaux + logo dans l'entête + // ?-> est l'opérateur de chainage optionnel $header_logo = Asset::USER_PATH . $node_data->getAssetByRole('header_logo')?->getFileName() ?? ''; $header_background = Asset::USER_PATH . $node_data->getAssetByRole('header_background')?->getFileName() ?? ''; @@ -55,8 +56,7 @@ class HeaderBuilder extends AbstractBuilder // boutons mode admin if($_SESSION['admin']){ - // assets dans classe editing_zone - $editing_zone_margin = '5px'; + // assets dans classe header_additional_inputs $admin_favicon = ' @@ -83,10 +83,21 @@ class HeaderBuilder extends AbstractBuilder '; // icônes réseaux sociaux + $social_networks_inputs = ''; + /*$admin_social_networks = $social_networks_inputs . ' + + ';*/ $admin_social_networks = ''; } else{ - $editing_zone_margin = '0'; $admin_favicon = ''; $admin_background = ''; $admin_header_logo = ''; diff --git a/src/view/templates/footer.php b/src/view/templates/footer.php index dc1c6cb..0bc85f5 100644 --- a/src/view/templates/footer.php +++ b/src/view/templates/footer.php @@ -17,7 +17,7 @@ diff --git a/src/view/templates/header.php b/src/view/templates/header.php index 4d3b323..9c74f9b 100644 --- a/src/view/templates/header.php +++ b/src/view/templates/header.php @@ -5,8 +5,8 @@ -
-
+
+
@@ -16,7 +16,7 @@
@@ -25,7 +25,7 @@

- +

@@ -35,7 +35,9 @@

- +
+ +
@@ -43,12 +45,12 @@
\ No newline at end of file -- cgit v1.2.3