import { useEffect, useState } from "react"; import { Globe, Link2, Pencil, Settings2, Tag, Unplug } from "lucide-react"; import { api } from "../lib/api.ts"; import type { Conversation, User } from "../lib/types.ts"; import { Avatar, Button, CopyButton, Field, Input, Modal, Picker, Spinner } from "./ui.tsx"; /* ---------- Rename + topic ---------- */ export function ConvEditDialog({ conv, onClose, onSaved, }: { conv: Conversation | null; onClose: () => void; onSaved: (c: Conversation) => void; }) { const [title, setTitle] = useState(""); const [topic, setTopic] = useState(""); const [busy, setBusy] = useState(false); const [error, setError] = useState(""); useEffect(() => { if (conv) { setTitle(conv.title); setTopic(conv.topic); setError(""); } }, [conv]); async function save(e: React.FormEvent) { e.preventDefault(); if (!conv || busy) return; setBusy(true); setError(""); try { const res = await api.patchConv(conv.id, { title: title.trim(), topic: topic.trim() }); onSaved(res.conversation); onClose(); } catch (err) { setError(err instanceof Error ? err.message : "Save failed"); } finally { setBusy(false); } } return (
setTitle(e.target.value)} maxLength={120} required />
setTopic(e.target.value)} maxLength={120} placeholder="No topic" />
{error &&

{error}

}
); } /* ---------- Share ---------- */ export function ShareModal({ conv, onClose }: { conv: Conversation | null; onClose: () => void }) { const [url, setUrl] = useState(null); const [busy, setBusy] = useState(false); const [error, setError] = useState(""); useEffect(() => { if (!conv) { setUrl(null); return; } setBusy(true); setError(""); api.share(conv.id) .then((r) => setUrl(window.location.origin + r.url)) .catch((err) => setError(err instanceof Error ? err.message : "Share failed")) .finally(() => setBusy(false)); }, [conv]); async function unshare() { if (!conv) return; await api.unshare(conv.id); onClose(); } return ( {busy &&

Creating public link…

} {error &&

{error}

} {url && (

Anyone with this link can read {conv?.title}. No login required.

{url}
)}
); } /* ---------- Settings (profile) ---------- */ export function SettingsModal({ user, onClose, onSaved, }: { user: User | null; onClose: () => void; onSaved: (u: User) => void; }) { const [displayName, setDisplayName] = useState(""); const [avatarUrl, setAvatarUrl] = useState(""); const [theme, setTheme] = useState("auto"); const [busy, setBusy] = useState(false); const [error, setError] = useState(""); useEffect(() => { if (user) { setDisplayName(user.displayName); setAvatarUrl(user.avatarUrl); setTheme(user.theme); setError(""); } }, [user]); async function save(e: React.FormEvent) { e.preventDefault(); if (!user || busy) return; setBusy(true); setError(""); try { const res = await api.updateMe({ displayName: displayName.trim(), avatarUrl: avatarUrl.trim(), theme }); onSaved(res.user); onClose(); } catch (err) { setError(err instanceof Error ? err.message : "Save failed"); } finally { setBusy(false); } } return (

@{user?.username}

setDisplayName(e.target.value)} maxLength={60} required /> setAvatarUrl(e.target.value)} placeholder="https://…" inputMode="url" /> {error &&

{error}

}
); }