Page Association : mission développée et bloc « ce que l'association apporte »

Le bandeau Mission tenait en une phrase et ne disait pas ce que l'adhésion
apporte concrètement.

- Mission réécrite en trois paragraphes : le réseau et les rencontres, la mise
  en avant de chaque adhérent auprès des habitants et des professionnels, et
  l'objectif double clients de proximité / courants d'affaires locaux.
- Nouveau bloc de quatre cartes sous le bandeau : se rencontrer, gagner en
  visibilité (site et réseaux sociaux), attirer des clients en B to C,
  développer des affaires en B to B.
- Les deux contenus sont éditables dans Paramètres : la mission accepte des
  paragraphes séparés par une ligne vide, les apports suivent la convention
  « Titre|Description » déjà utilisée pour le directoire.
- Migration 0009 : le texte de mission n'est remplacé que s'il est resté celui
  d'origine, une version réécrite à la main n'est jamais écrasée.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QXNXRC4j5VLfKvpyyisrnb
This commit is contained in:
Claude committed 2026-07-25 08:36:51 +00:00
1 parent e86c67c17e
commit fb3d5e337e
7 files changed
+1525 -13

No files matched your search

+54 -11
View File
@@ -6,7 +6,13 @@ import { meetingRegistrations, meetings, pastMeetingPhotos, pastMeetings } from
import { PastMeetingGallery } from "@/components/PastMeetingGallery";
import { SiteFooter } from "@/components/SiteFooter";
import { SiteHeader } from "@/components/SiteHeader";
import { getSiteSettings, parseBoardMembers, splitLines } from "@/lib/site-settings";
import {
getSiteSettings,
parseBoardMembers,
parseParagraphs,
parsePillars,
splitLines,
} from "@/lib/site-settings";
export const dynamic = "force-dynamic";
@@ -96,6 +102,8 @@ export default async function AssociationPage() {
["Secrétariat", settings.association_secretary],
].filter(([, name]) => name);
const board = parseBoardMembers(settings.association_board_members);
const missionParagraphs = parseParagraphs(settings.association_mission);
const pillars = parsePillars(settings.association_pillars);
return (
<div style={{ background: "#F6F2E8", minHeight: "100vh", fontFamily: "'Public Sans',sans-serif", color: "#33291D" }}>
@@ -117,18 +125,53 @@ export default async function AssociationPage() {
</section>
<section style={{ background: "#13324F", color: "#fff" }}>
<div className="container grid grid-2" style={{ paddingTop: 44, paddingBottom: 44, alignItems: "start" }}>
<div>
<div style={{ color: "#E0A63C", fontSize: 12, letterSpacing: "0.14em", textTransform: "uppercase", fontWeight: 800, marginBottom: 10 }}>
Mission
<div className="container" style={{ paddingTop: 44, paddingBottom: 48 }}>
<div className="grid grid-2" style={{ alignItems: "start" }}>
<div>
<div style={{ color: "#E0A63C", fontSize: 12, letterSpacing: "0.14em", textTransform: "uppercase", fontWeight: 800, marginBottom: 10 }}>
Mission
</div>
<h2 className="font-display" style={{ margin: 0, fontSize: "clamp(28px, 4vw, 44px)" }}>
Réseau, rencontres, réussite locale.
</h2>
</div>
<div>
{missionParagraphs.map((paragraph, index) => (
<p
key={index}
style={{
margin: index === 0 ? 0 : "14px 0 0",
color: "#cfe0ee",
fontSize: 16,
lineHeight: 1.75,
}}
>
{paragraph}
</p>
))}
</div>
<h2 className="font-display" style={{ margin: 0, fontSize: "clamp(28px, 4vw, 44px)" }}>
Réseau, rencontres, réussite locale.
</h2>
</div>
<p style={{ margin: 0, color: "#cfe0ee", fontSize: 16, lineHeight: 1.75 }}>
{settings.association_mission}
</p>
{pillars.length > 0 && (
<>
<div style={{ color: "#E0A63C", fontSize: 12, letterSpacing: "0.14em", textTransform: "uppercase", fontWeight: 800, margin: "44px 0 16px" }}>
Ce que l&apos;association vous apporte
</div>
<div className="pillars-grid">
{pillars.map((pillar, index) => (
<article key={pillar.title} className="pillar-card">
<span className="font-display pillar-card__index">
{String(index + 1).padStart(2, "0")}
</span>
<h3 className="font-display pillar-card__title">{pillar.title}</h3>
{pillar.description && (
<p className="pillar-card__text">{pillar.description}</p>
)}
</article>
))}
</div>
</>
)}
</div>
</section>
+10 -1
View File
@@ -41,7 +41,16 @@ export default async function ParametresPage() {
<Field label="Adresse" name="association_address" value={settings.association_address} />
</div>
<Area label="Texte d'introduction Association" name="association_intro" value={settings.association_intro} />
<Area label="Mission" name="association_mission" value={settings.association_mission} />
<Area
label="Mission (une ligne vide sépare les paragraphes)"
name="association_mission"
value={settings.association_mission}
/>
<Area
label="Ce que l'association apporte (Titre|Description, une ligne par point)"
name="association_pillars"
value={settings.association_pillars}
/>
</div>
<div style={{ marginTop: 14, color: "#9a6638", fontSize: 13, lineHeight: 1.6 }}>
Les pages Facebook et LinkedIn s&apos;affichent sur la page d&apos;accueil et dans le pied
+43
View File
@@ -449,6 +449,49 @@ img {
-webkit-overflow-scrolling: touch;
}
/* ---- « Ce que l'association vous apporte » (page Association) ---- */
.pillars-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 14px;
}
.pillar-card {
padding: 18px 18px 20px;
border: 1px solid rgba(255, 255, 255, 0.14);
border-radius: 16px;
background: rgba(255, 255, 255, 0.05);
}
.pillar-card__index {
color: var(--gold);
font-size: 13px;
font-weight: 800;
letter-spacing: 0.08em;
}
.pillar-card__title {
margin: 8px 0 7px;
color: #fff;
font-size: 17px;
font-weight: 700;
line-height: 1.25;
}
.pillar-card__text {
margin: 0;
color: #a9c4da;
font-size: 13.5px;
line-height: 1.65;
}
@media (max-width: 1024px) {
.pillars-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 620px) {
.pillars-grid {
grid-template-columns: 1fr;
}
}
/* ---- Compteurs du tableau de bord ---- */
.stat-card {
padding: 20px;