Merge branch 'main' into laura

This commit is contained in:
Yass 2026-02-25 15:31:19 +01:00 committed by GitHub
commit 2d9e88f570
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
150 changed files with 12964 additions and 772 deletions

View file

@ -5,7 +5,7 @@
<li><a href="#">Découvrir</a>
<li><a href="#">Customisation</a>
<li><a href="#">Emploi</a>
<li><a href="#">A propos</a>
<li><a href="?ctrl=project&action=about">A propos</a>
</ul>
</div>
<div class="col-3">
@ -19,7 +19,7 @@
<div class="col-3">
<ul>
<li><a href="#">Politique de confidentialité</a>
<li><a href="#">Politique sur les données</a>
<li><a href="?ctrl=project&action=mentions">Mentions légales</a>
<li><a href="#">CGU</a>
<li><a href="#">CGV</a>
</ul>
@ -31,4 +31,4 @@
<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>
</html>

View file

@ -7,7 +7,7 @@
<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</title>
<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">
@ -27,7 +27,7 @@
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="?ctrl=&action=">À propos</a>
<a class="nav-link" href="?ctrl=project&action=about">À propos</a>
</li>
<li class="nav-item">
@ -51,7 +51,7 @@
{* Utilisateur non connecté *}
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="index.php?ctrl=user&action=signin" title="Créer un compte" aria-label="Créer un compte">
<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>
@ -65,15 +65,15 @@
{* Utilisateur connecté *}
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="edit_account.php" title="Modifier mon compte" aria-label="Modifier mon compte">
<img src="{$smarty.session.user.user_image}"
<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 class="nav-item">
<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>

View file

@ -16,7 +16,7 @@
<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="{$objProject->getUser_image()}"
<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">
@ -26,7 +26,7 @@
<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&id={$objProject->getUser_id()}"
<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()}
@ -52,7 +52,7 @@
{if isset($smarty.session.user)}
{if $smarty.session.user.user_id == $objProject->getUser_id()}
<a href="index.php?ctrl=project&action=display&id={$objProject->getId()}"
<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
@ -80,7 +80,7 @@
</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">Portfolio refusé</p>
<p class="text-danger fw-bold text-center mb-0 small">Projet refusé</p>
</div>
{/if}
</div>

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}

View file

@ -40,14 +40,56 @@
<input name="thumbnail" class="form-control" type="file">
{if $objProject && $objProject->getId()}
<label class="h5">Miniature actuelle :</label>
<img src="uploads/projects/{$objProject->getThumbnail()}" alt="Miniature">
<img src="{$smarty.env.IMG_PROJECT_PATH}{$objProject->getThumbnail()}" alt="Miniature">
{/if}
</div>
<div class="mb-3">
<label class="h5">Images de votre projet</label>
<input name="imageProject" class="form-control" type="file" multiple>
</div>
<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>

View file

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

View file

@ -1,116 +1,88 @@
{extends file="views/layout.tpl"}
{block name="title" append} - Connexion{/block}
{block name="content"}
<section aria-label="Se connecter">
{* Affichage des erreurs *}
{if $arrError|count > 0}
<div class="alert alert-danger">
{foreach from=$arrError item=strError}
<p>{$strError}</p>
{/foreach}
</div>
{/if}
<!-- Contenu principal de la page -->
<main class="container py-5">
<!-- Centrage horizontal du formulaire -->
<div class="row justify-content-center">
<!-- Contenu principal de la page -->
<main class="container py-5">
<div class="py-5">
<!-- Centrage horizontal du formulaire -->
<div class="row justify-content-center">
<div class="col-12 col-md-8 col-lg-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">
<!-- 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>
<!-- Titre principal -->
<h1 class="h3 fw-bold mb-1">Connexion</h1>
<!-- Texte descriptif -->
<p class="text-secondary mb-4">
Connectez-vous à votre compte.
</p>
<!-- 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">
<!-- Formulaire de connexion -->
<!-- Le traitement sera effectué en PHP via la méthode POST -->
<form method="POST">
<!-- 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>
<div class="row g-3">
<!-- 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>
<!-- 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.mail)}is-invalid{/if}"
id="user_mail"
name="user_mail"
required
>
</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>
<!-- 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.pwd)}is-invalid{/if}"
id="user_password"
name="user_password"
required
>
</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>
<!-- Option "Se souvenir de moi" (fonctionnalité optionnelle côté PHP) -->
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="remember_me" name="remember_me">
<label class="form-check-label" for="remember_me">
Se souvenir de moi
</label>
</div>
</div>
</div>
</form>
<!-- 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>
</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=signin" class="link-primary">Créer un compte</a>
</small>
</div>
</div>
</div>
</div>
<!-- Lien pour la récupération du mot de passe -->
<div class="col-12 text-center">
<small>
<a href="#" class="link-primary">
Mot de passe oublié ?
</a>
</small>
</div>
</div>
</form>
</div>
</div>
</div>
</main>
</section>
{/block}
{/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}

View file

@ -22,7 +22,7 @@
</p>
<div class="mb-4 shadow-sm">
<img src="{$objProject->getThumbnail()}"
<img src="{$smarty.env.IMG_PROJECT_PATH}{$objProject->getThumbnail()}"
class="img-fluid rounded w-100">
</div>
@ -34,10 +34,50 @@
{$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}">
<!-- Formulaire qui envoie la demande au contrôleur (sendEmail) -->
{* 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=sendEmail">
<form method="post" action="index.php?ctrl=project&action=shareProject">
<input type="hidden" name="project_id"
value="{$objProject->getId()}">
@ -59,7 +99,7 @@
<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="{$objProject->getUser_image()}"
<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>
@ -67,7 +107,6 @@
<p class="text-muted small">
Publié le {$objProject->getCreation_date()}
</p>
<button class="btn btn-primary">Contacter le talent</button>
@ -97,7 +136,6 @@
</div>
</div>
</main>
{/block}

View file

@ -1,4 +1,5 @@
{extends file="views/layout.tpl"}
{block name="title" append} - Rechercher{/block}
{block name="content"}
<section aria-label="Blog">
@ -41,7 +42,7 @@
</select>
</div>
<div class="col-6">
<div class="col-6">
<fieldset>
<legend class="form-label">Recherche par date</legend>
@ -73,27 +74,9 @@
</div>
</fieldset>
</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-md-6" id="date-exact">
<div class="col-12" id="date-exact">
<label for="date" class="form-label">Date</label>
<input
type="date"
@ -129,7 +112,26 @@
</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>
@ -185,4 +187,4 @@
// Initialisation au chargement
toggleDateFields();
</script>
{/block}
{/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}

View file

@ -5,11 +5,11 @@
<section class="user-profile mb-5 mt-5/*vh /*">
<div class="row">
<div class="col-md-4 text-center">
<img src="{$user->getImage()}" alt="Avatar de {$user->getPseudo()}" class="rounded-circle flex-shrink-0 border border-2 border-white"
<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 d-flex align-items-center">
<div class="col-md-8 align-items-center p-0">
<div>
<h1>{$user->getPseudo()}</h1>
<p class="text-muted">{$user->getMail()}</p>
@ -23,7 +23,12 @@
{/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>
@ -31,13 +36,15 @@
<section>
<h2 class="mb-4 border-bottom pb-2">Les projets de {$user->getPseudo()}</h2>
<div class="row">
<div class="row m-0">
{if count($arrProjectToDisplay) > 0}
{foreach $arrProjectToDisplay as $objProject}
{include file="views/_partial/preview.tpl"}
{/foreach}
{else}
<p class="alert alert-info">Cet utilisateur n'a pas encore publié de projets.</p>
<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>

View file

@ -14,12 +14,8 @@
<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>
<h1 class="h3 fw-bold mb-1">Edit du profile</h1>
<!-- Texte descriptif -->
<p class="text-secondary mb-4">
Créez votre compte utilisateur.
</p>
{if (isset($arrError) && count($arrError) > 0) }
<div class="alert alert-danger">
{foreach $arrError as $strError}
@ -29,41 +25,39 @@
{/if}
<!-- Formulaire d'inscription -->
<!-- Les données seront traitées côté serveur en PHP via la méthode POST -->
<form method="POST">
<form method="POST" enctype="multipart/form-data">
<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 *
Prénom
</label>
<input
class="form-control"
type="text"
id="user_firstname"
name="user_firstname"
required >
value="{$objUser->getFirstname()}"
>
</div>
<!-- Champ : nom de l'utilisateur -->
<div class="col-md-6">
<label class="form-label" for="user_name">
Nom *
Nom
</label>
<input
class="form-control"
type="text"
id="user_name"
name="user_name"
required
value="{$objUser->getName()}"
>
</div>
<!-- Champ : pseudo -->
<div class="col-12">
<label class="form-label" for="user_pseudo">
Pseudo *
Pseudo
</label>
<div class="input-group">
<span class="input-group-text">@</span>
@ -72,53 +66,44 @@
type="text"
id="user_pseudo"
name="user_pseudo"
required
value="{$objUser->getPseudo()}"
>
</div>
</div>
<!-- Champ : adresse e-mail -->
<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 *
Adresse e-mail
</label>
<input
class="form-control"
type="email"
id="user_mail"
name="user_mail"
required
value="{$objUser->getMail()}"
>
</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
@ -128,10 +113,11 @@
type="text"
id="user_phone"
name="user_phone"
value="{$objUser->getPhone()}"
>
</div>
<!-- Champ optionnel : profession de l'utilisateur -->
<div class="col-12">
<label class="form-label" for="user_work">
Profession
@ -141,10 +127,11 @@
type="text"
id="user_work"
name="user_work"
value="{$objUser->getWork()}"
>
</div>
<!-- Champ optionnel : localisation de l'utilisateur -->
<div class="col-12">
<label class="form-label" for="user_location">
Localisation
@ -154,10 +141,11 @@
type="text"
id="user_location"
name="user_location"
value="{$objUser->getLocation()}"
>
</div>
<!-- Champ optionnel : phrase d'accroche -->
<div class="col-12">
<label class="form-label" for="user_description">
Phrase d'accroche
@ -167,23 +155,17 @@
id="user_description"
name="user_description"
rows="3"
></textarea>
>
{$objUser->getDescription()}
</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
Edit profile
</button>
</div>
<!-- Lien vers la page de connexion -->
<div class="col-12 text-center">
<small class="text-secondary">
Déjà un compte ?
<a href="index.php?ctrl=user&action=login">Se connecter</a>
</small>
</div>
</form>
</div>