Files
aragrp/components/consulting-form.tsx
ar.badieiandCursor c2376b3b9e
Build & Push Docker Image / build (push) Has been cancelled
feat: redesign landing page with brand system and section blocks
Refresh the homepage around new hero/services/roadmap sections, shared design tokens, and updated brand assets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 17:00:55 +03:30

213 lines
6.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'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 = [
'یکپارچه‌سازی سامانه‌ها',
'هوشمندسازی',
'جستجوی معنایی و دانش‌بنیان',
'بهینه‌سازی عملکرد',
'امنیت',
'معماری نرم‌افزار',
'داده و تحلیل',
'سایر',
] as const
const formSchema = z.object({
fullName: z.string().min(2, 'نام و نام خانوادگی الزامی است'),
organization: z.string().min(1, 'نام سازمان الزامی است'),
phone: z
.string()
.min(1, 'شماره تماس الزامی است')
.refine(
(val) => {
const normalized = val
.replace(/[۰-۹]/g, (c) => '۰۱۲۳۴۵۶۷۸۹'.indexOf(c).toString())
.replace(/\D/g, '')
return normalized.length === 11 && normalized.startsWith('09')
},
'لطفاً شماره موبایل معتبر وارد کنید'
),
area: z.string().min(1, 'حوزه مشاوره را انتخاب کنید'),
description: z.string().max(1000, 'حداکثر ۱۰۰۰ کاراکتر مجاز است').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"
maxLength={1000}
{...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>
)
}