Files
platform/src/apps/officer-web/Screens/Dashboard/ChatScreen/ChatScreen.tsx
T
2026-02-22 00:05:29 +00:00

82 lines
2.5 KiB
TypeScript

import { useRef, useEffect, useState } from 'react';
import { useNavigate, useLocation } from 'react-router';
import { useChatSessions } from 'state/useChatSessions';
import { SessionBar, EmbeddableChat, type UsePiChatType, type Attachment } from 'officerdev';
import { Card } from '@/components/Card';
export type { Attachment };
type ChatPanelProps = {
chat: UsePiChatType;
};
export const ChatScreen = ({ chat }: ChatPanelProps) => {
const { isConnected, isGenerating, sessionId, setSelectedModel, sendPrompt } = chat;
const location = useLocation();
const navigate = useNavigate();
const [fullscreen, setFullscreen] = useState(false);
const { sessions, deleteSession } = useChatSessions();
const sessionTitle = sessionId ? sessions.find((s) => s.id === sessionId)?.title : undefined;
const listPath = '/chat';
// Capture initial state from navigation
const locationState = location.state as {
initialMessage?: string;
prefillInput?: string;
model?: string;
cwd?: { root?: string; path: string };
attachmentIds?: string[];
images?: { filename: string; dataUrl: string }[];
} | null;
const initialMessage = locationState?.initialMessage
? {
text: locationState.initialMessage,
attachmentIds: locationState.attachmentIds,
images: locationState.images,
cwd: locationState.cwd,
}
: undefined;
const defaultInput = locationState?.prefillInput ?? '';
const initialModel = locationState?.model ?? null;
// Clear location state after capturing
useEffect(() => {
if (locationState) {
window.history.replaceState({}, '', location.pathname);
}
}, []);
return (
<Card
className={`flex flex-col overflow-hidden transition-all duration-200 rounded-none border-0 md:rounded-xl md:border-2 ${fullscreen ? 'fixed inset-0 m-auto z-50 w-[90vw] h-[calc(90vh-4.5rem)]' : 'h-full'
}`}
>
<SessionBar
listPath={listPath}
sessionTitle={sessionTitle}
isConnected={isConnected}
isGenerating={isGenerating}
fullscreen={fullscreen}
onDelete={async () => {
if (!sessionId) return;
await deleteSession(sessionId);
navigate(listPath);
}}
onToggleFullscreen={() => setFullscreen((f) => !f)}
/>
<EmbeddableChat
sessionId={sessionId ?? undefined}
initialModel={initialModel}
initialMessage={initialMessage}
defaultInput={defaultInput}
className="flex-1 min-h-0"
/>
</Card>
);
};