From b36e00a559ebf8def32710812c10e20a390e9082 Mon Sep 17 00:00:00 2001 From: Pierre Date: Mon, 5 Oct 2026 15:08:54 +0000 Subject: [PATCH] =?UTF-8?q?Mise=20=C3=A0=20jour=20du=20CSS=20d'affichage?= =?UTF-8?q?=20de=20shipmember.php,=20administration.php=20et=20bateaux.php?= =?UTF-8?q?=20pour=20les=20pages=20de=20connexion=20et=20pour=20les=20page?= =?UTF-8?q?s=20d'affectation=20de=20droits=20su=20run=20bateau?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/fonctions_html.php | 28 + html/bateaux.php | 329 +++++---- html/format_bateaux.css | 1352 +++++++++++++++++++---------------- html/format_shipmembers.css | 63 ++ html/shipmembers.php | 9 +- 5 files changed, 1032 insertions(+), 749 deletions(-) diff --git a/config/fonctions_html.php b/config/fonctions_html.php index 4ab62cf..3d160b1 100644 --- a/config/fonctions_html.php +++ b/config/fonctions_html.php @@ -394,3 +394,31 @@ echo ''; + + +//************************************************************************************************************ +// Jeton anti-CSRF (synthèse §48) : un jeton aléatoire par session, inclus dans chaque formulaire et vérifié à chaque +// requête POST - un formulaire envoyé depuis un autre site ne peut pas le connaître. Complète SameSite=Lax. +//************************************************************************************************************ + +// Fonction : Jeton de la session (créé au premier appel). +// Retour : Le jeton (64 caractères hexadécimaux) +function Jeton_csrf() +{ + if (empty($_SESSION['jeton_csrf'])) $_SESSION['jeton_csrf'] = bin2hex(random_bytes(32)); + return $_SESSION['jeton_csrf']; +} + +// Fonction : Champ caché portant le jeton, à placer dans chaque formulaire POST. +// Retour : Le code HTML du champ +function Champ_jeton_csrf() +{ + return ''; +} + +// Fonction : Vérifie le jeton reçu dans la requête POST (comparaison à temps constant). +// Retour : true si le jeton est présent et correct +function Jeton_csrf_valide() +{ + return (isset($_POST['jeton_csrf']) && is_string($_POST['jeton_csrf']) && hash_equals(Jeton_csrf(), $_POST['jeton_csrf'])); +} diff --git a/html/bateaux.php b/html/bateaux.php index 4252383..0f5f9e9 100644 --- a/html/bateaux.php +++ b/html/bateaux.php @@ -37,6 +37,42 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session if (!isset($_SESSION['Bateaux']['bateau']['Commentaires'])) $_SESSION['Bateaux']['bateau']['Commentaires'] = ""; + //--------------------------------------------------------------------------- + // Contrôles PRÉALABLES à toute action (synthèse §48) - auparavant, les actions GET et POST s'exécutaient avant tout + // contrôle : n'importe quel utilisateur connecté pouvait créer, modifier ou dévalider un bateau. + //--------------------------------------------------------------------------- + if (!$_SESSION['acces_valide']) + { + Fermeture_bdd(); + header('Location:shipmembers.php?action=navigation&destination=Login'); + exit(); + } + $est_administrateur = ($_SESSION['shipmember']['Niveau_acces'] >= NIVEAU_ACCES_MINI_ADMINISTRATEUR); + + // Toute requête POST doit porter le jeton de la session (protection contre les formulaires envoyés depuis un autre site, + // en complément de SameSite=Lax) : + if ($_SERVER['REQUEST_METHOD'] === 'POST' && !Jeton_csrf_valide()) + { + $_SESSION['Bateaux']['flash_erreur'] = t("Formulaire expiré ou invalide : merci de recommencer."); + Fermeture_bdd(); + header('Location: bateaux.php'); + exit(); + } + + // Gestion de la flotte (liste, création, modification, dévalidation d'un bateau) : réservée aux administrateurs : + $actions_flotte = array('tri_liste', 'creation_bateau', 'modification_bateau', 'demande_suppression_bateau'); + if (!$est_administrateur && + ((isset($_GET['action']) && in_array($_GET['action'], $actions_flotte, true)) + || isset($_POST['validation_creation_bateau']) || isset($_POST['validation_modification_bateau']) + || isset($_POST['confirmation_suppression_bateau']))) + { + $_SESSION['Bateaux']['flash_erreur'] = t("Action réservée aux administrateurs."); + Fermeture_bdd(); + header('Location: bateaux.php'); + exit(); + } + + // Variables GET : if (isset($_GET['ancre'])) $_SESSION['Bateaux']['ancre'] = $_GET['ancre']; @@ -47,7 +83,9 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session //=================================== case "navigation": { - if (isset($_GET['destination'])) + // Seules les pages consultables par simple navigation ; création, modification et suppression passent par leurs + // actions dédiées (contrôlées ci-dessus) : + if (isset($_GET['destination']) && in_array($_GET['destination'], array('Accueil', 'Details_bateau'), true)) { $_SESSION['Bateaux']['page'] = $_GET['destination']; } @@ -95,7 +133,7 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session { if (isset($_GET['id_bateau'])) { - $_SESSION['Bateaux']['bateau']['Cle_primaire'] = $_GET['id_bateau']; + $_SESSION['Bateaux']['bateau']['Cle_primaire'] = (int)$_GET['id_bateau']; $_SESSION['Bateaux']['type_details_bateau'] = "resume"; $_SESSION['Bateaux']['page'] = "Details_bateau"; @@ -109,7 +147,7 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session //=================================== case "type_details_bateau": { - if (isset($_GET['type'])) $_SESSION['Bateaux']['type_details_bateau'] = $_GET['type']; + if (isset($_GET['type']) && in_array($_GET['type'], array('resume', 'gerer_les_acces'), true)) $_SESSION['Bateaux']['type_details_bateau'] = $_GET['type']; $_SESSION['Bateaux']['ancre'] = ""; break; } @@ -119,8 +157,9 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session { if (isset($_GET['id_bateau'])) { - $_SESSION['Bateaux']['bateau']['Cle_primaire'] = $_GET['id_bateau']; + $_SESSION['Bateaux']['bateau']['Cle_primaire'] = (int)$_GET['id_bateau']; $_SESSION['Bateaux']['page'] = "Modification_bateau"; + $_SESSION['Bateaux']['charger_bateau'] = true; // Valeurs lues en base à l'affichage du formulaire } break; } @@ -129,6 +168,9 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session case "creation_bateau": { $_SESSION['Bateaux']['page'] = "Creation_bateau"; + // Formulaire vierge - réinitialisé ICI et non plus à chaque affichage : après une erreur de saisie, le formulaire + // réaffiché garde les valeurs saisies : + $_SESSION['Bateaux']['bateau'] = array('Cle_primaire' => 0, 'Nom' => "", 'ID_Flotte' => 0, 'Date_mes' => date("Y-m-d"), 'Commentaires' => ""); break; } @@ -137,81 +179,74 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session { if (isset($_GET['id_bateau'])) { - $_SESSION['Bateaux']['bateau']['Cle_primaire'] = $_GET['id_bateau']; + $_SESSION['Bateaux']['bateau']['Cle_primaire'] = (int)$_GET['id_bateau']; $_SESSION['Bateaux']['page'] = "Confirmation_suppression_bateau"; } break; } - //=================================== - case "confirmation_suppression_bateau": - { - if (isset($_GET['id_bateau'])) - { - $_SESSION['Bateaux']['bateau']['Cle_primaire'] = $_GET['id_bateau']; - - // Suppression du bateau : - $requete = 'UPDATE TB_Bateaux SET Validite=0 WHERE Cle_primaire=?'; - Requete_preparee_bdd($requete, - array( - array('s', $_SESSION['Bateaux']['bateau']['Cle_primaire'])), - __FILE__, __LINE__); - - $flag_redirection = true; // Evite que le message d'erreur soit supprimé par la redirection de purge d'URL - - $message_information = 'Le bateau '.$_SESSION['Bateaux']['bateau']['Nom'].' a été dévalidé dans la base de données.'; - - $_SESSION['Bateaux']['page'] = "Accueil"; - } - - break; - } + // NB : la confirmation de suppression n'est plus une action GET (un simple lien suffisait à dévalider un bateau) : + // elle est envoyée en POST, avec le jeton de session (voir plus bas). } + Fermeture_bdd(); if ($_SESSION['Bateaux']['ancre'] == "") header('Location:bateaux.php'); // Permet de "vider" la barre d'URL des champs GET et donc de doubler le traitement en cas de raffraichissement de page... else header('Location:bateaux.php#'.$_SESSION['Bateaux']['ancre'].''); + exit(); } // Variables POST : //--------------------------------------------------------------------------- - // Création/Modification Bateau : + // Création/Modification Bateau (administrateurs - contrôlé plus haut) : // NB : l'affectation d'un module ShipBase à un bateau ne se fait plus ici mais via TB_Affectations_bateaux // (administration de la flotte, lot 4 - synthèse §44.10). Les anciens champs ID_Carte/Date_carte et les // répertoires download/upload/archives du modèle CM4 ont été retirés (synthèse §47). + // Valeurs enregistrées TELLES QUELLES (requêtes préparées) : l'ancien addslashes() les stockait avec des barres + // obliques (d\'Artagnan), retirées ensuite à l'affichage par stripcslashes() (synthèse §48). if (isset($_POST['validation_creation_bateau']) OR isset($_POST['validation_modification_bateau'])) { - // Mémorisation des valeurs saisies pour éviter de les perdre en cas d'erreur rendant la création impossible : - $_SESSION['Bateaux']['bateau']['Nom'] = isset($_POST['Nom']) ? addslashes ($_POST['Nom']) : ""; - $_SESSION['Bateaux']['bateau']['ID_Flotte'] = isset($_POST['ID_Flotte']) ? addslashes ($_POST['ID_Flotte']) : 0; - $_SESSION['Bateaux']['bateau']['Date_mes'] = isset($_POST['Date_mes']) ? addslashes ($_POST['Date_mes']) : date("Y-m-d"); - $_SESSION['Bateaux']['bateau']['Commentaires'] = isset($_POST['Commentaires']) ? addslashes ($_POST['Commentaires']) : ""; + // Mémorisation des valeurs saisies pour les réafficher en cas d'erreur : + $_SESSION['Bateaux']['bateau']['Nom'] = trim((string)($_POST['Nom'] ?? "")); + $_SESSION['Bateaux']['bateau']['ID_Flotte'] = (int)($_POST['ID_Flotte'] ?? 0); + $_SESSION['Bateaux']['bateau']['Date_mes'] = trim((string)($_POST['Date_mes'] ?? "")); + $_SESSION['Bateaux']['bateau']['Commentaires'] = (string)($_POST['Commentaires'] ?? ""); - if (isset($_POST['validation_creation_bateau'])) + // Vérifications : + $longueur_nom = mb_strlen($_SESSION['Bateaux']['bateau']['Nom']); + if ($longueur_nom < 1 || $longueur_nom > 50) $message_erreur .= t("Le nom du bateau doit comporter de 1 à 50 caractères.")."
"; + $date = date_create_from_format('!Y-m-d', $_SESSION['Bateaux']['bateau']['Date_mes']); + if ($date === false || $date->format('Y-m-d') !== $_SESSION['Bateaux']['bateau']['Date_mes']) $message_erreur .= t("Date de mise en service invalide (format AAAA-MM-JJ).")."
"; + if ($_SESSION['Bateaux']['bateau']['ID_Flotte'] != 0) { - // Création du bateau : - $requete = 'INSERT INTO TB_Bateaux (Nom, ID_Flotte, Date_mes, Commentaires) VALUES (?, ?, ?, ?)'; - Requete_preparee_bdd($requete, + $reponse = Requete_preparee_bdd("SELECT COUNT(*) AS nb FROM TB_Flottes WHERE Cle_primaire=? AND Validite=1", + array(array('i', $_SESSION['Bateaux']['bateau']['ID_Flotte'])), __FILE__, __LINE__); + $donnees = Recherche_ligne_bdd($reponse); + Liberation_jeu_de_resultat_bdd($reponse); + if ($donnees['nb'] == 0) $message_erreur .= t("Flotte inconnue.")."
"; + } + + if ($message_erreur == "") // Sinon : le formulaire est réaffiché avec les valeurs saisies et le message d'erreur + { + if (isset($_POST['validation_creation_bateau'])) + { + $requete = 'INSERT INTO TB_Bateaux (Nom, ID_Flotte, Date_mes, Commentaires) VALUES (?, ?, ?, ?)'; + Requete_preparee_bdd($requete, array( array('s', $_SESSION['Bateaux']['bateau']['Nom']), array('i', $_SESSION['Bateaux']['bateau']['ID_Flotte']), array('s', $_SESSION['Bateaux']['bateau']['Date_mes']), array('s', $_SESSION['Bateaux']['bateau']['Commentaires'])), __FILE__, __LINE__); - - // Récup de la clé primaire de l'enregistrement créé : - $_SESSION['Bateaux']['bateau']['Cle_primaire'] = Recuperation_id_cree_bdd(); - - // Retour à la liste si la création s'est bien passée : - $_SESSION['Bateaux']['page'] = "Accueil"; - } - else if (isset($_POST['validation_modification_bateau'])) - { - // Mise à jour du bateau : - $requete = 'UPDATE TB_Bateaux SET Nom=?, ID_Flotte=?, Date_mes=?, Commentaires=? WHERE Cle_primaire=?'; - Requete_preparee_bdd($requete, + $_SESSION['Bateaux']['bateau']['Cle_primaire'] = Recuperation_id_cree_bdd(); + $_SESSION['Bateaux']['flash_information'] = str_replace("[[Nom]]", htmlspecialchars($_SESSION['Bateaux']['bateau']['Nom']), t("Le bateau [[Nom]] vient d'être créé.")); + } + else + { + $requete = 'UPDATE TB_Bateaux SET Nom=?, ID_Flotte=?, Date_mes=?, Commentaires=? WHERE Cle_primaire=? AND Validite=1'; + Requete_preparee_bdd($requete, array( array('s', $_SESSION['Bateaux']['bateau']['Nom']), array('i', $_SESSION['Bateaux']['bateau']['ID_Flotte']), @@ -219,15 +254,30 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session array('s', $_SESSION['Bateaux']['bateau']['Commentaires']), array('i', $_SESSION['Bateaux']['bateau']['Cle_primaire'])), __FILE__, __LINE__); - - // Message d'information : - $message_information = 'Le bateau '.$_SESSION['Bateaux']['bateau']['Nom'].' vient d\'être modifié'; - - // Retour à la liste si la modification s'est bien passée : + $_SESSION['Bateaux']['flash_information'] = str_replace("[[Nom]]", htmlspecialchars($_SESSION['Bateaux']['bateau']['Nom']), t("Le bateau [[Nom]] vient d'être modifié.")); + } $_SESSION['Bateaux']['page'] = "Accueil"; + Fermeture_bdd(); + header('Location: bateaux.php'); + exit(); } } + //--------------------------------------------------------------------------- + // Dévalidation d'un bateau (administrateurs - contrôlé plus haut ; POST avec jeton) : + if (isset($_POST['confirmation_suppression_bateau'])) + { + $id_bateau = (int)$_POST['confirmation_suppression_bateau']; + Requete_preparee_bdd('UPDATE TB_Bateaux SET Validite=0 WHERE Cle_primaire=? AND Validite=1', array(array('i', $id_bateau)), __FILE__, __LINE__); + if (Nb_lignes_modifiees() == 1) $_SESSION['Bateaux']['flash_information'] = t("Le bateau a été dévalidé dans la base de données."); + else $_SESSION['Bateaux']['flash_erreur'] = t("Ce bateau n'existe pas ou a déjà été dévalidé."); + $_SESSION['Bateaux']['page'] = "Accueil"; + Fermeture_bdd(); + header('Location: bateaux.php'); + exit(); + } + + //--------------------------------------------------------------------------- // NB : les actions sur les accès et invitations (création, suspension, réactivation, révocation, modification, PDF) // sont traitées plus bas, dans la page Details_bateau, APRÈS le calcul des droits de l'utilisateur sur le bateau @@ -318,10 +368,9 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; $bateaux[$nb_bateaux] = $donnees; // Mise en forme de certaines variables : - if ($bateaux[$nb_bateaux]['version'] == "") $bateaux[$nb_bateaux]['version'] = 'inconnue'; + $bateaux[$nb_bateaux]['version'] = ($donnees['version'] == "") ? 'inconnue' : htmlspecialchars($donnees['version']); if ($donnees['Date_derniere_maj'] < "2020-01-02") $bateaux[$nb_bateaux]['Date_derniere_maj'] = "Jamais"; else $bateaux[$nb_bateaux]['Date_derniere_maj'] = Formatage_date($donnees['Date_derniere_maj']); - $bateaux[$nb_bateaux]['Commentaires'] = htmlspecialchars(stripcslashes($bateaux[$nb_bateaux]['Commentaires'])); $nb_bateaux ++; } @@ -572,30 +621,21 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; case "Modification_bateau": { //-------------------------------------------------- - // Préparation des variables du bateau : - if ($_SESSION['Bateaux']['page'] == "Creation_bateau") + // Préparation des variables du bateau. Création : formulaire réinitialisé par l'action "creation_bateau". + // Modification : valeurs lues en base à l'ouverture du formulaire seulement (après une erreur de saisie, les + // valeurs saisies sont conservées) : + if ($_SESSION['Bateaux']['page'] == "Modification_bateau" && !empty($_SESSION['Bateaux']['charger_bateau'])) { - $_SESSION['Bateaux']['bateau']['Cle_primaire'] = 0; - $_SESSION['Bateaux']['bateau']['Nom'] = ""; - $_SESSION['Bateaux']['bateau']['ID_Flotte'] = 0; - $_SESSION['Bateaux']['bateau']['Date_mes'] = date("Y-m-d"); - $_SESSION['Bateaux']['bateau']['Commentaires'] = ""; - } - else // Modification : - { - $requete = 'SELECT * FROM TB_Bateaux WHERE Cle_primaire=? '; + unset($_SESSION['Bateaux']['charger_bateau']); + $requete = 'SELECT Cle_primaire, Nom, ID_Flotte, Date_mes, Commentaires FROM TB_Bateaux WHERE Cle_primaire=? AND Validite=1'; $reponse = Requete_preparee_bdd($requete, array( array('i', $_SESSION['Bateaux']['bateau']['Cle_primaire'])), __FILE__, __LINE__); - while ($donnees = Recherche_ligne_bdd($reponse)) - { - $_SESSION['Bateaux']['bateau'] = $donnees; - - // Mise en forme de textes : - $_SESSION['Bateaux']['bateau']['Commentaires'] = htmlspecialchars(stripcslashes($_SESSION['Bateaux']['bateau']['Commentaires'])); - } + $donnees = Recherche_ligne_bdd($reponse); Liberation_jeu_de_resultat_bdd($reponse); + if ($donnees) $_SESSION['Bateaux']['bateau'] = $donnees; + else $_SESSION['Bateaux']['page'] = "Accueil"; } //-------------------------------------------------- @@ -623,6 +663,13 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; //**************************************************************************************************************************** case "Confirmation_suppression_bateau": { + // Nom du bateau à confirmer, relu en base (auparavant : le dernier nom chargé en session, qui pouvait être celui + // d'un AUTRE bateau) : + $reponse = Requete_preparee_bdd('SELECT Cle_primaire, Nom FROM TB_Bateaux WHERE Cle_primaire=? AND Validite=1', + array(array('i', $_SESSION['Bateaux']['bateau']['Cle_primaire'])), __FILE__, __LINE__); + $bateau_a_supprimer = Recherche_ligne_bdd($reponse); + Liberation_jeu_de_resultat_bdd($reponse); + if (!$bateau_a_supprimer) $_SESSION['Bateaux']['page'] = "Accueil"; break; } @@ -677,12 +724,12 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; echo ' - '.$bateaux[$i]['Nom'].' + '.htmlspecialchars($bateaux[$i]['Nom']).' '; - echo ''.$bateaux[$i]['nom_flotte'].''; + echo ''.htmlspecialchars((string)$bateaux[$i]['nom_flotte']).''; // echo ''.$bateaux[$i]['nom_carte'].''; - echo ''.$bateaux[$i]['adresse_carte'].''; + echo ''.htmlspecialchars((string)$bateaux[$i]['adresse_carte']).''; echo ''.$bateaux[$i]['version'].''; echo ''.$bateaux[$i]['Date_derniere_maj'].''; // echo ''.$bateaux[$i]['Commentaires'].''; @@ -708,7 +755,7 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; { echo '
'; - echo '

Bateau '.$bateau['Nom'].'

'; + echo '

Bateau '.htmlspecialchars($bateau['Nom']).'

'; echo '
'; if ($_SESSION['shipmember']['Niveau_acces'] >= NIVEAU_ACCES_MINI_ADMINISTRATEUR || $acces_profil['Consultation_donnees'] == 2) @@ -716,12 +763,12 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; echo ''; } - echo '
'.t("Derniere_connexion").' : '.$bateau['Date_derniere_maj'].' [UTC]
'; + echo '
'.t("Dernières données reçues").' : '.$bateau['Date_derniere_maj'].' [UTC]
'; echo '
'; //-------------------------------- // Boutons de haut de page (les anciens onglets Carte/Batteries/Circuits/Réservoirs/Capteurs/Système, liés au @@ -740,8 +787,8 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; //=========================================================== case "gerer_les_acces": { - // Texte sûr pour le HTML (les données viennent des utilisateurs : noms, adresses...) : - $h = function($texte) { return htmlspecialchars((string)$texte, ENT_QUOTES, 'UTF-8'); }; + // Convention (synthèse §48) : les textes traduits (t()) sont affichés tels quels - ils sont écrits dans les + // fichiers de langue, pas saisis par les utilisateurs ; seules les DONNÉES (base, saisie) sont échappées. echo '
'; @@ -750,16 +797,17 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; if ($peut_inviter) { echo '
'; - echo '
'; - echo ' '; - echo ' '; - echo ' '; + echo '

'.t("Inviter une personne sur ce bateau").'

'; + echo ' '; echo Champ_jeton_csrf(); + echo ' '; + echo ' '; + echo ' '; echo ' '; - echo ' '; - echo ' '; + echo ' '; + echo ' '; echo '
'; echo '
'; } @@ -769,14 +817,14 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; echo '
'; echo ' '; echo ' '; - echo ' '; - echo ' '; - echo ' '; - echo ' '; - echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; echo ' '; echo ' '; - if ($utilisateur_acces_nb == 0) echo ''; + if ($utilisateur_acces_nb == 0) echo ''; for ($i = 0; $i < $utilisateur_acces_nb; $i++) { $acces = $utilisateur_acces[$i]; @@ -784,11 +832,15 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; // Statut affiché : switch ($acces['Statut']) { - case 'actif': $statut = t("Actif"); break; - case 'suspendu': $statut = t("Suspendu"); break; + case 'actif': $statut = t("Actif"); $classe_statut = 'actif'; break; + case 'suspendu': $statut = t("Suspendu"); $classe_statut = 'suspendu'; break; default: - if ($acces['Expiree']) $statut = t("Invitation expirée"); - else $statut = str_replace("[[Date]]", date_format(date_create($acces['Expiration_invitation']), 'd/m/Y'), t("Invitation en attente (jusqu'au [[Date]])")); + if ($acces['Expiree']) { $statut = t("Invitation expirée"); $classe_statut = 'expiree'; } + else + { + $statut = str_replace("[[Date]]", date_format(date_create($acces['Expiration_invitation']), 'd/m/Y'), t("Invitation en attente (jusqu'au [[Date]])")); + $classe_statut = 'en_attente'; + } break; } @@ -801,29 +853,29 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; if ($peut_devalider || ($acces['Statut'] == 'en_attente' && $peut_inviter)) $actions['revoquer'] = t("Révoquer"); echo ' '; - echo ' '; - echo ' '; - echo ' '; - echo ' '; - echo ' '; - echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ''; echo ' '; } echo '
'.$h(t("Statut")).''.$h(t("Shipmember")).''.$h(t("Créé_par")).''.$h(t("Type de profil")).''.$h(t("Fin de validité")).''.t("Statut").''.t("Destinataire").''.t("Créé par").''.t("Type de profil").''.t("Fin de validité").'
'.$h(t("Aucun accès ni invitation en cours.")).'
'.t("Aucun accès ni invitation en cours.").'
'.$h($statut).''.$h($acces['Destinataire']).''.$h($acces['Cree_par_nom']).''.$h($acces['Niveau_acces_nom']).''.((substr($acces['Fin_validite'], 0, 10) == "9999-12-31") ? $h(t("Aucune")) : $h(date_format(date_create($acces['Fin_validite']), 'd/m/Y'))).''; + echo ' '.$statut.''.htmlspecialchars((string)$acces['Destinataire']).''.htmlspecialchars((string)$acces['Cree_par_nom']).''.htmlspecialchars((string)$acces['Niveau_acces_nom']).''.((substr($acces['Fin_validite'], 0, 10) == "9999-12-31") ? t("Aucune") : date_format(date_create($acces['Fin_validite']), 'd/m/Y')).'
'; if (count($actions) > 0) { - echo '
'; + echo ''; echo Champ_jeton_csrf(); echo ''; foreach ($actions as $code_action => $libelle) { - echo ' '; + echo ' '; } echo '
'; } if ($acces_profil['Modification_acces'] == 1) { - echo ''; + echo ''; } - echo '
'; @@ -839,31 +891,31 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; echo ''; @@ -929,12 +981,12 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; echo '

Bateaux

'; - echo '
'; + echo ''; echo Champ_jeton_csrf(); if ($_SESSION['Bateaux']['page'] == "Creation_bateau") echo '

Nouveau bateau

'; - else echo '

Modification du bateau '.$_SESSION['Bateaux']['bateau']['Nom'].'

'; + else echo '

Modification du bateau '.htmlspecialchars($_SESSION['Bateaux']['bateau']['Nom']).'

'; //---------------------------------------- // Nom : @@ -943,7 +995,7 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; Nom
- +
'; @@ -954,7 +1006,7 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; Date de mise en service
- +
'; @@ -969,7 +1021,7 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; for ($i=0; $i<$nb_flottes; $i++) { echo ' '; } @@ -984,7 +1036,7 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; Commentaires
- +
'; @@ -1000,7 +1052,7 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; { echo 'Annuler'; echo ''; - echo 'Supprimer la bateau'; + echo 'Supprimer le bateau'; } echo ''; @@ -1020,21 +1072,16 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, '; echo '

Bateaux

'; echo '
'; - - echo '

- Confirmez-vous la suppression du bateau - '; - echo $_SESSION['Bateaux']['bateau']['Nom']; - echo ' ? -

'; - echo '

Si oui, son entrée dans la base de données sera dévalidée de la base de données.

'; - + echo '

Confirmez-vous la suppression du bateau '.htmlspecialchars($bateau_a_supprimer['Nom']).' ?

'; + echo '

Si oui, son entrée dans la base de données sera dévalidée.

'; echo '
'; - echo '
'; + // Confirmation envoyée en POST avec le jeton de session (auparavant : un simple lien GET suffisait) : + echo ''; + echo Champ_jeton_csrf(); echo 'Annuler'; - echo 'Confirmer la suppression'; - echo '
'; + echo ''; + echo ''; echo ''; diff --git a/html/format_bateaux.css b/html/format_bateaux.css index 3e7145c..4bfb077 100644 --- a/html/format_bateaux.css +++ b/html/format_bateaux.css @@ -1,604 +1,748 @@ - - - -/*********************************************************************************************************************** -Fichier bateaux.php -***********************************************************************************************************************/ - -#Bateaux .entete_bateau { - border-bottom: 2px solid var(--bleu_koriolan_fonce); - height: 60px; -} -#Bateaux .entete_bateau .derniere_maj { - width: 60%; - padding: 10px 0px; -} -#Bateaux .entete_bateau .bouton_gestion_acces { - text-align: right; - float: right -} -#Bateaux .entete_bateau .bouton_gestion_acces a { - background-color: var(--bleu_koriolan_fonce); - color: var(--blanc); - width: 100%; - padding: 5px 20px; - display: block; -} -#Bateaux .entete_bateau .bouton_gestion_acces a:hover { - color: var(--bleu_koriolan); - background-color: var(--bleu_koriolan_fonce); -} -#Bateaux .entete_bateau .bouton_gestion_acces a.actif { - background-color: var(--bleu_koriolan); - color: var(--bleu_koriolan_fonce); -} - - -#Bateaux .boutons_haut_de_page { - text-align: center; - display: grid; - grid-template-columns: repeat(6, 1fr); - grid-column-gap: 20px; - grid-row-gap: 20px; - align-items: center; - margin: 20px 0px 30px 0px; -} -#Bateaux .boutons_haut_de_page a { - background-color: var(--bleu_koriolan_fonce); - color: var(--blanc); - width: 100%; - display: block; -} -#Bateaux .boutons_haut_de_page a:hover { - color: var(--bleu_koriolan); - background-color: var(--bleu_koriolan_fonce); -} -#Bateaux .boutons_haut_de_page a.actif { - background-color: var(--bleu_koriolan); - color: var(--bleu_koriolan_fonce); -} - - - - -#Bateaux #details_bateau .graphique .top_part_graph .vars .var{ - cursor: pointer; -} -#Bateaux #details_bateau .graphique .top_part_graph .vars .var.actif { - border-radius: 5px; - background-color: var(--bleu_koriolan_transparent); - color: var(--bleu_koriolan_fonce); - font-weight: 600; -} -.page_principale { - width: 80% !important; - max-width: unset !important; -} - -.table_wrapper { - overflow-x: auto; -} - -#Bateaux #accueil table { - width: 100%; - margin-top: 20px; - text-align: center; -} -#Bateaux #accueil table th { - text-align: center; - padding: 3px 10px; -} -#Bateaux #accueil table td { - border-top: 1px solid var(--gris_tres_tres_pale); - text-align: center; - padding: 3px 10px; - font-size: 0.9em; -} -#Bateaux #accueil table td:nth-child(7) { - text-align: left; -} -#Bateaux #accueil table td a { - margin: 0px; - padding: 0px; -} - -#Bateaux #details_bateau .onglets a { - background-color: var(--bleu_koriolan_fonce); - border-radius: 1em 1em 0 0; - color: var(--blanc); - display: inline-block; - padding: 3px 20px; - margin: 1px 1px 0px 1px; -} -#Bateaux #details_bateau .onglets a:hover { - color: var(--bleu_koriolan); - background-color: var(--bleu_koriolan_fonce); -} -#Bateaux #details_bateau .onglets a.actif { - background-color: var(--bleu_koriolan); - color: var(--bleu_koriolan_fonce); -} - -#Bateaux #details_bateau .corps_details_bateau { - background-color: var(--blanc_casse); -} -#Bateaux #details_bateau .corps_details_bateau h2:nth-child(2) { - margin: 0px; -/* border-top: 0px;*/ -} - -#Bateaux #details_bateau .corps_details_bateau .champs { - display: grid; - grid-template-columns: 1fr 1fr; - margin-top: 5px; -} -#Bateaux #details_bateau .corps_details_bateau .champs .champs_titre { - text-align: left; - font-weight: bold; - padding-left: 20px; - /* background-color: var(--blanc_casse); */ -} -#Bateaux #details_bateau .corps_details_bateau .champs .champs_valeur { - text-align: left; - /* background-color: var(--blanc_casse); */ -} -.red { - color: red; -} -.orange { - color: #ffa600; -} -.green { - color: #02a602; -} -.capteur_state{ - display: block; - padding: 0px; - height: 60px; - line-height: 60px; - width: 80px; - text-align: center !important; - font-size: 1.5em; - border-radius: 5px; -} -.capteur_off{ - background-color: rgba(255, 30, 0, 0.2); - color: rgb(255,30,0); -} -.consommation_instantanee { - font-size: 1em; - padding: 6px; - background-image: url(images/icone_consommation_electrique.png); - background-size: contain; - background-position: center; - background-repeat: no-repeat; - margin-right: 5px; -} -.capteur_on{ - background-color: rgba(177, 251, 23, 0.3); - color: rgb(177, 251, 23); -} -#Bateaux #details_bateau .corps_details_bateau .champs .champs_description { - grid-column: 1 / span 2; - text-align: justify; - font-size:0.8em; -} -#Bateaux #details_bateau .boutons_graphique { - text-align: center; - display: grid; - grid-template-columns: 1fr ; - grid-column-gap: 20px; - align-items: center; - margin: 20px 0px 20px 0px; -} -#Bateaux #details_bateau .boutons_graphique a { - background-color: var(--bleu_koriolan_fonce); - color: var(--blanc); - width: 300px; - margin: auto; -} -#Bateaux #details_bateau .boutons_graphique a:hover { - color: var(--bleu_koriolan); - background-color: var(--bleu_koriolan_fonce); -} -#Bateaux #details_bateau .boutons_graphique a.actif { - background-color: var(--bleu_koriolan); - color: var(--bleu_koriolan_fonce); -} -#Bateaux #details_bateau .corps_details_bateau .titre_composant { - display: grid; - grid-template-columns: 2fr 3fr 60px; - /* height: 70px; */ - padding: 15px 0px 15px 0px; - margin: 2em 0px 0.2em 0px; - border-top: 1px solid var(--bleu_koriolan_fonce); - border-bottom: 1px solid var(--bleu_koriolan_fonce); -} -#Bateaux #details_bateau .corps_details_bateau .titre_composant p{ - margin: unset; - text-align : unset; -} -#Bateaux #details_bateau .corps_details_bateau .titre_composant .titre_text{ - font-size: 1.8em; - font-weight: 500; -} -#Bateaux #details_bateau .corps_details_bateau .titre_composant .titre_desc{ - /* font-size: 1.8em; */ -} -#Bateaux #details_bateau .corps_details_bateau .titre_composant .titre_capt{ - display: flex; -} -#Bateaux #details_bateau .corps_details_bateau .titre_composant .titre_icon { - background-size: contain; - background-repeat: no-repeat; - cursor: pointer; - background-position: center; - margin-right: 10px; -} -#Bateaux #details_bateau .corps_details_bateau .titre_composant .more { - background-image: url("images/show_more.png"); -} -#Bateaux #details_bateau .corps_details_bateau .titre_composant .less { - background-image: url("images/show_less.png"); -} -#Bateaux #creation_bateau .champs { - display: grid; - grid-template-columns: 1fr; -} -#Bateaux #creation_bateau .champs .champs_titre { - text-align: left; - margin-top: 20px; -} -#Bateaux #creation_bateau .champs .champs_valeur { - text-align: left; -} -#Bateaux #creation_bateau .champs .champs_valeur select option.selection_actuelle { - color: var(--bleu_koriolan_fonce); - font-weight: bold; -} -#Bateaux #creation_bateau .champs .champs_valeur select option[disabled] { - color: var(--gris_tres_pale); - background-color: var(--gris_tres_tres_pale); -} -#Bateaux #creation_bateau .champs .champs_valeur input { - text-align: left; -} -#Bateaux #creation_bateau .champs .champs_valeur textarea { - border:1px solid var(--bleu_koriolan); - border-radius: 10px; - text-align: left; -} -#Bateaux #creation_bateau .champs .champs_valeur a img { - width: 60%; -} -#Bateaux #creation_bateau .champs .champs_nb { - font-size: 0.8em; - font-style: italic; -} - -#Bateaux #confirmation_suppression_bateau .message_confirmation { - border-radius: 10px; - padding: 20px; - background-color: var(--rouge); - color: var(--jaune_post_it); -} - -#Bateaux .boutons_bas_de_page { - text-align: center; - display: grid; - grid-template-columns: 1fr 1fr 1fr; - grid-column-gap: 20px; - grid-row-gap: 20px; - align-items: center; - margin-top: 50px; -} -#Bateaux .boutons_bas_de_page a { - background-color: var(--bleu_koriolan_fonce); - color: var(--blanc); -} -#Bateaux .boutons_bas_de_page a:hover { - color: var(--bleu_koriolan); - background-color: var(--bleu_koriolan_fonce); -} -.graphique { - display: flex; - flex-direction: column; - height: unset !important; - margin: 20px 0px 20px 0px !important; -} -.graphique .graph { - width: 100%; - height: 100%; - position: relative; -} -.graphique .titre{ - margin-bottom: 20px; -} -.top_part_graph { - display: flex; - height: 100%; -} -.var { - /* display: flex; */ - flex-direction: row; -} -.var input{ - width: unset !important; - margin-right: 10px !important; -} -.var label{ - display: unset !important; -} -.date_pick form{ - display: flex; - flex-direction: column; -} - -.date_pick input { - width: 100%; - position: relative; - margin: auto; -} - -.date_pick label { - display: grid; - grid-template-columns: 2fr 3fr; -} - -.date_pick span { - position: relative; - margin: auto; -} - -.date_maj_version{ - display: flex; -} - -.date_maj_version input,.date_maj_version select{ - width: 200px !important; - margin-left: 30px !important; - margin-right: 30px !important; -} - -.gestion_acces{ - /* height: 100; */ - /* display: flex; */ -} - -.gestion_acces .users{ - margin-bottom: 50px; - overflow-x: auto; -} - -.gestion_acces .users table { - text-align: center; -} - -.gestion_acces .users table tr { - height: 35px; -} - -.gestion_acces .users table td { - border-top: 1px solid var(--gris_tres_tres_pale); - padding: 3px 10px; - font-size: 0.9em; -} - -.gestion_acces .users table td#modifier_acces { - background-image: url(images/stylo.png); - background-repeat: no-repeat; - background-size: 80%; - background-position: center; - cursor: pointer; -} -.gestion_acces .generer_code form{ - display: grid; - grid-template-columns: 2fr 2fr 1fr; - margin-bottom: 30px; - margin-top: 30px; -} - -.download{ - font-weight: 800; - padding: 0; - color: red; -} -.download:hover { - background: red; - color: var(--blanc_casse); -} -#type_acces { - height: unset; -} - -form.variables { - display: grid; - padding-left: 100px; - grid-template-columns: 2fr 2fr 100px; - padding-right: 100px; -} - -form.variables input{ - padding: 5px 10px; -} -.variables button{ - height: 40px; - padding: 0; - top: 20; - position: relative; -} -.help { - position: fixed; - height: 50px; - width: 50px; - background-size: contain; - background-repeat: no-repeat; - cursor: pointer; - bottom: 20px; - right: 20px; - z-index: 100; -} -.help_open { - background-image: url("images/question.png"); -} -.help_close{ - background-image: url("images/fermer_aide.png"); -} -.help:hover{ - animation: heart_pulse 2s ease-in 0s infinite; -} -.help_note{ - width: 300px; - background-color: var(--blanc_casse); - min-height: 40px; - max-height: 600px; - position: fixed; - bottom: 26px; - right: 26px; - border-radius: 5px; - border: var(--bleu_koriolan) 1px solid; - padding-bottom: 20px; - z-index: 50; -} -#maCarte { - height: 600px; - z-index: 1; -} - -/* --------------------- POP UP EDIT ACCESS----------------------*/ -#popUpAcces{ - display: block; - width: 100vw; - height: 100vh; - position: fixed; - background: rgba(255, 255, 255, 0.8); - backdrop-filter: blur(3px); - left: 0; - top: 0; - z-index: 9999; -} -#popUpAccesModal{ - width: 50%; - background: white; - height: 45%; - border-radius: 10px; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - position: fixed; - box-shadow: 0px 0px 7px 2px var(--bleu_koriolan); - overflow-y: auto; -} -#popUpAccesModal #top_part{ - display: grid; - grid-template-columns: auto 50px; -} -#popUpAccesModal #top_part p{ - margin: unset; - text-align: left; - margin-left: 30px; - margin-top: 20px; - margin-bottom: 20px; - color: var(--bleu_koriolan_fonce); - font-weight: 600; - font-size: 25px; -} -#popUpAccesModal #top_part p#close{ - background-image: url(images/croix_carre.png); - background-repeat: no-repeat; - background-size: contain; - cursor: pointer; - width: 30px; - height: 30px; - margin: 10px; -} -#popUpAccesModal form{ - display: grid; - grid-template-columns: 1fr 1fr; - padding: 20px; - column-gap: 30px; - row-gap: 50px; -} -#popUpAccesModal form label{ - position: relative; -} -#popUpAccesModal form label input, #popUpAccesModal form label select{ - width: 100%; -} -#popUpAccesModal form label span { - position: absolute; - top: 0; - left: 10px; - transform: translateY(-18px); - font-size: 18px; - transition-duration: 300ms; - padding-left: 10px; - padding-right: 10px; - color: var(--bleu_koriolan_fonce); - font-weight: 600; - background-color: white; -} -#popUpAccesModal form .buttons_acces{ - display: grid; -} - -/* ------------------ Autres ---------------- */ -#dateSlider{ - margin-bottom: 50px !important; - margin-top: 50px !important; -} - -#dateSlider .noUi-connect{ - background-color: var(--bleu_koriolan); -} -@media only screen and (max-width: 580px) { - #Bateaux .boutons_haut_de_page { - grid-template-columns: minmax(50px, auto); - } - form.variables { - display: flex; - margin-bottom: 50px; - flex-direction: column; - padding : 0; - } - .vars { - display: grid !important; - grid-template-columns: 1fr !important; - } - #popUpAccesModal{ - width: 95% !important; - height: 60% !important; - } - #popUpAccesModal form { - grid-template-columns: 1fr; - row-gap: 30px; - } -} - -@media only screen and (max-width: 850px) { - .top_part_graph { - flex-direction: column-reverse; - } - .vars { - display: grid !important; - grid-template-columns: 1fr 1fr; - } - .page_principale { - width: 96% !important; - } - .gestion_acces{ - flex-direction: column-reverse; - } - form.variables { - - padding : 0; - } - #popUpAccesModal{ - width: 80%; - height: 40%; - } - #dateSlider{ - margin: auto; - width: 80%; - } -} + + + +/*********************************************************************************************************************** +Fichier bateaux.php +***********************************************************************************************************************/ + +#Bateaux .entete_bateau { + border-bottom: 2px solid var(--bleu_koriolan_fonce); + height: 60px; +} +#Bateaux .entete_bateau .derniere_maj { + width: 60%; + padding: 10px 0px; +} +#Bateaux .entete_bateau .bouton_gestion_acces { + text-align: right; + float: right +} +#Bateaux .entete_bateau .bouton_gestion_acces a { + background-color: var(--bleu_koriolan_fonce); + color: var(--blanc); + width: 100%; + padding: 5px 20px; + display: block; +} +#Bateaux .entete_bateau .bouton_gestion_acces a:hover { + color: var(--bleu_koriolan); + background-color: var(--bleu_koriolan_fonce); +} +#Bateaux .entete_bateau .bouton_gestion_acces a.actif { + background-color: var(--bleu_koriolan); + color: var(--bleu_koriolan_fonce); +} + + +#Bateaux .boutons_haut_de_page { + text-align: center; + display: grid; + grid-template-columns: repeat(6, 1fr); + grid-column-gap: 20px; + grid-row-gap: 20px; + align-items: center; + margin: 20px 0px 30px 0px; +} +#Bateaux .boutons_haut_de_page a { + background-color: var(--bleu_koriolan_fonce); + color: var(--blanc); + width: 100%; + display: block; +} +#Bateaux .boutons_haut_de_page a:hover { + color: var(--bleu_koriolan); + background-color: var(--bleu_koriolan_fonce); +} +#Bateaux .boutons_haut_de_page a.actif { + background-color: var(--bleu_koriolan); + color: var(--bleu_koriolan_fonce); +} + + + + +#Bateaux #details_bateau .graphique .top_part_graph .vars .var{ + cursor: pointer; +} +#Bateaux #details_bateau .graphique .top_part_graph .vars .var.actif { + border-radius: 5px; + background-color: var(--bleu_koriolan_transparent); + color: var(--bleu_koriolan_fonce); + font-weight: 600; +} +.page_principale { + width: 80% !important; + max-width: unset !important; +} + +.table_wrapper { + overflow-x: auto; +} + +#Bateaux #accueil table { + width: 100%; + margin-top: 20px; + text-align: center; +} +#Bateaux #accueil table th { + text-align: center; + padding: 3px 10px; +} +#Bateaux #accueil table td { + border-top: 1px solid var(--gris_tres_tres_pale); + text-align: center; + padding: 3px 10px; + font-size: 0.9em; +} +#Bateaux #accueil table td:nth-child(7) { + text-align: left; +} +#Bateaux #accueil table td a { + margin: 0px; + padding: 0px; +} + +#Bateaux #details_bateau .onglets a { + background-color: var(--bleu_koriolan_fonce); + border-radius: 1em 1em 0 0; + color: var(--blanc); + display: inline-block; + padding: 3px 20px; + margin: 1px 1px 0px 1px; +} +#Bateaux #details_bateau .onglets a:hover { + color: var(--bleu_koriolan); + background-color: var(--bleu_koriolan_fonce); +} +#Bateaux #details_bateau .onglets a.actif { + background-color: var(--bleu_koriolan); + color: var(--bleu_koriolan_fonce); +} + +#Bateaux #details_bateau .corps_details_bateau { + background-color: var(--blanc_casse); +} +#Bateaux #details_bateau .corps_details_bateau h2:nth-child(2) { + margin: 0px; +/* border-top: 0px;*/ +} + +#Bateaux #details_bateau .corps_details_bateau .champs { + display: grid; + grid-template-columns: 1fr 1fr; + margin-top: 5px; +} +#Bateaux #details_bateau .corps_details_bateau .champs .champs_titre { + text-align: left; + font-weight: bold; + padding-left: 20px; + /* background-color: var(--blanc_casse); */ +} +#Bateaux #details_bateau .corps_details_bateau .champs .champs_valeur { + text-align: left; + /* background-color: var(--blanc_casse); */ +} +.red { + color: red; +} +.orange { + color: #ffa600; +} +.green { + color: #02a602; +} +.capteur_state{ + display: block; + padding: 0px; + height: 60px; + line-height: 60px; + width: 80px; + text-align: center !important; + font-size: 1.5em; + border-radius: 5px; +} +.capteur_off{ + background-color: rgba(255, 30, 0, 0.2); + color: rgb(255,30,0); +} +.consommation_instantanee { + font-size: 1em; + padding: 6px; + background-image: url(images/icone_consommation_electrique.png); + background-size: contain; + background-position: center; + background-repeat: no-repeat; + margin-right: 5px; +} +.capteur_on{ + background-color: rgba(177, 251, 23, 0.3); + color: rgb(177, 251, 23); +} +#Bateaux #details_bateau .corps_details_bateau .champs .champs_description { + grid-column: 1 / span 2; + text-align: justify; + font-size:0.8em; +} +#Bateaux #details_bateau .boutons_graphique { + text-align: center; + display: grid; + grid-template-columns: 1fr ; + grid-column-gap: 20px; + align-items: center; + margin: 20px 0px 20px 0px; +} +#Bateaux #details_bateau .boutons_graphique a { + background-color: var(--bleu_koriolan_fonce); + color: var(--blanc); + width: 300px; + margin: auto; +} +#Bateaux #details_bateau .boutons_graphique a:hover { + color: var(--bleu_koriolan); + background-color: var(--bleu_koriolan_fonce); +} +#Bateaux #details_bateau .boutons_graphique a.actif { + background-color: var(--bleu_koriolan); + color: var(--bleu_koriolan_fonce); +} +#Bateaux #details_bateau .corps_details_bateau .titre_composant { + display: grid; + grid-template-columns: 2fr 3fr 60px; + /* height: 70px; */ + padding: 15px 0px 15px 0px; + margin: 2em 0px 0.2em 0px; + border-top: 1px solid var(--bleu_koriolan_fonce); + border-bottom: 1px solid var(--bleu_koriolan_fonce); +} +#Bateaux #details_bateau .corps_details_bateau .titre_composant p{ + margin: unset; + text-align : unset; +} +#Bateaux #details_bateau .corps_details_bateau .titre_composant .titre_text{ + font-size: 1.8em; + font-weight: 500; +} +#Bateaux #details_bateau .corps_details_bateau .titre_composant .titre_desc{ + /* font-size: 1.8em; */ +} +#Bateaux #details_bateau .corps_details_bateau .titre_composant .titre_capt{ + display: flex; +} +#Bateaux #details_bateau .corps_details_bateau .titre_composant .titre_icon { + background-size: contain; + background-repeat: no-repeat; + cursor: pointer; + background-position: center; + margin-right: 10px; +} +#Bateaux #details_bateau .corps_details_bateau .titre_composant .more { + background-image: url("images/show_more.png"); +} +#Bateaux #details_bateau .corps_details_bateau .titre_composant .less { + background-image: url("images/show_less.png"); +} +#Bateaux #creation_bateau .champs { + display: grid; + grid-template-columns: 1fr; +} +#Bateaux #creation_bateau .champs .champs_titre { + text-align: left; + margin-top: 20px; +} +#Bateaux #creation_bateau .champs .champs_valeur { + text-align: left; +} +#Bateaux #creation_bateau .champs .champs_valeur select option.selection_actuelle { + color: var(--bleu_koriolan_fonce); + font-weight: bold; +} +#Bateaux #creation_bateau .champs .champs_valeur select option[disabled] { + color: var(--gris_tres_pale); + background-color: var(--gris_tres_tres_pale); +} +#Bateaux #creation_bateau .champs .champs_valeur input { + text-align: left; +} +#Bateaux #creation_bateau .champs .champs_valeur textarea { + border:1px solid var(--bleu_koriolan); + border-radius: 10px; + text-align: left; +} +#Bateaux #creation_bateau .champs .champs_valeur a img { + width: 60%; +} +#Bateaux #creation_bateau .champs .champs_nb { + font-size: 0.8em; + font-style: italic; +} + +#Bateaux #confirmation_suppression_bateau .message_confirmation { + border-radius: 10px; + padding: 20px; + background-color: var(--rouge); + color: var(--jaune_post_it); +} + +#Bateaux .boutons_bas_de_page { + text-align: center; + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-column-gap: 20px; + grid-row-gap: 20px; + align-items: center; + margin-top: 50px; +} +#Bateaux .boutons_bas_de_page a { + background-color: var(--bleu_koriolan_fonce); + color: var(--blanc); +} +#Bateaux .boutons_bas_de_page a:hover { + color: var(--bleu_koriolan); + background-color: var(--bleu_koriolan_fonce); +} +.graphique { + display: flex; + flex-direction: column; + height: unset !important; + margin: 20px 0px 20px 0px !important; +} +.graphique .graph { + width: 100%; + height: 100%; + position: relative; +} +.graphique .titre{ + margin-bottom: 20px; +} +.top_part_graph { + display: flex; + height: 100%; +} +.var { + /* display: flex; */ + flex-direction: row; +} +.var input{ + width: unset !important; + margin-right: 10px !important; +} +.var label{ + display: unset !important; +} +.date_pick form{ + display: flex; + flex-direction: column; +} + +.date_pick input { + width: 100%; + position: relative; + margin: auto; +} + +.date_pick label { + display: grid; + grid-template-columns: 2fr 3fr; +} + +.date_pick span { + position: relative; + margin: auto; +} + +.date_maj_version{ + display: flex; +} + +.date_maj_version input,.date_maj_version select{ + width: 200px !important; + margin-left: 30px !important; + margin-right: 30px !important; +} + +.gestion_acces{ + /* height: 100; */ + /* display: flex; */ +} + +.gestion_acces .users{ + margin-bottom: 50px; + overflow-x: auto; +} + +.gestion_acces .users table { + text-align: center; +} + +.gestion_acces .users table tr { + height: 35px; +} + +.gestion_acces .users table td { + border-top: 1px solid var(--gris_tres_tres_pale); + padding: 3px 10px; + font-size: 0.9em; +} + + +.download{ + font-weight: 800; + padding: 0; + color: red; +} +.download:hover { + background: red; + color: var(--blanc_casse); +} +#type_acces { + height: unset; +} + +form.variables { + display: grid; + padding-left: 100px; + grid-template-columns: 2fr 2fr 100px; + padding-right: 100px; +} + +form.variables input{ + padding: 5px 10px; +} +.variables button{ + height: 40px; + padding: 0; + top: 20; + position: relative; +} +.help { + position: fixed; + height: 50px; + width: 50px; + background-size: contain; + background-repeat: no-repeat; + cursor: pointer; + bottom: 20px; + right: 20px; + z-index: 100; +} +.help_open { + background-image: url("images/question.png"); +} +.help_close{ + background-image: url("images/fermer_aide.png"); +} +.help:hover{ + animation: heart_pulse 2s ease-in 0s infinite; +} +.help_note{ + width: 300px; + background-color: var(--blanc_casse); + min-height: 40px; + max-height: 600px; + position: fixed; + bottom: 26px; + right: 26px; + border-radius: 5px; + border: var(--bleu_koriolan) 1px solid; + padding-bottom: 20px; + z-index: 50; +} +#maCarte { + height: 600px; + z-index: 1; +} + +/* --------------------- POP UP EDIT ACCESS----------------------*/ +#popUpAcces{ + display: block; + width: 100vw; + height: 100vh; + position: fixed; + background: rgba(255, 255, 255, 0.8); + backdrop-filter: blur(3px); + left: 0; + top: 0; + z-index: 9999; +} +#popUpAccesModal{ + width: 50%; + background: white; + height: 45%; + border-radius: 10px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + position: fixed; + box-shadow: 0px 0px 7px 2px var(--bleu_koriolan); + overflow-y: auto; +} +#popUpAccesModal #top_part{ + display: grid; + grid-template-columns: auto 50px; +} +#popUpAccesModal #top_part p{ + margin: unset; + text-align: left; + margin-left: 30px; + margin-top: 20px; + margin-bottom: 20px; + color: var(--bleu_koriolan_fonce); + font-weight: 600; + font-size: 25px; +} +#popUpAccesModal #top_part p#close{ + background-image: url(images/croix_carre.png); + background-repeat: no-repeat; + background-size: contain; + cursor: pointer; + width: 30px; + height: 30px; + margin: 10px; +} +#popUpAccesModal form{ + display: grid; + grid-template-columns: 1fr 1fr; + padding: 20px; + column-gap: 30px; + row-gap: 50px; +} +#popUpAccesModal form label{ + position: relative; +} +#popUpAccesModal form label input, #popUpAccesModal form label select{ + width: 100%; +} +#popUpAccesModal form label span { + position: absolute; + top: 0; + left: 10px; + transform: translateY(-18px); + font-size: 18px; + transition-duration: 300ms; + padding-left: 10px; + padding-right: 10px; + color: var(--bleu_koriolan_fonce); + font-weight: 600; + background-color: white; +} +#popUpAccesModal form .buttons_acces{ + display: grid; +} + +/* --------------------- GESTION DES ACCÈS (synthèse §48) ----------------------*/ + +/* Formulaire d'invitation : 4 colonnes - adresse (2) / prénom / nom, puis type (2) / fin d'accès / bouton */ +.gestion_acces .generer_code { + margin: 20px 0px 30px 0px; + padding: 0px 20px 20px 20px; + border: 1px solid var(--bleu_koriolan_transparent); + border-radius: 10px; + background-color: var(--blanc); +} +.gestion_acces .generer_code h3 { + text-align: left; + margin-bottom: 15px; +} +.gestion_acces .generer_code form { + display: grid; + grid-template-columns: 2fr 2fr 1fr 1fr; + column-gap: 15px; + row-gap: 15px; + align-items: end; +} +.gestion_acces .generer_code form input[name="email_invite"] { + grid-column: span 2; +} +.gestion_acces .generer_code form select { + grid-column: span 2; +} +.gestion_acces .generer_code form input, +.gestion_acces .generer_code form select { + box-sizing: border-box; + width: 100%; + height: 42px; + padding: 0px 10px; +} +.gestion_acces .generer_code form .fin_acces { + display: flex; + flex-direction: column; + text-align: left; +} +.gestion_acces .generer_code form .fin_acces span { + font-size: 0.75em; + color: var(--gris_pale); + margin: 0px 0px 3px 5px; +} +.gestion_acces .generer_code form button { + height: 42px; + line-height: 1em; + padding: 0px 10px; +} + +/* Tableau des accès */ +.gestion_acces .users table th { + padding: 5px 10px; + white-space: nowrap; +} +.gestion_acces .users table td:nth-child(1), +.gestion_acces .users table th:nth-child(1) { + text-align: left; +} + +/* Pastilles de statut */ +.gestion_acces .statut { + display: inline-block; + padding: 2px 10px; + border-radius: 1em; + font-size: 0.85em; + white-space: nowrap; +} +.gestion_acces .statut_actif { + background-color: rgba(2, 166, 2, 0.12); + color: #027a02; +} +.gestion_acces .statut_suspendu { + background-color: var(--jaune_post_it_transparent); + color: #8a6d00; +} +.gestion_acces .statut_en_attente { + background-color: var(--bleu_koriolan_transparent); + color: var(--bleu_koriolan_fonce); +} +.gestion_acces .statut_expiree { + background-color: var(--gris_tres_tres_pale); + color: var(--gris_fonce); +} + +/* Actions de chaque ligne : boutons compacts ; "Révoquer" (définitif) en rouge, "Suspendre" en contour */ +.gestion_acces .actions_acces { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 6px; +} +.gestion_acces .actions_acces form { + display: flex; + gap: 6px; + flex-wrap: wrap; + justify-content: flex-end; +} +.gestion_acces .actions_acces button { + padding: 2px 12px; + line-height: 1.6em; + font-size: 0.85em; + border-radius: 0.8em; + white-space: nowrap; +} +.gestion_acces .actions_acces button.action_suspendre { + background-color: var(--blanc); + color: var(--bleu_koriolan_fonce); +} +.gestion_acces .actions_acces button.action_suspendre:hover { + background-color: var(--bleu_koriolan_transparent); +} +.gestion_acces .actions_acces button.action_revoquer { + background-color: var(--blanc); + border-color: var(--rouge); + color: var(--rouge); +} +.gestion_acces .actions_acces button.action_revoquer:hover { + background-color: var(--rouge); + color: var(--blanc); +} +.gestion_acces .actions_acces .modifier_acces { + display: inline-block; + width: 22px; + height: 22px; + flex: none; + background-image: url(images/stylo.png); + background-repeat: no-repeat; + background-size: contain; + background-position: center; + cursor: pointer; +} + +/* Confirmation de suppression d'un bateau : formulaire (bouton) aligné comme les liens de bas de page */ +#Bateaux #confirmation_suppression_bateau form.boutons_bas_de_page button { + line-height: 2em; +} + +/* ------------------ Autres ---------------- */ +#dateSlider{ + margin-bottom: 50px !important; + margin-top: 50px !important; +} + +#dateSlider .noUi-connect{ + background-color: var(--bleu_koriolan); +} +@media only screen and (max-width: 580px) { + #Bateaux .boutons_haut_de_page { + grid-template-columns: minmax(50px, auto); + } + form.variables { + display: flex; + margin-bottom: 50px; + flex-direction: column; + padding : 0; + } + .vars { + display: grid !important; + grid-template-columns: 1fr !important; + } + #popUpAccesModal{ + width: 95% !important; + height: 60% !important; + } + #popUpAccesModal form { + grid-template-columns: 1fr; + row-gap: 30px; + } +} + +@media only screen and (max-width: 850px) { + .top_part_graph { + flex-direction: column-reverse; + } + .vars { + display: grid !important; + grid-template-columns: 1fr 1fr; + } + .page_principale { + width: 96% !important; + } + .gestion_acces{ + flex-direction: column-reverse; + } + .gestion_acces .generer_code form { + grid-template-columns: 1fr 1fr; + } + .gestion_acces .actions_acces, + .gestion_acces .actions_acces form { + justify-content: flex-start; + } + form.variables { + + padding : 0; + } + #popUpAccesModal{ + width: 80%; + height: 40%; + } + #dateSlider{ + margin: auto; + width: 80%; + } +} + +/* Petits écrans : formulaire d'invitation sur une colonne. Placé EN FIN de fichier : le bloc "max-width: 850px" + ci-dessus s'applique aussi sous 580px et, venant après, l'emporterait sinon. */ +@media only screen and (max-width: 580px) { + .gestion_acces .generer_code form { + grid-template-columns: 1fr; + } + .gestion_acces .generer_code form input[name="email_invite"], + .gestion_acces .generer_code form select { + grid-column: auto; + } +} diff --git a/html/format_shipmembers.css b/html/format_shipmembers.css index 47f70c8..b953087 100644 --- a/html/format_shipmembers.css +++ b/html/format_shipmembers.css @@ -131,6 +131,69 @@ Fichier shipmembers.php text-align: justify; } +/* Mes invitations (synthèse §48) : une carte par invitation (texte, Accepter, Refuser), puis la saisie d'un code */ +#Shipmembers #accueil .invitations .aucune { + text-align: left; + font-style: italic; + color: var(--gris_pale); +} +#Shipmembers #accueil .invitations form.invitation { + display: grid; + grid-template-columns: 1fr auto auto; + column-gap: 10px; + align-items: center; + margin-bottom: 10px; + padding: 10px 15px; + border: 1px solid var(--bleu_koriolan); + border-radius: 10px; + background-color: var(--bleu_koriolan_transparent); +} +#Shipmembers #accueil .invitations form.invitation p { + margin: 0px; + text-align: left; +} +#Shipmembers #accueil .invitations button { + padding: 2px 16px; + line-height: 1.8em; + border-radius: 0.8em; + white-space: nowrap; +} +#Shipmembers #accueil .invitations button.refuser { + background-color: var(--blanc); + border-color: var(--rouge); + color: var(--rouge); +} +#Shipmembers #accueil .invitations button.refuser:hover { + background-color: var(--rouge); + color: var(--blanc); +} +#Shipmembers #accueil .invitations form.saisie_code { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 10px; + margin-top: 25px; +} +#Shipmembers #accueil .invitations form.saisie_code input { + width: 12em; + text-transform: uppercase; + letter-spacing: 0.15em; + text-align: center; +} +#Shipmembers #accueil .invitations form.saisie_code input::placeholder { + text-transform: none; + letter-spacing: normal; +} +@media only screen and (max-width: 580px) { + #Shipmembers #accueil .invitations form.invitation { + grid-template-columns: 1fr 1fr; + row-gap: 10px; + } + #Shipmembers #accueil .invitations form.invitation p { + grid-column: span 2; + } +} + /*--------------------------------------------------*/ #Shipmembers #profil form { diff --git a/html/shipmembers.php b/html/shipmembers.php index 36c933f..3c6a764 100644 --- a/html/shipmembers.php +++ b/html/shipmembers.php @@ -171,7 +171,7 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session // Création du ShipMember : - $requete = 'INSERT INTO TB_Shipmembers(Nom, Prenom, Entreprise, Rue, Code_postal, Ville, ID_PAYS, Telephone, Email, ID_LANGUAGES, Mdp, Date_creation_compte) VALUES (?,?,?,?,?,?,?,?,?,(SELECT ID FROM TB_Langues WHERE Prefix=?),?,?)'; + $requete = 'INSERT INTO TB_Shipmembers(Nom, Prenom, Entreprise, Rue, Code_postal, Ville, ID_PAYS, Telephone, Email, ID_LANGUAGES, Commentaires, Mdp, Date_creation_compte) VALUES (?,?,?,?,?,?,?,?,?,(SELECT ID FROM TB_Langues WHERE Prefix=?),?,?,?)'; Requete_preparee_bdd($requete, array( array('s', $_SESSION['shipmember']['Nom']), @@ -184,6 +184,7 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session array('s', $_SESSION['shipmember']['Telephone']), array('s', $_SESSION['shipmember']['Email']), array('s', $_SESSION['langue']), + array('s', ""), array('s', password_hash($password, PASSWORD_DEFAULT)), array('s', date("Y-m-d H:i:s"))), __FILE__, __LINE__); @@ -1256,7 +1257,7 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session // Mes invitations (synthèse §47) : echo '
'; echo '

'.t("Mes invitations").'

'; - if (count($invitations) == 0) echo '

'.t("Aucune invitation en attente.").'

'; + if (count($invitations) == 0) echo '

'.t("Aucune invitation en attente.").'

'; foreach ($invitations as $invitation) { $texte = t("Bateau [[Bateau]] - accès [[Type]], proposé par [[Invitant]] (valable jusqu'au [[Date]])."); @@ -1266,8 +1267,8 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session $texte = str_replace("[[Date]]", date_format(date_create($invitation['Expiration_invitation']), 'd/m/Y'), $texte); echo '
'; echo '

'.$texte.'

'; - echo ' '; - echo ''; + echo ' '; + echo ''; echo '
'; } // Saisie manuelle d'un code (invitation papier, sans appareil photo) :