| "use client"; |
| import { useState } from "react"; |
| import { FileUpload } from "@/components/FileUpload"; |
| import { PromptInput } from "@/components/PromptInput"; |
| import { ResultDisplay } from "@/components/ResultDisplay"; |
| import { FileIcon, FileText } from "lucide-react"; |
| import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; |
|
|
| export default function Home() { |
| const [schema, setSchema] = useState<string | null>(null); |
| const [file, setFile] = useState<File | null>(null); |
| const [result, setResult] = useState<string | null>(null); |
| const [loading, setLoading] = useState(false); |
|
|
| const handleFileSelect = (selectedFile: File) => { |
| setFile(selectedFile); |
| }; |
|
|
| const handlePromptSubmit = async (prompt: string) => { |
| try { |
| setLoading(true); |
| |
| const schemaResponse = await fetch("/api/schema", { |
| method: "POST", |
| headers: { |
| "Content-Type": "application/json", |
| }, |
| body: JSON.stringify({ prompt }), |
| }); |
|
|
| const { schema } = await schemaResponse.json(); |
|
|
| setSchema(schema); |
| |
| const formData = new FormData(); |
| formData.append("file", file!); |
| formData.append("schema", JSON.stringify(schema)); |
|
|
| const extractResponse = await fetch("/api/extract", { |
| method: "POST", |
| body: formData, |
| }); |
|
|
| const data = await extractResponse.json(); |
| setResult(data); |
| } catch (error) { |
| console.error("Error processing request:", error); |
| } finally { |
| setLoading(false); |
| } |
| }; |
|
|
| const handleReset = () => { |
| setFile(null); |
| setResult(null); |
| setSchema(null); |
| setLoading(false); |
| }; |
|
|
| return ( |
| <main className="min-h-screen flex items-center justify-center bg-background p-8"> |
| <Card className="w-full max-w-2xl border-0 bg-card shadow-none"> |
| <CardHeader className="flex flex-col items-center justify-center space-y-2"> |
| <CardTitle className="flex items-center gap-2 text-foreground"> |
| <FileText className="w-8 h-8 text-primary" /> |
| PDF to Structured Data |
| </CardTitle> |
| <span className="text-sm font-mono text-muted-foreground"> |
| powered by Google DeepMind Gemini 2.0 Flash |
| </span> |
| </CardHeader> |
| <CardContent className="space-y-6 pt-6 w-full"> |
| {!result && !loading ? ( |
| <> |
| <FileUpload onFileSelect={handleFileSelect} /> |
| <PromptInput onSubmit={handlePromptSubmit} file={file} /> |
| </> |
| ) : loading ? ( |
| <div |
| role="status" |
| className="flex items-center mx-auto justify-center h-56 max-w-sm bg-gray-300 rounded-lg animate-pulse dark:bg-secondary" |
| > |
| <FileIcon className="w-10 h-10 text-gray-200 dark:text-muted-foreground" /> |
| <span className="pl-4 font-mono font-xs text-muted-foreground"> |
| Processing... |
| </span> |
| </div> |
| ) : ( |
| <ResultDisplay |
| result={result || ""} |
| schema={schema || ""} |
| onReset={handleReset} |
| /> |
| )} |
| </CardContent> |
| </Card> |
| </main> |
| ); |
| } |
|
|