mirror of
https://github.com/R0m1k3/PleinR.git
synced 2026-10-24 15:48:05 +02:00
Promotions : période de validité (date de début / date de fin)
Une promotion peut désormais porter une date de début et une date de fin, toutes deux facultatives et indépendantes. Sans date, rien n'est affiché. - Schéma : `promotions.starts_on` / `ends_on` (`date`), migration 0015. - `src/lib/promo-validity.ts` (pur, testé) : `formatValidity()` produit « Valable du 1er au 15 mars 2027 », « Valable jusqu'au … », « Valable à partir du … » en repliant mois et année quand ils se répètent ; `formatValidityShort()` pour les lignes de méta ; `isRangeInvalid()` pour la validation. - Espace adhérent : deux champs date, aperçu en direct de la phrase et blocage de l'envoi si la fin précède le début. - `publishPromo` relit et revalide les bornes côté serveur. - Affichage : carte d'accueil, fiche adhérent, liste de l'adhérent, carte de modération — et le message Facebook / LinkedIn, via le même formateur. - L'ancien texte libre `valid_until` reste comme repli d'affichage pour les promotions de démonstration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QXNXRC4j5VLfKvpyyisrnb
This commit is contained in:
15 files changed
+1700
-6
No files matched your search
@@ -8,6 +8,7 @@ import { configuredNetworks, SOCIAL_LABELS } from "@/lib/social";
|
||||
import { moderatePromo, retryPromoShare } from "../actions";
|
||||
import { PromoImage } from "@/components/PromoImage";
|
||||
import { SOCIAL_BRAND, SocialIcon } from "@/components/SocialIcons";
|
||||
import { formatValidity } from "@/lib/promo-validity";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -41,6 +42,9 @@ export default async function PromotionsPage() {
|
||||
text: promotions.text,
|
||||
category: promotions.category,
|
||||
status: promotions.status,
|
||||
validUntil: promotions.validUntil,
|
||||
startsOn: promotions.startsOn,
|
||||
endsOn: promotions.endsOn,
|
||||
imageUrl: promotions.imageUrl,
|
||||
suspendedBy: promotions.suspendedBy,
|
||||
suspendedAt: promotions.suspendedAt,
|
||||
@@ -176,6 +180,14 @@ export default async function PromotionsPage() {
|
||||
{p.text}
|
||||
</p>
|
||||
|
||||
{/* Le modérateur voit la période de validité avant de valider :
|
||||
c'est elle qui partira dans le message réseaux sociaux. */}
|
||||
{formatValidity(p) && (
|
||||
<div style={{ fontSize: 12, color: "#9a8d72", fontWeight: 600, margin: "0 0 12px" }}>
|
||||
{formatValidity(p)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isSuspended && (
|
||||
<div style={{ background: "#fbe9e6", border: "1px solid #f2d5cf", color: "#a8503c", borderRadius: 10, padding: "9px 11px", fontSize: 12, lineHeight: 1.45, marginBottom: 11 }}>
|
||||
Suspendue par {p.suspendedBy === "member" ? "l'adhérent" : "l'association"}
|
||||
|
||||
Reference in new issue
Block a user