526 lines
25 KiB
TypeScript
526 lines
25 KiB
TypeScript
import { useState, useEffect } from 'react';
|
||
import { Building2, CheckCircle2, XCircle, Clock, PhoneCall, Filter, X, Plus, ShieldCheck } from 'lucide-react';
|
||
import { toast } from 'react-hot-toast';
|
||
import api from '../services/api';
|
||
import Spinner from '../components/ui/Spinner';
|
||
import type { B2BInquiry, PartnerAccount } from '../types/admin';
|
||
|
||
export default function B2BManager() {
|
||
const [activeTab, setActiveTab] = useState<'inquiries' | 'partners'>('inquiries');
|
||
|
||
// Inquiries State
|
||
const [inquiries, setInquiries] = useState<B2BInquiry[]>([]);
|
||
const [isInquiriesLoading, setIsInquiriesLoading] = useState(true);
|
||
const [statusFilter, setStatusFilter] = useState<string>('ALL');
|
||
|
||
// Inquiry Review Modal State
|
||
const [selectedInquiry, setSelectedInquiry] = useState<B2BInquiry | null>(null);
|
||
const [inquiryStatus, setInquiryStatus] = useState<'PENDING' | 'CONTACTED' | 'APPROVED' | 'REJECTED'>('CONTACTED');
|
||
const [inquiryAdminNotes, setInquiryAdminNotes] = useState('');
|
||
const [isInquirySubmitting, setIsInquirySubmitting] = useState(false);
|
||
|
||
// Partners State
|
||
const [partners, setPartners] = useState<PartnerAccount[]>([]);
|
||
const [isPartnersLoading, setIsPartnersLoading] = useState(false);
|
||
const [isPartnerModalOpen, setIsPartnerModalOpen] = useState(false);
|
||
const [partnerFormData, setPartnerFormData] = useState({
|
||
userId: '',
|
||
companyName: '',
|
||
taxId: '',
|
||
creditLimit: '100000000',
|
||
discountTier: 'tier1',
|
||
status: 'ACTIVE',
|
||
});
|
||
const [isPartnerSubmitting, setIsPartnerSubmitting] = useState(false);
|
||
|
||
const fetchInquiries = async () => {
|
||
try {
|
||
const res = await api.get('/b2b/inquiries');
|
||
const data = Array.isArray(res.data) ? res.data : (res.data?.data || []);
|
||
setInquiries(data);
|
||
} catch (err) {
|
||
console.error('Failed to fetch B2B inquiries:', err);
|
||
toast.error('خطا در دریافت لیست درخواستهای B2B');
|
||
} finally {
|
||
setIsInquiriesLoading(false);
|
||
}
|
||
};
|
||
|
||
const fetchPartners = async () => {
|
||
try {
|
||
const res = await api.get('/b2b/partners');
|
||
const data = Array.isArray(res.data) ? res.data : (res.data?.data || []);
|
||
setPartners(data);
|
||
} catch (err) {
|
||
console.warn('Failed to fetch partner accounts:', err);
|
||
// Fallback empty if backend endpoint not populated
|
||
setPartners([]);
|
||
} finally {
|
||
setIsPartnersLoading(false);
|
||
}
|
||
};
|
||
|
||
useEffect(() => {
|
||
let isMounted = true;
|
||
if (activeTab === 'inquiries') {
|
||
api.get('/b2b/inquiries')
|
||
.then(res => {
|
||
if (!isMounted) return;
|
||
const data = Array.isArray(res.data) ? res.data : (res.data?.data || []);
|
||
setInquiries(data);
|
||
})
|
||
.catch(err => {
|
||
console.error('Failed to fetch B2B inquiries:', err);
|
||
toast.error('خطا در دریافت لیست درخواستهای B2B');
|
||
})
|
||
.finally(() => {
|
||
if (isMounted) setIsInquiriesLoading(false);
|
||
});
|
||
} else {
|
||
api.get('/b2b/partners')
|
||
.then(res => {
|
||
if (!isMounted) return;
|
||
const data = Array.isArray(res.data) ? res.data : (res.data?.data || []);
|
||
setPartners(data);
|
||
})
|
||
.catch(err => {
|
||
console.warn('Failed to fetch partner accounts:', err);
|
||
if (isMounted) setPartners([]);
|
||
})
|
||
.finally(() => {
|
||
if (isMounted) setIsPartnersLoading(false);
|
||
});
|
||
}
|
||
return () => {
|
||
isMounted = false;
|
||
};
|
||
}, [activeTab]);
|
||
|
||
const openInquiryReview = (inquiry: B2BInquiry) => {
|
||
setSelectedInquiry(inquiry);
|
||
setInquiryStatus(inquiry.status || 'CONTACTED');
|
||
setInquiryAdminNotes(inquiry.adminNotes || '');
|
||
};
|
||
|
||
const handleInquiryReviewSubmit = async (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
if (!selectedInquiry) return;
|
||
|
||
try {
|
||
setIsInquirySubmitting(true);
|
||
await api.patch(`/b2b/inquiries/${selectedInquiry.id}`, {
|
||
status: inquiryStatus,
|
||
adminNotes: inquiryAdminNotes.trim() || undefined,
|
||
});
|
||
|
||
toast.success('وضعیت درخواست B2B بروزرسانی شد');
|
||
setSelectedInquiry(null);
|
||
fetchInquiries();
|
||
} catch (err) {
|
||
console.error('Failed to review B2B inquiry:', err);
|
||
toast.error('خطا در بروزرسانی وضعیت درخواست B2B');
|
||
} finally {
|
||
setIsInquirySubmitting(false);
|
||
}
|
||
};
|
||
|
||
const handlePartnerSave = async (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
if (!partnerFormData.userId.trim() || !partnerFormData.companyName.trim()) {
|
||
toast.error('شناسه کاربر و نام شرکت اجباری هستند');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
setIsPartnerSubmitting(true);
|
||
await api.post('/admin/b2b/partners', partnerFormData);
|
||
toast.success('حساب همکار B2B جدید ایجاد شد');
|
||
setIsPartnerModalOpen(false);
|
||
fetchPartners();
|
||
} catch (err) {
|
||
console.error('Failed to create partner account:', err);
|
||
toast.error('خطا در ثبت حساب همکار B2B');
|
||
} finally {
|
||
setIsPartnerSubmitting(false);
|
||
}
|
||
};
|
||
|
||
const filteredInquiries = inquiries.filter(inq => {
|
||
if (statusFilter === 'ALL') return true;
|
||
return inq.status === statusFilter;
|
||
});
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
|
||
<div>
|
||
<h2 className="text-2xl font-black text-gray-900 flex items-center gap-2">
|
||
<Building2 className="w-6 h-6 text-purple-600" />
|
||
مدیریت همکاران عمدهفروشی و B2B
|
||
</h2>
|
||
<p className="text-gray-500 font-medium mt-1">بررسی درخواستهای نمایندگی، تنظیم سقف اعتبار و اعطای کدهای تخفیف همکار</p>
|
||
</div>
|
||
|
||
{/* Tab Toggle */}
|
||
<div className="flex items-center gap-2 bg-white p-1.5 rounded-2xl border border-gray-200 shadow-sm">
|
||
<button
|
||
onClick={() => setActiveTab('inquiries')}
|
||
className={`px-4 py-2 rounded-xl text-xs font-bold transition-all ${
|
||
activeTab === 'inquiries' ? 'bg-purple-600 text-white shadow-sm' : 'text-gray-600 hover:bg-gray-50'
|
||
}`}
|
||
>
|
||
درخواستهای دریافت نمایندگی ({inquiries.length})
|
||
</button>
|
||
<button
|
||
onClick={() => setActiveTab('partners')}
|
||
className={`px-4 py-2 rounded-xl text-xs font-bold transition-all ${
|
||
activeTab === 'partners' ? 'bg-purple-600 text-white shadow-sm' : 'text-gray-600 hover:bg-gray-50'
|
||
}`}
|
||
>
|
||
حسابهای تاییدشده همکار (Partners)
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{activeTab === 'inquiries' ? (
|
||
<div className="space-y-4">
|
||
<div className="flex justify-end">
|
||
<div className="flex items-center gap-2 bg-white p-1.5 rounded-2xl border border-gray-200 shadow-sm">
|
||
<Filter className="w-4 h-4 text-gray-400 mr-2" />
|
||
{[
|
||
{ id: 'ALL', label: 'همه' },
|
||
{ id: 'PENDING', label: 'جدید' },
|
||
{ id: 'CONTACTED', label: 'تماس گرفته شده' },
|
||
{ id: 'APPROVED', label: 'تایید شده' },
|
||
{ id: 'REJECTED', label: 'رد شده' },
|
||
].map(f => (
|
||
<button
|
||
key={f.id}
|
||
onClick={() => setStatusFilter(f.id)}
|
||
className={`px-3 py-1.5 rounded-xl text-xs font-bold transition-all ${
|
||
statusFilter === f.id ? 'bg-purple-50 text-purple-700 border border-purple-200' : 'text-gray-600 hover:bg-gray-50'
|
||
}`}
|
||
>
|
||
{f.label}
|
||
</button>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div className="bg-white rounded-2xl shadow-sm border border-gray-200 overflow-hidden">
|
||
<div className="overflow-x-auto">
|
||
<table className="w-full text-right">
|
||
<thead className="bg-gray-50 border-b border-gray-100">
|
||
<tr>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">شرکت / رابط</th>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">اطلاعات تماس</th>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">نوع کسبوکار / حجم متقاضی</th>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">متن پیام</th>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">وضعیت</th>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500 w-28">عملیات</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody className="divide-y divide-gray-100">
|
||
{isInquiriesLoading ? (
|
||
<tr>
|
||
<td colSpan={6} className="py-12 text-center">
|
||
<Spinner size="lg" className="mx-auto text-purple-600" />
|
||
</td>
|
||
</tr>
|
||
) : filteredInquiries.length === 0 ? (
|
||
<tr>
|
||
<td colSpan={6} className="py-12 text-center text-gray-500 font-medium">درخواستی یافت نشد</td>
|
||
</tr>
|
||
) : (
|
||
filteredInquiries.map((inq) => (
|
||
<tr key={inq.id} className="hover:bg-gray-50/50 transition-colors">
|
||
<td className="py-4 px-6">
|
||
<div className="flex flex-col">
|
||
<span className="font-bold text-gray-900">{inq.companyName}</span>
|
||
<span className="text-xs text-gray-500">{inq.contactName}</span>
|
||
</div>
|
||
</td>
|
||
<td className="py-4 px-6">
|
||
<div className="flex flex-col font-mono text-xs text-gray-600" dir="ltr">
|
||
<span>{inq.phone}</span>
|
||
<span>{inq.email}</span>
|
||
</div>
|
||
</td>
|
||
<td className="py-4 px-6">
|
||
<div className="flex flex-col">
|
||
<span className="inline-block px-2.5 py-0.5 bg-purple-50 text-purple-700 text-xs font-bold rounded-lg border border-purple-100 w-max">
|
||
{inq.businessType}
|
||
</span>
|
||
{inq.estimatedVolume && <span className="text-[11px] text-gray-400 mt-1">{inq.estimatedVolume}</span>}
|
||
</div>
|
||
</td>
|
||
<td className="py-4 px-6 text-gray-600 text-xs max-w-xs line-clamp-2">
|
||
{inq.message}
|
||
</td>
|
||
<td className="py-4 px-6">
|
||
{inq.status === 'APPROVED' ? (
|
||
<span className="inline-flex items-center gap-1 px-2.5 py-1 bg-green-50 text-green-700 text-xs font-bold rounded-full border border-green-200">
|
||
<CheckCircle2 className="w-3.5 h-3.5" /> تایید شده
|
||
</span>
|
||
) : inq.status === 'CONTACTED' ? (
|
||
<span className="inline-flex items-center gap-1 px-2.5 py-1 bg-blue-50 text-blue-700 text-xs font-bold rounded-full border border-blue-200">
|
||
<PhoneCall className="w-3.5 h-3.5" /> تماس گرفته شده
|
||
</span>
|
||
) : inq.status === 'REJECTED' ? (
|
||
<span className="inline-flex items-center gap-1 px-2.5 py-1 bg-red-50 text-red-700 text-xs font-bold rounded-full border border-red-200">
|
||
<XCircle className="w-3.5 h-3.5" /> رد شده
|
||
</span>
|
||
) : (
|
||
<span className="inline-flex items-center gap-1 px-2.5 py-1 bg-amber-50 text-amber-700 text-xs font-bold rounded-full border border-amber-200">
|
||
<Clock className="w-3.5 h-3.5" /> در انتظار بررسی
|
||
</span>
|
||
)}
|
||
</td>
|
||
<td className="py-4 px-6">
|
||
<button
|
||
onClick={() => openInquiryReview(inq)}
|
||
className="px-3 py-1.5 bg-purple-600 text-white hover:bg-purple-700 rounded-lg text-xs font-bold transition-all shadow-sm"
|
||
>
|
||
تغییر وضعیت
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
))
|
||
)}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<div className="space-y-4">
|
||
<div className="flex justify-between items-center">
|
||
<h3 className="font-bold text-gray-800">فهرست حسابهای تایید شده همکار</h3>
|
||
<button
|
||
onClick={() => setIsPartnerModalOpen(true)}
|
||
className="bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded-xl flex items-center gap-2 font-bold text-xs shadow-md shadow-purple-200"
|
||
>
|
||
<Plus className="w-4 h-4" />
|
||
افزودن همکار B2B جدید
|
||
</button>
|
||
</div>
|
||
|
||
<div className="bg-white rounded-2xl shadow-sm border border-gray-200 overflow-hidden">
|
||
<div className="overflow-x-auto">
|
||
<table className="w-full text-right">
|
||
<thead className="bg-gray-50 border-b border-gray-100">
|
||
<tr>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">نام شرکت / موسسه</th>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">User ID</th>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">کد اقتصادی (Tax ID)</th>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">سقف اعتبار (تومان)</th>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">سطح تخفیف</th>
|
||
<th className="py-4 px-6 text-sm font-bold text-gray-500">وضعیت</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody className="divide-y divide-gray-100">
|
||
{isPartnersLoading ? (
|
||
<tr>
|
||
<td colSpan={6} className="py-12 text-center">
|
||
<Spinner size="lg" className="mx-auto text-purple-600" />
|
||
</td>
|
||
</tr>
|
||
) : partners.length === 0 ? (
|
||
<tr>
|
||
<td colSpan={6} className="py-12 text-center text-gray-500 font-medium">هیچ حساب همکار B2B به صورت دستی تعریف نشده است</td>
|
||
</tr>
|
||
) : (
|
||
partners.map((partner) => (
|
||
<tr key={partner.id} className="hover:bg-gray-50/50 transition-colors">
|
||
<td className="py-4 px-6 font-bold text-gray-900">{partner.companyName}</td>
|
||
<td className="py-4 px-6 font-mono text-xs text-gray-500">{partner.userId}</td>
|
||
<td className="py-4 px-6 font-mono text-xs text-gray-500">{partner.taxId || '-'}</td>
|
||
<td className="py-4 px-6 font-bold text-purple-700">
|
||
{Number(partner.creditLimit).toLocaleString()} تومان
|
||
</td>
|
||
<td className="py-4 px-6">
|
||
<span className="px-2.5 py-1 bg-purple-50 text-purple-700 text-xs font-bold rounded-lg border border-purple-100">
|
||
{partner.discountTier}
|
||
</span>
|
||
</td>
|
||
<td className="py-4 px-6">
|
||
<span className="inline-flex items-center gap-1 text-green-600 text-xs font-bold">
|
||
<ShieldCheck className="w-4 h-4" /> {partner.status}
|
||
</span>
|
||
</td>
|
||
</tr>
|
||
))
|
||
)}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Inquiry Review Modal */}
|
||
{selectedInquiry && (
|
||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-gray-900/60 backdrop-blur-sm">
|
||
<div className="bg-white rounded-2xl w-full max-w-lg shadow-2xl overflow-hidden animate-in zoom-in duration-200">
|
||
<div className="px-6 py-4 border-b border-gray-100 flex justify-between items-center bg-gray-50/50">
|
||
<h3 className="text-lg font-bold text-gray-900">
|
||
بررسی درخواست B2B ({selectedInquiry.companyName})
|
||
</h3>
|
||
<button onClick={() => setSelectedInquiry(null)} className="text-gray-400 hover:text-red-500 transition-colors">
|
||
<X className="w-6 h-6" />
|
||
</button>
|
||
</div>
|
||
|
||
<form onSubmit={handleInquiryReviewSubmit} className="p-6 space-y-4">
|
||
<div className="p-4 bg-purple-50/50 rounded-xl border border-purple-100 space-y-1 text-xs">
|
||
<div><span className="font-bold text-gray-600">شخص رابط: </span>{selectedInquiry.contactName} ({selectedInquiry.phone})</div>
|
||
<div><span className="font-bold text-gray-600">پیام درخواست: </span>{selectedInquiry.message}</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="block text-sm font-bold text-gray-700 mb-2">تغییر وضعیت درخواست *</label>
|
||
<select
|
||
value={inquiryStatus}
|
||
onChange={(e) => setInquiryStatus(e.target.value as 'PENDING' | 'CONTACTED' | 'APPROVED' | 'REJECTED')}
|
||
className="w-full px-4 py-2.5 rounded-xl border border-gray-200 focus:border-purple-500 outline-none text-sm font-bold bg-white"
|
||
>
|
||
<option value="PENDING">در انتظار بررسی (PENDING)</option>
|
||
<option value="CONTACTED">تماس حاصل شد (CONTACTED)</option>
|
||
<option value="APPROVED">تایید شده (APPROVED)</option>
|
||
<option value="REJECTED">رد شده (REJECTED)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="block text-sm font-bold text-gray-700 mb-1">یادداشت ادمین (adminNotes)</label>
|
||
<textarea
|
||
rows={4}
|
||
value={inquiryAdminNotes}
|
||
onChange={(e) => setInquiryAdminNotes(e.target.value)}
|
||
placeholder="مذاکره انجام شد. لیست قیمت عمده ارسال گردید."
|
||
className="w-full px-4 py-2.5 rounded-xl border border-gray-200 focus:border-purple-500 outline-none text-sm"
|
||
/>
|
||
</div>
|
||
|
||
<div className="pt-4 flex justify-end gap-3 border-t border-gray-100">
|
||
<button
|
||
type="button"
|
||
onClick={() => setSelectedInquiry(null)}
|
||
className="px-5 py-2.5 rounded-xl border border-gray-200 text-gray-600 font-bold hover:bg-gray-50 transition-colors"
|
||
>
|
||
انصراف
|
||
</button>
|
||
<button
|
||
type="submit"
|
||
disabled={isInquirySubmitting}
|
||
className="px-6 py-2.5 rounded-xl bg-purple-600 text-white font-bold hover:bg-purple-700 transition-colors shadow-md shadow-purple-200 flex items-center gap-2"
|
||
>
|
||
{isInquirySubmitting && <Spinner size="sm" />}
|
||
بروزرسانی وضعیت
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Partner Account Setup Modal */}
|
||
{isPartnerModalOpen && (
|
||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-gray-900/60 backdrop-blur-sm">
|
||
<div className="bg-white rounded-2xl w-full max-w-lg shadow-2xl overflow-hidden animate-in zoom-in duration-200">
|
||
<div className="px-6 py-4 border-b border-gray-100 flex justify-between items-center bg-gray-50/50">
|
||
<h3 className="text-lg font-bold text-gray-900">
|
||
تعریف حساب همکار B2B جدید
|
||
</h3>
|
||
<button onClick={() => setIsPartnerModalOpen(false)} className="text-gray-400 hover:text-red-500 transition-colors">
|
||
<X className="w-6 h-6" />
|
||
</button>
|
||
</div>
|
||
|
||
<form onSubmit={handlePartnerSave} className="p-6 space-y-4">
|
||
<div>
|
||
<label className="block text-sm font-bold text-gray-700 mb-1">شناسه کاربر (User ID) *</label>
|
||
<input
|
||
required
|
||
type="text"
|
||
value={partnerFormData.userId}
|
||
onChange={(e) => setPartnerFormData({ ...partnerFormData, userId: e.target.value })}
|
||
placeholder="uuid-string-of-user"
|
||
className="w-full px-4 py-2.5 rounded-xl border border-gray-200 focus:border-purple-500 outline-none text-xs font-mono"
|
||
dir="ltr"
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="block text-sm font-bold text-gray-700 mb-1">نام شرکت / سازمان *</label>
|
||
<input
|
||
required
|
||
type="text"
|
||
value={partnerFormData.companyName}
|
||
onChange={(e) => setPartnerFormData({ ...partnerFormData, companyName: e.target.value })}
|
||
placeholder="کلینیک دامپزشکی پارت"
|
||
className="w-full px-4 py-2.5 rounded-xl border border-gray-200 focus:border-purple-500 outline-none text-sm"
|
||
/>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-2 gap-4">
|
||
<div>
|
||
<label className="block text-sm font-bold text-gray-700 mb-1">کد اقتصادی (Tax ID)</label>
|
||
<input
|
||
type="text"
|
||
value={partnerFormData.taxId}
|
||
onChange={(e) => setPartnerFormData({ ...partnerFormData, taxId: e.target.value })}
|
||
className="w-full px-4 py-2.5 rounded-xl border border-gray-200 focus:border-purple-500 outline-none text-xs font-mono"
|
||
dir="ltr"
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="block text-sm font-bold text-gray-700 mb-1">سقف اعتبار (تومان)</label>
|
||
<input
|
||
type="number"
|
||
value={partnerFormData.creditLimit}
|
||
onChange={(e) => setPartnerFormData({ ...partnerFormData, creditLimit: e.target.value })}
|
||
className="w-full px-4 py-2.5 rounded-xl border border-gray-200 focus:border-purple-500 outline-none text-sm font-bold"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="block text-sm font-bold text-gray-700 mb-1">سطح تخفیف (Discount Tier)</label>
|
||
<select
|
||
value={partnerFormData.discountTier}
|
||
onChange={(e) => setPartnerFormData({ ...partnerFormData, discountTier: e.target.value })}
|
||
className="w-full px-4 py-2.5 rounded-xl border border-gray-200 focus:border-purple-500 outline-none text-sm font-bold bg-white"
|
||
>
|
||
<option value="tier1">سطح ۱ (۱۵٪ تخفیف)</option>
|
||
<option value="tier2">سطح ۲ (۲۵٪ تخفیف)</option>
|
||
<option value="tier3">سطح ۳ (۳۵٪ تخفیف)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div className="pt-4 flex justify-end gap-3 border-t border-gray-100">
|
||
<button
|
||
type="button"
|
||
onClick={() => setIsPartnerModalOpen(false)}
|
||
className="px-5 py-2.5 rounded-xl border border-gray-200 text-gray-600 font-bold hover:bg-gray-50 transition-colors"
|
||
>
|
||
انصراف
|
||
</button>
|
||
<button
|
||
type="submit"
|
||
disabled={isPartnerSubmitting}
|
||
className="px-6 py-2.5 rounded-xl bg-purple-600 text-white font-bold hover:bg-purple-700 transition-colors shadow-md shadow-purple-200 flex items-center gap-2"
|
||
>
|
||
{isPartnerSubmitting && <Spinner size="sm" />}
|
||
ایجاد حساب همکار
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|