mirror of
https://github.com/R0m1k3/PleinR.git
synced 2026-10-22 06:38:05 +02:00
`/promotions` liste toutes les offres en cours ; l'accueil en montre six et renvoie vers elle. Les deux listes partagent `PromoCard`, extrait de la page d'accueil : un seul rendu de carte à maintenir. - `getLivePromotions(limit)` accepte `null` pour « toutes les offres », la limite restant appliquée en SQL et non après coup. - Page complète : `<h1>` unique, `<main>`, métadonnées et canonique via `pageMetadata`, JSON-LD `BreadcrumbList` + `ItemList`, entrée au sitemap, état vide qui renvoie vers l'annuaire. - Les liens « Promotions » de l'en-tête, du pied de page et de l'espace adhérent visent désormais cette page. Idem pour le lien d'une publication réseau sans adhérent rattaché, qui pointait sur l'ancre `/#promotions`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QXNXRC4j5VLfKvpyyisrnb
92 lines
3.4 KiB
TypeScript
92 lines
3.4 KiB
TypeScript
import Link from "next/link";
|
|
import { getSiteSettings, socialLinks } from "@/lib/site-settings";
|
|
import { ContactModalButton } from "./ContactModalButton";
|
|
import { SOCIAL_BRAND, SocialIcon } from "./SocialIcons";
|
|
|
|
export async function SiteFooter() {
|
|
const year = new Date().getFullYear();
|
|
const settings = await getSiteSettings();
|
|
const socials = socialLinks(settings);
|
|
|
|
const email = settings.association_email.trim();
|
|
const phone = settings.association_phone.trim();
|
|
const address = settings.association_address.trim();
|
|
const hasContact = !!(email || phone || address);
|
|
|
|
return (
|
|
<footer className="site-footer">
|
|
<div className="container" style={{ paddingTop: 40, paddingBottom: 26 }}>
|
|
<div className="footer-grid">
|
|
<div className="footer-brand">
|
|
<Link href="/" aria-label="Plein R — accueil" style={{ display: "inline-flex" }}>
|
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
<img src="/assets/logo.png" alt="Plein R" />
|
|
</Link>
|
|
<p className="footer-tagline">
|
|
Association des commerçants et entreprises du Bassin de Pompey.
|
|
Réseau · Rencontre · Réussite.
|
|
</p>
|
|
</div>
|
|
|
|
<div>
|
|
<div className="footer-title">Accès rapide</div>
|
|
<div className="footer-links">
|
|
<Link href="/annuaire">Annuaire</Link>
|
|
<Link href="/promotions">Promotions</Link>
|
|
<Link href="/association">L'association</Link>
|
|
<Link href="/rencontres-passees">Rencontres passées</Link>
|
|
<Link href="/login">Espace adhérent</Link>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<div className="footer-title">Informations</div>
|
|
<div className="footer-links">
|
|
<ContactModalButton label="Nous contacter" />
|
|
<Link href="/mentions-legales">Mentions légales</Link>
|
|
<Link href="/confidentialite">Confidentialité</Link>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
{socials.length > 0 && (
|
|
<>
|
|
<div className="footer-title">Nous suivre</div>
|
|
<div className="footer-social">
|
|
{socials.map((s) => (
|
|
<a
|
|
key={s.network}
|
|
href={s.href}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
aria-label={`Plein R sur ${s.label}`}
|
|
>
|
|
<span style={{ color: SOCIAL_BRAND[s.network], display: "inline-flex", width: 17, flexShrink: 0 }}>
|
|
<SocialIcon network={s.network} size={17} />
|
|
</span>
|
|
{s.label}
|
|
</a>
|
|
))}
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
{hasContact && (
|
|
<div className="footer-contact">
|
|
{email && <a href={`mailto:${email}`}>{email}</a>}
|
|
{phone && <a href={`tel:${phone.replace(/[^\d+]/g, "")}`}>{phone}</a>}
|
|
{address && <span>{address}</span>}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="footer-bottom">
|
|
<span>© {year} Plein R. Tous droits réservés.</span>
|
|
<span className="footer-bottom__place">Bassin de Pompey</span>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
);
|
|
}
|