255 lines
10 KiB
TypeScript
255 lines
10 KiB
TypeScript
"use client";
|
||
|
||
import { useEffect, useState } from "react";
|
||
import { Mail, Phone, MapPin, Send, CheckCircle2 } from "lucide-react";
|
||
import api from "../lib/services/api";
|
||
|
||
interface ContactInfoItem {
|
||
key: string;
|
||
title: string;
|
||
value: string;
|
||
icon?: string;
|
||
}
|
||
|
||
export default function ContactFormClient() {
|
||
const [infoItems, setInfoItems] = useState<ContactInfoItem[]>([]);
|
||
const [name, setName] = useState("");
|
||
const [phone, setPhone] = useState("");
|
||
const [subject, setSubject] = useState("");
|
||
const [message, setMessage] = useState("");
|
||
const [loading, setLoading] = useState(false);
|
||
const [success, setSuccess] = useState(false);
|
||
const [error, setError] = useState("");
|
||
|
||
useEffect(() => {
|
||
async function fetchContactInfo() {
|
||
try {
|
||
const res = await api.get("/contact/info");
|
||
setInfoItems(res.data || []);
|
||
} catch (err) {
|
||
console.error("Failed to fetch contact info", err);
|
||
}
|
||
}
|
||
fetchContactInfo();
|
||
}, []);
|
||
|
||
const handleSubmit = async (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
const cleanPhone = phone.trim();
|
||
if (!name.trim() || !cleanPhone || !message.trim()) {
|
||
setError("لطفاً نام، شماره موبایل و متن پیام را وارد کنید.");
|
||
return;
|
||
}
|
||
|
||
if (!/^09\d{9}$/.test(cleanPhone)) {
|
||
setError("شماره همراه وارد شده معتبر نیست. (مثال: ۰۹۱۲۳۴۵۶۷۸۹)");
|
||
return;
|
||
}
|
||
|
||
setError("");
|
||
setLoading(true);
|
||
|
||
try {
|
||
await api.post("/contact", {
|
||
name,
|
||
phone,
|
||
subject,
|
||
message,
|
||
});
|
||
setSuccess(true);
|
||
setName("");
|
||
setPhone("");
|
||
setSubject("");
|
||
setMessage("");
|
||
} catch (err: unknown) {
|
||
const errorObj = err as { response?: { data?: { message?: string } } };
|
||
setError(
|
||
errorObj.response?.data?.message || "خطایی در ثبت پیام رخ داده است. لطفاً مجدداً تلاش کنید."
|
||
);
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
const getIcon = (iconName?: string) => {
|
||
switch (iconName) {
|
||
case "mail":
|
||
return <Mail className="w-6 h-6" />;
|
||
case "map-pin":
|
||
return <MapPin className="w-6 h-6" />;
|
||
case "phone":
|
||
default:
|
||
return <Phone className="w-6 h-6" />;
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="grid lg:grid-cols-12 gap-12 items-start">
|
||
{/* Contact Details */}
|
||
<div className="lg:col-span-5 space-y-8">
|
||
<h3 className="text-2xl font-black text-medical-gray-900">اطلاعات نمایندگی</h3>
|
||
|
||
<div className="space-y-6">
|
||
{infoItems.length > 0 ? (
|
||
infoItems.map((item) => (
|
||
<div
|
||
key={item.key}
|
||
className="flex gap-4 p-6 bg-white border border-medical-gray-200 rounded-[2rem] shadow-sm"
|
||
>
|
||
<div className="w-12 h-12 bg-canina-blue/5 text-canina-blue rounded-2xl flex items-center justify-center shrink-0">
|
||
{getIcon(item.icon)}
|
||
</div>
|
||
<div>
|
||
<h4 className="text-xs font-black text-medical-gray-400 uppercase tracking-wider mb-1">
|
||
{item.title}
|
||
</h4>
|
||
<div className="text-sm font-bold text-medical-gray-900 leading-relaxed whitespace-pre-wrap">
|
||
{item.value}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))
|
||
) : (
|
||
<>
|
||
<div className="flex gap-4 p-6 bg-white border border-medical-gray-200 rounded-[2rem] shadow-sm">
|
||
<div className="w-12 h-12 bg-canina-blue/5 text-canina-blue rounded-2xl flex items-center justify-center shrink-0">
|
||
<Phone className="w-6 h-6" />
|
||
</div>
|
||
<div>
|
||
<h4 className="text-xs font-black text-medical-gray-400 uppercase tracking-wider mb-1">
|
||
تلفنهای تماس
|
||
</h4>
|
||
<p className="text-lg font-black text-medical-gray-900 tracking-wider">
|
||
۰۲۱-۸۸۸۸ ۴۴۴۴
|
||
</p>
|
||
<p className="text-sm text-medical-gray-500 font-bold">
|
||
شنبه تا چهارشنبه ۹:۰۰ الی ۱۸:۰۰
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex gap-4 p-6 bg-white border border-medical-gray-200 rounded-[2rem] shadow-sm">
|
||
<div className="w-12 h-12 bg-canina-blue/5 text-canina-blue rounded-2xl flex items-center justify-center shrink-0">
|
||
<Mail className="w-6 h-6" />
|
||
</div>
|
||
<div>
|
||
<h4 className="text-xs font-black text-medical-gray-400 uppercase tracking-wider mb-1">
|
||
پست الکترونیک
|
||
</h4>
|
||
<p className="text-sm font-black text-medical-gray-900">info@canina-iran.com</p>
|
||
<p className="text-xs text-medical-gray-500 font-bold">
|
||
پاسخگویی در کمتر از ۲۴ ساعت کاری
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex gap-4 p-6 bg-white border border-medical-gray-200 rounded-[2rem] shadow-sm">
|
||
<div className="w-12 h-12 bg-canina-blue/5 text-canina-blue rounded-2xl flex items-center justify-center shrink-0">
|
||
<MapPin className="w-6 h-6" />
|
||
</div>
|
||
<div>
|
||
<h4 className="text-xs font-black text-medical-gray-400 uppercase tracking-wider mb-1">
|
||
نشانی دفتر مرکزی
|
||
</h4>
|
||
<p className="text-sm font-bold text-medical-gray-900 leading-relaxed">
|
||
تهران، جردن، خیابان سعیدی، ساختمان کنینا، طبقه ۵، واحد ۱۹
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Contact Form */}
|
||
<div className="lg:col-span-7 bg-white border border-medical-gray-200 rounded-[3rem] p-10 shadow-xl">
|
||
<h3 className="text-2xl font-black text-medical-gray-900 mb-8">ارسال پیام مستقیم</h3>
|
||
|
||
{success ? (
|
||
<div className="p-6 bg-emerald-50 border border-emerald-200 text-emerald-800 rounded-2xl text-center space-y-3">
|
||
<CheckCircle2 className="w-12 h-12 text-emerald-600 mx-auto" />
|
||
<h4 className="text-lg font-black">پیام شما با موفقیت ثبت شد</h4>
|
||
<p className="text-sm font-medium leading-relaxed">
|
||
پیامک تایید به شماره شما ارسال شد. کارشناسان کنینا به زودی با شما تماس خواهند گرفت.
|
||
</p>
|
||
<button
|
||
onClick={() => setSuccess(false)}
|
||
className="mt-4 px-6 py-2 bg-emerald-600 text-white rounded-xl text-xs font-black"
|
||
>
|
||
ارسال پیام جدید
|
||
</button>
|
||
</div>
|
||
) : (
|
||
<form onSubmit={handleSubmit} className="space-y-6">
|
||
{error && (
|
||
<div className="p-4 bg-rose-50 border border-rose-200 text-rose-700 text-xs font-bold rounded-2xl">
|
||
{error}
|
||
</div>
|
||
)}
|
||
|
||
<div className="grid md:grid-cols-2 gap-6">
|
||
<div className="space-y-2">
|
||
<label className="text-xs font-black text-medical-gray-500">
|
||
نام و نام خانوادگی *
|
||
</label>
|
||
<input
|
||
type="text"
|
||
value={name}
|
||
onChange={(e) => setName(e.target.value)}
|
||
className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl p-4 text-sm font-bold focus:outline-none focus:ring-2 focus:ring-canina-blue/20"
|
||
placeholder="مثال: علی محمدی"
|
||
required
|
||
/>
|
||
</div>
|
||
<div className="space-y-2">
|
||
<label className="text-xs font-black text-medical-gray-500">شماره موبایل *</label>
|
||
<input
|
||
type="text"
|
||
value={phone}
|
||
onChange={(e) => setPhone(e.target.value)}
|
||
className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl p-4 text-sm font-bold text-left focus:outline-none focus:ring-2 focus:ring-canina-blue/20"
|
||
dir="ltr"
|
||
placeholder="09123456789"
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
<label className="text-xs font-black text-medical-gray-500">موضوع پیام</label>
|
||
<input
|
||
type="text"
|
||
value={subject}
|
||
onChange={(e) => setSubject(e.target.value)}
|
||
className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl p-4 text-sm font-bold focus:outline-none focus:ring-2 focus:ring-canina-blue/20"
|
||
placeholder="مثال: مشاوره تخصصی مکمل یا خرید عمده"
|
||
/>
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
<label className="text-xs font-black text-medical-gray-500">متن پیام *</label>
|
||
<textarea
|
||
rows={4}
|
||
value={message}
|
||
onChange={(e) => setMessage(e.target.value)}
|
||
className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl p-4 text-sm font-bold focus:outline-none focus:ring-2 focus:ring-canina-blue/20"
|
||
placeholder="متن درخواست یا پیام خود را بنویسید..."
|
||
required
|
||
></textarea>
|
||
</div>
|
||
|
||
<button
|
||
type="submit"
|
||
disabled={loading}
|
||
className="w-full bg-canina-blue text-white py-4 rounded-2xl font-black flex items-center justify-center gap-2 hover:shadow-xl hover:shadow-canina-blue/20 transition-all disabled:opacity-50"
|
||
>
|
||
<Send className="w-5 h-5 rotate-180" />
|
||
{loading ? "در حال ثبت..." : "ارسال پیام"}
|
||
</button>
|
||
</form>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|