Version temporaire du site généré à partir d'une stack React
  • JavaScript 82.3%
  • CSS 16.9%
  • HTML 0.6%
  • Dockerfile 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Gaetan c7fdbcb828 Publie le worker PDF.js en .js plutôt qu'en .mjs
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>
2026-10-08 15:54:02 +02:00
scripts news update 2026-10-08 09:54:07 +02:00
src news update 2026-10-08 09:54:07 +02:00
.dockerignore Corrige le build Docker cassé par le symlink chromium-browser d'Alpine 2026-09-11 12:26:22 +02:00
.gitignore First version 2026-09-06 16:32:35 +02:00
actualites-page.png First version 2026-09-06 16:32:35 +02:00
CLAUDE.md Ajoute les règles Performance et Accessibilité dans CLAUDE.md 2026-09-11 00:51:34 +02:00
docker-compose.yml First version 2026-09-06 16:32:35 +02:00
Dockerfile Corrige le build Docker cassé par le symlink chromium-browser d'Alpine 2026-09-11 12:26:22 +02:00
eslint.config.js First version 2026-09-06 16:32:35 +02:00
index.html Ajoute une barre d'accessibilité (thème sombre, contraste, taille du texte) 2026-09-10 16:04:32 +02:00
nginx.conf Sert le worker PDF.js (.mjs) en JavaScript pour le feuilletage du Quintinais 2026-10-08 13:21:17 +02:00
package-lock.json news update 2026-10-08 09:54:07 +02:00
package.json news update 2026-10-08 09:54:07 +02:00
README.md news update 2026-10-08 09:54:07 +02:00
vite.config.js Publie le worker PDF.js en .js plutôt qu'en .mjs 2026-10-08 15:54:02 +02:00

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

  1. Créez le fichier de données dans src/data/ (ex: histoire.json)
  2. Créez le composant page dans src/pages/ (ex: Histoire.jsx)
  3. Ajoutez la route dans src/App.jsx
  4. 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 :

  1. Commiter et pousser les changements de code/contenu (git push) → Coolify rebuild et redéploie automatiquement.
  2. Si des fichiers ont été ajoutés/modifiés dans public/, les synchroniser vers le VPS avec la commande scp ou rsync ci-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.