From 0f502d6536d95ddda75604b296e48f14ee6a7df1 Mon Sep 17 00:00:00 2001 From: leosw Date: Sun, 18 Jan 2026 19:40:59 +0100 Subject: [PATCH] View of a POI is working fine --- controllers/d.poi.php | 38 ++++++++- includes/poi_types.struct.php | 150 ++++++++++++++++++++-------------- models/d.poi.php | 4 +- views/css/d.poi.css | 136 ++++++++++++++++++++---------- views/d.poi.view.html | 105 +++++++++++++++++++----- 5 files changed, 302 insertions(+), 131 deletions(-) diff --git a/controllers/d.poi.php b/controllers/d.poi.php index 11d442e..aa71f59 100755 --- a/controllers/d.poi.php +++ b/controllers/d.poi.php @@ -3,6 +3,7 @@ require_once($config['models_folder']."d.poi.php"); require_once($config['models_folder']."d.comments.php"); require_once($config['models_folder']."d.users.php"); +require_once($config['includes_folder']."poi_types.struct.php"); $head['css'] = "d.index.css;d.poi.css"; @@ -21,7 +22,42 @@ switch ($controller->splitted_url[1]) { $poi->author = $user->id; $poi->source = "kab"; $poi->is_commentable = isset($_POST['is_commentable']) ? 't' : 'f'; - $poi->parameters = new \stdClass(); // tu pourras y mettre ton JSON plus tard + + $definition = $poi_types[$poi->poi_type][5]; + $params = []; + + foreach ($definition as $key => $label) { + + if (isset($_POST[$key])) { + $value = $_POST[$key]; + + if (str_starts_with($key, 'b_')) { + // 3 états : 1 = oui, 0 = non, -1 = non renseigné + $params[$key] = ($value === "1" ? 1 : + ($value === "0" ? 0 : -1)); + } + elseif (str_starts_with($key, 'n_')) { + $params[$key] = is_numeric($value) ? (0 + $value) : null; + } + elseif (str_starts_with($key, 't_') || str_starts_with($key, 'l_')) { + $params[$key] = trim($value); + } + else { + $params[$key] = $value; + } + + } else { + // Champ absent → booléen = -1 (non renseigné) + if (str_starts_with($key, 'b_')) { + $params[$key] = -1; + } else { + $params[$key] = null; + } + } + } + + + $poi->parameters = json_encode($params, JSON_UNESCAPED_UNICODE); if (!$poi->checkPermalink($_POST['permalink'], 1)) { $poi->permalink = $_POST['permalink']; diff --git a/includes/poi_types.struct.php b/includes/poi_types.struct.php index c716328..70a1f29 100644 --- a/includes/poi_types.struct.php +++ b/includes/poi_types.struct.php @@ -1,65 +1,93 @@ - array("Abri sommaire", "Abri", "#ef2929", "basic_hut", "Un abri sommaire est un bâtiment qui ne permet pas l'hébergement, comme un kiosque.", array( - 't_owner' => "Informations sur le⋅la propriétaire et moyens de contacts", - 't_access' => "Description de l'accès, des transports en commun, et d'éventuels passages délicats", - 't_description' => "Description sur l'abri et remarques (mobilier, dates de disponibilité...)", - 'b_usable' => "Abri condamné, détruit ou fermé ?", - 'b_water' => "Eau à proximité ?", - 'b_wood' => "Bois à proximité ?")), - "wilderness_hut" => array("Cabane non gardée", "Cabane", "#ef2929", "wilderness_hut", "Une cabane non gardée est un bâtiment qui permet l'hébergement, même sommaire, sans gardien.", array( - 't_owner' => "Informations sur le⋅la propriétaire et moyens de contacts", - 't_access' => "Description de l'accès, des transports en commun, et d'éventuels passages délicats", - 't_description' => "Description sur la cabane et remarques (mobilier, isolation, dates de disponibilité...)", - 'b_key' => "Nécessite une clé ?", - 'b_usable' => "Cabane condamnée, détruite ou fermée ?", - 'n_bed' => "Nombre de places prévues pour dormir :", - 'n_mattress' => "Nombre de matelas disponibles :", - 'b_cover' => "Couvertures ?", - 'b_water' => "Eau à proximité ?", - 'b_wood' => "Bois à proximité ?", - 'b_fireplace' => "Cheminée ou poêle à bois ?", - 'b_toilet' => "Latrines ou toilettes ?")), - "alpine_hut" => array("Refuge gardé", "Refuge", "#ef2929", "alpine_hut", "Un refuge gardé est un bâtiment qui permet l'hébergement toute l'année, gardé tout ou partie de l'année.", array( - 't_owner' => "Informations sur le⋅la propriétaire, le⋅la gardien⋅ne et moyens de contacts", - 't_access' => "Description de l'accès, des transports en commun, et d'éventuels passages délicats", - 't_description' => "Description sur le refuge et remarques (mobilier, isolation, dates de gardiennage, tarifs, prestations, réservations...)", - 'b_usable' => "Refuge condamné, détruit ou fermé ?", - 'n_bed' => "Nombre de places prévues pour dormir en période gardée :", - 'n_bed_winter' => "Nombre de places prévues pour dormir en période non gardée :", - 'n_mattress' => "Nombre de matelas en période non gardée :", - 'b_cover' => "Couvertures disponibles en période non gardée ?", - 'b_water' => "Possibilité de se ravitailler en eau ?", - 'b_wood' => "Bois à proximité ?", - 'b_fireplace' => "Cheminée ou poêle à bois en période non gardée ?", - 'b_toilet' => "Latrines ou toilettes en période non gardée ?", - 'l_water' => "URL du site web :")), - "halt" => array("Gîte d'étape", "Gîte", "#4e9a06", "halt", "Un gîte d'étape est un bâtiment qui permet l'hébergement uniquement sur ses périodes d'ouvertures.", array( - 't_owner' => "Informations sur le⋅la propriétaire, le⋅la gardien⋅ne et moyens de contacts", - 't_access' => "Description de l'accès, des transports en commun, et d'éventuels passages délicats", - 't_description' => "Description sur le gîte et remarques (période d'ouverture, tarifs, prestations, réservations...)", - 'b_usable' => "Gîte condamné, détruit ou fermé ?", - 'n_bed' => "Nombre de places prévues pour dormir :", - 'b_water' => "Possibilité de se ravitailler en eau ?", - 'l_water' => "URL du site web :")), - "bivouac" => array("Zone de bivouac", "Bivouac", "#ef2929", "bivouac", "Une zone de bivouac est un espace aménagé permettant de planter la tente.", array( - 't_access' => "Description de l'accès, des transports en commun, et d'éventuels passages délicats", - 't_description' => "Description sur la zone de bivouac et remarques (réglementation spécifique...)", - 'n_bed' => "Nombre d'emplacements :", - 'b_water' => "Eau à proximité ?", - 'b_wood' => "Bois à proximité ?", - 'b_fireplace' => "Emplacement pour faire un feu ?")), - "campsite" => array("Camping", "Camping", "#4e9a06", "campsite", "Un camping est un espace aménagé permettant de planter la tente plusieurs jours, avec gardien.", array( - 't_owner' => "Informations sur le⋅la propriétaire, le⋅la gardien⋅ne et moyens de contacts", - 't_access' => "Description de l'accès, des transports en commun, et d'éventuels passages délicats", - 't_description' => "Description du camping et remarques (période d'ouverture, tarifs, prestations...)", - 'n_bed' => "Nombre d'emplacements :", - 'b_water' => "Possibilité de se ravitailler en eau ?", - 'l_water' => "URL du site web :")) + + "basic_hut" => array("Abri sommaire", "Abri", "#ef2929", "basic_hut", + "Un abri sommaire est un bâtiment qui ne permet pas l'hébergement, comme un kiosque.", + array( + 't_owner' => "👤 Informations sur le⋅la propriétaire et moyens de contacts", + 't_access' => "🧭 Description de l'accès, des transports en commun, et d'éventuels passages délicats", + 't_description' => "📝 Description sur l'abri et remarques", + 'b_usable' => "🚫 Abri condamné, détruit ou fermé ?", + 'b_water' => "💧 Eau à proximité ?", + 'b_wood' => "🌲 Bois à proximité ?" + ) + ), + + "wilderness_hut" => array("Cabane non gardée", "Cabane", "#ef2929", "wilderness_hut", + "Une cabane non gardée est un bâtiment qui permet l'hébergement, même sommaire, sans gardien.", + array( + 't_owner' => "👤 Informations sur le⋅la propriétaire et moyens de contacts", + 't_access' => "🧭 Description de l'accès, des transports en commun, et d'éventuels passages délicats", + 't_description' => "📝 Description sur la cabane et remarques", + 'b_key' => "🔑 Nécessite une clé ?", + 'b_usable' => "🚫 Cabane condamnée, détruite ou fermée ?", + 'n_bed' => "🛏️ Nombre de places prévues pour dormir :", + 'n_mattress' => "🛌 Nombre de matelas disponibles :", + 'b_cover' => "🧣 Couvertures ?", + 'b_water' => "💧 Eau à proximité ?", + 'b_wood' => "🌲 Bois à proximité ?", + 'b_fireplace' => "🔥 Cheminée ou poêle à bois ?", + 'b_toilet' => "🚽 Latrines ou toilettes ?" + ) + ), + + "alpine_hut" => array("Refuge gardé", "Refuge", "#ef2929", "alpine_hut", + "Un refuge gardé est un bâtiment qui permet l'hébergement toute l'année, gardé tout ou partie de l'année.", + array( + 't_owner' => "👤 Informations sur le⋅la propriétaire, le⋅la gardien⋅ne et moyens de contacts", + 't_access' => "🧭 Description de l'accès, des transports en commun, et d'éventuels passages délicats", + 't_description' => "📝 Description sur le refuge et remarques", + 'b_usable' => "🚫 Refuge condamné, détruit ou fermé ?", + 'n_bed' => "Places en période gardée ☀️ :", + 'n_bed_winter' => "Places en période non gardée ❄️ :", + 'n_mattress' => "🛌 Matelas en période non gardée :", + 'b_cover' => "🧣 Couvertures disponibles ?", + 'b_water' => "💧 Possibilité de se ravitailler en eau ?", + 'b_wood' => "🌲 Bois à proximité ?", + 'b_fireplace' => "🔥 Cheminée ou poêle à bois ?", + 'b_toilet' => "🚽 Latrines ou toilettes ?", + 'l_water' => "URL du site web :" + ) + ), + + "halt" => array("Gîte d'étape", "Gîte", "#4e9a06", "halt", + "Un gîte d'étape est un bâtiment qui permet l'hébergement uniquement sur ses périodes d'ouvertures.", + array( + 't_owner' => "👤 Informations sur le⋅la propriétaire, le⋅la gardien⋅ne et moyens de contacts", + 't_access' => "🧭 Description de l'accès, des transports en commun, et d'éventuels passages délicats", + 't_description' => "📝 Description sur le gîte et remarques", + 'b_usable' => "🚫 Gîte condamné, détruit ou fermé ?", + 'n_bed' => "🛏️ Nombre de places prévues pour dormir :", + 'b_water' => "💧 Possibilité de se ravitailler en eau ?", + 'l_water' => "URL du site web :" + ) + ), + + "bivouac" => array("Zone de bivouac", "Bivouac", "#ef2929", "bivouac", + "Une zone de bivouac est un espace aménagé permettant de planter la tente.", + array( + 't_access' => "🧭 Description de l'accès, des transports en commun, et d'éventuels passages délicats", + 't_description' => "📝 Description sur la zone de bivouac et remarques", + 'n_bed' => "⛺ Nombre d'emplacements :", + 'b_water' => "💧 Eau à proximité ?", + 'b_wood' => "🌲 Bois à proximité ?", + 'b_fireplace' => "🔥 Emplacement pour faire un feu ?" + ) + ), + + "campsite" => array("Camping", "Camping", "#4e9a06", "campsite", + "Un camping est un espace aménagé permettant de planter la tente plusieurs jours, avec gardien.", + array( + 't_owner' => "👤 Informations sur le⋅la propriétaire, le⋅la gardien⋅ne et moyens de contacts", + 't_access' => "🧭 Description de l'accès, des transports en commun, et d'éventuels passages délicats", + 't_description' => "📝 Description du camping et remarques", + 'n_bed' => "⛺ Nombre d'emplacements :", + 'b_water' => "💧 Possibilité de se ravitailler en eau ?", + 'l_water' => "URL du site web :" + ) + ) + ); -?> \ No newline at end of file +?> diff --git a/models/d.poi.php b/models/d.poi.php index 749721e..7697682 100755 --- a/models/d.poi.php +++ b/models/d.poi.php @@ -179,7 +179,7 @@ class Poi pg_prepare($con, "prepare3", $query) or die ("Cannot prepare statement\n"); - $result = pg_execute($con, "prepare3", array(date('r'), $this->name, json_encode($this->parameters), $this->locale_id)) + $result = pg_execute($con, "prepare3", array(date('r'), $this->name, $this->parameters, $this->locale_id)) or die ("Cannot execute statement\n"); $this->version_id = pg_fetch_assoc($result)['id']; @@ -238,7 +238,7 @@ class Poi pg_prepare($con, "poi_update_newversion", $query); - $result = pg_execute($con, "poi_update_newversion", array($this->version, date('r'), $this->name, json_encode($this->parameters), $this->locale_id)); + $result = pg_execute($con, "poi_update_newversion", array($this->version, date('r'), $this->name, $this->parameters, $this->locale_id)); $this->version_id = pg_fetch_assoc($result)['id']; diff --git a/views/css/d.poi.css b/views/css/d.poi.css index 2496b64..4bdc742 100755 --- a/views/css/d.poi.css +++ b/views/css/d.poi.css @@ -467,66 +467,112 @@ form.form input[type="checkbox"]:checked + span:before { } } +/***************************************** + * CHAMPS GÉNÉRIQUES + *****************************************/ -/* Ligne principale : coordonnées + type */ -.poi-id-main { +.field { display: flex; - justify-content: space-between; - align-items: center; - font-size: 19px; /* demandé */ + flex-direction: column; + gap: 4px; + padding-bottom: 12px; +} + +.field > label { font-weight: 600; + font-size: 17px; } -/* Coordonnées */ -.poi-id-coords { - display: flex; - align-items: center; - gap: 8px; +/***************************************** + * TEXTES LONGS (t_) + *****************************************/ + +.field-t .field-value { + padding: 10px 12px; + font-size: 15px; } -.poi-id-coords a { - color: #0055aa; - text-decoration: none; -} -.poi-id-coords a:hover { - text-decoration: underline; -} +/***************************************** + * NOMBRES ET LIENS EN LIGNE (n_ et l_) + *****************************************/ -.poi-id-elev { - color: #333; -} - -/* Type */ -.poi-id-type { - display: flex; - align-items: center; +/* Label + valeur sur une seule ligne */ +.field-n, +.field-l { + flex-direction: row; + align-items: baseline; gap: 6px; } -/* Label discret */ -.poi-id-label { - font-weight: 500; - color: #444; +/* On enlève le padding bas qui faisait “bloc” */ +.field-n, +.field-l { + padding-bottom: 4px; } -/* Dates en petit */ -.poi-id-dates { - font-size: 15px; /* demandé */ - color: #555; - display: flex; - gap: 20px; +/* Valeur inline */ +.inline-value { + display: inline-block; + font-size: 15px; + color: #222; } -/* Mobile */ -@media (max-width: 700px) { - .poi-id-main { - flex-direction: column; - align-items: flex-start; - gap: 4px; - } - .poi-id-dates { - flex-direction: column; - gap: 2px; +/* Liens */ +.inline-value a { + color: #1a5ad7; + font-weight: 600; + text-decoration: none; +} +.inline-value a:hover { + text-decoration: underline; +} + + +/***************************************** + * Booleans grid in poi view + *****************************************/ + +.bool-grid { + margin: 20px 0 0 0; + padding: 20px 15px; + background: rgba(200, 220, 255, 0.25); + border-top: 1px solid #bbb; +} + +.bool-row { + display: grid; + grid-auto-flow: column; + grid-auto-columns: 1fr; + text-align: center; + margin-bottom: 10px; +} + +.bool-row.labels { + font-weight: 600; + font-size: 16px; +} + +.bool-label { + padding: 5px; +} + +.bool-row.values { + margin-top: 5px; +} + +.boolean-pill { + display: inline-block; + padding: 8px 12px; + border-radius: 20px; + font-weight: 700; + font-size: 18px; + background: white; +} + +@media (max-width: 900px) { + .bool-row { + grid-auto-flow: row; + grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); } } diff --git a/views/d.poi.view.html b/views/d.poi.view.html index 15c7b8e..76dece3 100644 --- a/views/d.poi.view.html +++ b/views/d.poi.view.html @@ -75,33 +75,94 @@ +

-

Description

-
- content_html?> -
+ poi_type][5]; + $values = $poi->parameters ?? []; -
+ // Séparer les booléens des autres champs + $bool_fields = []; + $other_fields = []; -

Informations générales

-

- poi_type][4] ?? ""?> -

+ foreach ($fields as $key => $label) { + if ($key[0] === 'b') { + $bool_fields[$key] = $label; + } else { + $other_fields[$key] = $label; + } + } + ?> + +
+ + + $label): ?> + + +
+ + + + —" ?> + + +
+ Aucune information." ?> +
+ + + + + + + + + + + +
+ + + + + + +
+ + +
+ $label): ?> +
+ +
+ + +
+ $label): ?> + "✔️", + 0 => "", + -1 => "" + ][$value]; + ?> +
+ +
+ +
+ +
+ + +
-

Caractéristiques

-
- parameters)) { ?> - parameters as $key => $value) { ?> -
- - -
- - -

Aucune information spécifique.

- -
is_commentable == 't') { ?>

Commentaires