feat: integrate Zod validation schema for pipeline form and enhance error handling in form components

This commit is contained in:
Pattadon 2025-05-02 14:56:27 +07:00
parent 616cfabd70
commit a6b542a040
4 changed files with 43 additions and 2 deletions

View File

@ -14,6 +14,8 @@ import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Form } from "@/components/ui/form";
import { cn } from "@/lib/utils";
import { pipelineSchema, PipelineFormValues } from "@/lib/validations/pipeline";
import { zodResolver } from "@hookform/resolvers/zod";
const TOTAL_STEPS = 5;
@ -37,7 +39,9 @@ export default function CratePipelineForm() {
const isFirstStep = step === 0;
const isLastStep = step === TOTAL_STEPS - 1;
const form = useForm();
const form = useForm<PipelineFormValues>({
resolver: zodResolver(pipelineSchema),
});
const { handleSubmit, reset } = form;
const onSubmit = async (formData: unknown) => {

View File

@ -1,3 +1,4 @@
import { useFormContext } from "react-hook-form";
import {
Card,
CardContent,
@ -9,6 +10,12 @@ import { Label } from "../ui/label";
import { Textarea } from "../ui/textarea";
export function PipelineAiAssistant() {
const {
handleSubmit,
reset,
register,
formState: { errors },
} = useFormContext();
return (
<Card className="mt-6 border-0 hover:border-highlight-border transition-all duration-200">
<CardHeader>
@ -24,6 +31,7 @@ export function PipelineAiAssistant() {
placeholder="E.g., Focus on extracting pricing trends, ignore promotional content, prioritize property features..."
rows={4}
className="border-primary/20"
{...register("aiPrompt")}
/>
<p className="text-xs text-muted-foreground mt-1">
Provide specific instructions to guide the AI in processing your

View File

@ -13,7 +13,12 @@ import { Label } from "../ui/label";
import { Textarea } from "../ui/textarea";
export function PipelineDetails() {
const { register } = useFormContext();
const {
handleSubmit,
reset,
register,
formState: { errors },
} = useFormContext();
return (
<Card className="border-0 hover:border-highlight-border transition-all duration-200">
@ -33,6 +38,13 @@ export function PipelineDetails() {
{...register("name")}
/>
</div>
{errors.name && (
<p className="text-sm text-destructive mt-1">
{typeof errors.name?.message === "string"
? errors.name.message
: ""}
</p>
)}
<div className="space-y-2">
<Label htmlFor="description">Description</Label>
@ -43,6 +55,13 @@ export function PipelineDetails() {
{...register("description")}
/>
</div>
{errors.description && (
<p className="text-sm text-destructive mt-1">
{typeof errors.description?.message === "string"
? errors.description.message
: ""}
</p>
)}
<div className="space-y-2">
<Label htmlFor="tags">Tags (optional)</Label>

View File

@ -0,0 +1,10 @@
import { z } from "zod";
export const pipelineSchema = z.object({
name: z.string().min(1, "Pipeline name is required"),
description: z.string().min(1, "Description is required"),
aiPrompt: z.string().optional(),
tags: z.string().optional(),
});
export type PipelineFormValues = z.infer<typeof pipelineSchema>;