Refonte du bloc infos pratiques, suspension des promos et publication réseaux

Bloc « Informations pratiques » (fiche adhérent)
- Suppression des dégradés hors palette (radial doré de la section, dégradés
  crème/bleu des deux sous-cartes) au profit du vocabulaire visuel du site :
  carte blanche bordée, sous-cartes plates sur le fond de champ, variables CSS.
- La pastille « Préparer votre visite » devient une puce arrondie identique aux
  badges du reste du site ; le chip d'ouverture reprend les teintes de statut.
- Les glyphes texte ◷ et ↗ sont remplacés par des icônes SVG cohérentes.

Suspension des promotions
- Nouveau statut `suspended` + colonnes `suspended_by` / `suspended_by_id` /
  `suspended_at`.
- L'adhérent suspend et réactive ses propres promotions depuis Mon espace ;
  l'association suspend et réactive n'importe laquelle depuis le backoffice.
- Une suspension décidée par l'association ne peut pas être levée par
  l'adhérent : le motif est affiché dans son espace.
- Les lectures publiques filtrant déjà sur `live`, une promo suspendue quitte
  immédiatement l'accueil, l'annuaire et la fiche.

Publication Facebook / LinkedIn
- `src/lib/social.ts` : publication d'une promo en ligne sur la page Facebook
  (Graph API, upload multipart car les images sont en data-URI) et sur la page
  LinkedIn (Posts API + Images API en trois étapes).
- Jetons d'accès exclusivement en variables d'environnement ; un réseau non
  configuré masque son bouton.
- Table `social_posts` : chaque tentative est tracée, un échec est rattrapé et
  affiché sur la carte de la promo sans interrompre le backoffice.
- Nouvelle capacité RBAC `publishSocial` (admin + modérateur).

Liens sociaux publics
- Réglages `association_facebook` / `association_linkedin` éditables dans
  Paramètres, préremplis avec les pages de l'association.
- Section « Plein R sur les réseaux » sur l'accueil et icônes dans le pied de
  page, masquées si le réglage est vide.

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-24 22:20:51 +00:00
1 parent dd9697019c
commit e3a4771edf
20 files changed
+2370 -109

No files matched your search

+68 -55
View File
@@ -580,11 +580,9 @@ img {
.practical-section {
overflow: hidden;
padding: 26px 28px 28px;
border: 1px solid #e6dcc6;
border: 1px solid var(--border);
border-radius: 18px;
background:
radial-gradient(circle at 100% 0, rgba(224, 166, 60, 0.12), transparent 190px),
#fff;
background: #fff;
}
.practical-section__heading {
display: flex;
@@ -593,31 +591,44 @@ img {
gap: 18px;
margin-bottom: 20px;
}
/* Pastille de section, identique aux badges « Bons plans » du reste du site. */
.eyebrow {
color: #9a6638;
font-size: 10.5px;
display: inline-flex;
align-items: center;
gap: 8px;
padding: 5px 12px;
border-radius: 999px;
background: #fdeccd;
color: var(--brown);
font-size: 11.5px;
font-weight: 800;
letter-spacing: 0.14em;
letter-spacing: 0.1em;
text-transform: uppercase;
}
.eyebrow::before {
content: "";
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--gold);
}
.open-status {
display: flex;
align-items: center;
gap: 9px;
min-width: 154px;
padding: 8px 12px;
border: 1px solid #e7d3ce;
border-radius: 12px;
background: #fff8f6;
color: #9f3e2e;
padding: 8px 13px;
border: 1px solid #f2d5cf;
border-radius: 999px;
background: #fbe9e6;
color: var(--red);
}
.open-status > span {
width: 9px;
height: 9px;
width: 8px;
height: 8px;
flex: 0 0 auto;
border-radius: 50%;
background: #d8472b;
box-shadow: 0 0 0 4px rgba(216, 71, 43, 0.12);
background: var(--red);
}
.open-status div {
display: flex;
@@ -626,23 +637,25 @@ img {
}
.open-status strong {
font-size: 12.5px;
font-weight: 800;
line-height: 1.25;
}
.open-status small {
margin-top: 2px;
color: #916a61;
color: #b1786c;
font-size: 10.5px;
}
.open-status.is-open {
border-color: #cce7d7;
background: #f1faf5;
color: #176c48;
border-color: #c7e6d5;
background: #e6f4ec;
color: var(--green);
}
.open-status.is-open > span {
background: #1f8a5b;
box-shadow: 0 0 0 4px rgba(31, 138, 91, 0.12);
background: var(--green);
}
.open-status.is-open small {
color: #6d9d86;
}
.open-status.is-open small { color: #5d7f6e; }
.practical-grid {
display: grid;
grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
@@ -651,22 +664,17 @@ img {
.schedule-card,
.contact-card {
min-width: 0;
border: 1px solid #eadfca;
border-radius: 16px;
padding: 18px;
}
.schedule-card {
background: linear-gradient(145deg, #fffdf8, #fbf5e8);
}
.contact-card {
background: linear-gradient(145deg, #fff, #f3f7fa);
border: 1px solid var(--border-2);
border-radius: 16px;
background: var(--field-bg);
}
.practical-card-title {
display: flex;
align-items: center;
gap: 11px;
padding-bottom: 14px;
border-bottom: 1px solid rgba(216, 205, 180, 0.68);
border-bottom: 1px solid var(--border-2);
}
.practical-card-title__icon {
display: grid;
@@ -675,19 +683,21 @@ img {
flex: 0 0 auto;
place-items: center;
border-radius: 11px;
background: #f3dfb6;
color: #8c5f2e;
font-size: 20px;
font-weight: 800;
background: #f6efdc;
color: var(--brown);
}
.practical-card-title__icon svg {
width: 18px;
height: 18px;
}
.practical-card-title__icon--blue {
background: #dfeef5;
color: #2c6fb3;
background: #eaf0f6;
color: var(--blue);
}
.practical-card-title span:not(.practical-card-title__icon) {
display: block;
margin-bottom: 2px;
color: #a09279;
color: var(--muted-3);
font-size: 9.5px;
font-weight: 800;
letter-spacing: 0.12em;
@@ -695,8 +705,9 @@ img {
}
.practical-card-title h3 {
margin: 0;
color: #26201a;
color: var(--ink-strong);
font-size: 15.5px;
font-weight: 700;
line-height: 1.25;
}
.schedule-list {
@@ -710,14 +721,15 @@ img {
align-items: center;
gap: 12px;
min-height: 38px;
padding: 7px 8px;
border-radius: 9px;
color: #655b4c;
padding: 7px 9px;
border: 1px solid transparent;
border-radius: 10px;
color: var(--muted);
font-size: 12.5px;
}
.schedule-row.is-today {
border-color: var(--border);
background: #fff;
box-shadow: 0 5px 16px -12px rgba(80, 55, 22, 0.58);
}
.schedule-row__day {
display: flex;
@@ -727,20 +739,20 @@ img {
}
.schedule-row__day small {
margin-top: 1px;
color: #9a6638;
color: var(--brown);
font-size: 9px;
font-weight: 800;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.schedule-row > strong {
color: #352d22;
color: var(--ink-soft);
font-size: 12px;
font-weight: 700;
text-align: right;
}
.schedule-row > strong.is-closed {
color: #b16a5e;
color: var(--muted-4);
font-weight: 600;
}
.contact-actions {
@@ -758,12 +770,12 @@ img {
padding: 10px;
border: 1px solid transparent;
border-radius: 11px;
color: #4d4437;
color: var(--ink);
text-decoration: none;
transition: background 160ms ease, border-color 160ms ease, transform 160ms ease;
}
.contact-action:hover {
border-color: #d7e4eb;
border-color: var(--border);
background: #fff;
transform: translateX(2px);
}
@@ -773,8 +785,8 @@ img {
height: 34px;
place-items: center;
border-radius: 10px;
background: #eaf2f7;
color: #2c6fb3;
background: #eaf0f6;
color: var(--blue);
}
.contact-action__icon svg {
width: 17px;
@@ -786,24 +798,25 @@ img {
flex-direction: column;
}
.contact-action__copy strong {
color: #33291d;
color: var(--ink-strong);
font-size: 12.5px;
font-weight: 700;
}
.contact-action__copy > span {
overflow: hidden;
margin-top: 2px;
color: #7d715f;
color: var(--muted-2);
font-size: 10.5px;
text-overflow: ellipsis;
white-space: nowrap;
}
.contact-action__arrow {
color: #7f9db5;
color: var(--muted-4);
font-size: 14px;
}
.practical-empty {
padding: 20px 4px 8px;
color: #9b8e78;
color: var(--muted-4);
font-size: 13px;
}