- JavaScript 82.3%
- CSS 16.9%
- HTML 0.6%
- Dockerfile 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Le .mjs était servi en application/octet-stream en production, ce qui bloque le chargement du module worker (feuilletage du Quintinais). En .js, le type MIME est correct quelle que soit la configuration du serveur. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> |
||
| scripts | ||
| src | ||
| .dockerignore | ||
| .gitignore | ||
| actualites-page.png | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| eslint.config.js | ||
| index.html | ||
| nginx.conf | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| vite.config.js | ||
Site institutionnel — Mairie de Quintin
Site vitrine officiel de la ville de Quintin (Côtes d'Armor, Bretagne), construit avec React et Vite. Les contenus sont gérés via des fichiers JSON pour une mise à jour simple et rapide.
Stack technique
| Technologie | Rôle |
|---|---|
| Vite | Build tool & dev server (HMR) |
| React 18 | Bibliothèque UI |
| React Router v6 | Routage client (BrowserRouter) |
| react-helmet-async | Gestion des balises meta / SEO |
| CSS pur + variables | Design system (pas de framework CSS) |
Structure du projet
static-site/
├── public/
│ └── images/ # Images du site (logo, photos, etc.)
├── src/
│ ├── components/
│ │ ├── layout/ # Header, Footer, Layout (gabarit global)
│ │ ├── ui/ # Bibliothèque de composants réutilisables
│ │ └── icons/ # Icônes SVG (12 icônes disponibles)
│ ├── data/ # Contenus du site (fichiers JSON)
│ ├── pages/ # Pages (Accueil, Visiter, Agenda, Services, Contact)
│ └── styles/ # Feuilles de style
│ ├── tokens.css # Design tokens (couleurs, typo, espacements)
│ ├── global.css # Reset, base, typographie
│ └── components.css # Styles de tous les composants
├── index.html
├── package.json
└── vite.config.js
Installation
npm install
Commandes
# Mode développement
npm run dev
# → http://localhost:5173
# Build production
npm run build
# → dossier dist/
# Prévisualiser la build
npm run preview
Mettre à jour le contenu
Tout le contenu éditable se trouve dans les fichiers JSON du dossier src/data/. Le HMR (Hot Module Replacement) de Vite met à jour le navigateur instantanément dès qu'un fichier est modifié.
Fichiers de données
| Fichier | Contenu |
|---|---|
navigation.json |
Menu principal : logo, liens de navigation, bouton contact |
home.json |
Page d'accueil : hero vidéo, accès rapides, actualités, mosaïque photos, camping, coordonnées |
visit.json |
Page Visiter : patrimoine, sorties & loisirs, camping, office de tourisme |
agenda.json |
Page Agenda : événements (avec filtres culture/sport/municipal), actualités, magazine Le Quintinais |
services.json |
Page Services : démarches administratives, services de proximité, horaires |
contact.json |
Page Contact : adresse, téléphone, email, horaires, carte |
footer.json |
Pied de page : marque, navigation, liens utiles, mentions légales |
Le Quintinais de Noël (archives + moteur de recherche)
Page /quintinais-de-noel (src/pages/QuintinaisDeNoel.jsx) : recherche dans les 1 085 articles des 49 numéros de 1969 à 2022 (titre, auteur, thématique, numéro, texte intégral).
| Élément | Emplacement | Versionné ? |
|---|---|---|
| Index des articles (titre, page, auteurs, thématiques) | src/data/quintinais-de-noel/index.json |
oui |
| Texte intégral OCR, un fichier par numéro | public/data/quintinais-de-noel/texte/<année>.json |
non (public/) |
| PDF des numéros | public/documents/quintinais-de-noel/<fichier>.pdf (le nom du fichier est le champ fichier de l'index) |
non (public/) |
Chaque numéro peut être feuilleté (visionneuse tourne-page : src/components/quintinais/FlipbookViewer.jsx, avec page-flip et pdfjs-dist, chargée à la demande), lu en PDF, téléchargé ou fouillé mot à mot ; sur mobile la visionneuse passe en mode « slide » plein écran (balayage horizontal, options repliées). Les liens d'articles ouvrent la visionneuse (Ctrl/Maj + clic : PDF). Les couvertures sont dans public/documents/quintinais-de-noel/couvertures/<fichier>.webp.
Les PDF et le texte intégral sont servis depuis public/ : après les avoir ajoutés ou modifiés, les synchroniser vers le VPS (voir « Livrer une nouvelle version »). L'index et le texte intégral sont générés à partir du sommaire des numéros ; ils ne sont pas à éditer à la main. Pour ajouter le numéro de l'année suivante : ajouter une entrée numeros dans index.json (même structure que les précédentes), déposer le PDF et créer texte/<année>.json ({"annee": 2023, "pages": ["texte page 1", ...]}, une chaîne par page du PDF).
Ajouter une actualité
Dans le fichier home.json, section "news" :
{
"image": "/images/ma-photo.jpg",
"date": "15 juin 2026",
"title": "Titre de l'actualité",
"desc": "Description courte…",
"tag": { "label": "Culture", "variant": "orange" }
}
Variants de tag disponibles : orange (Culture), green (Tourisme/Sport), neutral (Municipal/Vie locale), "" (défaut).
Ajouter un événement à l'agenda
Dans le fichier agenda.json, section "events" :
{
"date": "1 — 3 août 2026",
"title": "Nom de l'événement",
"desc": "Description…",
"tag": { "label": "Culture", "variant": "orange" },
"organizer": "Organisateur"
}
Le filtrage par catégorie se base sur le variant du tag : orange → Culture, green → Sport, neutral → Municipal.
Ajouter une page
- Créez le fichier de données dans
src/data/(ex:histoire.json) - Créez le composant page dans
src/pages/(ex:Histoire.jsx) - Ajoutez la route dans
src/App.jsx - Ajoutez le lien dans
src/data/navigation.json
Remplacer les images
Les images sont stockées dans public/images/. Remplacez les fichiers SVG de placeholder par vos images réelles (PNG, JPG, WebP) en conservant les mêmes noms de fichier, ou mettez à jour les chemins dans les fichiers JSON.
Composants disponibles
Dans src/components/ui/ :
| Composant | Props | Variants |
|---|---|---|
Button |
variant, to, href, arrow |
primary, secondary, ghost, outline |
Tag |
label, variant |
green, orange, neutral |
Grid |
cols |
2, 3, 4, 1-2, 2-1 |
Section |
children, className |
— |
Hero |
title, lead, buttons, badge, videoUrl |
Texte ou vidéo |
Card |
children |
— |
Eyebrow |
children |
— |
LogRow |
image, date, title, desc, tag |
Ligne d'actualité |
EventCard |
date, title, desc, tag, organizer |
Carte d'événement |
SiteCard |
image, title, desc |
Carte tourisme (image + hover zoom) |
Feature |
icon, title, desc |
Service / activité |
QATile |
icon, label, desc, path |
Accès rapide |
ContactItem |
icon, label, value |
Coordonnées |
PhotoMosaic |
images[] |
Galerie photos |
FilterBar |
filters[], active, onFilter |
Filtres agenda |
InfoTable |
rows[] |
Tableau horaires |
Stack |
size |
xs, sm, md, lg, xl |
Row |
between |
Flex row |
Container |
children |
Max-width wrapper |
Pill |
children |
Badge coloré |
Icônes disponibles
Dans src/components/icons/ : map-pin, phone, mail, clock, passport, camping, calendar, building, family, election, cinema, music, swim.
Utilisation dans les composants : <Icon name="map-pin" size={20} /> ou via icon="map-pin" sur Feature, QATile, ContactItem.
Build de production
npm run build
Le dossier dist/ contient les fichiers statiques prêts à être déployés sur n'importe quel serveur (Nginx, Apache, Netlify, Vercel, etc.).
Déploiement — configuration serveur
Puisque le site utilise un BrowserRouter (URLs propres sans #), le serveur doit rediriger toutes les requêtes vers index.html :
Nginx :
location / {
try_files $uri $uri/ /index.html;
}
Apache (.htaccess) :
FallbackResource /index.html
Netlify (_redirects) :
/* /index.html 200
Livrer une nouvelle version
Le déploiement est géré par Coolify à partir du Dockerfile : un git push sur la branche de production déclenche le build et le redéploiement de l'application (voir Dockerfile / nginx.conf).
Le dossier public/ (images, PDF, documents) n'est cependant pas servi depuis l'image Docker : nginx.conf sert en priorité les fichiers du volume persistant /data/public sur le VPS, avec repli sur le build applicatif (try_files $uri @built). Après avoir ajouté ou modifié des fichiers dans public/, il faut donc aussi les synchroniser manuellement vers ce volume :
scp -r "E:/Quintin/websites/site-internet-static/public/*" quintin-vps:/opt/data/site-internet-static/public/
Ou, depuis WSL/Linux (nécessite rsync, absent de Git Bash sous Windows) — ne transfère que les fichiers nouveaux ou modifiés, plus rapide que scp -r une fois le premier envoi effectué :
rsync -avz --progress "/mnt/e/Quintin/websites/site-internet-static/public/" quintin-vps:/opt/data/site-internet-static/public/
Pour aussi supprimer sur le VPS les fichiers qui n'existent plus localement dans public/, ajouter --delete à la commande rsync — à utiliser avec précaution (vérifier d'abord avec --dry-run) car cela peut effacer des fichiers ajoutés uniquement côté serveur.
Étapes complètes pour livrer une nouvelle version :
- Commiter et pousser les changements de code/contenu (
git push) → Coolify rebuild et redéploie automatiquement. - Si des fichiers ont été ajoutés/modifiés dans
public/, les synchroniser vers le VPS avec la commandescpoursyncci-dessus.
Personnalisation du design
Tous les tokens de design sont dans src/styles/tokens.css :
:root {
--bg: #fdfdf8; /* Fond de page */
--accent: #da412a; /* Couleur principale (liens, accents) */
--surface: #eeefe9; /* Fond des cartes */
--fg: #23251d; /* Texte des titres */
--fg-body: #4d4f46; /* Texte des paragraphes */
--border: #bfc1b7; /* Bordures */
--font-display: "IBM Plex Sans", ...;
--font-mono: "Source Code Pro", ...;
/* etc. */
}
Modifiez les variables CSS pour changer l'apparence globale du site.