import { useMemo, useState } from 'react' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { Link, useNavigate, useParams } from 'react-router-dom' import { getEntity } from '../api/entitiesApi' import { buildTaskPreviewPrompt, createTask, generateTaskPreview, type EmailLookback, } from '../api/tasksApi' interface TaskFormState { name: string prompt: string scheduleCron: string emailLookback: EmailLookback } interface CronParts { minute: string hour: string dayOfMonth: string month: string dayOfWeek: string } interface RegularitySuggestion { id: string label: string description: string cronParts: CronParts } const DEFAULT_CRON_PARTS: CronParts = { minute: '0', hour: '9', dayOfMonth: '*', month: '*', dayOfWeek: '1-5', } const REGULARITY_SUGGESTIONS: RegularitySuggestion[] = [ { id: 'daily', label: 'Daily', description: 'Every day at 09:00', cronParts: { minute: '0', hour: '9', dayOfMonth: '*', month: '*', dayOfWeek: '*' }, }, { id: 'weekdays', label: 'Weekdays', description: 'Monday to Friday at 09:00', cronParts: { minute: '0', hour: '9', dayOfMonth: '*', month: '*', dayOfWeek: '1-5' }, }, { id: 'weekly', label: 'Weekly', description: 'Every Monday at 09:00', cronParts: { minute: '0', hour: '9', dayOfMonth: '*', month: '*', dayOfWeek: '1' }, }, { id: 'monthly', label: 'Monthly', description: 'Day 1 of each month at 09:00', cronParts: { minute: '0', hour: '9', dayOfMonth: '1', month: '*', dayOfWeek: '*' }, }, ] function buildCron(parts: CronParts): string { return [parts.minute, parts.hour, parts.dayOfMonth, parts.month, parts.dayOfWeek].join(' ') } const DEFAULT_TASK_FORM: TaskFormState = { name: '', prompt: '', scheduleCron: buildCron(DEFAULT_CRON_PARTS), emailLookback: 'last_week', } export default function CreateTaskPage() { const { entityId = '' } = useParams() const navigate = useNavigate() const queryClient = useQueryClient() const [cronParts, setCronParts] = useState(DEFAULT_CRON_PARTS) const [taskForm, setTaskForm] = useState(DEFAULT_TASK_FORM) const [preview, setPreview] = useState('') const [previewError, setPreviewError] = useState('') const { data: entity, isLoading } = useQuery({ queryKey: ['entity', entityId], queryFn: () => getEntity(entityId), enabled: Boolean(entityId), }) const createTaskMutation = useMutation({ mutationFn: createTask, onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ['entity-tasks', entityId] }) navigate(`/entities/${entityId}`) }, }) const previewMutation = useMutation({ mutationFn: generateTaskPreview, onMutate: () => { setPreview('') setPreviewError('') }, onSuccess: (value) => setPreview(value), onError: (error) => { setPreviewError( error instanceof Error ? error.message : 'Unable to generate a test message from the local model.' ) }, }) const canSubmit = useMemo(() => { const hasFilledCronParts = Object.values(cronParts).every((value) => value.trim().length > 0) return Boolean(taskForm.name.trim() && taskForm.prompt.trim() && hasFilledCronParts) }, [cronParts, taskForm.name, taskForm.prompt]) const currentTask = useMemo( () => ({ entityId, name: taskForm.name, prompt: taskForm.prompt, scheduleCron: taskForm.scheduleCron, emailLookback: taskForm.emailLookback, }), [entityId, taskForm.emailLookback, taskForm.name, taskForm.prompt, taskForm.scheduleCron] ) const finalPrompt = useMemo(() => { if (!entity) { return 'Entity details unavailable.' } return buildTaskPreviewPrompt(entity, currentTask) }, [currentTask, entity]) const applyCronParts = (nextCronParts: CronParts) => { setCronParts(nextCronParts) setTaskForm((prev) => ({ ...prev, scheduleCron: buildCron(nextCronParts) })) } const regularitySummary = useMemo( () => `At ${cronParts.hour.padStart(2, '0')}:${cronParts.minute.padStart(2, '0')} - day ${cronParts.dayOfMonth}, month ${cronParts.month}, week day ${cronParts.dayOfWeek}`, [cronParts.dayOfMonth, cronParts.dayOfWeek, cronParts.hour, cronParts.minute, cronParts.month] ) if (!entityId) { return
Entity identifier is missing.
} if (isLoading) { return
Loading...
} return (

New Task {entity && ( — {entity.name} )}

{ event.preventDefault() if (!canSubmit) return createTaskMutation.mutate({ entityId, name: taskForm.name, prompt: taskForm.prompt, scheduleCron: taskForm.scheduleCron, emailLookback: taskForm.emailLookback, }) }} >
setTaskForm((prev) => ({ ...prev, name: event.target.value }))} className="mt-1 w-full rounded-md border border-slate-700 bg-slate-900 px-3 py-2 text-sm text-slate-100" required />