backup du projet

This commit is contained in:
Yasder5
2026-02-26 00:19:11 +01:00
commit 4655c05be6
670 changed files with 87655 additions and 0 deletions

0
views/.gitkeep Normal file
View File

34
views/_partial/footer.tpl Normal file
View File

@@ -0,0 +1,34 @@
<footer class="footer container-fluid d-flex justify-content-around mt-auto">
<div class="col-3">
<ul>
<li><a href="#">Découvrir</a>
<li><a href="#">Customisation</a>
<li><a href="#">Emploi</a>
<li><a href="?ctrl=project&action=about">A propos</a>
</ul>
</div>
<div class="col-3">
<ul>
<li><a href="#">Recruter</a>
<li><a href="#">Partenariat</a>
<li><a href="#">Blog</a>
<li><a href="index.php?ctrl=page&action=help">Aide et support</a>
</ul>
</div>
<div class="col-3">
<ul>
<li><a href="#">Politique de confidentialité</a>
<li><a href="?ctrl=project&action=mentions">Mentions légales</a>
<li><a href="#">CGU</a>
<li><a href="#">CGV</a>
</ul>
</div>
<div class="col-3">
<p>Suivez-nous</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="js/scripts.js"></script>
</body>
</html>

87
views/_partial/header.tpl Normal file
View File

@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="assests/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script>
<title>Folliow{block name="title"}{/block}</title>
</head>
<body class="d-flex flex-column min-vh-100">
<nav class="navbar navbar-expand-lg navbar-light">
<div class="container-fluid">
{* Logo *}
<a class="navbar-brand d-flex align-items-center" href="index.php">
<img src="assests/img/logo.png" alt="Logo" class="logo-image">
</a>
{* Toggler pour mobile *}
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
{* Menu de navigation *}
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="?ctrl=project&action=about">À propos</a>
</li>
<li class="nav-item">
<a class="nav-link" href="?ctrl=project&action=search">Rechercher</a>
</li>
{if isset($smarty.session.user)}
<li class="nav-item">
<a class="nav-link" href="?ctrl=project&action=addedit_project">Ajouter un projet</a>
</li>
{if $smarty.session.user.authorisation_name == "Administrateur"}
<li class="nav-item">
<a class="nav-link" href="?ctrl=admin&action=admin">Admin</a>
</li>
{/if}
{/if}
</ul>
{* Menu secondaire *}
<nav class="col-4 d-flex justify-content-end align-items-center" aria-label="Connexion utilisateur">
{if !isset($smarty.session.user)}
{* Utilisateur non connecté *}
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="index.php?ctrl=user&action=signup" title="Créer un compte" aria-label="Créer un compte">
S'inscrire
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="index.php?ctrl=user&action=login" title="Se connecter" aria-label="Se connecter">
Se connecter
</a>
</li>
</ul>
{else}
{* Utilisateur connecté *}
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="index.php?ctrl=user&action=user&pseudo={$smarty.session.user.user_pseudo}" title="Modifier mon compte" aria-label="Modifier mon compte">
<img src="{$smarty.env.IMG_USER_PATH}{$smarty.session.user.user_image ?? "images.jpg"}"
class="rounded-circle flex-shrink-0 mt-2 ml-5"
style="width: 36px; height: 36px; object-fit: cover;"
alt="Photo de profil">
</a>
</li>
<li>
<a class="nav-link" href="index.php?ctrl=user&action=logout" title="Se déconnecter" aria-label="Se déconnecter">
Se déconnecter
</a>
</li>
</ul>
{/if}
</nav>
</div>
</div>
</nav>
{include file="views/_partial/messages.tpl"}

View File

@@ -0,0 +1,14 @@
{if ($success_message != '')}
<div class="alert alert-success">
<p>{$success_message}</p>
</div>
{/if}
{if (isset($arrError) && count($arrError) > 0) }
<div class="alert alert-danger">
{foreach $arrError as $strError}
<p>{$strError}</p>
{/foreach}
</div>
{/if}

View File

@@ -0,0 +1,87 @@
<article class="col-md-3 mb-5 {if isset($smarty.session.user) and $smarty.session.user.user_status == 2} pb-5 {/if}" style="border-radius: 100px ;">
<div class="card h-100 shadow article-card rounded-4" style="border-width: 2px; overflow: hidden;">
{* IMAGE (partie supérieure - plus grande) *}
<div class="ratio ratio-4x3">
<a href="index.php?ctrl=project&action=display&id={$objProject->getId()}"></a>
<img src="{$smarty.env.IMG_PROJECT_PATH}{$objProject->getThumbnail()}"
class="w-100 h-100 object-fit-cover"
alt=""
loading="lazy">
</a>
</div>
{* CONTENU (photo profil + infos) *}
<div class="card-body p-3 bg-light">
<div class="d-flex align-items-start gap-3">
{* PHOTO DE PROFIL (cercle à gauche - plus grand) *}
<a href="index.php?ctrl=user&action=user&id={$objProject->getUser_id()}">
<img src="{$smarty.env.IMG_USER_PATH}{$objProject->getUser_image() ?? "images.jpg"}"
class="rounded-circle flex-shrink-0 border border-2 border-white"
style="width: 64px; height: 64px; object-fit: cover; margin-top: 8px;"
alt="Photo de profil">
</a>
{* INFOS À DROITE *}
<div class="flex-grow-1">
<h3 class="h6 fw-bold mb-2 mt-1">{$objProject->getTitle()}</h3>
<p class="small text-muted mb-1">
<i class="bi bi-person"></i>
<a href="index.php?ctrl=user&action=user&pseudo={$objProject->getCreatorname()}"
class="text-decoration-none text-muted"
style="position: relative; z-index: 2;">
{$objProject->getCreatorname()}
</a>
</p>
<p class="small text-muted mb-0">
<i class="bi bi-geo-alt"></i> Colmar
</p>
</div>
</div>
<div class="d-flex justify-content-between align-items-center mt-3">
<small class="text-muted">
<i class="bi bi-clock"></i> <time>{$objProject->getCreation_date()}</time>
</small>
{if $objProject->getStatus() != "refusé"}
<a href="index.php?ctrl=project&action=display&id={$objProject->getId()}"
class="btn btn-sm btn-primary">
Voir →
</a>
{/if}
</div>
{if isset($smarty.session.user)}
{if $smarty.session.user.user_id == $objProject->getUser_id()}
<a href="index.php?ctrl=project&action=addedit_project&id={$objProject->getId()}"
class="btn btn-sm btn-outline-secondary mt-2 w-100"
style="position: relative; z-index: 2;">
Editer
</a>
{/if}
{/if}
</div>
{* BOUTONS EN BAS *}
{if isset($smarty.session.user)
and $smarty.session.user.user_status == 2
and $objProject->getStatus() == "en_attente"}
<div class="card-footer bg-white border-top-0 p-2">
<div class="d-flex gap-2">
<a class="btn btn-sm btn-success flex-fill"
href="?ctrl=project&action=accept&id={$objProject->getId()}"
name="toPublished">Accepter</a>
<a class="btn btn-sm btn-warning flex-fill"
href="?ctrl=project&action=refuse&id={$objProject->getId()}"
name="toRefused">Refuser</a>
<a class="btn btn-sm btn-danger flex-fill"
href="?ctrl=project&action=delete&id={$objProject->getId()}"
name="toDelete" onclick="return confirm('Attention ! Êtes-vous sûr de vouloir supprimer ce projet ? Cette action est irréversible.');">Supprimer</a>
</div>
</div>
{elseif $objProject->getStatus() == "refusé"}
<div class="card-footer bg-white border-top-0 p-2">
<p class="text-danger fw-bold text-center mb-0 small">Projet refusé</p>
</div>
{/if}
</div>
</article>

160
views/about.tpl Normal file
View File

@@ -0,0 +1,160 @@
{extends file="views/layout.tpl"}
{block name="title" append} - À propos{/block}
{block name="h2"}À propos de FOLLIOW{/block}
{block name="p"}Plateforme de partage de projets Projet pédagogique{/block}
{block name="content"}
<section aria-label="À propos de FOLLIOW">
<div class="row g-5">
<!-- Présentation principale -->
<div class="col-lg-8">
<section aria-labelledby="presentation">
<h3 id="presentation" class="h4 mb-3">
<i class="fas fa-lightbulb me-2 text-primary"></i>
Présentation du projet
</h3>
<p>
<strong>FOLLIOW</strong> est une plateforme web développée dans le cadre dun projet pédagogique.
Elle permet aux utilisateurs de publier, consulter et partager des projets numériques
à travers une interface simple et structurée.
</p>
<p>
Ce projet a été conçu afin de mettre en pratique les compétences acquises en
développement web, notamment larchitecture MVC, la gestion des bases de données
et la sécurisation des échanges.
</p>
</section>
<section aria-labelledby="fonctionnalites" class="mt-4">
<h3 id="fonctionnalites" class="h4 mb-3">
<i class="fas fa-cogs me-2 text-primary"></i>
Fonctionnalités principales
</h3>
<ul>
<li>Création et gestion de projets</li>
<li>Affichage dynamique des contenus</li>
<li>Gestion des utilisateurs</li>
<li>Partage dun projet par email</li>
<li>Interface responsive et accessible</li>
</ul>
</section>
<section aria-labelledby="objectifs" class="mt-4">
<h3 id="objectifs" class="h4 mb-3">
<i class="fas fa-bullseye me-2 text-primary"></i>
Objectifs pédagogiques
</h3>
<p>
Lobjectif principal de FOLLIOW est de démontrer la capacité à concevoir
une application web complète, structurée et sécurisée.
</p>
<ul>
<li>Structuration dun projet en architecture MVC</li>
<li>Manipulation de bases de données relationnelles</li>
<li>Validation et sécurisation des données</li>
<li>Implémentation dun système denvoi demails</li>
<li>Respect des bonnes pratiques (RGPD, accessibilité, organisation du code)</li>
</ul>
</section>
<section aria-labelledby="technologies" class="mt-4">
<h3 id="technologies" class="h4 mb-3">
<i class="fas fa-code me-2 text-primary"></i>
Technologies utilisées
</h3>
<div class="row g-3">
<div class="col-md-6">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body">
<strong>Backend</strong>
<p class="small mb-0">
PHP orienté objet Architecture MVC MySQL
</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body">
<strong>Frontend</strong>
<p class="small mb-0">
HTML5 CSS3 Bootstrap Smarty
</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body">
<strong>Emails</strong>
<p class="small mb-0">
PHPMailer SMTP Brevo
</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body">
<strong>Sécurité</strong>
<p class="small mb-0">
Validation des données Protection des formulaires Gestion des sessions
</p>
</div>
</div>
</div>
</div>
</section>
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<div class="card shadow-sm p-4">
<h4 class="h5 mb-3">
<i class="fas fa-graduation-cap me-2 text-primary"></i>
Projet pédagogique
</h4>
<p class="small">
FOLLIOW a été réalisé dans le cadre dune formation en développement web.
Il sagit dun projet démonstratif à visée éducative.
</p>
<hr>
<h4 class="h5 mb-3">
<i class="fas fa-envelope me-2 text-primary"></i>
Contact
</h4>
<p class="small mb-1">
Pour toute question :
</p>
<a href="mailto:projet.folliow@hotmail.com" class="small">
projet.folliow@hotmail.com
</a>
</div>
</div>
</div>
</section>
{/block}

104
views/addedit_project.tpl Normal file
View File

@@ -0,0 +1,104 @@
{extends file="views/layout.tpl"}
{block name="content"}
<section class="container mt-4">
{if isset($smarty.session.user)}
<form class="m-2" method="POST" enctype="multipart/form-data" onsubmit="return confirm('Êtes-vous certain de vouloir poster votre projet ?')">
<div class="mb-3">
<label class="form-label">Titre</label>
<input type="text" name="title" class="form-control {if (isset($arrError['title'])) } is-invalid {/if} " value="{if $objProject}{$objProject->getTitle()}{/if}" required>
</div>
<div class="mb-3">
<label class="form-label">Description (courte)</label>
<textarea name="description" class="form-control {if (isset($arrError['descProject'])) } is-invalid {/if} " rows="2">{if $objProject}{$objProject->getDescription()}{/if}</textarea>
</div>
<div class="mb-3">
<label class="form-label">Texte complet du Portfolio</label>
<textarea name="content" class="form-control {if (isset($arrError['content'])) } is-invalid {/if}" rows="5">{if $objProject}{$objProject->getContent()}{/if}</textarea>
</div>
<div class="col-6 mb-3">
<fieldset class="border p-2 rounded">
<legend class="form-label h6">Catégorie</legend>
<select class="form-select" id="category" name="category">
<option value="0" {if $objProject->getCategory() == 0}selected{/if}>Toutes les catégories</option>
{foreach $arrCategory as $arrDetCategory}
<option value="{$arrDetCategory['category_id']}"
{if $objProject->getCategory() == $arrDetCategory['category_id']}selected{/if}>
{$arrDetCategory['category_name']}
</option>
{/foreach}
</select>
</fieldset>
</div>
<div class="mb-3">
<label class="h5">Miniature de votre projet</label>
<input name="thumbnail" class="form-control" type="file">
{if $objProject && $objProject->getId()}
<label class="h5">Miniature actuelle :</label>
<img src="{$smarty.env.IMG_PROJECT_PATH}{$objProject->getThumbnail()}" alt="Miniature">
{/if}
</div>
<div class="mb-3">
<label class="form-label h5">Galerie de photos (Max 20)</label>
{assign var="nbActuel" value=$arrImages|@count}
{assign var="disponible" value=20 - $nbActuel}
{if $disponible > 0}
<p class="small text-muted">Il vous reste <strong>{$disponible}</strong> emplacement(s) libre(s).</p>
<input type="file" name="imageProject[]" multiple class="form-control" accept="image/*">
{else}
<div class="alert alert-warning p-2">
<i class="fas fa-exclamation-triangle"></i> Quota de 20 photos atteint.
</div>
{* On désactive l'input si le quota est plein *}
<input type="file" disabled class="form-control">
{/if}
</div>
{* Affichage de Images du projet (s'il y en a)*}
<div class="row mt-4">
<label class="h5">Galerie du projet</label>
{foreach $arrImages as $image}
<div class="col-md-3 mb-3 text-center">
<div class="card shadow-sm h-100 border-{if $image.image_status == 'approuvé'}success{elseif $image.image_status == 'refusé'}danger{else}warning{/if}">
<img src="{$smarty.env.IMG_PROJECT_PATH}{$image.image_name}"
class="card-img-top img-thumbnail"
alt="{$image.image_alt}"
style="height: 150px; object-fit: cover;">
<div class="card-body p-2">
<span class="badge {if $image.image_status == 'approuvé'}bg-success{elseif $image.image_status == 'refusé'}bg-danger{else}bg-warning text-dark{/if}">
{*Permet de remplacer certains character par d'autre*}
{$image.image_status|replace:'_':' '}
</span>
<div class="mt-2 d-flex flex-column gap-1">
<a href="index.php?ctrl=project&action=delete_image&id_img={$image.image_id}"
class="btn btn-sm btn-danger"
onclick="return confirm('Supprimer définitivement cette image ?')">Supprimer</a>
</div>
</div>
</div>
</div>
{foreachelse}
<p class="text-muted italic">Aucune photo dans la galerie pour le moment.</p>
{/foreach}
</div>
<div class="mt-4">
<button type="submit" class="btn btn-primary btn-md" name="sendProject">Envoyer</button>
</div>
</form>
{else}
<div class="alert alert-danger mt-5">
<p class="mb-0">Vous devez vous connecter pour accéder à cette fonctionnalité</p>
</div>
{/if}
</section>
{/block}

88
views/admin.tpl Normal file
View File

@@ -0,0 +1,88 @@
{extends file="views/layout.tpl"}
{block name="content"}
<section>
<div id="layoutSidenav_content">
<div class="container-fluid px-4">
<h1 class="mt-4">Dashboard</h1>
<div class="container-fluid px-4">
<!-- USER MODIF -->
<div class="p-3 mt-2 text-primary-emphasis bg-primary-subtle border border-primary-subtle rounded-3">
<div class="container-fluid pt-2">
<h2>Gestion de l'utilsateur</h2>
<p>Changer le statut ou supprimer un utilisateur</p>
<div class="row">
<form method="POST">
<div class="col-6">
<select class="form-select" aria-label="Default select example" name="user_id">
<option value="0">Choisir un utilisateur</option>
{foreach from=$arrUserToDisplay item=user}
<option value="{$user->getId()}">{$user->getName()} {$user->getFirstname()}</option>
{/foreach}
</select>
<br>
<select class="form-select" aria-label="Default select example" name="new_status">
<option value="0" selected>Modifier le statut de l'Utilisateur...</option>
{foreach from=$arrAuthorisationToDisplay item=arrDetAuthorisation}
<option value="{$arrDetAuthorisation->getId()}">{$arrDetAuthorisation->getName()}</option>
{/foreach}
</select>
</div>
<br>
<div class="col-2">
<button type="submit" name="action" value="update_status" class="btn bg-success text-light"> Valider</button>
<button type="submit" name="action" value="delete_user" class="btn bg-danger text-light" onclick="return confirm('Attention ! Êtes-vous sûr de vouloir supprimer cet utilisateur ? Cette action est irréversible.');">Supprimer l'utilisateur</button>
</div>
</form>
</div>
</div>
</div>
<!-- catégorie modif -->
<div class="p-3 mt-2 text-primary-emphasis bg-primary-subtle border border-primary-subtle rounded-3">
<div class="container-fluid pt-2">
<h2>Gestion des catégories</h2>
<div class="row">
<div class="col-6">
<form method="post">
<p>Modifier une catégorie existante</p>
<select class="form-select" aria-label="Default select example" name="id_to_edit">
<option value="0">Choix de la catégorie</option>
{foreach from=$arrCategoryToDisplay item=category}
<option value="{$category->getId()}">{$category->getName()}</option>
{/foreach}
</select>
<br>
<div class="form-floating mb-3">
<input type="text" class="form-control" id="floatingInput" name="new_name">
<label for="floatingInput">Nouveau nom de la catégorie</label>
</div>
<button type="submit" class="btn bg-success text-light rounded-circle"> ✓</button>
</form>
<div>
</div>
<br>
<div class="row">
<!-- creation cat-->
<div class="col-6">
<form method="POST">
<p>Créer une nouvelle catégorie</p>
<div class="form-floating mb-3">
<input type="text" class="form-control" id="floatingInput" name="new_category">
<label for="floatingInput">Nom de la nouvelle catégorie</label>
</div>
<div class="col-2">
<button type="submit" class="btn bg-success text-light rounded-circle"> ✓</button>
</div>
</form>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="small">Connecté avec le compte : {$smarty.session.user.user_name} {$smarty.session.user.user_firstname}
</section>
{/block}

9
views/error_403.tpl Normal file
View File

@@ -0,0 +1,9 @@
{extends file="views/layout.tpl"}
{block name="content"}
<div class="text-center">
<h1 class="display-1">Erreur 403</h1>
<h2 class="display-3">Vous n'êtes pas autorisé à accéder à cette page !</h2>
<img class="img-fluid" src="assests/img/error403.jpg">
</div>
{/block}

9
views/error_404.tpl Normal file
View File

@@ -0,0 +1,9 @@
{extends file="views/layout.tpl"}
{block name="content"}
<div class="text-center">
<h1 class="display-1">Erreur 404</h1>
<h2 class="display-3">Cette page n'existe pas !</h2>
<img class="img-fluid" src="assests/img/error404.webp">
</div>
{/block}

246
views/help.tpl Normal file
View File

@@ -0,0 +1,246 @@
{extends file="views/layout.tpl"}
{block name="content"}
<h1 class="display-2 text-center">Bienvenue sur l'aide & support de Folliow !</h1>
<br>
<p class="display-6 text-center">Ici, vous trouverez de l'aide pour naviguer sur notre site.</p>
<br>
<section class="container">
{if isset($smarty.session.user)}
{if $smarty.session.user.user_status == 3}
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Comment créer un nouveau projet ?
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse show" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Un haut, dans votre barre de navigation, vous avez un lien pour ajouter un nouveau projet.
Il faudra remplir votre projet avec un titre, une description, des images (jusqu'à 20 par projet) et une image de présentation qui apparaitra en illustration dans la liste des projets.<br>
Plus votre projet est rempli, plus il sera intéressant pour les autres profils, alors n'hésitez pas à bien le remplir !</p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Comment modifier mon projet ?
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Une fois votre projet créé, vous avez la possibilité de modifier son contenu. Si vous êtes bien connecté à votre compte, vous pouvez aller sur votre profil et dans la liste de vos projets,
il vous suffira de cliquer sur "éditer" pour voir toutes les informations apparaitres et changer directement ce que vous souhaitez modifier.
N'oubliez pas de valider vos modifications !</p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
Comment modifier mes informations personnelles ?
</button>
</h2>
<div id="collapseThree" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Si vous êtes bien connecté à votre compte, vous pouvez cliquer sur votre photo de profil en haut à droite de votre écran pour accéder à votre profil.
Vous pourrez ensuite modifier vos informations directement depuis votre profil !
Simple comme "bonjour" :) </p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
Nous contacter
</button>
</h2>
<div id="collapseFour" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Si vous avez des questions ? Un problème avec votre compte ?
Vous souhaitez supprimer toutes vos données ou débloquer votre compte suite à une modération ? N'hésitez pas à nous écrire à <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com </a> !</p>
</div>
</div>
</div>
</div>
{elseif $smarty.session.user.user_status == 2}
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Comment vérifier le statut d'un projet ou d'une image ?
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse show" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Bienvenue dans notre team de modérateurs ! Vous avez maintenant accès à de nouvelles fonctionnalités.
Vous verez le statut de chaque projet et image en dessous de chacun. Si rien n'est mentionné, celà signifie que le projet est déjà approuvé !</p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Comment modérer du contenu ?
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Très bonne question ! En plus du statut du projet ou de l'image, vous avez également accès à 3 boutons : approuver, refuser et supprimer.
Si le projet est valide à nos conditions d'utilisation de Folliow, vous pouvez l'approuver. Si vous pensez qu'il faut légèrement modifier ou adapter, vous pouvez le refuser et l'utilisateur pourra modifier son projet.</p>
<p>Et si le projet enfreint nos règles d'utilisation, vous pouvez supprimer le projet de l'utilisateur. Attention, cette action est définitive.
N'hésitez pas à signaler un utilisateur à l'administrateur en cas de besoin !</p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
Comment modérer une image ?
</button>
</h2>
<div id="collapseThree" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
De la même manière que vous pouvez modérer un projet ! Dans la liste des images, vous aurez la possibilité de refuser, approuver ou bien supprimer une image.
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
Nous contacter
</button>
</h2>
<div id="collapseFour" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Si vous avez des questions ? Une fonctionnalité que vous avez du mal à comprendre ? Des suggestions d'amélioration ? N'hésitez pas à nous écrire à <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com </a>! </p>
</div>
</div>
</div>
</div>
{elseif $smarty.session.user.user_status == 1}
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Comment accéder à mon espace administrateur ?
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse show" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Rien de plus simple ! Si vous êtes connecté à votre compte, un lien <a href="index.php?ctrl=admin&action=admin">"admin"</a> sera visible dans votre barre de navigation.
Cliquez dessus et vous voici dans l'antre réservée à nos fabuleux administrateurs !</p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Comment gérer un utilisateur ?
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>La première fonctionnalité accessible sur votre Dashbord est la maintenance utilisateur. Vous pouvez dans le menu déroulant seléctionner l'utilisateur concerné par votre action.
Un nouveau modérateurs rejoint l'équipe ? Il suffira ensuite de choisir dans le menu déroulant, son nouveau statut ! N'oubliez pas de valider la modification !</p>
<p>Oh, oh... Quelqu'un n'a pas respecté nos règles de modération et vous devez maintenant supprimer cette utilisateur... Après l'avoir séléctionné, vous pouvez appuyer sur le bouton "supprimer l'utilisateur".
Nous vous demanderons une confirmation avant de finaliser la suppression. Attention ! Cette action est définitive et l'utilisateur perdra tous ses projets !</p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
Comment modifier ou créer une catégorie de projet ?
</button>
</h2>
<div id="collapseThree" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Voici la seconde partie de votre Dashbord. Si celà vous semble judicieux ou suite à des suggestions d'utilisateurs, vous pouvez modifier l'intitulé d'une catégorie.
Dans le menu déroulant, choisissez la catégorie concerncée, puis écrivez son nouveau nom dans le champ "nouveau nom de la catégorie". N'oubliez pas de valider le changement !</p>
<p>Et si vous souhaitez créer une nouvelle catégorie, écrivez son intitulé dans le champ "nom de la nouvelle catégorie" et validez la création. Votre nouvelle catégorie apparait déjà dans le menu déroulant !</p>
<p>La suppression d'une catégorie n'est pas possible, car beaucoup de projet se retrouveraient orphelins :( Mais avec la modification et la création, vous avez les outils nécessaire pour organiser le classement de tous nos beaux projets.</p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
Nous contacter
</button>
</h2>
<div id="collapseFour" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p> Vous avez des questions ? Un problème avec votre espace administrateur ou une suggestion d'amélioration ? N'hésitez pas à nous écrire à <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com </a> !<p>
</div>
</div>
</div>
</div>
{/if}
{else}
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Qu'est-ce que Folliow ?
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse show" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Folliow est un réseau social de portfolio. Il vous permet de rassembler et mettre en avant tous les projets que vous avez effectué !
Et si vous êtes rectruteur à la recherche de talents, vous pourrez rechercher les profils en fonction de vos besoins, partager leur contenus et les contacter si vous souhaitez collaborer avec eux.</p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Comment créer un compte
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>En haut à droite de votre écran, vous avez le lien <a href="index.php?ctrl=user&action=signin">"s'inscrire"</a>. Nous demandons certaines informations obligatoires pour l'identification,
ensuite à vous de remplir les informations complémentaires pour alimenter votre profil et permettre aux autres utilisateurs de mieux vous connaitre et vous contacter.</p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
Partager un projet
</button>
</h2>
<div id="collapseThree" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Lorsque vous consultez un projet, vous pouvez remplir le champ "email" avec l'email de la personne à qui vous souhaitez partager le projet.
Votre contact recevra en moins de 5 minutes, un mail de notre part avec le lien vers le projet en question ! Pratique, n'est-ce pas ?</p>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
Nous contacter
</button>
</h2>
<div id="collapseFour" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
<div class="accordion-body">
<p>Si vous avez des questions, n'hésitez pas à nous écrire à <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com </a>!</p>
</div>
</div>
</div>
</div>
{/if}
</section>
<br>
<br>
{/block}

33
views/home.tpl Normal file
View File

@@ -0,0 +1,33 @@
{extends file="views/layout.tpl"}
{block name="content"}
<section class="container mt-5 p-5 d-flex flex-column align-items-center text-center">
<h1 class="logo">Folliow</h1>
<h2>Là où les talents rencontrent leur avenir</h2>
<p class="col-6">Une plateforme de portfolio adapté à vos besoins et aux besoins des entreprises.
Créer un portfolio réellement pertinent aux exigences du marché et rentrez
directement en contact avec les entreprises.</p>
</section>
<section class="container mt-5 p-5 d-flex flex-column align-items-center text-center">
<div class="mb-4">
<form method="GET" action="index.php">
<input type="hidden" name="ctrl" value="project">
<input type="hidden" name="action" value="home">
<button type="submit" name="filter_cat" value="1" class="btn btn-primary">Design</button>
<button type="submit" name="filter_cat" value="2" class="btn btn-primary">Développement Web</button>
<button type="submit" name="filter_old" value="true" class="btn btn-primary">Plus de 6 mois</button>
<a href="index.php?ctrl=project&action=home" class="btn btn-primary">Tout</a>
</form>
</div>
</section>
<section class="container-fluid" aria-label="Articles récents">
<h2 class="visually-hidden">Les 4 derniers articles</h2>
<div class="row mb-2">
{foreach from=$arrProjectToDisplay item=objProject}
{include file="views/_partial/preview.tpl"}
{/foreach}
</section>
{/block}

8
views/layout.tpl Normal file
View File

@@ -0,0 +1,8 @@
{include file="views/_partial/header.tpl"}
<main class="container">
{block name="content"}
{/block}
</main>
{include file="views/_partial/footer.tpl"}

88
views/login.tpl Normal file
View File

@@ -0,0 +1,88 @@
{extends file="views/layout.tpl"}
{block name="title" append} - Connexion{/block}
{block name="content"}
<section aria-label="Se connecter">
<div class="py-5">
<!-- Centrage horizontal du formulaire -->
<div class="row justify-content-center">
<div class="col-12 col-md-8 col-lg-5">
<!-- Carte contenant le formulaire de connexion -->
<div class="card shadow-sm border-0 rounded-4 p-4 p-lg-5">
<!-- Titre principal -->
<h1 class="h3 fw-bold mb-1">Connexion</h1>
<!-- Texte descriptif -->
<p class="text-secondary mb-4">
Connectez-vous à votre compte.
</p>
<!-- Formulaire de connexion -->
<!-- Le traitement sera effectué en PHP via la méthode POST -->
<form method="POST">
<div class="row g-3">
<!-- Champ : adresse e-mail de l'utilisateur -->
<div class="col-12">
<label for="user_mail" class="form-label">
Adresse e-mail
</label>
<input
value="{$strMail|default:''}"
type="email"
class="form-control {if isset($arrError.user_mail)}is-invalid{/if}"
id="user_mail"
name="user_mail"
required
>
</div>
<!-- Champ : mot de passe -->
<div class="col-12">
<label for="user_password" class="form-label">
Mot de passe
</label>
<input
type="password"
class="form-control {if isset($arrError.user_password)}is-invalid{/if}"
id="user_password"
name="user_password"
required
>
</div>
<div class="form-check col-12">
<input type="checkbox" class="form-check-input" id="remember_me" name="remember_me">
<label class="form-check-label" for="remember_me">Se souvenir de moi</label>
</div>
<!-- Bouton de soumission du formulaire -->
<div class="col-12 d-grid mt-2">
<button type="submit" class="btn btn-primary btn-lg rounded-3">
Se connecter
</button>
</div>
<!-- Lien vers la page d'inscription -->
<div class="col-12 text-center">
<small class="text-secondary">
Pas encore de compte ?
<a href="index.php?ctrl=user&action=signup" class="link-primary">
Créer un compte
</a>
</small>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
{/block}

26
views/mail_message.tpl Normal file
View File

@@ -0,0 +1,26 @@
<p>Bonjour,</p>
<p>
Un projet a été partagé avec vous via la plateforme <strong>Folliow</strong>.
</p>
<h3>{$projectTitle}</h3>
<p>
{$projectDescription}
</p>
<p>
Vous pouvez consulter le projet en cliquant sur le lien ci-dessous :
</p>
<p>
<a href="{$projectUrl}">
{$projectUrl}
</a>
</p>
<p>
Cordialement,<br>
Léquipe Folliow
</p>

288
views/mentions.tpl Normal file
View File

@@ -0,0 +1,288 @@
{extends file="views/layout.tpl"}
{block name="title" append} - Mentions légales{/block}
{block name="h2"}Mentions légales{/block}
{block name="p"}Informations légales et politique de confidentialité{/block}
{block name="date_maj"}
<p class="text-muted small mb-0">
<i class="fas fa-calendar-alt me-2" aria-hidden="true"></i>
Dernière mise à jour : <time datetime="2026-02-20">20 février 2026</time>
</p>
{/block}
{block name="js_footer" append}
<script>
{literal}
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
target.focus();
}
});
});
{/literal}
</script>
{/block}
{block name="content"}
<section aria-label="Mentions légales">
<h2 class="visually-hidden">Mentions légales</h2>
<div class="row g-5">
<div class="col-md-12">
<!-- Table des matières -->
<nav class="table-of-contents" aria-labelledby="toc-heading">
<h3 id="toc-heading" class="h5 mb-3">
<i class="fas fa-list me-2" aria-hidden="true"></i>
Sommaire
</h3>
<ul class="list-unstyled ms-3">
<li class="mb-2"><a href="#editeur">1. Éditeur du site</a></li>
<li class="mb-2"><a href="#hebergeur">2. Hébergement</a></li>
<li class="mb-2"><a href="#propriete">3. Propriété intellectuelle</a></li>
<li class="mb-2"><a href="#rgpd">4. Protection des données personnelles (RGPD)</a></li>
<li class="mb-2"><a href="#cookies">5. Cookies</a></li>
<li class="mb-2"><a href="#responsabilite">6. Limitation de responsabilité</a></li>
<li class="mb-2"><a href="#liens">7. Liens hypertextes</a></li>
<li class="mb-2"><a href="#droit">8. Droit applicable</a></li>
</ul>
</nav>
<!-- Section 1 : Éditeur -->
<section id="editeur" class="legal-section" aria-labelledby="editeur-heading">
<h3 id="editeur-heading" class="h4">
<i class="fas fa-building me-2 text-primary" aria-hidden="true"></i>
1. Éditeur du site
</h3>
<p class="text-muted">
FOLLIOW est un <strong>projet pédagogique</strong> réalisé dans le cadre dun exercice de formation.
</p>
<dl class="row">
<dt class="col-sm-3">Nom du projet</dt>
<dd class="col-sm-9">FOLLIOW</dd>
<dt class="col-sm-3">Nature</dt>
<dd class="col-sm-9">Projet scolaire / démonstration technique</dd>
<dt class="col-sm-3">Établissement</dt>
<dd class="col-sm-9">FOLLIOW</dd>
<dt class="col-sm-3">Forme juridique</dt>
<dd class="col-sm-9">Non applicable (projet pédagogique)</dd>
<dt class="col-sm-3">Capital social</dt>
<dd class="col-sm-9">Non applicable</dd>
<dt class="col-sm-3">Adresse</dt>
<dd class="col-sm-9">4 Rue du Rhin, 68000 Colmar</dd>
<dt class="col-sm-3">Téléphone</dt>
<dd class="col-sm-9">03 68 67 20 00</dd>
<dt class="col-sm-3">Email</dt>
<dd class="col-sm-9">
<a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a>
</dd>
<dt class="col-sm-3">Directeur de publication</dt>
<dd class="col-sm-9">Léquipe du projet FOLLIOW</dd>
<dt class="col-sm-3">SIRET</dt>
<dd class="col-sm-9">Non applicable (projet scolaire)</dd>
</dl>
</section>
<!-- Section 2 : Hébergeur -->
<section id="hebergeur" class="legal-section" aria-labelledby="hebergeur-heading">
<h3 id="hebergeur-heading" class="h4">
<i class="fas fa-server me-2 text-primary" aria-hidden="true"></i>
2. Hébergement
</h3>
<p>Le site est hébergé sur une infrastructure pédagogique mise à disposition pour le projet :</p>
<dl class="row">
<dt class="col-sm-3">Hébergeur</dt>
<dd class="col-sm-9">OVH<dd>
<dt class="col-sm-3">Domaine / accès</dt>
<dd class="col-sm-9">php.boulayoune.com</dd>
<dt class="col-sm-3">Adresse</dt>
<dd class="col-sm-9">4 Rue du Rhin, 68000 Colmar</dd>
<dt class="col-sm-3">Téléphone</dt>
<dd class="col-sm-9">03 68 67 20 00</dd>
</dl>
</section>
<!-- Section 3 : Propriété intellectuelle -->
<section id="propriete" class="legal-section" aria-labelledby="propriete-heading">
<h3 id="propriete-heading" class="h4">
<i class="fas fa-copyright me-2 text-primary" aria-hidden="true"></i>
3. Propriété intellectuelle
</h3>
<p>
Sauf mention contraire, lensemble des contenus présents sur FOLLIOW (textes, visuels, logo, éléments dinterface)
est utilisé dans le cadre du projet et reste la propriété de leurs auteurs respectifs.
</p>
<p>
Toute reproduction ou réutilisation à des fins commerciales est interdite sans autorisation préalable.
</p>
<p>
Les éventuels contenus tiers (images, icônes, bibliothèques) restent soumis à leurs licences dorigine.
</p>
</section>
<!-- Section 4 : RGPD -->
<section id="rgpd" class="legal-section" aria-labelledby="rgpd-heading">
<h3 id="rgpd-heading" class="h4">
<i class="fas fa-shield-alt me-2 text-primary" aria-hidden="true"></i>
4. Protection des données personnelles (RGPD)
</h3>
<h4 class="h5 mt-4">4.1 Responsable du traitement</h4>
<p>
Le responsable du traitement est léquipe du projet FOLLIOW (projet pédagogique).
</p>
<h4 class="h5 mt-4">4.2 Données collectées</h4>
<p>Selon lutilisation du site, les données pouvant être collectées sont :</p>
<ul>
<li>Nom / Prenom <li>
<li>Pseudo </li>
<li>Adresse email (inscription, connexion, partage de projet par email)</li>
<li>Contenus déposés par lutilisateur (projets, descriptions, images)</li>
<li>Données techniques minimales (logs de sécurité, adresse IP) à des fins de protection et de diagnostic</li>
</ul>
<h4 class="h5 mt-4">4.3 Finalités du traitement</h4>
<ul>
<li>Création et gestion de compte</li>
<li>Publication et affichage de projets</li>
<li>Partage dun projet par email à la demande de lutilisateur</li>
<li>Sécurisation du site et prévention des abus</li>
</ul>
<h4 class="h5 mt-4">4.4 Durée de conservation</h4>
<p>
Dans le cadre de ce projet pédagogique, les données sont conservées pendant la durée du projet et des évaluations,
puis supprimées ou anonymisées, sauf obligation légale contraire.
</p>
<h4 class="h5 mt-4">4.5 Vos droits</h4>
<p>Conformément au RGPD, vous disposez de droits daccès, de rectification, deffacement et dopposition.</p>
<p>
Pour exercer ces droits, contactez-nous à :
<a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a>
</p>
<p>
Vous pouvez également introduire une réclamation auprès de la CNIL
(<a href="https://www.cnil.fr" target="_blank" rel="noopener">www.cnil.fr</a>).
</p>
</section>
<!-- Section 5 : Cookies -->
<section id="cookies" class="legal-section" aria-labelledby="cookies-heading">
<h3 id="cookies-heading" class="h4">
<i class="fas fa-cookie-bite me-2 text-primary" aria-hidden="true"></i>
5. Cookies
</h3>
<p>
FOLLIOW peut utiliser des cookies <strong>strictement nécessaires</strong> au fonctionnement du site
(ex : session de connexion). Aucun cookie publicitaire nest utilisé.
</p>
<h4 class="h5 mt-4">5.1 Quest-ce quun cookie ?</h4>
<p>
Un cookie est un petit fichier texte déposé sur votre appareil lors de la visite dun site.
Il permet notamment de conserver une session ou des préférences.
</p>
<h4 class="h5 mt-4">5.2 Types de cookies utilisés</h4>
<ul>
<li><strong>Cookies techniques</strong> : indispensables (session, sécurité)</li>
<li><strong>Cookies de préférence</strong> : éventuels (langue, affichage) si implémentés</li>
</ul>
<h4 class="h5 mt-4">5.3 Gestion des cookies</h4>
<p>
Vous pouvez configurer votre navigateur pour refuser les cookies. Certaines fonctionnalités du site
peuvent alors ne pas fonctionner correctement.
</p>
</section>
<!-- Section 6 : Limitation de responsabilité -->
<section id="responsabilite" class="legal-section" aria-labelledby="responsabilite-heading">
<h3 id="responsabilite-heading" class="h4">
<i class="fas fa-exclamation-triangle me-2 text-primary" aria-hidden="true"></i>
6. Limitation de responsabilité
</h3>
<p>
Les informations présentées sur FOLLIOW sont fournies à titre démonstratif dans le cadre dun projet pédagogique.
Léquipe sefforce de maintenir le site accessible, sans garantie dabsence derreurs ou dinterruptions.
</p>
<p>
Léquipe FOLLIOW ne pourra être tenue responsable des dommages directs ou indirects résultant de lutilisation du site,
notamment en cas dindisponibilité ou de perte de données.
</p>
</section>
<!-- Section 7 : Liens hypertextes -->
<section id="liens" class="legal-section" aria-labelledby="liens-heading">
<h3 id="liens-heading" class="h4">
<i class="fas fa-link me-2 text-primary" aria-hidden="true"></i>
7. Liens hypertextes
</h3>
<p>
Le site peut contenir des liens vers des sites tiers. FOLLIOW nexerce aucun contrôle sur ces sites et décline toute
responsabilité quant à leur contenu ou leur disponibilité.
</p>
</section>
<!-- Section 8 : Droit applicable -->
<section id="droit" class="legal-section" aria-labelledby="droit-heading">
<h3 id="droit-heading" class="h4">
<i class="fas fa-gavel me-2 text-primary" aria-hidden="true"></i>
8. Droit applicable et juridiction compétente
</h3>
<p>
Les présentes mentions légales sont régies par le droit français. En cas de litige, et à défaut daccord amiable,
les tribunaux français seront seuls compétents.
</p>
</section>
<!-- Contact -->
<section class="mt-5 p-4 bg-light rounded" aria-labelledby="contact-legal">
<h3 id="contact-legal" class="h4 mb-3">
<i class="fas fa-envelope me-2 text-primary" aria-hidden="true"></i>
Questions ou réclamations
</h3>
<p>
Pour toute question concernant ces mentions légales ou pour exercer vos droits, vous pouvez nous contacter :
</p>
<ul class="list-unstyled">
<li class="mb-2">
<i class="fas fa-envelope me-2" aria-hidden="true"></i>
Par email : <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a>
</li>
</ul>
</section>
</div>
</div>
</section>
{/block}

75
views/project.tpl Normal file
View File

@@ -0,0 +1,75 @@
{extends file="views/layout.tpl"}
{block name="content"}
<body>
<section class="container mt-5 p-5 d-flex flex-column align-items-center">
<div>
<h2>Alimenter votre projet</h2>
<form method="post">
<button type="submit" class="btn btn-primary btn-lg" name="showForm">+</button>
{if isset($smarty.post.toContinue)}
<button type="submit" class="btn btn-warning btn-lg" name="showFormContinue">Reprendre</button>
{/if}
</form>
{* Affichage d'un formulaire en cas d'appuie sur le bouton "+" *}
{if isset($smarty.post.showForm) || isset($smarty.post.showFormContinue)}
{if isset($smarty.session.user)}
<form class="m-2" method="post" enctype="multipart/form-data" onsubmit="return confirm('Voulez-vous vraiment envoyer le formulaire ?')">
<div>
<label>Titre</label>
<input type="text" name="titleProject">
</div>
<div>
<label>Description</label>
<input type="text" name="descProject">
</div>
<div>
<label>Texte Portfolio</label>
<input type="text" name="textProject">
</div>
<div>
<h3>Image thumbnail</h3>
<input name="imageThumbnail" class="form-control" type="file">
</div>
<div>
<h3>Image du projet</h3>
<input name="imageProject" class="form-control" type="file">
</div>
<div class="mt-2">
<button type="submit" class="btn btn-primary btn-md" name="sendMessage">Envoyer</button>
<button type="submit" class="btn btn-warning btn-md" name="toContinue">Remettre à plus tard</button>
</div>
</form>
{else}
<div class="border rounded mt-5">
<p class="text-danger p-2">Vous devez vous connecter pour accéder à cette fonctionnalité</p>
</div>
{/if}
{/if}
</div>
<div>
<h3>Description</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div>
<h3>Photos behind the scene</h3>
<div class="row mb-2">
<img>
</div>
</div>
<div>
<h3>Other projects</h3>
<div class="row mb-2">
{foreach $arrProjectToDisplay as $objProject}
{include file="../app/views/partials/preview.tpl"}
{/foreach}
</div>
</div>
</div>
<section>
</body>
{/block}

141
views/project_display.tpl Normal file
View File

@@ -0,0 +1,141 @@
{extends file="views/layout.tpl"}
{block name="content"}
<main class="container mt-5 py-5">
<!-- Message après l'envoi d'email -->
{if isset($smarty.get.mail) && $smarty.get.mail === 'ok'}
<div class="alert alert-success">Email envoyé avec succès.</div>
{elseif isset($smarty.get.mail) && $smarty.get.mail === 'fail'}
<div class="alert alert-danger">Erreur lors de l'envoi de l'email.</div>
{/if}
<div class="row g-4">
<!-- Contenu principal du projet -->
<div class="col-lg-8">
<h1 class="fw-bold">{$objProject->getTitle()}</h1>
<p class="text-muted">
{$arrProject.category_name ?? 'Général'}
</p>
<div class="mb-4 shadow-sm">
<img src="{$smarty.env.IMG_PROJECT_PATH}{$objProject->getThumbnail()}"
class="img-fluid rounded w-100">
</div>
<div class="bg-light p-4 rounded mb-4">
<h4 class="border-bottom pb-2">Description</h4>
<p class="lead">{$objProject->getDescription()}</p>
<div class="mt-4">
{$objProject->getContent()}
</div>
</div>
<!-- Images du projet -->
<section id="galerie-projet">
<h2>Galerie du projet</h2>
<div class="row">
{foreach $arrImages as $image}
{* On affiche l'image si elle est approuvée OU si l'utlilisateur possède le projet OU si l'utlilisateur est Modérateur*}
{if ($image.image_status == 'approuvé') ||
(isset($smarty.session.user) && $smarty.session.user.user_status == 2) ||
(isset($smarty.session.user) && $smarty.session.user.user_id == $objProject->getUser_id())}
<div class="col-md-4 mb-4">
<div class="card {if $image.image_status != 'approuvé'}border-warning shadow-none opacity-75{/if}">
<img src="{$smarty.env.IMG_PROJECT_PATH}{$image.image_name}" class="card-img-top" alt="{$image.image_alt}">
{* Visible uniquement par le modérateur *}
{if isset($smarty.session.user.user_status) && $smarty.session.user.user_status == 2}
<div class="moderator-tools border-top pt-2 mt-2">
<div class="d-flex gap-2">
<a href="index.php?ctrl=project&action=change_image_status&id_img={$image.image_id}&status=approuvé"
class="btn btn-sm btn-success">Valider</a>
<a href="index.php?ctrl=project&action=delete_image&id_img={$image.image_id}"
class="btn btn-sm btn-outline-danger"
onclick="return confirm('Supprimer définitivement ?')">Supprimer</a>
</div>
</div>
{/if}
</div>
</div>
{/if}
{foreachelse}
<p>Aucune image disponible pour ce projet.</p>
{/foreach}
</div>
</section>
<!-- Formulaire qui envoie la demande au contrôleur (shareProject) -->
<div class="card shadow-sm p-4 mb-5">
<form method="post" action="index.php?ctrl=project&action=shareProject">
<input type="hidden" name="project_id"
value="{$objProject->getId()}">
<input type="email" name="to_email"
class="form-control mb-3"
placeholder="Adresse email" required>
<button type="submit" class="btn btn-primary w-100">
Envoyer par email
</button>
</form>
</div>
</div>
<!-- Sidebar : informations du créateur -->
<div class="col-lg-4">
<div class="card text-center shadow-sm p-4">
<a href="index.php?ctrl=user&action=user&id={$objProject->getUser_id()}" class="text-decoration-none text-dark">
<img src="{$smarty.env.IMG_USER_PATH}{$objProject->getUser_image() ?? "images.jpg"}"
class="rounded-circle mb-3 mx-auto"
style="width:100px;height:100px;object-fit:cover;">
</a>
<h5>{$objProject->getCreatorName()}</h5>
<p class="text-muted small">
Publié le {$objProject->getCreation_date()}
</p>
<button class="btn btn-primary">Contacter le talent</button>
</div>
{*Controle de l'utilisateur ainsi que du status du projet + Suppression disponible pour l'utilisateur possédant le projet*}
{if isset($smarty.session.user)}
{if ($smarty.session.user.user_status == 2 || $smarty.session.user.user_id == $objProject->getUser_id())}
<div class="border rounded text-center">
<a class="btn btn-sm m-1 btn-danger" href="?ctrl=project&action=delete&id={$objProject->getId()}" name="toDelete">Supprimer le projet</a>
{/if}
{if $smarty.session.user.user_id == $objProject->getUser_id()}
<a class="btn btn-sm m-1 btn-warning" href="?ctrl=project&action=addedit_project&id={$objProject->getId()}" name="addedit">Modifier le projet</a>
{/if}
{*Conditions permettant au Modérateur de modifier le status d'un projet*}
{if $smarty.session.user.user_status == 2 && $objProject->getStatus() == "en_attente"}
<a class="btn btn-sm m-1 btn-success" href="?ctrl=project&action=accept&id={$objProject->getId()}" name="toPublished">Accepter</a>
<a class="btn btn-sm m-1 btn-warning" href="?ctrl=project&action=refuse&id={$objProject->getId()}" name="toRefused">Refuser</a>
</div>
{elseif $projectStatus == "refusé"}
<p class="text-danger fw-bold">Portfolio refusé</p>
{/if}
{/if}
</div>
</div>
</main>
{/block}

190
views/search.tpl Normal file
View File

@@ -0,0 +1,190 @@
{extends file="views/layout.tpl"}
{block name="title" append} - Rechercher{/block}
{block name="content"}
<section aria-label="Blog">
<h2 class="visually-hidden">Rechercher parmi les articles</h2>
<div class="row mb-2">
<section class="mb-5" aria-labelledby="search-heading">
<form name="formSearch" method="post" action="?ctrl=project&action=search" class="border rounded p-4 bg-light">
<h3 id="search-heading" class="h4 mb-4">
<i class="fas fa-search me-2" aria-hidden="true"></i>
Rechercher des articles
</h3>
<div class="row g-3">
<div class="col-md-6">
<label for="keywords" class="form-label">Mots-clés</label>
<input
value=""
type="text"
class="form-control"
id="keywords"
name="keywords"
placeholder="Design, IA, back-end"
aria-describedby="keywords-help">
<small id="keywords-help" class="form-text text-muted">
Recherchez dans les titres et contenus
</small>
</div>
<div class="col-md-6">
<label for="author" class="form-label">Auteur</label>
<select class="form-select" id="author" name="author">
<option value="0" {if $intAuthor == 0}selected{/if}>Tous les auteurs</option>
{foreach $arrUser as $arrDetUser}
<option value="{$arrDetUser['user_id']}"
{if $intAuthor == $arrDetUser['user_id']}selected{/if}
>
{$arrDetUser['user_firstname']} {$arrDetUser['user_name']}
</option>
{/foreach}
</select>
</div>
<div class="col-6">
<div class="col-6">
<fieldset>
<legend class="form-label">Recherche par date</legend>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="period"
id="period-exact"
value="0"
{if $intPeriod == 0}checked{/if}
aria-controls="date-exact date-range">
<label class="form-check-label" for="period-exact">
Date exacte
</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="period"
id="period-range"
value="1"
{if $intPeriod == 1}checked{/if}
aria-controls="date-exact date-range">
<label class="form-check-label" for="period-range">
Période
</label>
</div>
</fieldset>
</div>
<div class="col-12" id="date-exact">
<label for="date" class="form-label">Date</label>
<input
type="date"
class="form-control"
id="date"
name="date"
aria-describedby="date-help"
value="{$strDate}" >
<small id="date-help" class="form-text text-muted">
Format: JJ/MM/AAAA
</small>
</div>
<div id="date-range" style="display: none;">
<div class="row g-3">
<div class="col-md-6">
<label for="startdate" class="form-label">Date de début</label>
<input
type="date"
class="form-control"
id="startdate"
name="startdate"
value="{$strStartDate}" >
</div>
<div class="col-md-6">
<label for="enddate" class="form-label">Date de fin</label>
<input
type="date"
class="form-control"
id="enddate"
name="enddate"
value="{$strEndDate}" >
</div>
</div>
</div>
</div>
<!-- AJOUT RECHERCHE PAR CATEGORIE -->
<div class="col-6">
<fieldset>
<legend class="form-label">Recherche par catégories</legend>
<div class="col-md-6">
<label for="author" class="form-label">Catégorie</label>
<select class="form-select" id="category" name="category">
<option value="0" {if $intCategory == 0}selected{/if}>Toutes les catégories</option>
{foreach $arrCategory as $arrDetCategory}
<option value="{$arrDetCategory['category_id']}"
{if $intCategory == $arrDetCategory['category_id']}selected{/if}
>
{$arrDetCategory['category_name']}
</option>
{/foreach}
</select>
</div>
</fieldset>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">
<i class="fas fa-search me-2" aria-hidden="true"></i>
Rechercher
</button>
<a href="index.php?ctrl=project&action=search" class="btn btn-secondary ms-2">
<i class="fas fa-redo me-2" aria-hidden="true"></i>
Réinitialiser
</a>
</div>
</div>
</form>
</section>
<!-- Liste des articles -->
<section aria-labelledby="articles-heading">
<h3 id="articles-heading" class="visually-hidden">Liste des projets</h3>
<div class="row mb-2">
{if count($arrProject) == 0}
<div class="alert alert-warning">
<p>Pas de résultats</p>
</div>
{/if}
{foreach $arrProjectToDisplay as $objProject}
{include file="views/_partial/preview.tpl"}
{/foreach}
</div>
</section>
</div>
</section>
<script>
// Gestion de l'affichage des champs de date
const periodRadios = document.querySelectorAll('input[name="period"]');
const dateExact = document.getElementById('date-exact');
const dateRange = document.getElementById('date-range');
function toggleDateFields() {
const selectedPeriod = document.querySelector('input[name="period"]:checked').value;
if (selectedPeriod === '0') {
dateExact.style.display = 'block';
dateRange.style.display = 'none';
} else {
dateExact.style.display = 'none';
dateRange.style.display = 'block';
}
}
periodRadios.forEach(radio => {
radio.addEventListener('change', toggleDateFields);
});
// Initialisation au chargement
toggleDateFields();
</script>
{/block}

202
views/signup.tpl Normal file
View File

@@ -0,0 +1,202 @@
{extends file="views/layout.tpl"}
{block name="title" append} - Inscription{/block}
{block name="content"}
<!-- Page : Inscription -->
<div class="py-5">
<!-- Centrage horizontal du formulaire -->
<div class="row justify-content-center">
<div class="col-12 col-md-10 col-lg-6">
<!-- Carte contenant le formulaire d'inscription -->
<div class="card shadow-sm border-0 rounded-4 p-4 p-lg-5">
<!-- Titre principal de la page -->
<h1 class="h3 fw-bold mb-1">Inscription</h1>
<!-- Texte descriptif -->
<p class="text-secondary mb-4">
Créez votre compte utilisateur.
</p>
<!-- Formulaire d'inscription -->
<!-- Les données seront traitées côté serveur en PHP via la méthode POST -->
<form method="POST">
<div class="row g-3">
<!-- Champ : prénom de l'utilisateur -->
<div class="col-md-6">
<label class="form-label" for="user_firstname">
Prénom *
</label>
<input
class="form-control"
type="text"
id="user_firstname"
name="user_firstname"
value="{$objUser->getFirstname()|default:''}"
required
>
</div>
<!-- Champ : nom de l'utilisateur -->
<div class="col-md-6">
<label class="form-label" for="user_name">
Nom *
</label>
<input
class="form-control"
type="text"
id="user_name"
name="user_name"
value="{$objUser->getName()|default:''}"
required
>
</div>
<!-- Champ : pseudo -->
<div class="col-12">
<label class="form-label" for="user_pseudo">
Pseudo *
</label>
<div class="input-group">
<span class="input-group-text">@</span>
<input
class="form-control"
type="text"
id="user_pseudo"
name="user_pseudo"
value="{$objUser->getPseudo()|default:''}"
required
>
</div>
</div>
<!-- Champ : adresse e-mail -->
<div class="col-12">
<label class="form-label" for="user_mail">
Adresse e-mail *
</label>
<input
class="form-control"
type="email"
id="user_mail"
name="user_mail"
value="{$objUser->getMail()|default:''}"
required
>
</div>
<!-- Champ : mot de passe -->
<div class="col-12">
<label class="form-label" for="user_password">
Mot de passe *
</label>
<input
class="form-control"
type="password"
id="user_password"
name="user_password"
required
>
</div>
<!-- Champ : confirmer le mot de passe -->
<div class="col-12">
<label class="form-label" for="pwd_confirm">
Confirmer le mot de passe *
</label>
<input
class="form-control"
type="password"
id="pwd_confirm"
name="pwd_confirm"
required
>
</div>
<!-- Champ optionnel : numéro de téléphone -->
<div class="col-12">
<label class="form-label" for="user_phone">
Téléphone
</label>
<input
class="form-control"
type="text"
id="user_phone"
name="user_phone"
value="{$objUser->getPhone()|default:''}"
>
</div>
<!-- Champ optionnel : profession de l'utilisateur -->
<div class="col-12">
<label class="form-label" for="user_work">
Profession
</label>
<input
class="form-control"
type="text"
id="user_work"
name="user_work"
value="{$objUser->getWork()|default:''}"
>
</div>
<!-- Champ optionnel : localisation de l'utilisateur -->
<div class="col-12">
<label class="form-label" for="user_location">
Localisation
</label>
<input
class="form-control"
type="text"
id="user_location"
name="user_location"
value="{$objUser->getLocation()|default:''}"
>
</div>
<!-- Champ optionnel : phrase d'accroche -->
<div class="col-12">
<label class="form-label" for="user_description">
Phrase d'accroche
</label>
<textarea
class="form-control"
id="user_description"
name="user_description"
value="{$objUser->getDescription()|default:''}"
rows="3"
></textarea>
</div>
<!-- Bouton de soumission du formulaire -->
<div class="col-12 d-grid mt-2">
<button type="submit" class="btn btn-primary btn-lg rounded-3">
Créer mon compte
</button>
</div>
<!-- Lien vers la page de connexion -->
<div class="col-12 text-center">
<small class="text-secondary">
Déjà un compte ?
<a class="link-primary" href="index.php?ctrl=user&action=login">
Se connecter
</a>
</small>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{/block}

52
views/user.tpl Normal file
View File

@@ -0,0 +1,52 @@
{extends file="views/layout.tpl"}
{block name="content"}
<section class="user-profile mb-5 mt-5/*vh /*">
<div class="row">
<div class="col-md-4 text-center">
<img src="{$smarty.env.IMG_USER_PATH}{$user->getImage() ?? "images.jpg"}" alt="Avatar de {$user->getPseudo()}" class="rounded-circle flex-shrink-0 border border-2 border-white"
style="width: 256px; height: 256px; object-fit: cover; margin-top: 8px;"
>
</div>
<div class="col-md-8 align-items-center p-0">
<div>
<h1>{$user->getPseudo()}</h1>
<p class="text-muted">{$user->getMail()}</p>
{if $user->getWork()}
<p>{$user->getWork()}</p>
{/if}
{if $user->getLocation()}
<p>{$user->getLocation()}</p>
{/if}
<p class="mt-3">{$user->getDescription()}</p>
{if $smarty.session.user.user_id == $user->getId()}
<a class="btn btn-sm btn-primary flex-fill"
href="?ctrl=user&action=edit">Edit account</a>
{/if}
</div>
</div>
</div>
</section>
<section>
<h2 class="mb-4 border-bottom pb-2">Les projets de {$user->getPseudo()}</h2>
<div class="row m-0">
{if count($arrProjectToDisplay) > 0}
{foreach $arrProjectToDisplay as $objProject}
{include file="views/_partial/preview.tpl"}
{/foreach}
{else}
<div class="col-12">
<p class="col-12 alert alert-info">Cet utilisateur n'a pas encore publié de projets.</p>
</div>
{/if}
</div>
</section>
{/block}

179
views/useredit.tpl Normal file
View File

@@ -0,0 +1,179 @@
{extends file="views/layout.tpl"}
{block name="content"}
<!-- Page : Inscription -->
<main class="container py-5">
<!-- Centrage horizontal du formulaire -->
<div class="row justify-content-center position-relative">
<div class="col-12 col-md-10 col-lg-6">
<!-- Carte contenant le formulaire d'inscription -->
<div class="card shadow-sm border-0 rounded-4 p-4 p-lg-5">
<!-- Titre principal de la page -->
<h1 class="h3 fw-bold mb-1">Edit du profile</h1>
{if (isset($arrError) && count($arrError) > 0) }
<div class="alert alert-danger">
{foreach $arrError as $strError}
<p>{$strError}</p>
{/foreach}
</div>
{/if}
<!-- Formulaire d'inscription -->
<!-- Les données seront traitées côté serveur en PHP via la méthode POST -->
<form method="POST" enctype="multipart/form-data">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label" for="user_firstname">
Prénom
</label>
<input
class="form-control"
type="text"
id="user_firstname"
name="user_firstname"
value="{$objUser->getFirstname()}"
>
</div>
<div class="col-md-6">
<label class="form-label" for="user_name">
Nom
</label>
<input
class="form-control"
type="text"
id="user_name"
name="user_name"
value="{$objUser->getName()}"
>
</div>
<div class="col-12">
<label class="form-label" for="user_pseudo">
Pseudo
</label>
<div class="input-group">
<span class="input-group-text">@</span>
<input
class="form-control"
type="text"
id="user_pseudo"
name="user_pseudo"
value="{$objUser->getPseudo()}"
>
</div>
</div>
<div class="col-12">
<label class="form-label" for="image">
Photo de profil
</label>
{if $objUser->getImage()}
<div class="mb-2">
<img src="{$smarty.env.IMG_USER_PATH}{$objUser->getImage()}" alt="image actuel" class="rounded-circle" width="80" height="80">
</div>
{/if}
<input
class="form-control"
type="file"
id="image"
name="image"
accept="image/jpeg, image/png, image/webp"
>
<div class="form-text">Formats acceptés : JPG, PNG, WEBP. Laisser vide pour ne pas changer.</div>
</div>
<div class="col-12">
<label class="form-label" for="user_mail">
Adresse e-mail
</label>
<input
class="form-control"
type="email"
id="user_mail"
name="user_mail"
value="{$objUser->getMail()}"
>
</div>
<div class="col-12">
<label class="form-label" for="user_phone">
Téléphone
</label>
<input
class="form-control"
type="text"
id="user_phone"
name="user_phone"
value="{$objUser->getPhone()}"
>
</div>
<div class="col-12">
<label class="form-label" for="user_work">
Profession
</label>
<input
class="form-control"
type="text"
id="user_work"
name="user_work"
value="{$objUser->getWork()}"
>
</div>
<div class="col-12">
<label class="form-label" for="user_location">
Localisation
</label>
<input
class="form-control"
type="text"
id="user_location"
name="user_location"
value="{$objUser->getLocation()}"
>
</div>
<div class="col-12">
<label class="form-label" for="user_description">
Phrase d'accroche
</label>
<textarea
class="form-control"
id="user_description"
name="user_description"
rows="3"
>
{$objUser->getDescription()}
</textarea>
</div>
<div class="col-12 d-grid mt-2">
<button type="submit" class="btn btn-primary btn-lg rounded-3">
Edit profile
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</main>
{/block}