import { AppLayout } from '@/components/AppLayout' import { CreateTaskDialog } from '@/components/schedulers/CreateTaskDialog' import { SchedulersHeader } from '@/components/schedulers/SchedulersHeader' import { SchedulersEmpty, SchedulersError, SchedulersLoading, } from '@/components/schedulers/SchedulersLoadingStates' import { SchedulersTable } from '@/components/schedulers/SchedulersTable' import { type CreateScheduledTaskRequest, type ScheduledTask, type TaskStatus, type TaskType, schedulersService, } from '@/lib/api/services/schedulers' import { useCallback, useEffect, useState } from 'react' import { toast } from 'sonner' export function SchedulersPage() { const [tasks, setTasks] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) // Search and filtering state const [searchQuery, setSearchQuery] = useState('') const [statusFilter, setStatusFilter] = useState('all') const [taskTypeFilter, setTaskTypeFilter] = useState('all') // Create task dialog state const [showCreateDialog, setShowCreateDialog] = useState(false) const [createLoading, setCreateLoading] = useState(false) // Debounce search query const [debouncedSearchQuery, setDebouncedSearchQuery] = useState(searchQuery) useEffect(() => { const handler = setTimeout(() => { setDebouncedSearchQuery(searchQuery) }, 300) return () => clearTimeout(handler) }, [searchQuery]) const fetchTasks = useCallback(async () => { try { setLoading(true) setError(null) const allTasks = await schedulersService.getUserTasks({ status: statusFilter !== 'all' ? statusFilter : undefined, task_type: taskTypeFilter !== 'all' ? taskTypeFilter : undefined, limit: 100, // Get all tasks for now, we'll implement pagination if needed }) // Client-side search filtering let filteredTasks = allTasks if (debouncedSearchQuery.trim()) { const query = debouncedSearchQuery.toLowerCase() filteredTasks = allTasks.filter(task => task.name.toLowerCase().includes(query) || task.task_type.toLowerCase().includes(query) || task.status.toLowerCase().includes(query) ) } setTasks(filteredTasks) } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to fetch tasks' setError(errorMessage) toast.error(errorMessage) } finally { setLoading(false) } }, [debouncedSearchQuery, statusFilter, taskTypeFilter]) useEffect(() => { fetchTasks() }, [fetchTasks]) const handleCreateTask = async (data: CreateScheduledTaskRequest) => { try { setCreateLoading(true) await schedulersService.createTask(data) toast.success('Task created successfully') // Close dialog and refresh tasks setShowCreateDialog(false) fetchTasks() } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to create task' toast.error(errorMessage) } finally { setCreateLoading(false) } } const handleCancelCreate = () => { setShowCreateDialog(false) } const handleTaskUpdated = (updatedTask: ScheduledTask) => { setTasks(prev => prev.map(task => task.id === updatedTask.id ? updatedTask : task )) } const handleTaskDeleted = (taskId: number) => { setTasks(prev => prev.filter(task => task.id !== taskId)) } const renderContent = () => { if (loading) { return } if (error) { return } if (tasks.length === 0) { return ( ) } return ( ) } return (
setShowCreateDialog(true)} loading={loading} error={error} taskCount={tasks.length} />
{renderContent()}
) }