- Both forms use useForm with zodResolver against shared schemas
(loginSchema, createTicketSchema)
- Field-level errors rendered inline under inputs
- isSubmitting drives button disabled state
- NewTicket: severity registered with valueAsNumber; CTISelect wrapped in
nested Controllers (one per categoryId/typeId/itemId) since it controls
three form fields as a single compound input
- Admin forms stay on useState for now — they get redesigned with shadcn
dialogs in Phase 3, RHF migration lands with that
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>