diff --git a/database/scriptDatabase.sql b/database/scriptDatabase.sql index 66b7e79..bc87f45 100644 --- a/database/scriptDatabase.sql +++ b/database/scriptDatabase.sql @@ -123,6 +123,30 @@ ALTER TABLE schools ADD COLUMN markdown LONGTEXT NULL, ADD COLUMN link_url VARCHAR(255) NULL; +-- ============================================================ +-- Juillet 2026 (4) : bandeaux de logos sur la page d'accueil +-- ("Outils que je sais manipuler" et "Ils m'ont fait confiance"), +-- gérés depuis le panel Admin +-- ============================================================ + +-- Une seule table pour les deux bandeaux, distingués par la colonne category : +-- - 'tool' => bandeau "Outils que je sais manipuler" +-- - 'partner' => bandeau "Ils m'ont fait confiance" +-- link_url est facultatif : si renseigné, le logo devient cliquable (nouvel onglet) +CREATE TABLE IF NOT EXISTS logo_banners ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + category ENUM('tool', 'partner') NOT NULL, + name VARCHAR(100) NOT NULL, + logo_url VARCHAR(255) NOT NULL, + link_url VARCHAR(255) NULL, + position INT NOT NULL DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id) +); + +-- Table créée vide volontairement : les logos sont ajoutés depuis le panel Admin +-- (section Logos) pour éviter d'afficher des images devinées/potentiellement cassées + -- ============================================================ -- Juillet 2026 (3) : PDF en drag & drop pour les projets, -- expériences et écoles, lu depuis un mini lecteur intégré diff --git a/docker/php-uploads.ini b/docker/php-uploads.ini deleted file mode 100644 index 3f4a5e9..0000000 --- a/docker/php-uploads.ini +++ /dev/null @@ -1,14 +0,0 @@ -; Config PHP pour le conteneur Docker (image php:8.2-apache) -; Copiée dans /usr/local/etc/php/conf.d/ par le Dockerfile généré par scriptsite.sh - -; Augmente les limites d'upload pour permettre le dépôt de PDF depuis le panel admin -; post_max_size doit toujours être >= upload_max_filesize -upload_max_filesize = 20M -post_max_size = 20M - -; Coupe l'affichage des erreurs PHP dans le HTML en production (sécurité : ne pas exposer -; les chemins serveur aux visiteurs) et les envoie dans les logs Apache/Docker à la place. -; Bonus : évite les warnings HTML qui provoquaient "headers already sent" une fois affichés -; avant le session_start()/header() des scripts. -display_errors = Off -log_errors = On diff --git a/elements/footer.php b/elements/footer.php index 8e6636f..9c1e99d 100644 --- a/elements/footer.php +++ b/elements/footer.php @@ -51,8 +51,8 @@ if (isset($_GET['success']) && $_GET['success'] === '1') { // Éléments qui apparaissent en glissant vers le haut quand ils entrent dans l'écran var cibles = document.querySelectorAll( '.project-card, .quick-link-card, .skill-category, .contact-card, ' + - '.login-card, .project-form-card, .cgu-card, ' + - '.page-header, .quick-links-header, .skills-header, .projects-title' + '.login-card, .project-form-card, .cgu-card, .logo-admin-item, ' + + '.page-header, .quick-links-header, .skills-header, .projects-title, .logo-banner-header' ); var observer = new IntersectionObserver(function (entries) { diff --git a/functions/listLogos.php b/functions/listLogos.php new file mode 100644 index 0000000..dcb763f --- /dev/null +++ b/functions/listLogos.php @@ -0,0 +1,111 @@ +prepare('SELECT id, category, name, logo_url, link_url, position FROM logo_banners WHERE category = :category ORDER BY position ASC, id ASC'); + $stmt->bindValue(':category', $category, PDO::PARAM_STR); + } else { + $stmt = $dbh->prepare('SELECT id, category, name, logo_url, link_url, position FROM logo_banners ORDER BY category ASC, position ASC, id ASC'); + } + $stmt->execute(); + return $stmt->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + return []; + } +} + +// Fonction qui permet de récupérer un logo par id (pour la modification dans le panel Admin) +function recupererLogoParId($id) { + global $dbh; + + try { + $stmt = $dbh->prepare('SELECT id, category, name, logo_url, link_url, position FROM logo_banners WHERE id = :id'); + $stmt->bindValue(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetch(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + return false; + } +} + +// Fonction qui affiche le bandeau défilant d'une catégorie de logos sur la page publique +// N'affiche rien si la catégorie est vide (la section entière est masquée côté page d'accueil) +function afficherLogos($category) { + $logos = listeLogos($category); + + if (empty($logos)) { + return; + } + + $sens = $category === 'partner' ? ' logo-marquee-reverse' : ''; + + echo '
'; + echo '
'; + + // On répète deux fois la liste : le défilement CSS boucle sur -50%, ce qui donne + // un effet de scroll infini fluide et sans coupure (voir styles/primary_css.css) + for ($repetition = 0; $repetition < 2; $repetition++) { + foreach ($logos as $logo) { + $nom = htmlspecialchars($logo['name']); + $image = htmlspecialchars($logo['logo_url']); + $lien = trim($logo['link_url'] ?? ''); + + if ($lien !== '') { + echo ''; + } else { + echo ''; + } + } + + echo '
'; + echo '
'; +} + +// Fonction qui affiche la liste des logos (toutes catégories) avec boutons de +// modification / suppression, pour le panel admin +function afficherLogosAdmin() { + $logos = listeLogos(); + + if (empty($logos)) { + echo '

Aucun logo pour le moment.

'; + return; + } + + echo '
'; + + foreach ($logos as $logo) { + $id = (int) $logo['id']; + $nom = htmlspecialchars($logo['name']); + $image = htmlspecialchars($logo['logo_url']); + $badge = $logo['category'] === 'partner' ? 'Entreprise' : 'Outil'; + + echo '
'; + echo '
' . $nom . '
'; + echo '
'; + echo '' . $badge . ''; + echo '

' . $nom . '

'; + echo '
'; + echo '
'; + echo 'Modifier'; + echo 'Supprimer'; + echo '
'; + echo '
'; + } + + echo '
'; +} diff --git a/pages/admin.php b/pages/admin.php index 2ac2b32..ffa7c85 100644 --- a/pages/admin.php +++ b/pages/admin.php @@ -13,6 +13,7 @@ require_once('../functions/listXP.php'); require_once('../functions/listSchool.php'); require_once('../functions/listSkills.php'); require_once('../functions/listSettings.php'); +require_once('../functions/listLogos.php'); // L'utilisateur doit être administrateur @@ -26,6 +27,7 @@ $projetAModifier = null; $xpAModifier = null; $ecoleAModifier = null; $skillAModifier = null; +$logoAModifier = null; // Si on modifie XP, Projets, École ou Compétence @@ -41,6 +43,9 @@ if (isset($_GET['edit_school']) && is_numeric($_GET['edit_school'])) { if (isset($_GET['edit_skill']) && is_numeric($_GET['edit_skill'])) { $skillAModifier = recupererSkillParId((int) $_GET['edit_skill']); } +if (isset($_GET['edit_logo']) && is_numeric($_GET['edit_logo'])) { + $logoAModifier = recupererLogoParId((int) $_GET['edit_logo']); +} // Valeurs actuelles de la notification de la page d'accueil $noticeTitle = recupererSetting('site_notice_title') ?? ''; @@ -55,7 +60,7 @@ $noticeEnabled = recupererSetting('site_notice_enabled') ?? '1'; @@ -64,6 +69,7 @@ $noticeEnabled = recupererSetting('site_notice_enabled') ?? '1'; Expériences Écoles Compétences + Logos Notification Utilisateurs Données @@ -311,6 +317,49 @@ $noticeEnabled = recupererSetting('site_notice_enabled') ?? '1'; + +
+

Logos (page d'accueil)

+ +
> + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+

Notification de la page d'accueil

diff --git a/pages/contact.php b/pages/contact.php index d11081b..755f949 100644 --- a/pages/contact.php +++ b/pages/contact.php @@ -13,7 +13,7 @@ require_once("../elements/header.php");

Contact

-

Moussu Esteban

+

Esteban MOUSSU

esteban.moussu@ik.me

20 Grande rue

52500 Broncourt

diff --git a/pages/home.php b/pages/home.php index 06d15b6..e369d95 100644 --- a/pages/home.php +++ b/pages/home.php @@ -12,6 +12,10 @@ require_once('./../elements/header.php'); // La notification est maintenant dynamique : modifiable depuis le panel Admin (table settings) require_once('../functions/listSettings.php'); +// Bandeaux de logos ("Outils que je sais manipuler" / "Ils m'ont fait confiance"), +// gérés depuis le panel Admin (table logo_banners) +require_once('../functions/listLogos.php'); + // Affichage de la notification (si elle est activée dans le panel Admin) afficherNotice(); ?> @@ -35,6 +39,16 @@ afficherNotice();
+ + +
+
+

Outils que je sais manipuler

+
+ +
+ + + + +
+
+

Ils m'ont fait confiance

+
+ +
+ + prepare('INSERT INTO logo_banners (category, name, logo_url, link_url, position) VALUES (:category, :name, :logo_url, :link_url, :position)'); + + // On execute la requete préparée + $stmt->execute([ + ':category' => $category, + ':name' => $name, + ':logo_url' => $logo_url, + ':link_url' => $link_url, + ':position' => $position + ]); + + // Log Discord + sendLog("Ajout d'un logo (" . $category . ") : " . $name); + + // Redirection vers home.php dès que la requete est executée + header('Location: ../pages/home.php'); + exit; + + } catch (PDOException $e) { + // En cas d'erreur : + echo "Erreur pendant l'ajout du logo: " . $e->getMessage(); + exit; + } + } else { + echo "Veuillez remplir tous les champs obligatoires."; + exit; + } +} else { + // Si on y accède de façon peu légitime sans requête POST on refuse + header('Location: ../pages/home.php'); + exit; +} +?> diff --git a/scripts/removeLogo.php b/scripts/removeLogo.php new file mode 100644 index 0000000..8dbad20 --- /dev/null +++ b/scripts/removeLogo.php @@ -0,0 +1,37 @@ +prepare('DELETE FROM logo_banners WHERE id = :id'); + $stmt->bindValue(':id', $id, PDO::PARAM_INT); + $stmt->execute(); // Sinon on renvoie l'erreur +} catch (PDOException $e) { + die("Erreur lors de la suppression du logo :" . $e->getMessage()); +} + +// Log Discord +sendLog("Suppression du logo id " . $id); + +// On renvoie l'utilisateur sur admin.php, directement sur la section Logos +header('Location: ../pages/admin.php#admin-logos'); +exit; diff --git a/scripts/updateLogo.php b/scripts/updateLogo.php new file mode 100644 index 0000000..4a43d94 --- /dev/null +++ b/scripts/updateLogo.php @@ -0,0 +1,54 @@ +prepare(' + UPDATE logo_banners + SET category = :category, name = :name, logo_url = :logo_url, link_url = :link_url, position = :position + WHERE id = :id + '); + $stmt->bindValue(':category', $category, PDO::PARAM_STR); + $stmt->bindValue(':name', $name, PDO::PARAM_STR); + $stmt->bindValue(':logo_url', $logourl, PDO::PARAM_STR); + $stmt->bindValue(':link_url', $linkurl, PDO::PARAM_STR); + $stmt->bindValue(':position', $position, PDO::PARAM_INT); + $stmt->bindValue(':id', $id, PDO::PARAM_INT); + $stmt->execute(); // Sinon on renvoie l'erreur +} catch (PDOException $e) { + die("Erreur lors de la modification du logo :" . $e->getMessage()); +} + +// Log Discord +sendLog("Modification du logo : " . $name . " (id " . $id . ")"); + +// On renvoie l'utilisateur sur admin.php, directement sur la section Logos +header('Location: ../pages/admin.php#admin-logos'); +exit;