'use client'; import { useState, useTransition } from 'react'; import ScreenPreview from '@/app/admin/ScreenPreview'; import { MESSAGE_MAX_CHARS } from '@/lib/screen/contract'; import { deleteMessage, saveMessage, setManualTranslation, translateMessage, } from './actions'; export type MessageRow = { id: string; textFr: string; textEn: string | null; translationStatus: 'PENDING' | 'DONE' | 'MANUAL' | 'ERROR'; startsAt: string | null; endsAt: string | null; priority: number; isActive: boolean; isLive: boolean; }; const STATUS: Record = { PENDING: { label: 'traduction en attente', className: 'bg-[var(--surface-muted)] text-[var(--ink-muted)]' }, DONE: { label: 'traduit', className: 'bg-[var(--success-tint)] text-[var(--success)]' }, MANUAL: { label: 'traduction manuelle', className: 'bg-[var(--accent-tint)] text-[var(--accent-ink)]' }, ERROR: { label: 'traduction en échec', className: 'bg-[var(--danger-tint)] text-[var(--danger)]' }, }; export default function MessageManager({ canEdit, messages, }: { canEdit: boolean; messages: MessageRow[]; }) { const [pending, startTransition] = useTransition(); const [message, setMessage] = useState<{ kind: 'ok' | 'error'; text: string } | null>(null); const [textFr, setTextFr] = useState(''); const [startsAt, setStartsAt] = useState(''); const [endsAt, setEndsAt] = useState(''); const [priority, setPriority] = useState(0); const remaining = MESSAGE_MAX_CHARS - textFr.length; function run(work: () => Promise<{ ok: true } | { ok: false; error: string }>, success: string) { setMessage(null); startTransition(async () => { const result = await work(); setMessage(result.ok ? { kind: 'ok', text: success } : { kind: 'error', text: result.error }); }); } function create() { setMessage(null); startTransition(async () => { const saved = await saveMessage({ textFr, startsAt: startsAt || null, endsAt: endsAt || null, priority, isActive: true, }); if (!saved.ok) { setMessage({ kind: 'error', text: saved.error }); return; } setTextFr(''); setStartsAt(''); setEndsAt(''); setPriority(0); setMessage({ kind: 'ok', text: 'Message enregistré. Traduction en cours…' }); // Translation is a separate call on purpose: a slow or broken service // must never cost the shop its message. const translated = await translateMessage(saved.value.id); setMessage( translated.ok ? { kind: 'ok', text: 'Message enregistré et traduit.' } : { kind: 'error', text: `Message enregistré, mais la traduction a échoué : ${translated.error}` }, ); }); } return (
{message ? (

{message.text}

) : null} {canEdit ? (

Nouveau message