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 React from 'react'
|
||||||
import { QueryClientProvider } from '@tanstack/react-query'
|
import { QueryClientProvider } from '@tanstack/react-query'
|
||||||
import { queryClient } from './lib/queries'
|
import { queryClient, useQueryDocument, useIngestDocument } from './lib/queries'
|
||||||
import { Film } from 'lucide-react'
|
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 = () => {
|
const VideoPlaceholder: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -14,25 +19,40 @@ const VideoPlaceholder: React.FC = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const RightTop: React.FC = () => {
|
const AppContent: React.FC = () => {
|
||||||
return <div className="h-full border rounded border-dashed border-gray-300" />
|
const queryMutation = useQueryDocument()
|
||||||
|
const ingestMutation = useIngestDocument()
|
||||||
|
|
||||||
|
const handleQuerySubmit = (question: string): void => {
|
||||||
|
queryMutation.mutate({ question })
|
||||||
}
|
}
|
||||||
|
|
||||||
const BottomArea: React.FC = () => {
|
const handleFileUpload = (file: File): void => {
|
||||||
return <div className="border border-dashed border-gray-300 rounded h-full" />
|
ingestMutation.mutate(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppLayout: React.FC = () => {
|
|
||||||
return (
|
return (
|
||||||
<div className="h-screen grid grid-rows-[1fr_auto] grid-cols-2">
|
<div className="h-screen grid grid-rows-[1fr_auto] grid-cols-2">
|
||||||
<div className="border-r border-b border-gray-200 p-4">
|
<div className="border-r border-b border-gray-200 p-4">
|
||||||
<VideoPlaceholder />
|
<VideoPlaceholder />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-gray-200 p-4">
|
<div className="border-b border-gray-200 p-4 flex flex-col gap-4 overflow-y-auto">
|
||||||
<RightTop />
|
<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>
|
||||||
<div className="col-span-2 p-4 border-t border-gray-200">
|
<div className="col-span-2 p-4 border-t border-gray-200 overflow-y-auto">
|
||||||
<BottomArea />
|
<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>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -41,7 +61,9 @@ const AppLayout: React.FC = () => {
|
||||||
export default function App(): JSX.Element {
|
export default function App(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<AppLayout />
|
<ErrorBoundary>
|
||||||
|
<AppContent />
|
||||||
|
</ErrorBoundary>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue