diff options
Diffstat (limited to 'public')
| -rw-r--r-- | public/css/foot.css | 26 | ||||
| -rw-r--r-- | public/css/head.css | 70 | ||||
| -rw-r--r-- | public/js/Input.js | 132 |
3 files changed, 146 insertions, 82 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 | |||
| 79 | margin: 0 3px; | 79 | margin: 0 3px; |
| 80 | }*/ | 80 | }*/ |
| 81 | 81 | ||
| 82 | #footer_logo_img | 82 | #footer_logo_content |
| 83 | { | 83 | { |
| 84 | max-width: 288px; | 84 | max-width: 288px; |
| 85 | min-width: 150px; | 85 | min-width: 150px; |
| 86 | } | 86 | } |
| 87 | @media screen and (max-width: 1000px) | 87 | @media screen and (max-width: 800px) |
| 88 | { | 88 | { |
| 89 | .footer .contact | 89 | footer .contact |
| 90 | { | 90 | { |
| 91 | width: 70px; | 91 | font-size: smaller; |
| 92 | } | 92 | } |
| 93 | } | 93 | } |
| 94 | 94 | ||
| @@ -119,10 +119,6 @@ footer .data > div | |||
| 119 | color: black; | 119 | color: black; |
| 120 | text-decoration: none; | 120 | text-decoration: none; |
| 121 | } | 121 | } |
| 122 | .empty_admin_zone | ||
| 123 | { | ||
| 124 | height: 70px; | ||
| 125 | } | ||
| 126 | .logged_in | 122 | .logged_in |
| 127 | { | 123 | { |
| 128 | /*height: 70px;*/ | 124 | /*height: 70px;*/ |
| @@ -149,6 +145,20 @@ footer .data > div | |||
| 149 | background-color: yellow; | 145 | background-color: yellow; |
| 150 | border-radius: 4px; | 146 | border-radius: 4px; |
| 151 | } | 147 | } |
| 148 | @media screen and (max-width: 550px){ | ||
| 149 | .logged_in, .logged_in button | ||
| 150 | { | ||
| 151 | font-size: 96%; | ||
| 152 | } | ||
| 153 | .admin_buttons_zone | ||
| 154 | { | ||
| 155 | margin: 3px; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | .empty_admin_zone | ||
| 159 | { | ||
| 160 | height: 93px; /* 40 => 1 ligne, 70/64 => 2 lignes, 93/83 => 3 lignes */ | ||
| 161 | } | ||
| 152 | .modif_mode | 162 | .modif_mode |
| 153 | { | 163 | { |
| 154 | background-color: #ffae1a; /* orange clair soupe de poisson */ | 164 | 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 | |||
| 21 | { | 21 | { |
| 22 | max-height: 24px; | 22 | max-height: 24px; |
| 23 | } | 23 | } |
| 24 | 24 | .header_additional_inputs | |
| 25 | { | ||
| 26 | display: flex; | ||
| 27 | flex-wrap: wrap; | ||
| 28 | justify-content: space-evenly; | ||
| 29 | align-items: center; | ||
| 30 | margin-top: 10px; | ||
| 31 | } | ||
| 25 | .header_content | 32 | .header_content |
| 26 | { | 33 | { |
| 27 | padding: 20px 0; | 34 | margin-top: 10px; |
| 35 | padding-bottom: 20px; | ||
| 28 | display: grid; | 36 | display: grid; |
| 29 | grid-template-columns: 1fr 1fr 1fr; | 37 | grid-template-columns: 1fr 1fr 1fr; |
| 30 | align-items: end; | 38 | align-items: end; |
| 31 | } | 39 | } |
| 32 | /*.header_left_col | 40 | /*.header_left_col |
| 33 | {}*/ | 41 | {}*/ |
| 34 | @media screen and (max-width: 1000px){ | ||
| 35 | .header_content{ | ||
| 36 | padding: 18px 0; | ||
| 37 | } | ||
| 38 | } | ||
| 39 | @media screen and (max-width: 450px){ | ||
| 40 | .header_content | ||
| 41 | { | ||
| 42 | /*grid-template-columns: 1fr 2fr 1fr;*/ | ||
| 43 | display: block; | ||
| 44 | padding: 18px; | ||
| 45 | } | ||
| 46 | #header_logo | ||
| 47 | { | ||
| 48 | display: none; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | 42 | ||
| 52 | .header_center_col | 43 | .header_center_col |
| 53 | { | 44 | { |
| @@ -73,7 +64,7 @@ header h2 | |||
| 73 | header img | 64 | header img |
| 74 | { | 65 | { |
| 75 | vertical-align: bottom; /* supprime espace sous l'image */ | 66 | vertical-align: bottom; /* supprime espace sous l'image */ |
| 76 | max-width: 150px; | 67 | max-width: 180px; |
| 77 | max-height: 100px; | 68 | max-height: 100px; |
| 78 | } | 69 | } |
| 79 | header a | 70 | header a |
| @@ -83,13 +74,46 @@ header a | |||
| 83 | } | 74 | } |
| 84 | /*.header_right_col | 75 | /*.header_right_col |
| 85 | {}*/ | 76 | {}*/ |
| 86 | #header_social img | 77 | #header_social |
| 78 | { | ||
| 79 | display: flex; | ||
| 80 | justify-content: center; | ||
| 81 | } | ||
| 82 | #header_social_content img | ||
| 87 | { | 83 | { |
| 88 | width: 28px; | 84 | width: 28px; |
| 89 | background-color: rgba(255, 255, 255, 0.7); | 85 | background-color: #ffffffb3; |
| 90 | border-radius: 50%; | 86 | border-radius: 50%; |
| 91 | } | 87 | } |
| 92 | #header_social img:hover | 88 | |
| 89 | #header_social_content img:hover | ||
| 93 | { | 90 | { |
| 94 | background-color: yellow; | 91 | background-color: yellow; |
| 92 | } | ||
| 93 | #header_social_input | ||
| 94 | { | ||
| 95 | background-color: #ffffff7f; | ||
| 96 | border-radius: 10px; | ||
| 97 | padding: 5px; | ||
| 98 | } | ||
| 99 | |||
| 100 | @media screen and (max-width: 1000px){ | ||
| 101 | .header_content{ | ||
| 102 | padding: 15px 0; | ||
| 103 | } | ||
| 104 | header img | ||
| 105 | { | ||
| 106 | max-width: 160px; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | @media screen and (max-width: 500px){ | ||
| 110 | .header_content | ||
| 111 | { | ||
| 112 | display: block; | ||
| 113 | padding: 10px; | ||
| 114 | } | ||
| 115 | #header_logo | ||
| 116 | { | ||
| 117 | display: none; | ||
| 118 | } | ||
| 95 | } \ No newline at end of file | 119 | } \ 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 @@ | |||
| 1 | class Input{ | 1 | class InputToggler{ |
| 2 | constructor(name){ | 2 | constructor(name, options = {}){ |
| 3 | this.name = name; | 3 | this.name = name; |
| 4 | /*const name_array = name.split('_'); | ||
| 5 | this.node = name_array[0]; | ||
| 6 | this.what = name_array[1];*/ | ||
| 7 | this.parent = document.getElementById(name); | 4 | this.parent = document.getElementById(name); |
| 5 | |||
| 6 | // ids alternatifs optionnels | ||
| 7 | this.content_elem = this.parent.querySelector(options.content_selector || `#${name}_content`); | ||
| 8 | this.input_elem = this.parent.querySelector(options.input_selector || `#${name}_input`); | ||
| 9 | this.open_elem = this.parent.querySelector(options.open_selector || `#${name}_open`); | ||
| 10 | this.submit_elem = this.parent.querySelector(options.submit_selector || `#${name}_submit`); | ||
| 11 | this.cancel_elem = this.parent.querySelector(options.cancel_selector || `#${name}_cancel`); | ||
| 12 | |||
| 13 | // balises à ne pas gérer (fonctionne mais inutilisé pour l'instant) | ||
| 14 | this.ignored_tags = { | ||
| 15 | has_content: options.has_content !== false, // => true sauf si le paramètre vaut false | ||
| 16 | has_input: options.has_input !== false, | ||
| 17 | has_open_button: options.has_open_button !== false, | ||
| 18 | has_submit_button: options.has_submit_button !== false, | ||
| 19 | has_cancel_button: options.has_cancel_button !== false | ||
| 20 | } | ||
| 8 | } | 21 | } |
| 9 | open(){ | 22 | open(){ |
| 10 | this.parent.querySelector('#' + this.name + '_content').classList.add('hidden'); | 23 | this.toggleVisibility(true); |
| 11 | this.parent.querySelector('#' + this.name + '_input').classList.remove('hidden'); | ||
| 12 | this.parent.querySelector('#' + this.name + '_open').classList.add('hidden'); | ||
| 13 | this.parent.querySelector('#' + this.name + '_submit').classList.remove('hidden'); | ||
| 14 | this.parent.querySelector('#' + this.name + '_cancel').classList.remove('hidden'); | ||
| 15 | } | 24 | } |
| 16 | close(){ | 25 | close(){ |
| 17 | this.parent.querySelector('#' + this.name + '_content').classList.remove('hidden'); | 26 | this.toggleVisibility(false); |
| 18 | this.parent.querySelector('#' + this.name + '_input').classList.add('hidden'); | 27 | } |
| 19 | this.parent.querySelector('#' + this.name + '_open').classList.remove('hidden'); | 28 | toggleVisibility(show_input = false){ |
| 20 | this.parent.querySelector('#' + this.name + '_submit').classList.add('hidden'); | 29 | // avec && si la partie de gauche est "false", on traite la partie de droite |
| 21 | this.parent.querySelector('#' + this.name + '_cancel').classList.add('hidden'); | 30 | // ?. est l'opérateur de chainage optionnel |
| 31 | this.ignored_tags.has_content && this.content_elem.classList.toggle('hidden', show_input); | ||
| 32 | this.ignored_tags.has_input && this.input_elem.classList.toggle('hidden', !show_input); | ||
| 33 | this.ignored_tags.has_open_button && this.open_elem.classList.toggle('hidden', show_input); | ||
| 34 | this.ignored_tags.has_submit_button && this.submit_elem.classList.toggle('hidden', !show_input); | ||
| 35 | this.ignored_tags.has_cancel_button && this.cancel_elem.classList.toggle('hidden', !show_input); | ||
| 22 | } | 36 | } |
| 23 | cancel(){ | 37 | cancel(){ |
| 24 | this.close(); | 38 | this.close(); |
| 25 | } | 39 | } |
| 26 | } | 40 | } |
| 27 | 41 | ||
| 28 | class InputFile extends Input{ | 42 | class InputText extends InputToggler{ |
| 43 | constructor(name, options = {}){ | ||
| 44 | super(name, options); | ||
| 45 | this.fetch_endpoint = options.endpoint || 'index.php'; | ||
| 46 | this.fetch_key = options.fetch_key || 'head_foot_text'; | ||
| 47 | } | ||
| 29 | submit(){ | 48 | submit(){ |
| 30 | const file = this.parent.querySelector('#' + this.name + '_input').files[0]; | 49 | fetch(this.fetch_endpoint + '?' + this.fetch_key + '=' + this.name, { |
| 31 | if(!file){ | 50 | method: 'POST', |
| 32 | console.error("Erreur: aucun fichier sélectionné."); | 51 | headers: { 'Content-Type': 'application/json' }, |
| 33 | toastNotify("Erreur: aucun fichier sélectionné."); | 52 | body: JSON.stringify({new_text: this.input_elem.value}) |
| 34 | return; | ||
| 35 | } | ||
| 36 | const form_data = new FormData(); | ||
| 37 | form_data.append('file', file); | ||
| 38 | |||
| 39 | fetch('index.php?head_foot_image=' + this.name, { | ||
| 40 | method: 'POST', // apparemment il faudrait utiliser PUT | ||
| 41 | body: form_data | ||
| 42 | }) | 53 | }) |
| 43 | .then(response => response.json()) | 54 | .then(response => response.json()) |
| 44 | .then(data => { | 55 | .then(data => { |
| 45 | if(data.success){ | 56 | if(data.success){ |
| 46 | // cas particuliers | 57 | this.content_elem.innerHTML = this.input_elem.value; |
| 47 | if(this.name === 'head_favicon'){ | ||
| 48 | const link = document.querySelector('link[rel="icon"]'); | ||
| 49 | link.type = data.mime_type; | ||
| 50 | link.href = data.location; | ||
| 51 | } | ||
| 52 | else if(this.name === 'header_background'){ | ||
| 53 | document.querySelector('header').style.backgroundImage = "url('" + data.location + "')"; | ||
| 54 | } | ||
| 55 | |||
| 56 | this.parent.querySelector('#' + this.name + '_content').src = data.location; | ||
| 57 | this.close(); | 58 | this.close(); |
| 58 | } | 59 | } |
| 59 | else{ | 60 | else{ |
| 60 | console.error("Erreur: le serveur n'a pas enregistré l'image'."); | 61 | console.error("Erreur: le serveur n'a pas enregistré le nouveau texte."); |
| 61 | } | 62 | } |
| 62 | }) | 63 | }) |
| 63 | .catch(error => { | 64 | .catch(error => { |
| 64 | console.error('Erreur:', error); | 65 | console.error('Erreur:', error); |
| 65 | }); | 66 | }); |
| 66 | } | 67 | } |
| 68 | cancel(){ | ||
| 69 | this.input_elem.value = this.content_elem.innerHTML; | ||
| 70 | super.cancel(); | ||
| 71 | } | ||
| 67 | } | 72 | } |
| 68 | 73 | ||
| 69 | class InputText extends Input{ | 74 | class InputFile extends InputToggler{ |
| 75 | constructor(name, options = {}){ | ||
| 76 | super(name, options); | ||
| 77 | this.fetch_endpoint = options.endpoint || 'index.php'; | ||
| 78 | this.fetch_key = options.fetch_key || 'head_foot_image'; | ||
| 79 | } | ||
| 70 | submit(){ | 80 | submit(){ |
| 71 | const new_text = this.parent.querySelector('#' + this.name + '_input').value; | 81 | const file = this.input_elem.files[0]; |
| 82 | if(!file){ | ||
| 83 | console.error("Erreur: aucun fichier sélectionné."); | ||
| 84 | toastNotify("Erreur: aucun fichier sélectionné."); | ||
| 85 | return; | ||
| 86 | } | ||
| 87 | const form_data = new FormData(); | ||
| 88 | form_data.append('file', file); | ||
| 72 | 89 | ||
| 73 | fetch('index.php?head_foot_text=' + this.name, { | 90 | fetch(this.fetch_endpoint + '?' + this.fetch_key + '=' + this.name, { |
| 74 | method: 'POST', | 91 | method: 'POST', // apparemment il faudrait utiliser PUT |
| 75 | headers: { 'Content-Type': 'application/json' }, | 92 | body: form_data |
| 76 | body: JSON.stringify({new_text: new_text}) | ||
| 77 | }) | 93 | }) |
| 78 | .then(response => response.json()) | 94 | .then(response => response.json()) |
| 79 | .then(data => { | 95 | .then(data => { |
| 80 | if(data.success){ | 96 | if(data.success){ |
| 81 | this.parent.querySelector('#' + this.name + '_content').innerHTML = new_text; | 97 | this.onSuccess(data); |
| 82 | this.close(); | 98 | this.close(); |
| 83 | } | 99 | } |
| 84 | else{ | 100 | else{ |
| 85 | console.error("Erreur: le serveur n'a pas enregistré le nouveau texte."); | 101 | console.error("Erreur: le serveur n'a pas enregistré l'image'."); |
| 86 | } | 102 | } |
| 87 | }) | 103 | }) |
| 88 | .catch(error => { | 104 | .catch(error => { |
| 89 | console.error('Erreur:', error); | 105 | console.error('Erreur:', error); |
| 90 | }); | 106 | }); |
| 91 | } | 107 | } |
| 92 | cancel(){ // surcharge | 108 | onSuccess(data){ |
| 93 | this.parent.querySelector('#' + this.name + '_input').value = this.parent.querySelector('#' + this.name + '_content').innerHTML; | 109 | this.content_elem.src = data.location; |
| 94 | this.close(); | ||
| 95 | } | 110 | } |
| 111 | } | ||
| 112 | |||
| 113 | class InputFileFavicon extends InputFile{ | ||
| 114 | onSuccess(data){ | ||
| 115 | const link = document.querySelector('link[rel="icon"]'); | ||
| 116 | link.type = data.mime_type; | ||
| 117 | link.href = data.location; | ||
| 118 | super.onSuccess(data); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | class InputFileHeaderBackground extends InputFile{ | ||
| 122 | onSuccess(data){ | ||
| 123 | document.querySelector('header').style.backgroundImage = `url('${data.location}')`; | ||
| 124 | super.onSuccess(data); | ||
| 125 | } | ||
| 96 | } \ No newline at end of file | 126 | } \ No newline at end of file |
