feat: B2B wholesale pricing per product & discount setting, dynamic payment gateways enable/disable & coming soon badges, B2B phone verification, trust seals menu link, dynamic contact info
Some checks failed
Deploy Canina / deploy (push) Failing after 15s
Some checks failed
Deploy Canina / deploy (push) Failing after 15s
This commit is contained in:
parent
f8e9ebfc44
commit
7bf6c47ee6
@ -128,6 +128,7 @@ export default function Products() {
|
||||
shortDescription: product.shortDescription || '',
|
||||
categoryId: product.categoryId || '',
|
||||
priceValue: Number(product.priceValue),
|
||||
wholesalePrice: product.wholesalePrice ? Number(product.wholesalePrice) : '',
|
||||
priceDisplay: product.priceDisplay || '',
|
||||
unit: product.unit || '',
|
||||
packageSize: Number(product.packageSize),
|
||||
@ -145,7 +146,7 @@ export default function Products() {
|
||||
setEditingProduct(null);
|
||||
setFormData({
|
||||
artNo: '', nameFa: '', nameEn: '', scientificTagline: '', description: '', shortDescription: '', categoryId: '',
|
||||
priceValue: 0, priceDisplay: '', unit: '', packageSize: 0, dosageLogic: '', suitableFor: 'سگ و گربه',
|
||||
priceValue: 0, wholesalePrice: '', priceDisplay: '', unit: '', packageSize: 0, dosageLogic: '', suitableFor: 'سگ و گربه',
|
||||
imageUrl: '', metaTitle: '', metaDescription: '', keywords: '', canonicalUrl: '', slug: '',
|
||||
symptoms: []
|
||||
});
|
||||
@ -535,6 +536,13 @@ export default function Products() {
|
||||
<label className="text-sm font-bold text-gray-700">قیمت (تومان) *</label>
|
||||
<input required type="number" min="0" value={formData.priceValue} onChange={(e) => setFormData({...formData, priceValue: Number(e.target.value)})} className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:border-purple-500 outline-none" dir="ltr" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-bold text-purple-700 flex items-center gap-1">
|
||||
<span>قیمت اختصاصی B2B (تومان)</span>
|
||||
<span className="text-[10px] font-normal text-gray-400">(اختیاری)</span>
|
||||
</label>
|
||||
<input type="number" min="0" placeholder="در صورت عدم ورود، درصد کلی اعمال میشود" value={formData.wholesalePrice} onChange={(e) => setFormData({...formData, wholesalePrice: e.target.value ? Number(e.target.value) : ''})} className="w-full px-4 py-3 rounded-xl border border-purple-200 focus:border-purple-600 outline-none font-bold bg-purple-50/20" dir="ltr" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-bold text-gray-700">نمایش قیمت (متنی) *</label>
|
||||
<input required type="text" placeholder="مثال: ۸۵۰,۰۰۰ تومان" value={formData.priceDisplay} onChange={(e) => setFormData({...formData, priceDisplay: e.target.value})} className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:border-purple-500 outline-none" />
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Settings as SettingsIcon, Save, Truck, ShieldAlert, Percent, AlertCircle } from 'lucide-react';
|
||||
import { Settings as SettingsIcon, Save, Truck, ShieldAlert, Percent, AlertCircle, CreditCard, Share2 } from 'lucide-react';
|
||||
import api from '../services/api';
|
||||
import Spinner from '../components/ui/Spinner';
|
||||
|
||||
@ -10,6 +10,16 @@ export default function Settings() {
|
||||
B2B_DISCOUNT_PERCENT: '',
|
||||
MAINTENANCE_MODE: 'false',
|
||||
CHARITY_ROUND_STEP: '10000',
|
||||
PAY_GATEWAY_CARD_ENABLE: 'true',
|
||||
PAY_GATEWAY_WALLET_ENABLE: 'true',
|
||||
PAY_GATEWAY_ONLINE_ENABLE: 'false',
|
||||
PAY_GATEWAY_COD_ENABLE: 'false',
|
||||
CONTACT_PHONE: '۰۲۱-۸۸۸۸ ۴۴۴۴',
|
||||
CONTACT_EMAIL: 'info@canina-iran.com',
|
||||
SOCIAL_WHATSAPP: '09120000000',
|
||||
SOCIAL_INSTAGRAM: 'https://instagram.com/canina_iran',
|
||||
SOCIAL_TELEGRAM: 'https://t.me/canina_iran',
|
||||
CONTACT_ADDRESS: 'تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹',
|
||||
});
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
@ -25,6 +35,16 @@ export default function Settings() {
|
||||
B2B_DISCOUNT_PERCENT: response.data.data.B2B_DISCOUNT_PERCENT || '0',
|
||||
MAINTENANCE_MODE: response.data.data.MAINTENANCE_MODE || 'false',
|
||||
CHARITY_ROUND_STEP: response.data.data.CHARITY_ROUND_STEP || '10000',
|
||||
PAY_GATEWAY_CARD_ENABLE: response.data.data.PAY_GATEWAY_CARD_ENABLE || 'true',
|
||||
PAY_GATEWAY_WALLET_ENABLE: response.data.data.PAY_GATEWAY_WALLET_ENABLE || 'true',
|
||||
PAY_GATEWAY_ONLINE_ENABLE: response.data.data.PAY_GATEWAY_ONLINE_ENABLE || 'false',
|
||||
PAY_GATEWAY_COD_ENABLE: response.data.data.PAY_GATEWAY_COD_ENABLE || 'false',
|
||||
CONTACT_PHONE: response.data.data.CONTACT_PHONE || '۰۲۱-۸۸۸۸ ۴۴۴۴',
|
||||
CONTACT_EMAIL: response.data.data.CONTACT_EMAIL || 'info@canina-iran.com',
|
||||
SOCIAL_WHATSAPP: response.data.data.SOCIAL_WHATSAPP || '09120000000',
|
||||
SOCIAL_INSTAGRAM: response.data.data.SOCIAL_INSTAGRAM || 'https://instagram.com/canina_iran',
|
||||
SOCIAL_TELEGRAM: response.data.data.SOCIAL_TELEGRAM || 'https://t.me/canina_iran',
|
||||
CONTACT_ADDRESS: response.data.data.CONTACT_ADDRESS || 'تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹',
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
@ -139,6 +159,156 @@ export default function Settings() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Payment Gateways Settings */}
|
||||
<div className="bg-white p-6 rounded-2xl shadow-sm border border-gray-200 space-y-6 lg:col-span-2">
|
||||
<h3 className="text-lg font-bold text-gray-900 border-b border-gray-100 pb-4 flex items-center gap-2">
|
||||
<CreditCard className="w-5 h-5 text-indigo-500" />
|
||||
مدیریت روشهای پرداخت
|
||||
</h3>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="flex items-center justify-between p-4 bg-gray-50 rounded-xl border border-gray-200">
|
||||
<div>
|
||||
<h4 className="font-bold text-gray-900 text-sm">کارت به کارت (واریز مستقیم)</h4>
|
||||
<p className="text-xs text-gray-500 mt-0.5">واریز به شماره کارت/شبا رسمی کانینا</p>
|
||||
</div>
|
||||
<label className="relative inline-flex items-center cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="sr-only peer"
|
||||
checked={settings.PAY_GATEWAY_CARD_ENABLE === 'true'}
|
||||
onChange={(e) => setSettings({ ...settings, PAY_GATEWAY_CARD_ENABLE: e.target.checked ? 'true' : 'false' })}
|
||||
/>
|
||||
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-purple-600"></div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-4 bg-gray-50 rounded-xl border border-gray-200">
|
||||
<div>
|
||||
<h4 className="font-bold text-gray-900 text-sm">اعتبار حساب (کیف پول)</h4>
|
||||
<p className="text-xs text-gray-500 mt-0.5">پرداخت لحظهای از موجودی کیف پول کاربر</p>
|
||||
</div>
|
||||
<label className="relative inline-flex items-center cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="sr-only peer"
|
||||
checked={settings.PAY_GATEWAY_WALLET_ENABLE === 'true'}
|
||||
onChange={(e) => setSettings({ ...settings, PAY_GATEWAY_WALLET_ENABLE: e.target.checked ? 'true' : 'false' })}
|
||||
/>
|
||||
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-purple-600"></div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-4 bg-gray-50 rounded-xl border border-gray-200">
|
||||
<div>
|
||||
<h4 className="font-bold text-gray-900 text-sm">درگاه آنلاین شتاب</h4>
|
||||
<p className="text-xs text-gray-500 mt-0.5">پرداخت الکترونیک (در صورت غیرفعال بودن: برچسب به زودی)</p>
|
||||
</div>
|
||||
<label className="relative inline-flex items-center cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="sr-only peer"
|
||||
checked={settings.PAY_GATEWAY_ONLINE_ENABLE === 'true'}
|
||||
onChange={(e) => setSettings({ ...settings, PAY_GATEWAY_ONLINE_ENABLE: e.target.checked ? 'true' : 'false' })}
|
||||
/>
|
||||
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-purple-600"></div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-4 bg-gray-50 rounded-xl border border-gray-200">
|
||||
<div>
|
||||
<h4 className="font-bold text-gray-900 text-sm">پرداخت در محل (COD)</h4>
|
||||
<p className="text-xs text-gray-500 mt-0.5">پرداخت با کارتخوان هنگام تحویل (در صورت غیرفعال بودن: به زودی)</p>
|
||||
</div>
|
||||
<label className="relative inline-flex items-center cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="sr-only peer"
|
||||
checked={settings.PAY_GATEWAY_COD_ENABLE === 'true'}
|
||||
onChange={(e) => setSettings({ ...settings, PAY_GATEWAY_COD_ENABLE: e.target.checked ? 'true' : 'false' })}
|
||||
/>
|
||||
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-purple-600"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Social Media & Contact Info Settings */}
|
||||
<div className="bg-white p-6 rounded-2xl shadow-sm border border-gray-200 space-y-6 lg:col-span-2">
|
||||
<h3 className="text-lg font-bold text-gray-900 border-b border-gray-100 pb-4 flex items-center gap-2">
|
||||
<Share2 className="w-5 h-5 text-blue-600" />
|
||||
راههای ارتباطی و شبکههای اجتماعی
|
||||
</h3>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-700 mb-1">تلفن پشتیبانی و فروش</label>
|
||||
<input
|
||||
type="text"
|
||||
value={settings.CONTACT_PHONE}
|
||||
onChange={(e) => setSettings({ ...settings, CONTACT_PHONE: e.target.value })}
|
||||
className="w-full border border-gray-200 rounded-xl p-2.5 outline-none focus:ring-2 focus:ring-purple-500 text-xs font-bold"
|
||||
dir="ltr"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-700 mb-1">ایمیل رسمی پشتیبانی</label>
|
||||
<input
|
||||
type="text"
|
||||
value={settings.CONTACT_EMAIL}
|
||||
onChange={(e) => setSettings({ ...settings, CONTACT_EMAIL: e.target.value })}
|
||||
className="w-full border border-gray-200 rounded-xl p-2.5 outline-none focus:ring-2 focus:ring-purple-500 text-xs font-bold"
|
||||
dir="ltr"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-700 mb-1">شماره واتساپ پشتیبانی</label>
|
||||
<input
|
||||
type="text"
|
||||
value={settings.SOCIAL_WHATSAPP}
|
||||
onChange={(e) => setSettings({ ...settings, SOCIAL_WHATSAPP: e.target.value })}
|
||||
className="w-full border border-gray-200 rounded-xl p-2.5 outline-none focus:ring-2 focus:ring-purple-500 text-xs font-bold"
|
||||
dir="ltr"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-700 mb-1">لینک پیج اینستاگرام</label>
|
||||
<input
|
||||
type="text"
|
||||
value={settings.SOCIAL_INSTAGRAM}
|
||||
onChange={(e) => setSettings({ ...settings, SOCIAL_INSTAGRAM: e.target.value })}
|
||||
className="w-full border border-gray-200 rounded-xl p-2.5 outline-none focus:ring-2 focus:ring-purple-500 text-xs font-bold"
|
||||
dir="ltr"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-700 mb-1">کانال تلگرام</label>
|
||||
<input
|
||||
type="text"
|
||||
value={settings.SOCIAL_TELEGRAM}
|
||||
onChange={(e) => setSettings({ ...settings, SOCIAL_TELEGRAM: e.target.value })}
|
||||
className="w-full border border-gray-200 rounded-xl p-2.5 outline-none focus:ring-2 focus:ring-purple-500 text-xs font-bold"
|
||||
dir="ltr"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-700 mb-1">آدرس دفتر مرکزی</label>
|
||||
<input
|
||||
type="text"
|
||||
value={settings.CONTACT_ADDRESS}
|
||||
onChange={(e) => setSettings({ ...settings, CONTACT_ADDRESS: e.target.value })}
|
||||
className="w-full border border-gray-200 rounded-xl p-2.5 outline-none focus:ring-2 focus:ring-purple-500 text-xs font-bold"
|
||||
dir="rtl"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* System Settings */}
|
||||
<div className="bg-white p-6 rounded-2xl shadow-sm border border-gray-200 space-y-6 lg:col-span-2">
|
||||
<h3 className="text-lg font-bold text-gray-900 border-b border-gray-100 pb-4 flex items-center gap-2">
|
||||
|
||||
@ -3,6 +3,7 @@ import React, { useState, useEffect } from "react";
|
||||
import { Product } from "../lib/data/products";
|
||||
import { useCartStore } from "../lib/store/cartStore";
|
||||
import { useUserStore } from "../lib/store/userStore";
|
||||
import { useSettingsStore } from "../lib/store/settingsStore";
|
||||
import { productService } from "../lib/services/productService";
|
||||
import { motion, AnimatePresence } from "motion/react";
|
||||
import {
|
||||
@ -127,27 +128,29 @@ export default function B2BPortal({ onClose }: { onClose: () => void }) {
|
||||
</p>
|
||||
|
||||
{!isWholesaleVerified && (
|
||||
<div className="bg-white/10 p-4 rounded-2xl border border-white/20 mt-4">
|
||||
<h4 className="text-xs font-black mb-2 text-amber-300">درخواست تایید حساب همکار</h4>
|
||||
<p className="text-[11px] text-white/80 mb-3">جهت مشاهده و خرید با قیمت عمده، شماره پروانه نظام دامپزشکی خود را وارد کنید.</p>
|
||||
<div className="bg-white/10 p-4 rounded-2xl border border-white/20 mt-4 font-vazir">
|
||||
<h4 className="text-xs font-black mb-2 text-amber-300">درخواست مشاوره و عضویت همکار B2B</h4>
|
||||
<p className="text-[11px] text-white/80 mb-3 leading-relaxed">
|
||||
جهت دریافت شرایط همکاری و فعالسازی دسترسی خرید عمده، شماره تماس خود را وارد کنید تا کارشناسان فروش با شما تماس بگیرند.
|
||||
</p>
|
||||
<form onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
const form = e.target as HTMLFormElement;
|
||||
const bName = (form.elements.namedItem('bName') as HTMLInputElement).value;
|
||||
const lNum = (form.elements.namedItem('lNum') as HTMLInputElement).value;
|
||||
const phone = (form.elements.namedItem('phone') as HTMLInputElement).value;
|
||||
try {
|
||||
const api = (await import('../lib/services/api')).default;
|
||||
await api.post('/wholesale/apply', { businessName: bName, licenseNumber: lNum });
|
||||
alert('درخواست ثبتنام همکار با موفقیت ارسال شد و به زودی توسط ادمین تایید میشود.');
|
||||
await api.post('/wholesale/apply', { businessName: bName, licenseNumber: phone });
|
||||
alert('درخواست شما با موفقیت ثبت شد. کارشناسان پشتیبانی B2B کانینا به زودی جهت تایید تلفنی با شما تماس خواهند گرفت.');
|
||||
form.reset();
|
||||
} catch (err) {
|
||||
alert('لطفاً ابتدا وارد حساب کاربری خود شوید.');
|
||||
alert('خطا در ثبت درخواست. لطفاً دوباره تلاش کنید.');
|
||||
}
|
||||
}} className="space-y-2">
|
||||
<input name="bName" required placeholder="نام کلینیک / داروخانه" className="w-full bg-white/20 text-white text-xs px-3 py-2 rounded-xl outline-none placeholder:text-white/50" />
|
||||
<input name="lNum" required placeholder="شماره پروانه / نظام" className="w-full bg-white/20 text-white text-xs px-3 py-2 rounded-xl outline-none placeholder:text-white/50" />
|
||||
<button type="submit" className="w-full bg-amber-400 hover:bg-amber-500 text-gray-900 font-black text-xs py-2 rounded-xl transition-colors">
|
||||
ثبت درخواست همکار
|
||||
<input name="bName" required placeholder="نام مجموعه / کلینیک / داروخانه" className="w-full bg-white/20 text-white text-xs px-3 py-2.5 rounded-xl outline-none placeholder:text-white/50" />
|
||||
<input name="phone" required type="tel" placeholder="شماره تماس همراه" className="w-full bg-white/20 text-white text-xs px-3 py-2.5 rounded-xl outline-none placeholder:text-white/50 dir-ltr text-right" />
|
||||
<button type="submit" className="w-full bg-amber-400 hover:bg-amber-500 text-gray-900 font-black text-xs py-2.5 rounded-xl transition-colors">
|
||||
ثبت درخواست تماس و تایید B2B
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@ -209,7 +212,11 @@ export default function B2BPortal({ onClose }: { onClose: () => void }) {
|
||||
<tbody className="divide-y divide-medical-gray-100">
|
||||
{filteredProducts.map(product => {
|
||||
const basePrice = product.priceValue || 0;
|
||||
const wholesalePrice = basePrice * 0.7; // 30% discount
|
||||
// Priority 1: Specific product wholesalePrice, Priority 2: General settings percentage discount (default 30%)
|
||||
const wholesaleDiscountPercent = Number(useSettingsStore.getState().getText('B2B_DISCOUNT_PERCENT', '30')) || 30;
|
||||
const wholesalePrice = (product as any).wholesalePrice
|
||||
? Number((product as any).wholesalePrice)
|
||||
: Math.round(basePrice * (1 - wholesaleDiscountPercent / 100));
|
||||
return (
|
||||
<tr key={product.id} className="hover:bg-medical-gray-50/50 transition-colors">
|
||||
<td className="px-6 py-4">
|
||||
|
||||
@ -388,51 +388,92 @@ export default function CheckoutPage() {
|
||||
<h2 className="text-xl sm:text-2xl font-black text-medical-gray-900 italic">شیوه پرداخت</h2>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
|
||||
{[
|
||||
{
|
||||
id: 'card',
|
||||
label: 'کارت به کارت (واریز مستقیم)',
|
||||
desc: 'واریز به شماره کارت بانک سامان',
|
||||
icon: <CreditCard className="w-5 h-5 sm:w-6 sm:h-6" />
|
||||
},
|
||||
{
|
||||
id: 'wallet',
|
||||
label: 'اعتبار حساب (کیف پول)',
|
||||
desc: `موجودی: ${toPersian((profile.walletBalance || 0).toLocaleString())} تومان`,
|
||||
icon: <Wallet className="w-5 h-5 sm:w-6 sm:h-6" />
|
||||
}
|
||||
].map((pay) => (
|
||||
<div
|
||||
key={pay.id}
|
||||
onClick={() => setPaymentMethod(pay.id)}
|
||||
className={cn("p-4 sm:p-6 rounded-2xl sm:rounded-3xl border-2 cursor-pointer transition-all group flex sm:flex-col items-center sm:items-start gap-4 sm:gap-0 relative", paymentMethod === pay.id ? "border-canina-blue bg-canina-blue/5" : "border-medical-gray-100 hover:border-canina-blue")}
|
||||
>
|
||||
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-medical-gray-50 rounded-xl sm:rounded-2xl flex items-center justify-center text-medical-gray-400 group-hover:text-canina-blue group-hover:bg-canina-blue/10 sm:mb-4 transition-all flex-shrink-0">
|
||||
{pay.icon}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
|
||||
{(() => {
|
||||
const getText = useSettingsStore.getState().getText;
|
||||
const allGateways = [
|
||||
{
|
||||
id: 'card',
|
||||
label: getText('PAY_GATEWAY_CARD_LABEL', 'کارت به کارت (واریز مستقیم)'),
|
||||
desc: getText('PAY_GATEWAY_CARD_DESC', 'واریز به شماره کارت بانک سامان'),
|
||||
icon: <CreditCard className="w-5 h-5 sm:w-6 sm:h-6" />,
|
||||
enabled: getText('PAY_GATEWAY_CARD_ENABLE', 'true') === 'true'
|
||||
},
|
||||
{
|
||||
id: 'wallet',
|
||||
label: getText('PAY_GATEWAY_WALLET_LABEL', 'اعتبار حساب (کیف پول)'),
|
||||
desc: `موجودی: ${toPersian((profile.walletBalance || 0).toLocaleString())} تومان`,
|
||||
icon: <Wallet className="w-5 h-5 sm:w-6 sm:h-6" />,
|
||||
enabled: getText('PAY_GATEWAY_WALLET_ENABLE', 'true') === 'true'
|
||||
},
|
||||
{
|
||||
id: 'online',
|
||||
label: getText('PAY_GATEWAY_ONLINE_LABEL', 'درگاه پرداخت آنلاین (شتاب)'),
|
||||
desc: getText('PAY_GATEWAY_ONLINE_DESC', 'پرداخت مستقیم با کلیه کارتهای شتاب'),
|
||||
icon: <ShieldCheck className="w-5 h-5 sm:w-6 sm:h-6" />,
|
||||
enabled: getText('PAY_GATEWAY_ONLINE_ENABLE', 'false') === 'true'
|
||||
},
|
||||
{
|
||||
id: 'cod',
|
||||
label: getText('PAY_GATEWAY_COD_LABEL', 'پرداخت در محل (کارتخوان)'),
|
||||
desc: getText('PAY_GATEWAY_COD_DESC', 'تحویل کالا و پرداخت درب منزل'),
|
||||
icon: <Truck className="w-5 h-5 sm:w-6 sm:h-6" />,
|
||||
enabled: getText('PAY_GATEWAY_COD_ENABLE', 'false') === 'true'
|
||||
}
|
||||
];
|
||||
|
||||
const sortedGateways = [...allGateways].sort((a, b) => (b.enabled ? 1 : 0) - (a.enabled ? 1 : 0));
|
||||
|
||||
return sortedGateways.map((pay) => (
|
||||
<div
|
||||
key={pay.id}
|
||||
onClick={() => {
|
||||
if (pay.enabled) {
|
||||
setPaymentMethod(pay.id);
|
||||
} else {
|
||||
toast.info("این روش پرداخت به زودی فعال خواهد شد.");
|
||||
}
|
||||
}}
|
||||
className={cn(
|
||||
"p-4 sm:p-6 rounded-2xl sm:rounded-3xl border-2 transition-all group flex sm:flex-col items-center sm:items-start gap-4 sm:gap-0 relative",
|
||||
pay.enabled
|
||||
? (paymentMethod === pay.id ? "border-canina-blue bg-canina-blue/5 cursor-pointer" : "border-medical-gray-100 hover:border-canina-blue cursor-pointer")
|
||||
: "border-medical-gray-100 bg-medical-gray-50/60 opacity-60 cursor-not-allowed"
|
||||
)}
|
||||
>
|
||||
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-medical-gray-50 rounded-xl sm:rounded-2xl flex items-center justify-center text-medical-gray-400 group-hover:text-canina-blue group-hover:bg-canina-blue/10 sm:mb-4 transition-all flex-shrink-0">
|
||||
{pay.icon}
|
||||
</div>
|
||||
<div className="min-w-0 flex-1 w-full">
|
||||
<div className="flex items-center justify-between gap-2 mb-0.5 sm:mb-1">
|
||||
<h4 className="font-black text-xs sm:text-sm text-medical-gray-900 truncate">{pay.label}</h4>
|
||||
{!pay.enabled && (
|
||||
<span className="text-[9px] font-black bg-amber-100 text-amber-800 px-2 py-0.5 rounded-full shrink-0 font-vazir">
|
||||
به زودی
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<p className={cn("text-[10px] font-bold truncate", pay.id === 'wallet' ? "text-canina-blue" : "text-medical-gray-400")}>{pay.desc}</p>
|
||||
{pay.id === 'wallet' && pay.enabled && (profile.walletBalance || 0) === 0 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowTopUpModal(true);
|
||||
}}
|
||||
className="text-[10px] bg-canina-blue text-white px-2 py-0.5 rounded-lg font-bold hover:bg-blue-700 transition-colors flex items-center gap-1 shrink-0 font-vazir"
|
||||
>
|
||||
<PlusCircle className="w-3 h-3" />
|
||||
<span>افزایش موجودی</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<h4 className="font-black text-xs sm:text-sm text-medical-gray-900 mb-0.5 sm:mb-1 truncate">{pay.label}</h4>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<p className={cn("text-[10px] font-bold truncate", pay.id === 'wallet' ? "text-canina-blue" : "text-medical-gray-400")}>{pay.desc}</p>
|
||||
{pay.id === 'wallet' && (profile.walletBalance || 0) === 0 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowTopUpModal(true);
|
||||
}}
|
||||
className="text-[10px] bg-canina-blue text-white px-2 py-0.5 rounded-lg font-bold hover:bg-blue-700 transition-colors flex items-center gap-1"
|
||||
>
|
||||
<PlusCircle className="w-3 h-3" />
|
||||
<span>افزایش موجودی</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
));
|
||||
})()}
|
||||
</div>
|
||||
|
||||
{paymentMethod === 'card' && (
|
||||
<div className="mt-6 bg-blue-50/80 border border-blue-200 rounded-2xl p-5 space-y-3 font-vazir">
|
||||
|
||||
@ -134,7 +134,7 @@ export default function Footer({
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-[11px] text-slate-400 font-extrabold uppercase mb-1">{getText('footer_phone_label', "خط ویژه فروش")}</p>
|
||||
<p className="text-lg font-extrabold tracking-widest text-left text-slate-200" dir="ltr">{getText('footer_phone', "۰۲۱-۸۸۸۸ ۴۴۴۴")}</p>
|
||||
<p className="text-lg font-extrabold tracking-widest text-left text-slate-200" dir="ltr">{getText('CONTACT_PHONE', getText('footer_phone', "۰۲۱-۸۸۸۸ ۴۴۴۴"))}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-4 group">
|
||||
@ -143,7 +143,7 @@ export default function Footer({
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-[11px] text-slate-400 font-extrabold uppercase mb-1">{getText('footer_email_label', "مکاتبات رسمی")}</p>
|
||||
<p className="text-sm font-bold text-slate-300">{getText('footer_email', "info@canina-iran.com")}</p>
|
||||
<p className="text-sm font-bold text-slate-300">{getText('CONTACT_EMAIL', getText('footer_email', "info@canina-iran.com"))}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -154,7 +154,7 @@ export default function Footer({
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-[11px] text-slate-400 font-extrabold uppercase mb-1">{getText('footer_address_label', "دفتر مرکزی")}</p>
|
||||
<p className="text-sm font-bold leading-relaxed text-slate-300">{getText('footer_address', "تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹")}</p>
|
||||
<p className="text-sm font-bold leading-relaxed text-slate-300">{getText('CONTACT_ADDRESS', getText('footer_address', "تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹"))}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -372,11 +372,15 @@ export default function Header({
|
||||
<ChevronDown className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
{activeDropdown === 'company' && (
|
||||
<div className="absolute top-full right-0 w-56 bg-white border border-medical-gray-200 shadow-xl rounded-xl p-2 z-50 space-y-1 text-xs">
|
||||
<div className="absolute top-full right-0 w-60 bg-white border border-medical-gray-200 shadow-xl rounded-xl p-2 z-50 space-y-1 text-xs">
|
||||
<Link href="/about" className="flex items-center gap-2 px-3 py-2 hover:bg-canina-blue/5 hover:text-canina-blue rounded-lg font-bold">
|
||||
<Award className="w-4 h-4 text-canina-blue" />
|
||||
درباره کمپانی کانینا آلمان
|
||||
</Link>
|
||||
<Link href="/trust-seals" className="flex items-center gap-2 px-3 py-2 hover:bg-canina-blue/5 hover:text-canina-blue rounded-lg font-bold text-emerald-600">
|
||||
<ShieldCheck className="w-4 h-4 text-emerald-600" />
|
||||
نمادهای اعتماد و مجوزهای رسمی
|
||||
</Link>
|
||||
<button
|
||||
onClick={onB2BOpen}
|
||||
className="w-full text-right flex items-center gap-2 px-3 py-2 hover:bg-canina-blue/5 hover:text-canina-blue rounded-lg font-bold"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user