import { AppLayout } from '@/components/AppLayout' import { CreateExtractionDialog } from '@/components/extractions/CreateExtractionDialog' import { ExtractionsHeader } from '@/components/extractions/ExtractionsHeader' import { ExtractionsEmpty, ExtractionsError, ExtractionsLoading, } from '@/components/extractions/ExtractionsLoadingStates' import { ExtractionsTable } from '@/components/extractions/ExtractionsTable' import { type ExtractionInfo, type ExtractionSortField, type ExtractionSortOrder, type ExtractionStatus, extractionsService, } from '@/lib/api/services/extractions' import { useEffect, useState } from 'react' import { toast } from 'sonner' export function ExtractionsPage() { const [extractions, setExtractions] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) // Search, sorting, and filtering state const [searchQuery, setSearchQuery] = useState('') const [sortBy, setSortBy] = useState('created_at') const [sortOrder, setSortOrder] = useState('desc') const [statusFilter, setStatusFilter] = useState('all') // Create extraction dialog state const [showCreateDialog, setShowCreateDialog] = useState(false) const [createLoading, setCreateLoading] = useState(false) const [url, setUrl] = useState('') // Debounce search query const [debouncedSearchQuery, setDebouncedSearchQuery] = useState(searchQuery) useEffect(() => { const handler = setTimeout(() => { setDebouncedSearchQuery(searchQuery) }, 300) return () => clearTimeout(handler) }, [searchQuery]) const fetchExtractions = async () => { try { setLoading(true) setError(null) const data = await extractionsService.getUserExtractions({ search: debouncedSearchQuery.trim() || undefined, sort_by: sortBy, sort_order: sortOrder, status_filter: statusFilter !== 'all' ? statusFilter : undefined, }) setExtractions(data) } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to fetch extractions' setError(errorMessage) toast.error(errorMessage) } finally { setLoading(false) } } useEffect(() => { fetchExtractions() }, [debouncedSearchQuery, sortBy, sortOrder, statusFilter]) const handleCreateExtraction = async () => { if (!url.trim()) { toast.error('Please enter a URL') return } try { setCreateLoading(true) const response = await extractionsService.createExtraction(url.trim()) toast.success(response.message) // Reset form and close dialog setUrl('') setShowCreateDialog(false) // Refresh the extractions list fetchExtractions() } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to create extraction' toast.error(errorMessage) } finally { setCreateLoading(false) } } const handleCancelCreate = () => { setUrl('') setShowCreateDialog(false) } const renderContent = () => { if (loading) { return } if (error) { return } if (extractions.length === 0) { return } return } return (
setShowCreateDialog(true)} loading={loading} error={error} extractionCount={extractions.length} /> {renderContent()}
) }