fullstuckdev's picture
Upload 25 files
2341446 verified
"use client"
import { useState, ComponentType } from 'react'
import FileUpload from './FileUpload'
import {
Box,
Container,
Typography,
TextField,
Button,
CircularProgress,
Paper,
Fade,
} from '@mui/material'
import QuestionAnswerIcon from '@mui/icons-material/QuestionAnswer'
import { motion } from 'framer-motion'
interface Document {
text: string
}
const MotionContainer = motion(Container as any)
const MotionPaper = motion(Paper as any)
export default function QASystem() {
const [query, setQuery] = useState('')
const [answer, setAnswer] = useState('')
const [loading, setLoading] = useState(false)
const [documents, setDocuments] = useState<Document[]>([])
const handleDocumentsLoaded = (newDocuments: Document[]) => {
setDocuments(newDocuments)
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (documents.length === 0) {
alert('Please upload some documents first')
return
}
setLoading(true)
try {
const response = await fetch('/api/qa', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query, documents }),
})
const data = await response.json()
setAnswer(data.answer)
} catch (error) {
console.error('Error:', error)
setAnswer('Failed to get answer. Please try again.')
} finally {
setLoading(false)
}
}
return (
<Box
sx={{
minHeight: '100vh',
background: 'linear-gradient(135deg, #f6f8fc 0%, #f0f4f8 100%)',
py: 8
}}
>
<MotionContainer
maxWidth="lg"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<Box sx={{ textAlign: 'center', mb: 8 }}>
<Typography
variant="h1"
component="h1"
sx={{
mb: 3,
fontSize: { xs: '2rem', md: '3rem' },
fontWeight: 800,
background: 'linear-gradient(135deg, #2563eb 0%, #7c3aed 100%)',
backgroundClip: 'text',
WebkitBackgroundClip: 'text',
color: 'transparent',
textShadow: '0 2px 10px rgba(37, 99, 235, 0.1)',
}}
>
AI Document Assistant
</Typography>
<Typography
variant="h6"
sx={{
color: 'text.secondary',
maxWidth: '600px',
mx: 'auto',
lineHeight: 1.6
}}
>
Upload your documents and get instant, AI-powered answers to your questions
</Typography>
</Box>
<MotionPaper
elevation={0}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.2 }}
sx={{
p: { xs: 3, md: 5 },
mb: 4,
border: '1px solid',
borderColor: 'grey.100',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
backdropFilter: 'blur(10px)',
borderRadius: 3,
boxShadow: '0 4px 20px rgba(0, 0, 0, 0.05)',
}}
>
<FileUpload onDocumentsLoaded={handleDocumentsLoaded} />
<Box component="form" onSubmit={handleSubmit} sx={{ mt: 4 }}>
<TextField
fullWidth
multiline
rows={3}
label="What would you like to know?"
value={query}
onChange={(e) => setQuery(e.target.value)}
sx={{
mb: 3,
'& .MuiOutlinedInput-root': {
backgroundColor: 'white',
borderRadius: 2,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.05)',
}
}}
variant="outlined"
/>
<Button
fullWidth
type="submit"
disabled={loading || documents.length === 0}
variant="contained"
size="large"
sx={{
py: 2,
background: 'linear-gradient(135deg, #2563eb 0%, #7c3aed 100%)',
borderRadius: 2,
transition: 'all 0.3s ease',
'&:hover': {
transform: 'translateY(-2px)',
boxShadow: '0 6px 20px rgba(37, 99, 235, 0.2)',
background: 'linear-gradient(135deg, #1d4ed8 0%, #6d28d9 100%)',
},
'&:disabled': {
background: '#e2e8f0',
color: '#94a3b8',
}
}}
startIcon={loading ? <CircularProgress size={20} color="inherit" /> : <QuestionAnswerIcon />}
>
{loading ? 'Processing...' : 'Ask Question'}
</Button>
</Box>
</MotionPaper>
<Fade in={!!answer}>
<MotionPaper
elevation={0}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
sx={{
p: { xs: 3, md: 5 },
border: '1px solid',
borderColor: 'grey.100',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
backdropFilter: 'blur(10px)',
borderRadius: 3,
boxShadow: '0 4px 20px rgba(0, 0, 0, 0.05)',
}}
>
<Typography
variant="h6"
sx={{
mb: 3,
fontWeight: 700,
color: 'text.primary',
fontSize: '1.25rem',
}}
>
Answer
</Typography>
<Box
sx={{
p: 4,
backgroundColor: '#f8fafc',
borderRadius: 2,
border: '1px solid',
borderColor: 'grey.100',
}}
>
<Typography sx={{
color: 'text.secondary',
lineHeight: 1.8,
fontSize: '1.1rem'
}}>
{answer}
</Typography>
</Box>
</MotionPaper>
</Fade>
</MotionContainer>
</Box>
)
}