import { object, string, Schema } from 'yup'; import { useFormContext } from 'react-hook-form'; import { TodoWithStats, CreateTodoRequest, UpdateTodoRequest } from '../../../api/controller/todo'; import Button from '@greatness/components/src/Button'; import Modal from '@greatness/components/src/Modal'; import Form from '@greatness/components/src/form/Form'; import TextInput from '@greatness/components/src/form/text/TextInput'; interface TodoFormProps { isOpen: boolean; onClose: () => void; onSubmit: (data: CreateTodoRequest | UpdateTodoRequest) => Promise; todo?: TodoWithStats; // If provided, we're editing isLoading?: boolean; } const DEFAULT_COLORS = [ '#3B82F6', // Blue '#EF4444', // Red '#10B981', // Green '#F59E0B', // Yellow '#8B5CF6', // Purple '#EC4899', // Pink '#06B6D4', // Cyan '#84CC16', // Lime '#F97316', // Orange '#6366F1', // Indigo ]; const todoValidation: Schema = object({ title: string() .required('Title is required') .max(200, 'Title must be less than 200 characters') .trim(), description: string() .max(1000, 'Description must be less than 1000 characters') .default(''), color: string() .required('Please select a color') .matches(/^#[0-9A-F]{6}$/i, 'Please select a valid color'), }); export default function TodoForm({ isOpen, onClose, onSubmit, todo, isLoading = false }: TodoFormProps) { const defaultValues: CreateTodoRequest = { title: todo?.title || '', description: todo?.description || '', color: todo?.color || DEFAULT_COLORS[0], }; const handleFormSubmit = async (data: CreateTodoRequest) => { try { await onSubmit(data); onClose(); } catch (error) { console.error('Failed to save todo:', error); throw error; // Let form handle the error } }; return (

{todo ? 'Edit Todo' : 'Create New Todo'}

); } // Separate component for form content to access form context interface TodoFormContentProps { isLoading: boolean; onClose: () => void; todo?: TodoWithStats; } function TodoFormContent({ isLoading, onClose, todo }: TodoFormContentProps) { const { watch, setValue } = useFormContext(); const watchedValues = watch(); return ( <> {/* Title */}
{/* Description */}
{/* Color Selection */}
{DEFAULT_COLORS.map((color) => (
{/* Custom color input */}
setValue('color', e.target.value)} className="w-16 h-8 border border-gray-300 rounded cursor-pointer" title="Choose custom color" /> {watchedValues.color}
{/* Preview */}

{watchedValues.title || 'Todo Title'}

{watchedValues.description && (

{watchedValues.description}

)}
{/* Form Actions */}
); }