Les visuels promo sont carrés (posts Facebook) : un cadre 1200/630 laissait des
bandes floues sur les côtés. Passage du cadre image en 1:1 partout (accueil,
fiche, aperçu espace adhérent, modération) → les images carrées remplissent
sans bords. Conseil d'upload : image carrée (1080×1080).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
Aligne les cartes promo sur la dernière refonte Claude Design : la zone image
passe d'une hauteur fixe à un ratio 1200/630, au-dessus du composant PromoImage
existant (remplissage flou + contain). Appliqué à l'accueil, la fiche adhérent,
l'aperçu de l'espace adhérent et la modération. Conseil d'upload : 1200×630.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
Replace cover-crop background with PromoImage component: sharp
contain image over a blurred cover copy. Whole image visible on
any aspect ratio, no flat letterbox bars. Applied to accueil,
adherent profile, backend promotions, member space preview +
upload dropzone.
Also retheme adherent logo frame (cream gradient + warm border)
instead of flat white.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Anti-debordement horizontal global (overflow-x hidden, img max-width)
- Container : padding reduit a 16px sous 640px
- En-tete/pied de page : padding horizontal fluide (clamp), en-tete wrap
- Titres principaux en clamp() (accueil hero/h2, annuaire, fiche) pour
ne plus deborder sur petit ecran
- Liste adherents du back-office : defilement horizontal (.table-scroll)
au lieu de colonnes ecrasees
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Avatar logo de la fiche adherent : <img> object-fit contain centre,
cadre a overflow hidden -> plus de debordement quel que soit le ratio
- ImageField : prop fit (cover|contain). Champs logo en contain (apercu
centre, non etire) dans l'edition fiche et l'espace adherent
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Quand un adherent n'a pas de photo de couverture mais un logo, le logo
n'est plus etire en plein cadre : il est centre et contenu (~80%) sur
fond blanc. Composant partage VitrineImage applique a l'annuaire, au
carrousel d'accueil et a la fiche adherent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Retire le kill-switch prefers-reduced-motion (* { animation:none }) qui
coupait toutes les animations : etoiles, flottement du logo, apparitions
au defilement ne bougeaient pas. Animations desormais toujours actives.
- Nouveau StarField : champ d'etoiles qui scintillent ET derivent
(keyframe plr-drift via propriete translate, cumulee au scintillement),
place dans le hero. Contenu du hero passe au-dessus (z-index).
- Carrousel : fondu force (n'est plus desactive sous reduced-motion).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Remplace le defilement continu par 3 cartes fixes et propres. Toutes
les 20 s, les cartes disparaissent une a une (fondu decale) puis les
3 suivantes apparaissent une a une. Rotation equitable sur tous les
adherents actifs. Respecte prefers-reduced-motion (bascule sans fondu).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Hero : logo centre verticalement (alignItems center)
- Titre "A l'honneur ce mois-ci" -> "A l'honneur"
- Remplace les 3 fiches "mise en avant" par un carrousel auto-defilant
de tous les adherents actifs, en rotation equitable (l'ordre pivote
d'un cran par heure). Pause au survol, respecte prefers-reduced-motion.
- Retire la coche "Mettre a l'honneur" du back-office (edition adherent)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Constante BASSIN_POMPEY_COMMUNES (13 communes) dans src/lib/communes.ts
- Champ commune devenu un select dans : ajout adherent, edition fiche,
espace adherent. communeOptions() conserve une valeur existante hors liste.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
L'entete de la fiche utilise coverUrl, sinon logoUrl, sinon placeholder
(meme logique que les cartes de l'annuaire).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- approveMembershipRequest : cree la fiche adherent (statut actif) et son
compte de connexion (mot de passe temporaire), marque la demande approuvee
- Bouton "Approuver & creer" redirige vers la fiche (login + mdp visibles)
- Demande sans e-mail : erreur explicite (creation manuelle requise)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Le login et le mot de passe temporaire s'affichent sur la fiche de
l'adherent. Apres creation, AddMemberPanel redirige desormais vers
/backend/adherents/[id] pour les rendre visibles immediatement.
addMember retourne l'id du nouvel adherent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- getActiveMembersWithCategory renvoie coverUrl + logoUrl
- Carte annuaire affiche l'image de vitrine (coverUrl) ; si absente,
bascule sur le logo (logoUrl) ; sinon placeholder raye
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Action createMissingMemberAccounts : cree un compte de connexion
(mdp temporaire a changer) pour chaque adherent ayant un e-mail mais
pas encore de compte. Ignore ceux sans e-mail ou e-mail deja pris.
- Banniere sur /backend/adherents : compte des fiches sans compte +
bouton "Creer les comptes manquants" (pas besoin de CLI serveur)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comptes de connexion adherent
- addMember cree desormais un compte users (role member, lie a la fiche)
avec un mot de passe temporaire genere
- Le mdp temporaire s'affiche sur la fiche admin (/backend/adherents/[id])
jusqu'a la 1ere connexion ; bouton "Reinitialiser le mot de passe"
- 1ere connexion : changement de mot de passe force (must_change_password)
via /backend/changer-mot-de-passe, redirection geree dans authorized()
- users += must_change_password, temp_password (migration 0003)
Boite de reception admin (consultation)
- Page /backend/demandes : demandes d'adhesion + messages de contact
avec statuts (approuvee/rejetee, lu/archive)
- Lien sidebar + badge (nouveaux), carte tableau de bord cliquable
Espace adherent
- L'adherent peut editer sa propre fiche (updateOwnProfile) : infos,
description, horaires, tags, image d'entete + logo
- Statut/categorie/mise a l'honneur restent reserves au staff
Promotions : moderation deja en place, inchangee.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Champs upload image d'entete (coverUrl) et logo (logoUrl) dans le
formulaire d'edition d'un adherent (composant ImageField, fichier ->
data-URL via hidden input)
- updateMember persiste desormais coverUrl + logoUrl, et revalide la
fiche publique /adherents/[id]
- serverActions.bodySizeLimit a 4mb (les data-URL depassent la limite
par defaut de 1mb)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Logo en haut a gauche de la page Annuaire (prop logo sur SiteHeader)
- Modal "Devenir adherent" sur les CTA accueil + annuaire : cree une
demande d'adhesion (membership_requests) et alerte les admins via le
journal d'activite (compteur tableau de bord deja cable)
- Formulaire de contact (modal depuis le pied de page) : nouvelle table
contact_messages + alerte admin
- Composant Modal partage, server actions publiques (sans auth)
- Migration drizzle 0002
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Nouvelle page /backend/categories : lister, ajouter (slug + couleur auto),
renommer et supprimer des catégories. Capacité RBAC manageCategories (admin) ;
lien ajouté à la barre latérale. La suppression détache les adhérents concernés
(transaction) pour éviter toute violation de clé étrangère.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
Seed enrichi avec ~59 catégories (bouche, mode/beauté, maison/bâtiment, auto,
santé, services aux particuliers & entreprises, loisirs/culture, industrie),
slugs existants conservés. Le select « Catégorie » de l'espace adhérent lit
désormais la liste depuis la base (plus de liste codée en dur). Insertion
idempotente : relancer le seed ajoute les nouvelles catégories sans doublon.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
- Menu identique sur toutes les pages publiques (Accueil, Annuaire, Promotions,
L'association, Espace adhérent) via SiteHeader/SiteFooter : on peut toujours
revenir à l'accueil depuis l'annuaire et inversement (page courante en gras).
- Retire la section « Parcourir par métier » de la page d'accueil.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
Enrichit la fiche : couverture + avatar, identité (catégorie, localisation,
adhérent depuis, boutons Appeler/Itinéraire), à propos multi-paragraphes + tags,
informations pratiques (horaires + contact tél/email/site), carte Google Maps,
colonne promotions en cours et CTA contact.
Ajoute les champs members: cover_url, phone, website, postal_code, member_since,
hours, tags (migration 0001) ; éditables dans le back-office ; seed enrichi
(Au Bon Pain conforme à la maquette).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
Liste des adhérents actifs avec recherche (nom/métier), filtre par commune,
filtres catégories (chips + compteurs), tri (A–Z / avec promotions), état vide
et CTA d'adhésion — fidèle à la maquette. Chaque carte ouvre la fiche adhérent
(/adherents/[id]). La recherche de l'accueil et la nav pointent vers /annuaire
(la barre de recherche pré-remplit via ?q=). Nouvelles requêtes annuaire.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
Profil public d'un commerçant : vitrine, catégorie, localisation, description,
bouton de contact et promotions en cours. Réservée aux adhérents actifs (404
sinon). Les cartes « À l'honneur » de l'accueil pointent désormais vers la fiche.
Nouvelles requêtes getPublicMember / getMemberLivePromotions.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
- deleteMember: supprime d'abord les promotions liées et détache les comptes
utilisateurs (transaction) avant de supprimer l'adhérent, ce qui évite la
violation de clé étrangère (erreur serveur au clic « Supprimer »).
- Logo: remplace le SVG provisoire par le logo officiel (public/assets/logo.png)
et met à jour toutes les références (accueil, login, backend, favicon).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
La redirection vers /login utilisait http://localhost:8413 (ancienne valeur par
défaut d'AUTH_URL). On retire ce défaut localhost : AUTH_URL prend la valeur
fournie (ex. https://pleinr.ffnancy.fr) et pilote la redirection. Ajout de
AUTH_TRUST_HOST=true (confiance aux en-têtes X-Forwarded-*) et l'entrypoint
supprime AUTH_URL si vide. Vérifié : la redirection pointe vers le domaine public.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
Le nom générique "postgres" entrait en collision avec d'autres conteneurs
"postgres" présents sur le réseau proxy partagé (nginx_default), d'où les
ECONNREFUSED vers de mauvaises IP. On utilise désormais pleinr-postgres,
unique et présent uniquement sur le réseau interne.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
Corrige ECONNREFUSED vers postgres:5432 apparu après l'ajout du réseau proxy.
Postgres et l'app sont désormais tous deux sur un réseau "internal" dédié
(résolution fiable de l'hôte "postgres"), l'app étant en plus sur le réseau
externe "proxy" pour le reverse proxy.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
Le conteneur app rejoint son réseau interne (accès Postgres) ET le réseau
externe partagé avec Nginx Proxy Manager, afin que NPM puisse l'atteindre par
nom (pleinr-app:3000) sans 504. Nom du réseau paramétrable via PROXY_NETWORK
(défaut: nginx_default).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
`next build` collecte les données de page en important les modules serveur sans
DATABASE_URL ; l'ancien client jetait une erreur dès l'import. Le client Drizzle
est désormais initialisé paresseusement (via un Proxy) à la première requête,
donc l'import est sans effet de bord et le build n'exige plus DATABASE_URL.
Vérifié : build OK sans variables d'env, et requêtes runtime OK via le proxy.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
Le compose ne requiert plus AUTH_SECRET (`:?` retiré). Si la variable est vide,
docker-entrypoint.sh génère un secret aléatoire et le persiste dans le volume
app-data (/app/data/auth_secret), réutilisé aux redémarrages. Surcharge possible
en définissant AUTH_SECRET. Déploiement Portainer sans configuration requise.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
- App : 8413 (hôte) → 3000 (conteneur)
- Postgres : 54329 (hôte) → 5432 (conteneur)
AUTH_URL, .env.example et README mis à jour en conséquence. Les ports internes
des conteneurs (3000, 5432) et DATABASE_URL (réseau interne) restent inchangés.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL