import { useState, useEffect } from 'react'; import type { GoalDefinition, CreateDefinitionDto, GoalType, MetricType, PeriodType, DataSource, GoalStatus, Milestone, } from '@/services/goals'; interface GoalFormProps { initialData?: GoalDefinition; onSubmit: (data: CreateDefinitionDto) => void; onCancel: () => void; isSubmitting?: boolean; } export function GoalForm({ initialData, onSubmit, onCancel, isSubmitting = false }: GoalFormProps) { const [formData, setFormData] = useState({ name: '', description: '', category: '', type: 'target', metric: 'number', targetValue: 0, unit: '', period: 'monthly', startsAt: new Date().toISOString().split('T')[0], endsAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], source: 'manual', milestones: [], status: 'draft', tags: [], }); const [tagInput, setTagInput] = useState(''); const [milestoneInput, setMilestoneInput] = useState({ percentage: 50, notify: true }); useEffect(() => { if (initialData) { setFormData({ name: initialData.name, description: initialData.description || '', category: initialData.category || '', type: initialData.type, metric: initialData.metric, targetValue: initialData.targetValue, unit: initialData.unit || '', period: initialData.period, startsAt: initialData.startsAt.split('T')[0], endsAt: initialData.endsAt.split('T')[0], source: initialData.source, milestones: initialData.milestones || [], status: initialData.status, tags: initialData.tags || [], }); } }, [initialData]); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onSubmit(formData); }; const handleChange = (field: keyof CreateDefinitionDto, value: unknown) => { setFormData((prev) => ({ ...prev, [field]: value })); }; const addTag = () => { if (tagInput.trim() && !formData.tags?.includes(tagInput.trim())) { handleChange('tags', [...(formData.tags || []), tagInput.trim()]); setTagInput(''); } }; const removeTag = (tag: string) => { handleChange('tags', (formData.tags || []).filter((t) => t !== tag)); }; const addMilestone = () => { if (milestoneInput.percentage > 0 && milestoneInput.percentage <= 100) { const exists = (formData.milestones || []).some( (m) => m.percentage === milestoneInput.percentage ); if (!exists) { handleChange('milestones', [ ...(formData.milestones || []), { ...milestoneInput }, ].sort((a, b) => a.percentage - b.percentage)); setMilestoneInput({ percentage: 50, notify: true }); } } }; const removeMilestone = (percentage: number) => { handleChange( 'milestones', (formData.milestones || []).filter((m) => m.percentage !== percentage) ); }; return (
{/* Basic Information */}

Basic Information

handleChange('name', e.target.value)} required className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm" placeholder="e.g., Monthly Sales Target" />