diff --git a/.kiro/specs/ultimate-lists-app/tasks.md b/.kiro/specs/ultimate-lists-app/tasks.md index 24bd1d5..153e227 100644 --- a/.kiro/specs/ultimate-lists-app/tasks.md +++ b/.kiro/specs/ultimate-lists-app/tasks.md @@ -199,7 +199,7 @@ - Implement skeleton loaders - _Requirements: 7.3_ -- [-] 16. Implement error handling +- [x] 16. Implement error handling - Add try-catch blocks to all server actions - Implement error boundaries in React components - Add user-friendly error messages @@ -207,7 +207,7 @@ - Implement retry logic for failed operations - _Requirements: All (error handling is cross-cutting)_ -- [ ] 17. Add input validation +- [x] 17. Add input validation - Validate all form inputs before submission - Add inline validation errors - Prevent empty task/list creation diff --git a/components/InlineItemCreate.tsx b/components/InlineItemCreate.tsx index bf757a5..111cae7 100644 --- a/components/InlineItemCreate.tsx +++ b/components/InlineItemCreate.tsx @@ -5,6 +5,7 @@ import { useRouter } from 'next/navigation' import { createItem } from '@/lib/actions' import { Plus } from 'lucide-react' import { useToast } from './ToastContainer' +import { validateItemTitle, sanitizeString } from '@/lib/validation' interface InlineItemCreateProps { listId: string @@ -16,25 +17,36 @@ export default function InlineItemCreate({ listId }: InlineItemCreateProps) { const [isCreating, setIsCreating] = useState(false) const [title, setTitle] = useState('') const [isSubmitting, setIsSubmitting] = useState(false) + const [error, setError] = useState('') const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() - if (!title.trim() || isSubmitting) { + // Validate title + const validationResult = validateItemTitle(title) + if (!validationResult.isValid) { + setError(validationResult.error || 'Invalid title') + return + } + + if (isSubmitting) { return } setIsSubmitting(true) + setError('') try { - await createItem(listId, title.trim()) + await createItem(listId, sanitizeString(title)) showToast('Task added successfully', 'success') setTitle('') setIsCreating(false) router.refresh() } catch (error) { console.error('Error creating item:', error) - showToast('Failed to add task', 'error') + const errorMessage = error instanceof Error ? error.message : 'Failed to add task' + setError(errorMessage) + showToast(errorMessage, 'error') } finally { setIsSubmitting(false) } @@ -65,15 +77,30 @@ export default function InlineItemCreate({ listId }: InlineItemCreateProps) { return (