forked from cardosofelipe/fast-next-template
fix(frontend): show validation errors when agent type form fails
When form validation fails (e.g., personality_prompt is empty), the form would silently not submit. Now it shows a toast with the first error and navigates to the tab containing the error field. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,9 +7,10 @@
|
||||
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import { useForm, Controller, type FieldErrors } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { toast } from 'sonner';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
@@ -89,6 +90,30 @@ export function AgentTypeForm({
|
||||
formState: { errors },
|
||||
} = form;
|
||||
|
||||
// Handle form validation errors - show toast with first error
|
||||
const handleFormError = useCallback((formErrors: FieldErrors<AgentTypeCreateFormValues>) => {
|
||||
// Find the first error and show it
|
||||
const firstErrorKey = Object.keys(formErrors)[0] as keyof AgentTypeCreateFormValues;
|
||||
if (firstErrorKey) {
|
||||
const error = formErrors[firstErrorKey];
|
||||
const message = error && 'message' in error ? error.message : 'Validation error';
|
||||
toast.error('Please fix form errors', {
|
||||
description: `${String(firstErrorKey)}: ${message}`,
|
||||
});
|
||||
|
||||
// Navigate to the tab containing the error
|
||||
if (['name', 'slug', 'description', 'expertise', 'is_active'].includes(firstErrorKey)) {
|
||||
setActiveTab('basic');
|
||||
} else if (['primary_model', 'fallback_models', 'model_params'].includes(firstErrorKey)) {
|
||||
setActiveTab('model');
|
||||
} else if (['mcp_servers', 'tool_permissions'].includes(firstErrorKey)) {
|
||||
setActiveTab('permissions');
|
||||
} else if (firstErrorKey === 'personality_prompt') {
|
||||
setActiveTab('personality');
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const watchName = watch('name');
|
||||
/* istanbul ignore next -- defensive fallback, expertise always has default */
|
||||
const watchExpertise = watch('expertise') || [];
|
||||
@@ -133,7 +158,7 @@ export function AgentTypeForm({
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} className={className}>
|
||||
<form onSubmit={handleSubmit(onSubmit, handleFormError)} className={className}>
|
||||
{/* Header */}
|
||||
<div className="mb-6 flex items-center gap-4">
|
||||
<Button type="button" variant="ghost" size="icon" onClick={onCancel}>
|
||||
|
||||
Reference in New Issue
Block a user