'use client'; import { useEffect, useRef, useState } from 'react'; import type { MessageDTO } from '@/lib/types'; const POLL_MS = 4000; function formatTime(iso: string) { return new Date(iso).toLocaleString(undefined, { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', }); } export default function Chat({ proofId, role, otherPartyLabel, }: { proofId: string; role: 'ADMIN' | 'CUSTOMER'; otherPartyLabel: string; }) { const [messages, setMessages] = useState([]); const [input, setInput] = useState(''); const [sending, setSending] = useState(false); const scrollRef = useRef(null); useEffect(() => { let cancelled = false; const load = async () => { try { const res = await fetch(`/api/proofs/${proofId}/messages`); if (!res.ok || cancelled) return; const data: MessageDTO[] = await res.json(); if (!cancelled) setMessages(data); } catch { // silently retry on next poll } }; load(); const interval = setInterval(load, POLL_MS); return () => { cancelled = true; clearInterval(interval); }; }, [proofId]); useEffect(() => { scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight }); }, [messages.length]); const send = async () => { const trimmed = input.trim(); if (!trimmed || sending) return; setSending(true); setInput(''); try { const res = await fetch(`/api/proofs/${proofId}/messages`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sender: role, body: trimmed }), }); if (res.ok) { const created: MessageDTO = await res.json(); setMessages((prev) => [...prev, created]); } } finally { setSending(false); } }; return (

Chat with {otherPartyLabel}

{messages.length === 0 ? (

No messages yet — say hello.

) : ( messages.map((m) => { const mine = m.sender === role; return (

{m.body}

{formatTime(m.createdAt)}

); }) )}
setInput(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); send(); } }} placeholder="Type a message…" className="flex-1 border border-line px-3 py-2 text-sm" />
); }