feat(settings): add Maintenance Mode, Catalog Mode, Brand Identity & UI Text management (TASK-2.14, TASK-2.15, TASK-2.16)
This commit is contained in:
parent
38c1e287dc
commit
88521c6bac
@ -397,19 +397,8 @@ export class AdminService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Settings ---
|
|
||||||
async getSettings() {
|
async getSettings() {
|
||||||
const keys = [
|
const settings = await this.prisma.uiText.findMany();
|
||||||
'SHIPPING_FEE',
|
|
||||||
'MIN_ORDER_AMOUNT',
|
|
||||||
'B2B_DISCOUNT_PERCENT',
|
|
||||||
'MAINTENANCE_MODE',
|
|
||||||
];
|
|
||||||
const settings = await this.prisma.uiText.findMany({
|
|
||||||
where: { key: { in: keys } },
|
|
||||||
});
|
|
||||||
|
|
||||||
// Transform to an object { SHIPPING_FEE: '50000', ... }
|
|
||||||
return settings.reduce(
|
return settings.reduce(
|
||||||
(acc, curr) => ({ ...acc, [curr.key]: curr.value }),
|
(acc, curr) => ({ ...acc, [curr.key]: curr.value }),
|
||||||
{},
|
{},
|
||||||
|
|||||||
@ -40,9 +40,9 @@
|
|||||||
- [x] **TASK-2.13 [Admin Panel UX]:** حذف کامل `alert()`های مرورگر و جایگزینی آنها با Toastهای مدرن و Modalهای Confirmation قبل از تمامی عملیاتهای حساس (حذف، ویرایش، تغییر وضعیت).
|
- [x] **TASK-2.13 [Admin Panel UX]:** حذف کامل `alert()`های مرورگر و جایگزینی آنها با Toastهای مدرن و Modalهای Confirmation قبل از تمامی عملیاتهای حساس (حذف، ویرایش، تغییر وضعیت).
|
||||||
|
|
||||||
### ⚙️ سیستم تنظیمات پیشرفته سایت (Advanced Site Settings)
|
### ⚙️ سیستم تنظیمات پیشرفته سایت (Advanced Site Settings)
|
||||||
- [ ] **TASK-2.14 [DB & Backend Settings]:** ایجاد ساختار جامع تنظیمات سایت شامل حالت Maintenance Mode واقعی (با صفحه اختصاصی)، فعال/غیرفعالسازی فروشگاه (تبدیل به کاتالوگ بدون قابلیت خرید).
|
- [x] **TASK-2.14 [DB & Backend Settings]:** ایجاد ساختار جامع تنظیمات سایت شامل حالت Maintenance Mode واقعی (با صفحه اختصاصی)، فعال/غیرفعالسازی فروشگاه (تبدیل به کاتالوگ بدون قابلیت خرید).
|
||||||
- [ ] **TASK-2.15 [Admin Panel Settings]:** پنل جامع مدیریت هویت برند (آدرسهای فروشگاه، ایمیلها، شبکههای اجتماعی، لوگو، اینماد، تم رنگی، تایپوگرافی).
|
- [x] **TASK-2.15 [Admin Panel Settings]:** پنل جامع مدیریت هویت برند (آدرسهای فروشگاه، ایمیلها، شبکههای اجتماعی، لوگو، اینماد، تم رنگی، تایپوگرافی).
|
||||||
- [ ] **TASK-2.16 [DB & Admin Content Management]:** تبدیل "متون رابط کاربری" به "مدیریت جامع رابط کاربری" با قابلیت جستجوی متنی بر اساس کلید/مقدار و ویرایش فونت، رنگ، تصاویر و آیکونهای هر بخش.
|
- [x] **TASK-2.16 [DB & Admin Content Management]:** تبدیل "متون رابط کاربری" به "مدیریت جامع رابط کاربری" با قابلیت جستجوی متنی بر اساس کلید/مقدار و ویرایش فونت، رنگ، تصاویر و آیکونهای هر بخش.
|
||||||
|
|
||||||
### 🎥 ویدیوها، پزشکان و پروفایل ادمین (Videos, Doctors & Admin Profile)
|
### 🎥 ویدیوها، پزشکان و پروفایل ادمین (Videos, Doctors & Admin Profile)
|
||||||
- [ ] **TASK-2.17 [Backend & Admin]:** ارتقاء مدیریت ویدیوها با قابلیت آپلود مستقیم فایل ویدیو روی سرور/S3 علاوه بر لینکهای Iframe.
|
- [ ] **TASK-2.17 [Backend & Admin]:** ارتقاء مدیریت ویدیوها با قابلیت آپلود مستقیم فایل ویدیو روی سرور/S3 علاوه بر لینکهای Iframe.
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export default function Settings() {
|
|||||||
MIN_ORDER_AMOUNT: '',
|
MIN_ORDER_AMOUNT: '',
|
||||||
B2B_DISCOUNT_PERCENT: '',
|
B2B_DISCOUNT_PERCENT: '',
|
||||||
MAINTENANCE_MODE: 'false',
|
MAINTENANCE_MODE: 'false',
|
||||||
|
CATALOG_ONLY_MODE: 'false',
|
||||||
CHARITY_ROUND_STEP: '10000',
|
CHARITY_ROUND_STEP: '10000',
|
||||||
PAY_GATEWAY_CARD_ENABLE: 'true',
|
PAY_GATEWAY_CARD_ENABLE: 'true',
|
||||||
PAY_GATEWAY_WALLET_ENABLE: 'true',
|
PAY_GATEWAY_WALLET_ENABLE: 'true',
|
||||||
@ -21,6 +22,10 @@ export default function Settings() {
|
|||||||
SOCIAL_INSTAGRAM: 'https://instagram.com/canina_iran',
|
SOCIAL_INSTAGRAM: 'https://instagram.com/canina_iran',
|
||||||
SOCIAL_TELEGRAM: 'https://t.me/canina_iran',
|
SOCIAL_TELEGRAM: 'https://t.me/canina_iran',
|
||||||
CONTACT_ADDRESS: 'تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹',
|
CONTACT_ADDRESS: 'تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹',
|
||||||
|
BRAND_LOGO_URL: '/logo.png',
|
||||||
|
ENAMAD_CODE: '',
|
||||||
|
THEME_PRIMARY_COLOR: '#7c3aed',
|
||||||
|
BRAND_TYPOGRAPHY: 'vazirmatn',
|
||||||
});
|
});
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [isSaving, setIsSaving] = useState(false);
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
@ -35,6 +40,7 @@ export default function Settings() {
|
|||||||
MIN_ORDER_AMOUNT: response.data.data.MIN_ORDER_AMOUNT || '0',
|
MIN_ORDER_AMOUNT: response.data.data.MIN_ORDER_AMOUNT || '0',
|
||||||
B2B_DISCOUNT_PERCENT: response.data.data.B2B_DISCOUNT_PERCENT || '0',
|
B2B_DISCOUNT_PERCENT: response.data.data.B2B_DISCOUNT_PERCENT || '0',
|
||||||
MAINTENANCE_MODE: response.data.data.MAINTENANCE_MODE || 'false',
|
MAINTENANCE_MODE: response.data.data.MAINTENANCE_MODE || 'false',
|
||||||
|
CATALOG_ONLY_MODE: response.data.data.CATALOG_ONLY_MODE || 'false',
|
||||||
CHARITY_ROUND_STEP: response.data.data.CHARITY_ROUND_STEP || '10000',
|
CHARITY_ROUND_STEP: response.data.data.CHARITY_ROUND_STEP || '10000',
|
||||||
PAY_GATEWAY_CARD_ENABLE: response.data.data.PAY_GATEWAY_CARD_ENABLE || 'true',
|
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_WALLET_ENABLE: response.data.data.PAY_GATEWAY_WALLET_ENABLE || 'true',
|
||||||
@ -46,6 +52,10 @@ export default function Settings() {
|
|||||||
SOCIAL_INSTAGRAM: response.data.data.SOCIAL_INSTAGRAM || 'https://instagram.com/canina_iran',
|
SOCIAL_INSTAGRAM: response.data.data.SOCIAL_INSTAGRAM || 'https://instagram.com/canina_iran',
|
||||||
SOCIAL_TELEGRAM: response.data.data.SOCIAL_TELEGRAM || 'https://t.me/canina_iran',
|
SOCIAL_TELEGRAM: response.data.data.SOCIAL_TELEGRAM || 'https://t.me/canina_iran',
|
||||||
CONTACT_ADDRESS: response.data.data.CONTACT_ADDRESS || 'تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹',
|
CONTACT_ADDRESS: response.data.data.CONTACT_ADDRESS || 'تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹',
|
||||||
|
BRAND_LOGO_URL: response.data.data.BRAND_LOGO_URL || '/logo.png',
|
||||||
|
ENAMAD_CODE: response.data.data.ENAMAD_CODE || '',
|
||||||
|
THEME_PRIMARY_COLOR: response.data.data.THEME_PRIMARY_COLOR || '#7c3aed',
|
||||||
|
BRAND_TYPOGRAPHY: response.data.data.BRAND_TYPOGRAPHY || 'vazirmatn',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -311,30 +321,117 @@ export default function Settings() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* System Settings */}
|
{/* Brand Identity & Theme Settings (TASK-2.15) */}
|
||||||
|
<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">
|
||||||
|
<SettingsIcon className="w-5 h-5 text-purple-600" />
|
||||||
|
مدیریت هویت برند، نمادها و ظاهر سایت (TASK-2.15)
|
||||||
|
</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">لینک لوگوی برند (Brand Logo URL)</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={settings.BRAND_LOGO_URL}
|
||||||
|
onChange={(e) => setSettings({ ...settings, BRAND_LOGO_URL: 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-mono"
|
||||||
|
dir="ltr"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs font-bold text-gray-700 mb-1">کد / شناسه اینماد (Enamad Code/HTML)</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={settings.ENAMAD_CODE}
|
||||||
|
onChange={(e) => setSettings({ ...settings, ENAMAD_CODE: e.target.value })}
|
||||||
|
placeholder="https://trustseal.enamad.ir/..."
|
||||||
|
className="w-full border border-gray-200 rounded-xl p-2.5 outline-none focus:ring-2 focus:ring-purple-500 text-xs font-mono"
|
||||||
|
dir="ltr"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs font-bold text-gray-700 mb-1">رنگ اصلی تم سایت (Hex Color)</label>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<input
|
||||||
|
type="color"
|
||||||
|
value={settings.THEME_PRIMARY_COLOR}
|
||||||
|
onChange={(e) => setSettings({ ...settings, THEME_PRIMARY_COLOR: e.target.value })}
|
||||||
|
className="w-10 h-10 rounded-lg cursor-pointer border border-gray-200"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={settings.THEME_PRIMARY_COLOR}
|
||||||
|
onChange={(e) => setSettings({ ...settings, THEME_PRIMARY_COLOR: e.target.value })}
|
||||||
|
className="flex-1 border border-gray-200 rounded-xl p-2.5 outline-none focus:ring-2 focus:ring-purple-500 text-xs font-mono"
|
||||||
|
dir="ltr"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs font-bold text-gray-700 mb-1">تایپوگرافی و فونت سایت</label>
|
||||||
|
<select
|
||||||
|
value={settings.BRAND_TYPOGRAPHY}
|
||||||
|
onChange={(e) => setSettings({ ...settings, BRAND_TYPOGRAPHY: 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"
|
||||||
|
>
|
||||||
|
<option value="vazirmatn">وزیرمتن (Vazirmatn)</option>
|
||||||
|
<option value="iransans">ایرانسانس (IRANSans)</option>
|
||||||
|
<option value="dana">دانا (Dana)</option>
|
||||||
|
<option value="shabnam">شبنم (Shabnam)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* System Settings (TASK-2.14) */}
|
||||||
<div className="bg-white p-6 rounded-2xl shadow-sm border border-gray-200 space-y-6 lg:col-span-2">
|
<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">
|
<h3 className="text-lg font-bold text-gray-900 border-b border-gray-100 pb-4 flex items-center gap-2">
|
||||||
<ShieldAlert className="w-5 h-5 text-orange-500" />
|
<ShieldAlert className="w-5 h-5 text-orange-500" />
|
||||||
وضعیت سیستم
|
وضعیت سیستم و کنترل حالت کاتالوگ (TASK-2.14)
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div className="flex items-center justify-between p-4 bg-orange-50 rounded-xl border border-orange-100">
|
<div className="space-y-4">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center justify-between p-4 bg-orange-50 rounded-xl border border-orange-100">
|
||||||
<AlertCircle className="w-6 h-6 text-orange-500" />
|
<div className="flex items-center gap-3">
|
||||||
<div>
|
<AlertCircle className="w-6 h-6 text-orange-500" />
|
||||||
<h4 className="font-bold text-gray-900">حالت تعمیرات (Maintenance Mode)</h4>
|
<div>
|
||||||
<p className="text-sm text-gray-600 mt-1">با فعال کردن این گزینه، سایت برای کاربران از دسترس خارج شده و پیام «در حال بروزرسانی» نمایش داده میشود.</p>
|
<h4 className="font-bold text-gray-900 text-sm">حالت تعمیرات (Maintenance Mode)</h4>
|
||||||
|
<p className="text-xs text-gray-600 mt-0.5">با فعال کردن این گزینه، سایت برای کاربران از دسترس خارج شده و صفحه اختصاصی «در حال بروزرسانی» نمایش داده میشود.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<label className="relative inline-flex items-center cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="sr-only peer"
|
||||||
|
checked={settings.MAINTENANCE_MODE === 'true'}
|
||||||
|
onChange={(e) => setSettings({ ...settings, MAINTENANCE_MODE: e.target.checked ? 'true' : 'false' })}
|
||||||
|
/>
|
||||||
|
<div className="w-14 h-7 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-6 after:w-6 after:transition-all peer-checked:bg-orange-500"></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center justify-between p-4 bg-purple-50 rounded-xl border border-purple-100">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<AlertCircle className="w-6 h-6 text-purple-600" />
|
||||||
|
<div>
|
||||||
|
<h4 className="font-bold text-gray-900 text-sm">حالت کاتالوگ بدون خرید (Catalog Only Mode)</h4>
|
||||||
|
<p className="text-xs text-gray-600 mt-0.5">با فعالسازی این گزینه، دکمههای افزودن به سبد خرید غیرفعال شده و سایت به کاتالوگ آنلاین تبدیل میشود.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<label className="relative inline-flex items-center cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="sr-only peer"
|
||||||
|
checked={settings.CATALOG_ONLY_MODE === 'true'}
|
||||||
|
onChange={(e) => setSettings({ ...settings, CATALOG_ONLY_MODE: e.target.checked ? 'true' : 'false' })}
|
||||||
|
/>
|
||||||
|
<div className="w-14 h-7 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-6 after:w-6 after:transition-all peer-checked:bg-purple-600"></div>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<label className="relative inline-flex items-center cursor-pointer">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
className="sr-only peer"
|
|
||||||
checked={settings.MAINTENANCE_MODE === 'true'}
|
|
||||||
onChange={(e) => setSettings({ ...settings, MAINTENANCE_MODE: e.target.checked ? 'true' : 'false' })}
|
|
||||||
/>
|
|
||||||
<div className="w-14 h-7 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-6 after:w-6 after:transition-all peer-checked:bg-orange-500"></div>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user