nomadweb/frontend/src/components/ChatThreadClient.tsx
eric ff7b721acb feat: NomadCNA community layer, social matching, payments, and ebook
Port meetups, discussions, gigs, dating/chat, VIP pay (ZPay/XorPay), MiroTalk live, digital academy, and ebook reader. Add persistent community_store, git-first deploy docs, and env template for production secrets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-30 09:38:13 -05:00

68 lines
1.9 KiB
TypeScript

"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 type { ChatMessage } from "@/lib/types";
export default function ChatThreadClient({ convId }: { convId: string }) {
const { token } = useAuth();
const { t } = useI18n();
const [messages, setMessages] = useState<ChatMessage[]>([]);
const [text, setText] = useState("");
const bottomRef = useRef<HTMLDivElement>(null);
const load = () => {
if (!token) return;
api.getMessages(token, convId).then(setMessages).catch(() => setMessages([]));
};
useEffect(() => {
load();
const id = setInterval(load, 4000);
return () => clearInterval(id);
}, [token, convId]);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
const send = async () => {
if (!token || !text.trim()) return;
try {
await api.sendMessage(token, convId, text.trim());
setText("");
load();
} catch { /* ignore */ }
};
return (
<div className="chat-thread-page">
<div className="container chat-thread-wrap">
<nav className="detail-nav">
<Link href="/chat">← {t.chat.back}</Link>
</nav>
<div className="chat-thread-messages">
{messages.map((m) => (
<div key={m.id} className={`chat-bubble${m.mine ? " mine" : ""}`}>
{m.body}
</div>
))}
<div ref={bottomRef} />
</div>
<div className="chat-compose">
<input
value={text}
onChange={(e) => setText(e.target.value)}
placeholder={t.chat.placeholder}
onKeyDown={(e) => e.key === "Enter" && send()}
/>
<button type="button" className="btn btn-primary" onClick={send}>{t.chat.send}</button>
</div>
</div>
</div>
);
}