'use client'; import { useState, useEffect } from 'react'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { toast } from 'sonner'; interface Project { id: string; name: string; description: string | null; status: 'active' | 'paused' | 'completed' | 'archived'; domainId: string; color: string | null; icon: string | null; targetDate: string | null; } interface ProjectEditDialogProps { open: boolean; onOpenChange: (open: boolean) => void; project: Project; domainId: string; onUpdated: () => void; } export function ProjectEditDialog({ open, onOpenChange, project, domainId, onUpdated, }: ProjectEditDialogProps) { const [name, setName] = useState(''); const [description, setDescription] = useState(''); const [status, setStatus] = useState<'active' | 'paused' | 'completed' | 'archived'>('active'); const [color, setColor] = useState(''); const [targetDate, setTargetDate] = useState(''); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(''); const [archiveOpen, setArchiveOpen] = useState(false); const [archiving, setArchiving] = useState(false); useEffect(() => { if (open && project) { setName(project.name); setDescription(project.description || ''); setStatus(project.status); setColor(project.color || ''); setTargetDate(project.targetDate ? project.targetDate.split('T')[0] : ''); setError(''); } }, [open, project]); async function handleSubmit(event: React.FormEvent) { event.preventDefault(); if (!domainId) { setError('No domain selected'); return; } setSubmitting(true); setError(''); const body: Record = { name, status }; if (description) body.description = description; if (color) body.color = color; if (targetDate) body.targetDate = new Date(targetDate).toISOString(); try { const response = await fetch(`/api/domains/${domainId}/projects/${project.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); if (!response.ok) { const err = await response.json(); throw new Error(err.error?.message || 'Unable to update project'); } toast.success('Project updated'); onOpenChange(false); onUpdated(); } catch (err) { setError(err instanceof Error ? err.message : 'Unable to update project'); } finally { setSubmitting(false); } } async function handleArchive() { setArchiving(true); try { const response = await fetch(`/api/domains/${domainId}/projects/${project.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: 'archived' }), }); if (!response.ok) { const err = await response.json(); throw new Error(err.error?.message || 'Unable to archive project'); } toast.success('Project archived'); setArchiveOpen(false); onOpenChange(false); onUpdated(); } catch (err) { toast.error(err instanceof Error ? err.message : 'Unable to archive project'); } finally { setArchiving(false); } } return ( <> Edit Project Update your project details.
setName(e.target.value)} placeholder="Project name" autoFocus required />