feat(frontend): wire Phase 1.2 components into App layout
Replaces placeholder areas with QueryInput, KeywordsDisplay, ResponsePanel, IngestPanel, and ErrorBoundary. App.tsx now holds TanStack Query mutation state and passes props to all components. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
a7d5dc610a
commit
6b544808de
|
|
@ -1,7 +1,12 @@
|
|||
import React from 'react'
|
||||
import { QueryClientProvider } from '@tanstack/react-query'
|
||||
import { queryClient } from './lib/queries'
|
||||
import { queryClient, useQueryDocument, useIngestDocument } from './lib/queries'
|
||||
import { Film } from 'lucide-react'
|
||||
import { QueryInput } from './components/QueryInput'
|
||||
import { KeywordsDisplay } from './components/KeywordsDisplay'
|
||||
import { ResponsePanel } from './components/ResponsePanel'
|
||||
import { IngestPanel } from './components/IngestPanel'
|
||||
import { ErrorBoundary } from './components/ErrorBoundary'
|
||||
|
||||
const VideoPlaceholder: React.FC = () => {
|
||||
return (
|
||||
|
|
@ -14,25 +19,40 @@ const VideoPlaceholder: React.FC = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const RightTop: React.FC = () => {
|
||||
return <div className="h-full border rounded border-dashed border-gray-300" />
|
||||
const AppContent: React.FC = () => {
|
||||
const queryMutation = useQueryDocument()
|
||||
const ingestMutation = useIngestDocument()
|
||||
|
||||
const handleQuerySubmit = (question: string): void => {
|
||||
queryMutation.mutate({ question })
|
||||
}
|
||||
|
||||
const BottomArea: React.FC = () => {
|
||||
return <div className="border border-dashed border-gray-300 rounded h-full" />
|
||||
const handleFileUpload = (file: File): void => {
|
||||
ingestMutation.mutate(file)
|
||||
}
|
||||
|
||||
const AppLayout: React.FC = () => {
|
||||
return (
|
||||
<div className="h-screen grid grid-rows-[1fr_auto] grid-cols-2">
|
||||
<div className="border-r border-b border-gray-200 p-4">
|
||||
<VideoPlaceholder />
|
||||
</div>
|
||||
<div className="border-b border-gray-200 p-4">
|
||||
<RightTop />
|
||||
<div className="border-b border-gray-200 p-4 flex flex-col gap-4 overflow-y-auto">
|
||||
<QueryInput onSubmit={handleQuerySubmit} isLoading={queryMutation.isPending} />
|
||||
<KeywordsDisplay keywords={queryMutation.data?.keywords} isLoading={queryMutation.isPending} />
|
||||
<IngestPanel
|
||||
onUpload={handleFileUpload}
|
||||
isLoading={ingestMutation.isPending}
|
||||
success={ingestMutation.isSuccess ? ingestMutation.data?.filename ?? null : null}
|
||||
error={ingestMutation.isError ? (ingestMutation.error instanceof Error ? ingestMutation.error.message : 'Upload failed') : null}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-2 p-4 border-t border-gray-200">
|
||||
<BottomArea />
|
||||
<div className="col-span-2 p-4 border-t border-gray-200 overflow-y-auto">
|
||||
<ResponsePanel
|
||||
answer={queryMutation.data?.answer ?? null}
|
||||
sources={queryMutation.data?.sources ?? []}
|
||||
isLoading={queryMutation.isPending}
|
||||
error={queryMutation.isError ? (queryMutation.error instanceof Error ? queryMutation.error.message : 'Query failed') : null}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
@ -41,7 +61,9 @@ const AppLayout: React.FC = () => {
|
|||
export default function App(): JSX.Element {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AppLayout />
|
||||
<ErrorBoundary>
|
||||
<AppContent />
|
||||
</ErrorBoundary>
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue