diff --git a/apps/web/src/components/CreateErrandDialog.tsx b/apps/web/src/components/CreateErrandDialog.tsx new file mode 100644 index 0000000..0e76e17 --- /dev/null +++ b/apps/web/src/components/CreateErrandDialog.tsx @@ -0,0 +1,142 @@ +import { useEffect, useState } from 'react'; +import { useNavigate } from '@tanstack/react-router'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Textarea } from '@/components/ui/textarea'; +import { toast } from 'sonner'; +import { cn } from '@/lib/utils'; +import { trpc } from '@/lib/trpc'; + +interface CreateErrandDialogProps { + open: boolean; + onOpenChange: (open: boolean) => void; +} + +export function CreateErrandDialog({ open, onOpenChange }: CreateErrandDialogProps) { + const [description, setDescription] = useState(''); + const [projectId, setProjectId] = useState(''); + const [baseBranch, setBaseBranch] = useState(''); + const [error, setError] = useState(null); + + const navigate = useNavigate(); + const utils = trpc.useUtils(); + + const projectsQuery = trpc.listProjects.useQuery(); + + const createMutation = trpc.errand.create.useMutation({ + onSuccess: (data) => { + toast.success('Errand started'); + onOpenChange(false); + utils.errand.list.invalidate(); + navigate({ to: '/errands', search: { selected: data.id } }); + }, + onError: (err) => { + setError(err.message); + }, + }); + + useEffect(() => { + if (open) { + setDescription(''); + setProjectId(''); + setBaseBranch(''); + setError(null); + } + }, [open]); + + function handleSubmit(e: React.FormEvent) { + e.preventDefault(); + setError(null); + createMutation.mutate({ + description: description.trim(), + projectId, + baseBranch: baseBranch.trim() || undefined, + }); + } + + const canSubmit = + description.trim().length > 0 && + description.length <= 200 && + projectId !== '' && + !createMutation.isPending; + + return ( + + + + New Errand + + Start a small isolated change with a dedicated agent. + + +
+
+ +