diff --git a/src/components/ui/backgrounds/aurora-background.tsx b/src/components/ui/backgrounds/aurora-background.tsx index afea0e1..e689c4e 100644 --- a/src/components/ui/backgrounds/aurora-background.tsx +++ b/src/components/ui/backgrounds/aurora-background.tsx @@ -15,13 +15,9 @@ const SPEED_DURATIONS: Record = { }; export default function AuroraBackground({ settings }: Props) { - const isLegacySeed = - settings.firstColor === '#00d2ff' && - settings.secondColor === '#7928ca' && - settings.thirdColor === '#ff0080'; - const firstColor = isLegacySeed ? '#3b82f6' : sanitizeColor(settings.firstColor, '#3b82f6'); - const secondColor = isLegacySeed ? '#a5b4fc' : sanitizeColor(settings.secondColor, '#a5b4fc'); - const thirdColor = isLegacySeed ? '#93c5fd' : sanitizeColor(settings.thirdColor, '#93c5fd'); + const firstColor = sanitizeColor(settings.firstColor, '#3b82f6'); + const secondColor = sanitizeColor(settings.secondColor, '#a5b4fc'); + const thirdColor = sanitizeColor(settings.thirdColor, '#93c5fd'); const speed = safeSelect(settings.speed, ['slow', 'normal', 'fast'] as const, 'normal'); const showRadialGradient = safeBoolean(settings.showRadialGradient, true); const paused = useAnimationPause(); diff --git a/src/locales/fa.json b/src/locales/fa.json index bfac9e6..a62e7f1 100644 --- a/src/locales/fa.json +++ b/src/locales/fa.json @@ -1130,7 +1130,8 @@ "landings": "صفحات فرود", "referralNetwork": "شبکه ارجاع", "news": "اخبار", - "infoPages": "صفحات اطلاعات" + "infoPages": "صفحات اطلاعات", + "legalPages": "صفحات سیستمی" }, "panel": { "title": "پنل مدیریت", @@ -2304,7 +2305,14 @@ "noPromoGroups": "هیچ گروه تبلیغاتی نیست", "cancelButton": "لغو", "saveButton": "ذخیره", - "notFound": "روش پرداخت یافت نشد" + "notFound": "روش پرداخت یافت نشد", + "quickAmounts": "مبالغ سریع (₽)", + "quickAmountsHint": "دکمه‌های مبلغ شارژ سریع. خالی — مقادیر پیش‌فرض استفاده می‌شوند: {{defaults}} ₽", + "quickAmountsPlaceholder": "مبلغ به روبل", + "quickAmountsAdd": "افزودن", + "quickAmountsInvalid": "یک مبلغ مثبت به روبل وارد کنید", + "quickAmountsLimit": "حداکثر ۱۰ مبلغ مجاز است", + "quickAmountsRemove": "حذف مبلغ {{value}} ₽" }, "campaigns": { "title": "کمپین‌های تبلیغاتی", @@ -3813,7 +3821,8 @@ "sortOrder": "ترتیب", "icon": "آیکون (ایموجی)", "pageType": "نوع صفحه", - "replacesTab": "جایگزینی تب" + "replacesTab": "جایگزینی تب", + "displayMode": "نمایش" }, "replacesTabNone": "بدون جایگزینی", "replacesTabOptions": { @@ -3855,6 +3864,11 @@ "en": "انگلیسی", "zh": "چینی", "fa": "فارسی" + }, + "displayModes": { + "bot": "فقط ربات", + "web": "فقط وب", + "both": "ربات و وب" } }, "bulkActions": { @@ -3965,6 +3979,43 @@ "trafficGbUnit": "GB", "selectAllSubs": "انتخاب همه اشتراک‌ها", "deselectAllSubs": "لغو انتخاب همه اشتراک‌ها" + }, + "legalPages": { + "title": "صفحات سیستمی", + "subtitle": "قوانین، سیاست حریم خصوصی، پیشنهاد عمومی و FAQ", + "open": "صفحات سیستمی", + "tabs": { + "privacy": "حریم خصوصی", + "offer": "پیشنهاد", + "rules": "قوانین", + "faq": "FAQ" + }, + "displayMode": "نمایش", + "displayModes": { + "bot": "فقط ربات", + "web": "فقط وب", + "both": "ربات و وب" + }, + "displayModeLocked": "از طریق متغیر محیطی تنظیم شده", + "enabled": "نمایش به کاربران", + "language": "زبان محتوا", + "content": "متن", + "contentPlaceholder": "متن HTML صفحه...", + "save": "ذخیره", + "saving": "در حال ذخیره...", + "saveError": "ذخیره ناموفق بود. لطفاً دوباره تلاش کنید.", + "unsavedWarning": "تغییرات ذخیره‌نشده از بین می‌رود. ادامه می‌دهید؟", + "faqPages": "سوالات و پاسخ‌ها", + "addQuestion": "افزودن سوال", + "newQuestion": "سوال جدید", + "questionTitle": "سوال", + "questionContent": "پاسخ (HTML پشتیبانی می‌شود)", + "confirmDeleteQuestion": "این سوال حذف شود؟", + "noQuestions": "هنوز سوالی وجود ندارد", + "active": "فعال", + "moveUp": "انتقال به بالا", + "moveDown": "انتقال به پایین", + "delete": "حذف" } }, "adminUpdates": { diff --git a/src/locales/zh.json b/src/locales/zh.json index f90e762..f35e9f2 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -1130,7 +1130,8 @@ "landings": "落地页", "referralNetwork": "推荐网络", "news": "新闻", - "infoPages": "信息页面" + "infoPages": "信息页面", + "legalPages": "系统页面" }, "panel": { "title": "管理面板", @@ -1456,7 +1457,14 @@ "noPromoGroups": "没有促销组", "cancelButton": "取消", "saveButton": "保存", - "notFound": "未找到支付方式" + "notFound": "未找到支付方式", + "quickAmounts": "快捷金额(₽)", + "quickAmountsHint": "快捷充值金额按钮。留空 — 使用默认值:{{defaults}} ₽", + "quickAmountsPlaceholder": "金额(卢布)", + "quickAmountsAdd": "添加", + "quickAmountsInvalid": "请输入正的卢布金额", + "quickAmountsLimit": "最多 10 个金额", + "quickAmountsRemove": "删除金额 {{value}} ₽" }, "emailTemplates": { "title": "邮件模板", @@ -3812,7 +3820,8 @@ "sortOrder": "排序", "icon": "图标(表情)", "pageType": "页面类型", - "replacesTab": "替换标签" + "replacesTab": "替换标签", + "displayMode": "显示" }, "replacesTabNone": "不替换", "replacesTabOptions": { @@ -3854,6 +3863,11 @@ "en": "英语", "zh": "中文", "fa": "波斯语" + }, + "displayModes": { + "bot": "仅机器人", + "web": "仅网页", + "both": "机器人和网页" } }, "bulkActions": { @@ -3964,6 +3978,43 @@ "trafficGbUnit": "GB", "selectAllSubs": "选择所有订阅", "deselectAllSubs": "取消选择所有订阅" + }, + "legalPages": { + "title": "系统页面", + "subtitle": "规则、隐私政策、公开要约和 FAQ", + "open": "系统页面", + "tabs": { + "privacy": "隐私", + "offer": "条款", + "rules": "规则", + "faq": "FAQ" + }, + "displayMode": "显示", + "displayModes": { + "bot": "仅机器人", + "web": "仅网页", + "both": "机器人和网页" + }, + "displayModeLocked": "通过环境变量设置", + "enabled": "对用户可见", + "language": "内容语言", + "content": "内容", + "contentPlaceholder": "HTML 页面内容...", + "save": "保存", + "saving": "保存中...", + "saveError": "保存失败,请重试。", + "unsavedWarning": "未保存的更改将丢失。是否继续?", + "faqPages": "问答", + "addQuestion": "添加问题", + "newQuestion": "新问题", + "questionTitle": "问题", + "questionContent": "答案(支持 HTML)", + "confirmDeleteQuestion": "确定删除此问题?", + "noQuestions": "暂无问题", + "active": "已激活", + "moveUp": "上移", + "moveDown": "下移", + "delete": "删除" } }, "adminUpdates": { diff --git a/src/pages/AdminLegalPages.tsx b/src/pages/AdminLegalPages.tsx index f6b16de..8680c5f 100644 --- a/src/pages/AdminLegalPages.tsx +++ b/src/pages/AdminLegalPages.tsx @@ -521,7 +521,14 @@ function FaqEditor({ onDirtyChange }: { onDirtyChange: (dirty: boolean) => void const reorderMutation = useMutation({ mutationFn: async ({ a, b }: { a: FaqPageItem; b: FaqPageItem }) => { await adminLegalPagesApi.updateFaqPage(a.id, { display_order: b.display_order }); - await adminLegalPagesApi.updateFaqPage(b.id, { display_order: a.display_order }); + try { + await adminLegalPagesApi.updateFaqPage(b.id, { display_order: a.display_order }); + } catch (err) { + await adminLegalPagesApi + .updateFaqPage(a.id, { display_order: a.display_order }) + .catch(() => {}); + throw err; + } }, onSuccess: () => { haptic.success(); diff --git a/src/pages/AdminPaymentMethodEdit.tsx b/src/pages/AdminPaymentMethodEdit.tsx index f71c33c..67abd17 100644 --- a/src/pages/AdminPaymentMethodEdit.tsx +++ b/src/pages/AdminPaymentMethodEdit.tsx @@ -383,7 +383,9 @@ export default function AdminPaymentMethodEdit() { {quickAmountsError &&

{quickAmountsError}

}

{t('admin.paymentMethods.quickAmountsHint', { - defaults: config.default_quick_amounts.map((kopeks) => kopeks / 100).join(', '), + defaults: (config.default_quick_amounts ?? []) + .map((kopeks) => kopeks / 100) + .join(', '), })}