201 lines
6.1 KiB
TypeScript
201 lines
6.1 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import { useForm } from 'react-hook-form'
|
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
import { z } from 'zod'
|
|
import { Button } from '@/components/ui/button'
|
|
import { Input } from '@/components/ui/input'
|
|
import { Textarea } from '@/components/ui/textarea'
|
|
import {
|
|
Form,
|
|
FormControl,
|
|
FormField,
|
|
FormItem,
|
|
FormLabel,
|
|
FormMessage,
|
|
} from '@/components/ui/form'
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from '@/components/ui/select'
|
|
import { Alert, AlertDescription } from '@/components/ui/alert'
|
|
import { CheckCircle2, Loader2 } from 'lucide-react'
|
|
|
|
const consultingAreas = [
|
|
'اینتگریشن',
|
|
'هوشمندسازی',
|
|
'RAG',
|
|
'Performance',
|
|
'امنیت',
|
|
'معماری نرمافزار',
|
|
'داده و تحلیل',
|
|
'سایر',
|
|
] as const
|
|
|
|
const formSchema = z.object({
|
|
fullName: z.string().min(2, 'نام و نام خانوادگی الزامی است'),
|
|
organization: z.string().min(1, 'نام سازمان الزامی است'),
|
|
phone: z.string().min(10, 'شماره تماس معتبر وارد کنید'),
|
|
area: z.string().min(1, 'حوزه مشاوره را انتخاب کنید'),
|
|
description: z.string().optional(),
|
|
})
|
|
|
|
type FormValues = z.infer<typeof formSchema>
|
|
|
|
export function ConsultingForm() {
|
|
const [submitted, setSubmitted] = useState(false)
|
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
|
const [submitError, setSubmitError] = useState<string | null>(null)
|
|
|
|
const form = useForm<FormValues>({
|
|
resolver: zodResolver(formSchema),
|
|
defaultValues: {
|
|
fullName: '',
|
|
organization: '',
|
|
phone: '',
|
|
area: '',
|
|
description: '',
|
|
},
|
|
})
|
|
|
|
async function onSubmit(data: FormValues) {
|
|
setSubmitError(null)
|
|
setIsSubmitting(true)
|
|
try {
|
|
const res = await fetch('/api/consulting', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(data),
|
|
})
|
|
const json = await res.json().catch(() => ({}))
|
|
if (!res.ok) {
|
|
setSubmitError(json.error || 'ارسال درخواست ناموفق بود. لطفاً دوباره تلاش کنید.')
|
|
return
|
|
}
|
|
setSubmitted(true)
|
|
form.reset()
|
|
} catch {
|
|
setSubmitError('خطا در ارتباط با سرور. لطفاً دوباره تلاش کنید.')
|
|
} finally {
|
|
setIsSubmitting(false)
|
|
}
|
|
}
|
|
|
|
if (submitted) {
|
|
return (
|
|
<Alert className="border-primary/50 bg-primary/5 text-center">
|
|
<CheckCircle2 className="h-5 w-5 text-primary" />
|
|
<AlertDescription className="text-base font-medium">
|
|
در سریعترین زمان ممکن با شما تماس میگیریم.
|
|
</AlertDescription>
|
|
</Alert>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Form {...form}>
|
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
|
{submitError && (
|
|
<Alert variant="destructive">
|
|
<AlertDescription>{submitError}</AlertDescription>
|
|
</Alert>
|
|
)}
|
|
<FormField
|
|
control={form.control}
|
|
name="fullName"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>نام و نام خانوادگی</FormLabel>
|
|
<FormControl>
|
|
<Input placeholder="نام و نام خانوادگی" {...field} className="h-11" />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name="organization"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>نام سازمان</FormLabel>
|
|
<FormControl>
|
|
<Input placeholder="نام سازمان یا شرکت" {...field} className="h-11" />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name="phone"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>شماره تماس</FormLabel>
|
|
<FormControl>
|
|
<Input type="tel" placeholder="۰۹۱۲۳۴۵۶۷۸۹" {...field} className="h-11" />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name="area"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>در چه حوزهای مشاوره میخواهید؟</FormLabel>
|
|
<Select onValueChange={field.onChange} value={field.value}>
|
|
<FormControl>
|
|
<SelectTrigger className="h-11 w-full">
|
|
<SelectValue placeholder="انتخاب حوزه" />
|
|
</SelectTrigger>
|
|
</FormControl>
|
|
<SelectContent>
|
|
{consultingAreas.map((area) => (
|
|
<SelectItem key={area} value={area}>
|
|
{area}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name="description"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>توضیحات (اختیاری)</FormLabel>
|
|
<FormControl>
|
|
<Textarea
|
|
placeholder="در صورت نیاز توضیح بیشتری بنویسید..."
|
|
className="min-h-24"
|
|
{...field}
|
|
/>
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<Button type="submit" size="lg" className="w-full" disabled={isSubmitting}>
|
|
{isSubmitting ? (
|
|
<>
|
|
<Loader2 className="size-5 animate-spin" aria-hidden />
|
|
در حال ارسال...
|
|
</>
|
|
) : (
|
|
'ثبت درخواست'
|
|
)}
|
|
</Button>
|
|
</form>
|
|
</Form>
|
|
)
|
|
}
|