# Task 7: Implement Epic/Story/Task Forms

**Task ID**: TASK-007 | **Story**: [STORY-002](sprint_1_story_2.md) | **Sprint**: [Sprint 1](sprint_1.md)
**Estimated Hours**: 5h | **Assignee**: Frontend Developer 2 | **Priority**: P0 | **Status**: Not Started

## Task Description
Build React forms for creating/editing Epic/Story/Task with validation, parent selection, and error handling.

## Implementation

### Example: EpicForm.tsx
```typescript
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useCreateEpic, useUpdateEpic } from '../hooks/useEpics';

const epicSchema = z.object({
  title: z.string().min(3, 'Title must be at least 3 characters'),
  description: z.string().optional(),
  projectId: z.string().uuid('Invalid project ID'),
  priority: z.enum(['Low', 'Medium', 'High', 'Critical']),
  status: z.enum(['Backlog', 'Todo', 'InProgress', 'Done'])
});

type EpicFormData = z.infer<typeof epicSchema>;

export const EpicForm: React.FC<{ epic?: Epic, onSuccess: () => void }> = ({ epic, onSuccess }) => {
  const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<EpicFormData>({
    resolver: zodResolver(epicSchema),
    defaultValues: epic || {}
  });

  const createEpic = useCreateEpic();
  const updateEpic = useUpdateEpic();

  const onSubmit = async (data: EpicFormData) => {
    try {
      if (epic) {
        await updateEpic.mutateAsync({ id: epic.id, dto: data });
      } else {
        await createEpic.mutateAsync(data);
      }
      onSuccess();
    } catch (error) {
      console.error('Form submission error:', error);
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
      <div>
        <label htmlFor="title">Title *</label>
        <input id="title" {...register('title')} className="form-input" />
        {errors.title && <span className="text-red-500">{errors.title.message}</span>}
      </div>

      <div>
        <label htmlFor="description">Description</label>
        <textarea id="description" {...register('description')} className="form-textarea" />
      </div>

      <div>
        <label htmlFor="priority">Priority *</label>
        <select id="priority" {...register('priority')} className="form-select">
          <option value="Low">Low</option>
          <option value="Medium">Medium</option>
          <option value="High">High</option>
          <option value="Critical">Critical</option>
        </select>
      </div>

      <button type="submit" disabled={isSubmitting} className="btn-primary">
        {isSubmitting ? 'Saving...' : (epic ? 'Update Epic' : 'Create Epic')}
      </button>
    </form>
  );
};
```

## Acceptance Criteria
- [ ] EpicForm component with validation
- [ ] StoryForm with parent epic selection dropdown
- [ ] TaskForm with parent story selection dropdown
- [ ] Zod schemas for all forms
- [ ] Loading states during submission
- [ ] Error messages displayed

## Deliverables
1. EpicForm.tsx
2. StoryForm.tsx (with parent epic selector)
3. TaskForm.tsx (with parent story selector)
4. Validation schemas
5. Unit tests (15+ tests)

**Status**: Not Started | **Created**: 2025-11-04
