Promotions : logo de l'adhérent dans l'angle des cartes

Le logo du commerce identifie l'offre avant même qu'on lise le nom. Il est
posé en pastille ronde dans l'angle haut-gauche de la carte, la catégorie se
décalant juste à côté sur la même ligne.

- `src/components/MemberAvatar.tsx` : logo en `contain` sur fond blanc (les
  logos d'adhérents sont des marques sur fond clair, un `cover` les rognerait),
  repli sur les initiales colorées quand la fiche n'a pas de logo.
- Appliqué à la carte d'accueil, à la carte de la fiche adhérent, à l'aperçu
  en direct de l'espace adhérent et à la carte de modération : même composition
  partout, l'aperçu montre donc bien ce que verra le visiteur.
- `getLivePromotions` remonte `members.logo_url` ; la page espace le passe au
  formulaire.

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-09-06 14:02:53 +00:00
1 parent e980ab6e04
commit d99ee7ec07
7 files changed
+126 -25

No files matched your search

+11 -5
View File
@@ -7,6 +7,7 @@ import { can } from "@/lib/rbac";
import { configuredNetworks, SOCIAL_LABELS } from "@/lib/social";
import { moderatePromo, retryPromoShare } from "../actions";
import { PromoImage } from "@/components/PromoImage";
import { MemberAvatar } from "@/components/MemberAvatar";
import { SOCIAL_BRAND, SocialIcon } from "@/components/SocialIcons";
import { formatValidity, visibilityNote } from "@/lib/promo-validity";
import { formatSchedule, scheduleLabel, toScheduleInput } from "@/lib/promo-schedule";
@@ -54,6 +55,7 @@ export default async function PromotionsPage() {
shareFacebook: promotions.shareFacebook,
shareLinkedin: promotions.shareLinkedin,
memberName: members.name,
memberLogoUrl: members.logoUrl,
})
.from(promotions)
.leftJoin(members, eq(promotions.memberId, members.id))
@@ -157,11 +159,15 @@ export default async function PromotionsPage() {
}}
>
{p.imageUrl && <PromoImage src={p.imageUrl} alt={p.title ?? ""} />}
{p.category && (
<span style={{ position: "absolute", top: 10, left: 10, background: "#9a6638", color: "#fff", borderRadius: 999, padding: "4px 11px", fontSize: 11, fontWeight: 700 }}>
{p.category}
</span>
)}
{/* Comme sur le site : logo de l'adhérent puis catégorie. */}
<div style={{ position: "absolute", top: 10, left: 10, display: "flex", alignItems: "center", gap: 7 }}>
<MemberAvatar name={p.memberName ?? ""} logoUrl={p.memberLogoUrl} size={30} />
{p.category && (
<span style={{ background: "#9a6638", color: "#fff", borderRadius: 999, padding: "4px 11px", fontSize: 11, fontWeight: 700 }}>
{p.category}
</span>
)}
</div>
<span
style={{
position: "absolute",