mirror of
https://github.com/R0m1k3/PleinR.git
synced 2026-10-22 06:38:05 +02:00
- Espace adhérent : /backend/espace (profil, inscriptions, droit à l'image) et /backend/espace/promotions (dépôt et suivi). Bandeau et onglets communs (EspaceHeader) avec le nombre d'offres en ligne ; la page promotions ouvre sur « Mes promotions en cours », puis le formulaire, puis les offres en attente et l'historique. Deux entrées dans le menu, titres de page dédiés, revalidation des deux chemins. - Fiche adhérent : colonne members.contact_email (migration 0013), saisie dans l'espace adhérent et la fiche staff ; la fiche publique et le JSON-LD affichent contact_email, sinon l'e-mail du compte. - VitrineImage : sans photo de couverture, le logo est contenu à ~60 % d'un cadre à hauteur fixe sur un fond du logo flouté ; le conteneur sans hauteur qui laissait le logo déborder est supprimé. - Promotions : la catégorie devient un type de produit ou de service (src/lib/promo-categories.ts, 10 groupes, ~85 entrées) pré-sélectionné depuis le métier de l'adhérent, à la place de la liste des métiers. - Tests : catégories de promo (largeur, unicité, pré-sélection pour chaque métier du référentiel). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HDbKbJrPWweXXYSxA8MXW7
63 lines
2.5 KiB
TypeScript
63 lines
2.5 KiB
TypeScript
import Link from "next/link";
|
|
|
|
function initialsOf(name: string) {
|
|
return name.split(/\s+/).map((w) => w[0]).join("").slice(0, 2).toUpperCase();
|
|
}
|
|
|
|
const TABS = [
|
|
{ key: "profil", href: "/backend/espace", label: "Mon profil" },
|
|
{ key: "promotions", href: "/backend/espace/promotions", label: "Mes promotions" },
|
|
] as const;
|
|
|
|
export type EspaceTab = (typeof TABS)[number]["key"];
|
|
|
|
/**
|
|
* Bandeau de l'espace adhérent et onglets Profil / Promotions : deux pages
|
|
* distinctes pour que la fiche publique et la vie des promotions ne se
|
|
* mélangent pas dans une seule longue page.
|
|
*/
|
|
export function EspaceHeader({
|
|
memberName,
|
|
subtitle,
|
|
active,
|
|
publicPath,
|
|
promoBadge,
|
|
}: {
|
|
memberName: string;
|
|
subtitle: string;
|
|
active: EspaceTab;
|
|
publicPath?: string | null;
|
|
/** Nombre de promotions en ligne, affiché sur l'onglet. */
|
|
promoBadge?: number;
|
|
}) {
|
|
return (
|
|
<div style={{ marginBottom: 22 }}>
|
|
<div style={{ background: "#13324F", borderRadius: "16px 16px 0 0", padding: "20px 24px", display: "flex", alignItems: "center", gap: 15, flexWrap: "wrap" }}>
|
|
<span className="font-display" style={{ width: 46, height: 46, borderRadius: 12, background: "#E0A63C", color: "#33291D", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 800, fontSize: 16, flexShrink: 0 }}>
|
|
{initialsOf(memberName)}
|
|
</span>
|
|
<div style={{ flex: 1, minWidth: 200 }}>
|
|
<div className="font-display" style={{ fontWeight: 700, fontSize: 18, color: "#fff" }}>{memberName}</div>
|
|
<div style={{ fontSize: 13, color: "#9bb6cd" }}>{subtitle}</div>
|
|
</div>
|
|
{publicPath && (
|
|
<Link href={publicPath} target="_blank" style={{ color: "#fff", border: "1px solid rgba(255,255,255,0.35)", borderRadius: 10, padding: "8px 14px", fontSize: 13, fontWeight: 700, textDecoration: "none", whiteSpace: "nowrap" }}>
|
|
Voir ma fiche publique ↗
|
|
</Link>
|
|
)}
|
|
</div>
|
|
<nav className="espace-tabs" aria-label="Sections de l'espace adhérent">
|
|
{TABS.map((tab) => {
|
|
const isActive = tab.key === active;
|
|
return (
|
|
<Link key={tab.key} href={tab.href} className={`espace-tab${isActive ? " active" : ""}`} aria-current={isActive ? "page" : undefined}>
|
|
{tab.label}
|
|
{tab.key === "promotions" && promoBadge ? <span className="espace-tab__badge">{promoBadge}</span> : null}
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
</div>
|
|
);
|
|
}
|