"use client"; import { useEffect, useRef, useState } from "react"; import Link from "next/link"; import { api } from "@/lib/api"; import { useAuth } from "@/lib/auth"; import { useI18n } from "@/lib/i18n"; import { useToast } from "@/lib/toast"; import type { ChatMessage, ConversationItem } from "@/lib/types"; import RingNext from "@/components/RingNext"; import { useRingSteps } from "@/lib/rings"; import { clearDraft, loadDraft, saveDraft } from "@/lib/localDraft"; export default function ChatThreadClient({ convId }: { convId: string }) { const { token, user } = useAuth(); const { t } = useI18n(); const { toast } = useToast(); const rings = useRingSteps(); const [messages, setMessages] = useState([]); const [conv, setConv] = useState(null); const [text, setText] = useState(""); const [sending, setSending] = useState(false); const [loading, setLoading] = useState(Boolean(token)); const [draftReady, setDraftReady] = useState(false); const bottomRef = useRef(null); const draftKey = `nomadro-chat-draft:${convId}`; const load = () => { if (!token) return; api .getMessages(token, convId) .then(setMessages) .catch(() => setMessages([])) .finally(() => setLoading(false)); }; useEffect(() => { if (!token) { setLoading(false); return; } api.getConversation(token, convId).then(setConv).catch(() => setConv(null)); load(); const id = setInterval(load, 4000); return () => clearInterval(id); // eslint-disable-next-line react-hooks/exhaustive-deps }, [token, convId]); useEffect(() => { const draft = loadDraft<{ text?: string }>(draftKey); if (draft?.text?.trim()) { setText(draft.text); toast(t.chat.draftRestored, "info"); } setDraftReady(true); // eslint-disable-next-line react-hooks/exhaustive-deps }, [convId]); useEffect(() => { if (!draftReady || !token) return; const id = window.setTimeout(() => { if (!text.trim()) { clearDraft(draftKey); return; } saveDraft(draftKey, { text }); }, 400); return () => window.clearTimeout(id); }, [text, draftReady, token, draftKey]); useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: "smooth" }); }, [messages]); const send = async () => { if (!token || !text.trim() || sending) return; setSending(true); try { await api.sendMessage(token, convId, text.trim()); setText(""); clearDraft(draftKey); load(); } catch { toast(t.chat.sendFail, "error"); } finally { setSending(false); } }; const peer = conv?.peer; const peerHref = peer?.userId ? `/members/${peer.userId}` : peer?.id ? `/members/${peer.id}` : "/dating"; if (!user || !token) { return (

{t.chat.loginTitle}

{t.chat.loginDesc}

{t.nav.login} {t.dating.meetAtEvents} {t.nav.dating}
); } return (
{peer && (
{peer.photo || peer.name?.[0] || "💬"}
{peer.name}

{peer.location || t.dating.globalNomad}

{t.dating.viewProfile}
)}
{loading && messages.length === 0 &&

{t.chat.loadingMessages}

} {!loading && messages.length === 0 && (

{t.chat.sayHi}

{t.dating.meetAtEvents} {t.nav.dating}
)} {messages.map((m) => (
{m.body}
))}
setText(e.target.value)} placeholder={t.chat.placeholder} onKeyDown={(e) => e.key === "Enter" && void send()} disabled={sending} />
); }