Ajout d'une selection a la page home.php + Système de badge (non fini mais fonctionnel)

This commit is contained in:
Esteban
2026-06-12 19:13:40 +02:00
parent 3015c56583
commit 12bba69908
9 changed files with 258 additions and 14 deletions
+6
View File
@@ -52,3 +52,9 @@ CREATE TABLE IF NOT EXISTS experiences (
-- VALUES ('admin', 'admin', 'admin'); -- VALUES ('admin', 'admin', 'admin');
insert into `users` (`created_at`, `id`, `last_login`, `password`, `role`, `username`) insert into `users` (`created_at`, `id`, `last_login`, `password`, `role`, `username`)
values ('2026-06-08 11:10:21', 11, '2026-06-08 13:10:41', '$2y$12$x01fDqrHQEYIyj7MDHa72eRyl2j/n5cNq9sv3.FIiQCaRsB50Q4iK', 'admin', 'admin'); values ('2026-06-08 11:10:21', 11, '2026-06-08 13:10:41', '$2y$12$x01fDqrHQEYIyj7MDHa72eRyl2j/n5cNq9sv3.FIiQCaRsB50Q4iK', 'admin', 'admin');
-- Ajout d'une collonne status pour les projets et les expériences pour pouvoir différencier les projets/expériences en cours, terminés ou à venir
ALTER TABLE projects
ADD COLUMN status VARCHAR(100) NULL AFTER title;
ALTER TABLE experiences
ADD COLUMN status VARCHAR(100) NULL AFTER title;
+1 -1
View File
@@ -15,7 +15,7 @@
<a href="https://www.instagram.com/ours_one_" target="_blank" rel="noopener noreferrer">Instagram</a> <a href="https://www.instagram.com/ours_one_" target="_blank" rel="noopener noreferrer">Instagram</a>
<a href="https://git.eldorianet.work/esteban" target="_blank" rel="noopener noreferrer">Git</a> <a href="https://git.eldorianet.work/esteban" target="_blank" rel="noopener noreferrer">Git</a>
<span class="discord-handle" title="@ours1" onclick="alert('Discord : @ours1')">Discord</span> <span class="discord-handle" title="@ours1" onclick="alert('Discord : @ours1')">Discord</span>
<a href="../pages/cgu.php">Conditions générales / Utilisations</a> <a href="../pages/cgu.php">Conditions générales et d'utilisation</a>
</div> </div>
</div> </div>
</footer> </footer>
+9 -8
View File
@@ -10,12 +10,12 @@ session_start();
// Ajout des logs sur toutes les pages // Ajout des logs sur toutes les pages
require_once('../functions/sendLogs.php'); require_once('../functions/sendLogs.php');
// Ajout du CSS Primaire (fait par IA)
?> ?>
<!-- Ajout du CSS Primaire (fait par IA) -->
<link rel="stylesheet" href="../styles/primary_css.css"> <link rel="stylesheet" href="../styles/primary_css.css">
<!-- Ajout de Font Awesome pour les icones de home.php-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<!-- Header + nav --> <!-- Header + nav -->
<header> <header>
@@ -25,9 +25,9 @@ require_once('../functions/sendLogs.php');
<!-- Module de navigation --> <!-- Module de navigation -->
<nav> <nav>
<a href="./../index.php">Accueil</a> <a href="./../index.php">Accueil</a>
<a href="./projects.php">Projets</a> <a href="./../pages/projects.php">Projets</a>
<a href="./xp.php">Expériences</a> <a href="./../pages/xp.php">Expériences</a>
<a href="./contact.php">Contact</a> <a href="./../pages/contact.php">Contact</a>
<?php <?php
// Vérification que l'utilisateur est admin, s'il est admin, il aura accès au panel admin // Vérification que l'utilisateur est admin, s'il est admin, il aura accès au panel admin
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') { if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
@@ -35,7 +35,8 @@ require_once('../functions/sendLogs.php');
} else { } else {
?> ?>
<a href="./admin.php">Administration</a> <!-- Lien vers le panneau admin -->
<a href="./../pages/admin.php">Administration</a>
<?php <?php
} }
@@ -50,7 +51,7 @@ require_once('../functions/sendLogs.php');
<?php <?php
} else { } else {
?> ?>
<a href="./login.php">Connexion</a> <a href="./../pages/login.php">Connexion</a>
<?php <?php
} }
?> ?>
+14 -2
View File
@@ -11,7 +11,7 @@ function listeProjets() {
// Essayer // Essayer
try { try {
// Requête SQL qui récupère titre, tags, description, image_url // Requête SQL qui récupère titre, tags, description, image_url
$stmt = $dbh->prepare('SELECT id, title, tags, description, image_url FROM projects ORDER BY id DESC'); $stmt = $dbh->prepare('SELECT id, title, status, tags, description, image_url FROM projects ORDER BY id DESC');
// Execution de la requête SQL // Execution de la requête SQL
$stmt->execute(); $stmt->execute();
// Retourne toutes les données collectés dans un ARRAY // Retourne toutes les données collectés dans un ARRAY
@@ -27,7 +27,7 @@ function recupererProjetParId($id) {
global $dbh; global $dbh;
try { try {
$stmt = $dbh->prepare('SELECT id, title, tags, description, image_url FROM projects WHERE id = :id'); $stmt = $dbh->prepare('SELECT id, title, status, tags, description, image_url FROM projects WHERE id = :id');
$stmt->bindValue(':id', $id, PDO::PARAM_INT); $stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute(); $stmt->execute();
return $stmt->fetch(PDO::FETCH_ASSOC); return $stmt->fetch(PDO::FETCH_ASSOC);
@@ -53,6 +53,7 @@ function afficherProjets() {
$titre = htmlspecialchars($projet['title']); $titre = htmlspecialchars($projet['title']);
$description = nl2br(htmlspecialchars($projet['description'])); $description = nl2br(htmlspecialchars($projet['description']));
$image = htmlspecialchars($projet['image_url']); $image = htmlspecialchars($projet['image_url']);
$status = htmlspecialchars($projet['status'] ?? '');
$tags = []; $tags = [];
// S'il y a des tags alors on les sépares grâce à la virgule que l'user à ajouté dans le champs (tags1,tags2,etcc...) // S'il y a des tags alors on les sépares grâce à la virgule que l'user à ajouté dans le champs (tags1,tags2,etcc...)
@@ -66,6 +67,11 @@ function afficherProjets() {
if (!empty($image)) { if (!empty($image)) {
echo '<div class="project-banner">'; echo '<div class="project-banner">';
echo '<img src="' . $image . '" alt="Image du projet ' . $titre . '">'; echo '<img src="' . $image . '" alt="Image du projet ' . $titre . '">';
if (!empty($status)) {
echo '<div class="project-state">' . $status . '</div>';
}
echo '</div>'; echo '</div>';
} }
@@ -103,6 +109,7 @@ function afficherProjetsAdmin() {
$titre = htmlspecialchars($projet['title']); $titre = htmlspecialchars($projet['title']);
$description = nl2br(htmlspecialchars($projet['description'])); $description = nl2br(htmlspecialchars($projet['description']));
$image = htmlspecialchars($projet['image_url']); $image = htmlspecialchars($projet['image_url']);
$status = htmlspecialchars($projet['status'] ?? '');
$tags = []; $tags = [];
if (!empty($projet['tags'])) { if (!empty($projet['tags'])) {
@@ -114,6 +121,11 @@ function afficherProjetsAdmin() {
if (!empty($image)) { if (!empty($image)) {
echo '<div class="project-banner">'; echo '<div class="project-banner">';
echo '<img src="' . $image . '" alt="Image du projet ' . $titre . '">'; echo '<img src="' . $image . '" alt="Image du projet ' . $titre . '">';
if (!empty($status)) {
echo '<div class="project-state">' . $status . '</div>';
}
echo '</div>'; echo '</div>';
} }
+22 -2
View File
@@ -14,7 +14,7 @@ function listeXP() {
// Essayer // Essayer
try { try {
// Requête SQL qui récupère titre, type, tags, description, durée, image_url // Requête SQL qui récupère titre, type, tags, description, durée, image_url
$stmt = $dbh->prepare('SELECT id, title, xptype, tags, description, duration, image_url FROM experiences ORDER BY id DESC'); $stmt = $dbh->prepare('SELECT id, title, status, xptype, tags, description, duration, image_url FROM experiences ORDER BY id DESC');
// Execution de la requête SQL // Execution de la requête SQL
$stmt->execute(); $stmt->execute();
// Retourne toutes les données collectés dans un ARRAY // Retourne toutes les données collectés dans un ARRAY
@@ -31,7 +31,8 @@ function recupererXPParId($id) {
try { try {
// Préparation de la requête préparée // Préparation de la requête préparée
$stmt = $dbh->prepare('SELECT id, title, xptype, tags, description, duration, image_url FROM experiences WHERE id = :id'); $stmt = $dbh->prepare('SELECT id, title, status, xptype, tags, description, duration, image_url FROM experiences WHERE id = :id');
$stmt->bindValue(':id', $id, PDO::PARAM_INT); $stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute(); $stmt->execute();
return $stmt->fetch(PDO::FETCH_ASSOC); return $stmt->fetch(PDO::FETCH_ASSOC);
@@ -62,6 +63,7 @@ function afficherXP() {
$description = nl2br(htmlspecialchars($experience['description'])); $description = nl2br(htmlspecialchars($experience['description']));
$duration = htmlspecialchars($experience['duration']); $duration = htmlspecialchars($experience['duration']);
$image = htmlspecialchars($experience['image_url']); $image = htmlspecialchars($experience['image_url']);
$status = htmlspecialchars($experience['status'] ?? '');
$tags = []; $tags = [];
@@ -78,6 +80,11 @@ function afficherXP() {
if (!empty($image)) { if (!empty($image)) {
echo '<div class="project-banner">'; echo '<div class="project-banner">';
echo '<img src="' . $image . '" alt="Image de l experience ' . $titre . '">'; echo '<img src="' . $image . '" alt="Image de l experience ' . $titre . '">';
if (!empty($status)) {
echo '<div class="project-state">' . $status . '</div>';
}
echo '</div>'; echo '</div>';
} }
@@ -85,6 +92,7 @@ function afficherXP() {
// Ajout de la class project-content et du titre // Ajout de la class project-content et du titre
echo '<div class="project-content">'; echo '<div class="project-content">';
echo '<h2>' . $titre . '</h2>'; echo '<h2>' . $titre . '</h2>';
echo '<p><strong>Type :</strong> ' . $xptype . '</p>'; echo '<p><strong>Type :</strong> ' . $xptype . '</p>';
echo '<p><strong>Durée :</strong> ' . $duration . '</p>'; echo '<p><strong>Durée :</strong> ' . $duration . '</p>';
@@ -123,6 +131,7 @@ function afficherXPAdmin() {
$xptype = htmlspecialchars($experience['xptype']); $xptype = htmlspecialchars($experience['xptype']);
$description = nl2br(htmlspecialchars($experience['description'])); $description = nl2br(htmlspecialchars($experience['description']));
$duration = htmlspecialchars($experience['duration']); $duration = htmlspecialchars($experience['duration']);
$status = htmlspecialchars($experience['status'] ?? '');
$image = htmlspecialchars($experience['image_url']); $image = htmlspecialchars($experience['image_url']);
$tags = []; $tags = [];
@@ -135,11 +144,22 @@ function afficherXPAdmin() {
if (!empty($image)) { if (!empty($image)) {
echo '<div class="project-banner">'; echo '<div class="project-banner">';
echo '<img src="' . $image . '" alt="Image de l experience ' . $titre . '">'; echo '<img src="' . $image . '" alt="Image de l experience ' . $titre . '">';
if (!empty($status)) {
echo '<div class="project-state">' . $status . '</div>';
}
echo '</div>'; echo '</div>';
} }
echo '<div class="project-content">'; echo '<div class="project-content">';
echo '<h2>' . $titre . '</h2>'; echo '<h2>' . $titre . '</h2>';
// Si le status n'est pas vide alors on l'affiche
if (!empty($status)) {
echo '<div class="project-state">' . $status . '</div>';
}
echo '<p><strong>Type :</strong> ' . $xptype . '</p>'; echo '<p><strong>Type :</strong> ' . $xptype . '</p>';
echo '<p><strong>Durée :</strong> ' . $duration . '</p>'; echo '<p><strong>Durée :</strong> ' . $duration . '</p>';
+4 -1
View File
@@ -3,7 +3,10 @@
// 2026 - Projet Hébergé par l'entreprise TerraTech Hebergement en collaboration avec l'association Eldoria Network // 2026 - Projet Hébergé par l'entreprise TerraTech Hebergement en collaboration avec l'association Eldoria Network
// Le CSS est **probablement** généré par intelligence artificielle ou récupéré d'autre projet, cependant le code PHP / HTML / JS est globalement fait par un humain // Le CSS est **probablement** généré par intelligence artificielle ou récupéré d'autre projet, cependant le code PHP / HTML / JS est globalement fait par un humain
// Note : Pour lancer un serveur local PHP Depuis VsCode : 'php -v' pour vérifier que php est bien installé et 'php -S localhost:8000' pour lancer le serveur // Note 1 : Pour lancer un serveur local PHP Depuis VsCode : 'php -v' pour vérifier que php est bien installé et 'php -S localhost:8000' pour lancer le serveur
// Note 2 : Je m'aide désormais de l'autocompletion de vsCode pour accélerer le développement avec Copilot (GitHub) mais le reste du code est entièrement développé par moi même mais copilot
// reste utile pour la génération de commentaires, de code répétitif ou de code basique (exemple : les formulaires de contact, les requêtes SQL basiques etc...)
// Le header n'y étant pas je rajoute ici un démarrage de session // Le header n'y étant pas je rajoute ici un démarrage de session
session_start(); session_start();
+52
View File
@@ -10,6 +10,58 @@ require_once('./../elements/header.php');
//Si du CSS / ou des images s'affichent mal, il faut penser à vider le cache, version de développement uniquement. //Si du CSS / ou des images s'affichent mal, il faut penser à vider le cache, version de développement uniquement.
?>
<!-- Message d'alerte pour les utilisateurs de la démo -->
<div class="alert-message">
<p>Si le CSS ou les images s'affichent mal, pensez à vider
le cache de votre navigateur (Ctrl + F5 ou Cmd + Shift + R) pour voir les dernières modifications. Version de développement uniquement.</p>
</div>
<!-- Section d'exploration rapide -->
<section class="quick-links-section">
<div class="quick-links-header">
<!-- Titre et description de la section -->
<h2>Explorer</h2>
<p>Accède rapidement aux sections principales du portfolio.</p>
</div>
<!-- Grille de cartes de redirection vers les différentes page -->
<div class="quick-links-grid">
<a href="../pages/projects.php" class="quick-link-card">
<div class="quick-link-icon">
<i class="fa-solid fa-folder-open"></i>
</div>
<h3>Projets</h3>
<p>Voir mes réalisations.</p>
</a>
<a href="../pages/xp.php" class="quick-link-card">
<div class="quick-link-icon">
<i class="fa-solid fa-briefcase"></i>
</div>
<h3>Expériences</h3>
<p>Découvrir mes stages et missions réalisées.</p>
</a>
<a href="../pages/skills.php" class="quick-link-card">
<div class="quick-link-icon">
<i class="fa-solid fa-code"></i>
</div>
<h3>Compétences</h3>
<!-- Page où il y aura toutes mes compétences -->
<p>PAS ENCORE DEV</p>
</a>
<a href="../pages/contact.php" class="quick-link-card">
<div class="quick-link-icon">
<i class="fa-solid fa-paper-plane"></i>
</div>
<h3>Contact</h3>
<p>Me contacter rapidement pour échanger.</p>
</a>
</div>
</section>
<?php
// Ajout du footer // Ajout du footer
require_once('../elements/footer.php'); require_once('../elements/footer.php');
?> ?>
+9
View File
@@ -0,0 +1,9 @@
<?php
// Compétences
// On ajoute ici le header
require_once('./../elements/header.php');
// Ajout du footer
require_once('../elements/footer.php'); ?>
+141
View File
@@ -134,6 +134,23 @@ nav a:hover {
max-width: 100%; max-width: 100%;
} }
.project-state {
position: absolute;
top: 14px;
left: 14px;
z-index: 2;
display: inline-flex;
align-items: center;
padding: 8px 16px;
background-color: rgba(39, 255, 83, 0.10);
color: #7dff98;
border: 2px solid #39ff5a;
border-radius: 16px;
font-size: 13px;
font-weight: bold;
line-height: 1;
}
.project-header h2 { .project-header h2 {
margin-top: 0; margin-top: 0;
margin-bottom: 20px; margin-bottom: 20px;
@@ -170,6 +187,11 @@ nav a:hover {
font-size: 14px; font-size: 14px;
} }
.project-banner {
position: relative;
overflow: hidden;
}
.project-form-card input[type="text"], .project-form-card input[type="text"],
.project-form-card input[type="url"], .project-form-card input[type="url"],
.project-form-card input[type="password"], .project-form-card input[type="password"],
@@ -547,3 +569,122 @@ main {
min-width: 0; min-width: 0;
} }
} }
/* ---- PAGE HOME ---- */
.quick-links-section {
max-width: 1200px;
margin: 70px auto;
padding: 0 40px;
}
.quick-links-header {
margin-bottom: 28px;
}
.quick-links-header h2 {
margin: 0 0 10px;
font-size: 42px;
font-weight: 800;
color: white;
}
.quick-links-header p {
margin: 0;
color: #aaaaaa;
font-size: 18px;
}
.quick-links-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 24px;
}
.quick-link-card {
display: flex;
flex-direction: column;
justify-content: flex-start;
min-height: 230px;
padding: 30px;
background: linear-gradient(180deg, #111116 0%, #0f1420 100%);
border: 1px solid #2a2a3e;
border-radius: 20px;
text-decoration: none;
color: white;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}
.quick-link-card:hover {
transform: translateY(-6px);
border-color: #6c63ff;
box-shadow: 0 18px 40px rgba(108, 99, 255, 0.18);
}
.quick-link-icon {
width: 62px;
height: 62px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 26px;
border-radius: 16px;
background: rgba(108, 99, 255, 0.14);
border: 1px solid rgba(108, 99, 255, 0.28);
color: #8f88ff;
font-size: 26px;
}
.quick-link-card h3 {
margin: 0 0 14px;
font-size: 30px;
font-weight: 800;
color: white;
}
.quick-link-card p {
margin: 0;
color: #aaaaaa;
font-size: 18px;
line-height: 1.7;
}
/* Responsive */
@media (max-width: 1100px) {
.quick-links-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 700px) {
.quick-links-section {
padding: 0 20px;
margin: 50px auto;
}
.quick-links-header h2 {
font-size: 32px;
}
.quick-links-header p {
font-size: 16px;
}
.quick-links-grid {
grid-template-columns: 1fr;
}
.quick-link-card {
min-height: auto;
padding: 24px;
}
.quick-link-card h3 {
font-size: 24px;
}
.quick-link-card p {
font-size: 16px;
}
}