"use client"; import { useRef, useState } from "react"; import { useRouter } from "next/navigation"; import { publishPromo } from "../actions"; import { PromoImage } from "@/components/PromoImage"; import { MemberAvatar } from "@/components/MemberAvatar"; import { SOCIAL_BRAND, SocialIcon } from "@/components/SocialIcons"; import type { SocialNetwork } from "@/lib/social"; import type { PromoCategoryGroup } from "@/lib/promo-categories"; import { formatValidity, isRangeInvalid } from "@/lib/promo-validity"; import { formatSchedule, parseScheduleInput } from "@/lib/promo-schedule"; import { imageNotes, imageSummary, type ImageInfo } from "@/lib/image-info"; const STRIPE_WARM = "repeating-linear-gradient(45deg,#efe9da,#efe9da 12px,#e6ddc9 12px,#e6ddc9 24px)"; const NETWORK_LABELS: Record = { facebook: "Facebook", linkedin: "LinkedIn", }; /** Une ligne du récapitulatif de dates, à droite du formulaire. */ function SummaryRow({ label, value, tone, last = false, }: { label: string; value: string; tone: "set" | "muted" | "error"; last?: boolean; }) { const color = tone === "error" ? "#d8472b" : tone === "set" ? "#3c3322" : "#a99c82"; return (
{label} {value}
); } /** * Taille, format et poids de l'image déposée, avec ce que les réseaux en * feront. Purement informatif : aucune remarque n'empêche l'envoi. */ function ImageReport({ info }: { info: ImageInfo }) { const notes = imageNotes(info); return (
{imageSummary(info)}
{notes.map((note, i) => (
{note.text}
))}
); } export function MemberSpaceForm({ memberName, memberLogoUrl, categoryGroups, defaultCategory, networks = [], }: { memberName: string; /** Logo de l'adhérent, affiché dans l'angle de l'aperçu comme sur le site. */ memberLogoUrl?: string | null; /** Types de produits / services, groupés pour le ` {imgInfo && } { setTitle(e.target.value); setSubmitted(false); }} placeholder="ex : Le 13e pain offert" className="field" style={{ marginBottom: 16 }} />
setBadge(e.target.value)} placeholder="ex : -20%" className="field" />
{ setStartsOn(e.target.value); setSubmitted(false); }} className="field" aria-label="Début de la promotion" />
Début
{ setEndsOn(e.target.value); setSubmitted(false); }} className="field" aria-label="Fin de la promotion" />
Fin
{badRange ? "La date de fin est antérieure à la date de début." : validity ? `Affiché sur le site et dans la publication : « ${validity} ». L'offre n'apparaît que pendant cette période.` : "Laissez vide si votre offre n'a pas de date limite : elle restera affichée sans échéance."}
{ setPublishAt(e.target.value); setSubmitted(false); }} className="field" aria-label="Date et heure de publication souhaitées" />
{scheduleHint ? `Mise en ligne demandée ${scheduleHint} — site et réseaux en même temps. L'association reste libre de la déplacer.` : "Laissez vide pour une mise en ligne dès la validation par l'association."}