import { useState, type ComponentProps, type ReactNode } from "react"; import Input from "@moduletrace/twui/form/Input"; import Modal from "@moduletrace/twui/elements/Modal"; import Button from "@moduletrace/twui/layout/Button"; import H2 from "@moduletrace/twui/layout/H2"; import Row from "@moduletrace/twui/layout/Row"; import Span from "@moduletrace/twui/layout/Span"; import Stack from "@moduletrace/twui/layout/Stack"; import { History, Plus, CircleAlert } from "lucide-react"; import type { BotWithLastMessage } from "@/src/types"; import useBotSessions from "@/src/hooks/use-bot-sessions"; import BotSessionRow from "./bot-session-row"; import HeaderIconButton from "./header-icon-button"; type Props = { bot: BotWithLastMessage; workspace_id?: number | null; /** * A bot message arrived in another session of this conversation. */ has_other_unread?: boolean; /** * What opens it; the conversation header's sessions icon by default. */ target?: ReactNode; target_wrapper_props?: ComponentProps["targetWrapperProps"]; }; /** * The sessions icon (or another target) that opens a conversation's * sessions. A conversation is split into sessions so a bot's context never * grows without bound; this lists them, searches them, starts a fresh one, * or reopens an old one to carry on. */ export default function BotSessionsModal({ bot, workspace_id, has_other_unread, target, target_wrapper_props, }: Props) { const [open, setOpen] = useState(false); const sessions = useBotSessions({ bot_id: Number(bot.id), workspace_id, open }); const name = bot.name || "the bot"; return ( ) } targetWrapperProps={target_wrapper_props ?? { className: target ? "w-full" : "shrink-0" }} open={open} setOpen={setOpen} className="max-w-lg bg-paper p-6" >

Sessions

{`Each session keeps ${name}'s context short. A new one starts with a summary of the last; reopen any to pick up where you left off.`}
sessions.setQuery(e.target.value)} wrapperWrapperProps={{ className: "mt-4" }} /> {sessions.error ? ( {sessions.error} ) : null} {sessions.sessions.map((session) => ( sessions.reopenSession({ session_id: Number(session.id) })} /> ))} {sessions.sessions.length || sessions.loading ? null : ( {sessions.query.trim() ? `No session matches "${sessions.query.trim()}".` : "No sessions yet."} )}
); }