feat: extract promocodes and promo groups into separate pages

- Add AdminPromocodeCreate page for creating/editing promocodes
- Add AdminPromoGroups page for listing discount groups
- Add AdminPromoGroupCreate page for creating/editing discount groups
- Move promo groups from Promocodes section to separate admin section
- Simplify AdminPromocodes by removing embedded modals and groups tab
- Add routes and navigation for new pages
- Add i18n keys for all 4 locales (ru, en, zh, fa)
This commit is contained in:
c0mrade
2026-02-02 05:40:25 +03:00
parent 0b4c75d7f7
commit a96ddde314
10 changed files with 1536 additions and 1015 deletions

View File

@@ -737,7 +737,8 @@
"paymentMethods": "Payment Methods",
"campaigns": "Campaigns",
"promoOffers": "Promo Offers",
"promocodes": "Promo Codes"
"promocodes": "Promo Codes",
"promoGroups": "Discount Groups"
},
"panel": {
"title": "Admin Panel",
@@ -758,7 +759,8 @@
"paymentMethodsDesc": "Configure payment methods and order",
"campaignsDesc": "Advertising campaigns",
"promoOffersDesc": "Personal discounts",
"promocodesDesc": "Manage promo codes"
"promocodesDesc": "Manage promo codes",
"promoGroupsDesc": "Discount groups for users"
},
"emailTemplates": {
"title": "Email Templates",
@@ -1596,6 +1598,62 @@
"deletePromocodeText": "The promo code will be permanently deleted.",
"deleteGroupText": "The group will be deleted. Users will lose discounts from this group.",
"deleteButton": "Delete"
},
"validation": {
"codeRequired": "Enter promo code",
"balanceRequired": "Bonus amount must be greater than 0",
"daysRequired": "Number of days must be greater than 0",
"groupRequired": "Select a discount group",
"discountPercentInvalid": "Discount percent must be between 1 and 100",
"discountHoursRequired": "Specify the discount validity period in hours"
}
},
"promoGroups": {
"title": "Discount Groups",
"subtitle": "Manage discount groups for users",
"addGroup": "Add Group",
"noGroups": "No discount groups",
"default": "Default",
"servers": "Servers",
"traffic": "Traffic",
"devices": "Devices",
"daysShort": "{{days}} days",
"autoFrom": "Auto from {{amount}} rub.",
"members": "{{count}} members",
"createTitle": "Create Discount Group",
"editTitle": "Edit Group",
"stats": {
"total": "Total groups",
"members": "Members",
"autoAssign": "With auto-assign"
},
"actions": {
"edit": "Edit",
"delete": "Delete"
},
"confirm": {
"title": "Delete group?",
"text": "The group will be deleted. Users will lose discounts from this group.",
"cancel": "Cancel",
"delete": "Delete"
},
"form": {
"name": "Group name",
"namePlaceholder": "VIP customers",
"categoryDiscounts": "Category discounts",
"periodDiscounts": "Period discounts",
"add": "Add",
"periodHint": "Discount is applied when purchasing a subscription for the specified number of days",
"noPeriods": "No period discounts",
"daysPlaceholder": "Days",
"arrow": "days →",
"autoAssign": "Auto-assign when spent from",
"rub": "rub.",
"autoAssignHint": "0 = don't auto-assign",
"applyToAddons": "Apply to additional services",
"cancel": "Cancel",
"saving": "Saving...",
"save": "Save"
}
},
"users": {

View File

@@ -626,6 +626,7 @@
"payments": "پرداخت‌ها",
"promoOffers": "پیشنهادات تبلیغاتی",
"promocodes": "کدهای تخفیف",
"promoGroups": "گروه‌های تخفیف",
"remnawave": "RemnaWave",
"users": "کاربران"
},
@@ -647,6 +648,7 @@
"paymentsDesc": "تأیید پرداخت",
"promoOffersDesc": "تخفیف‌های شخصی",
"promocodesDesc": "مدیریت کدهای تخفیف",
"promoGroupsDesc": "گروه‌های تخفیف برای کاربران",
"remnawaveDesc": "مدیریت پنل و آمار",
"usersDesc": "مدیریت کاربران ربات"
},
@@ -1389,6 +1391,62 @@
"deletePromocodeText": "کد تخفیف به طور دائم حذف خواهد شد.",
"deleteGroupText": "گروه حذف خواهد شد. کاربران تخفیف‌های این گروه را از دست خواهند داد.",
"deleteButton": "حذف"
},
"validation": {
"codeRequired": "کد تخفیف را وارد کنید",
"balanceRequired": "مبلغ پاداش باید بیشتر از 0 باشد",
"daysRequired": "تعداد روزها باید بیشتر از 0 باشد",
"groupRequired": "یک گروه تخفیف انتخاب کنید",
"discountPercentInvalid": "درصد تخفیف باید بین 1 تا 100 باشد",
"discountHoursRequired": "مدت اعتبار تخفیف را به ساعت مشخص کنید"
}
},
"promoGroups": {
"title": "گروه‌های تخفیف",
"subtitle": "مدیریت گروه‌های تخفیف برای کاربران",
"addGroup": "افزودن گروه",
"noGroups": "گروه تخفیفی وجود ندارد",
"default": "پیش‌فرض",
"servers": "سرورها",
"traffic": "ترافیک",
"devices": "دستگاه‌ها",
"daysShort": "{{days}} روز",
"autoFrom": "خودکار از {{amount}} روبل",
"members": "{{count}} عضو",
"createTitle": "ایجاد گروه تخفیف",
"editTitle": "ویرایش گروه",
"stats": {
"total": "کل گروه‌ها",
"members": "اعضا",
"autoAssign": "با تخصیص خودکار"
},
"actions": {
"edit": "ویرایش",
"delete": "حذف"
},
"confirm": {
"title": "گروه حذف شود؟",
"text": "گروه حذف خواهد شد. کاربران تخفیف‌های این گروه را از دست خواهند داد.",
"cancel": "انصراف",
"delete": "حذف"
},
"form": {
"name": "نام گروه",
"namePlaceholder": "مشتریان VIP",
"categoryDiscounts": "تخفیف‌های دسته‌بندی",
"periodDiscounts": "تخفیف‌های دوره‌ای",
"add": "افزودن",
"periodHint": "تخفیف هنگام خرید اشتراک برای تعداد روز مشخص شده اعمال می‌شود",
"noPeriods": "تخفیف دوره‌ای وجود ندارد",
"daysPlaceholder": "روز",
"arrow": "روز ←",
"autoAssign": "تخصیص خودکار هنگام هزینه از",
"rub": "روبل",
"autoAssignHint": "0 = تخصیص خودکار نشود",
"applyToAddons": "اعمال به خدمات اضافی",
"cancel": "انصراف",
"saving": "در حال ذخیره...",
"save": "ذخیره"
}
},
"users": {

View File

@@ -753,7 +753,8 @@
"paymentMethods": "Платёжные методы",
"campaigns": "Кампании",
"promoOffers": "Промопредложения",
"promocodes": "Промокоды"
"promocodes": "Промокоды",
"promoGroups": "Группы скидок"
},
"panel": {
"title": "Панель администратора",
@@ -774,7 +775,8 @@
"paymentMethodsDesc": "Настройка и порядок платежек",
"campaignsDesc": "Рекламные кампании",
"promoOffersDesc": "Персональные скидки",
"promocodesDesc": "Управление промокодами"
"promocodesDesc": "Управление промокодами",
"promoGroupsDesc": "Группы скидок для пользователей"
},
"emailTemplates": {
"title": "Email-шаблоны",
@@ -2107,6 +2109,62 @@
"deletePromocodeText": "Промокод будет удален безвозвратно.",
"deleteGroupText": "Группа будет удалена. Пользователи потеряют скидки этой группы.",
"deleteButton": "Удалить"
},
"validation": {
"codeRequired": "Введите код промокода",
"balanceRequired": "Сумма бонуса должна быть больше 0",
"daysRequired": "Количество дней должно быть больше 0",
"groupRequired": "Выберите группу скидок",
"discountPercentInvalid": "Процент скидки должен быть от 1 до 100",
"discountHoursRequired": "Укажите время действия скидки в часах"
}
},
"promoGroups": {
"title": "Группы скидок",
"subtitle": "Управление группами скидок для пользователей",
"addGroup": "Добавить группу",
"noGroups": "Нет групп скидок",
"default": "По умолчанию",
"servers": "Серверы",
"traffic": "Трафик",
"devices": "Устройства",
"daysShort": "{{days}} дн.",
"autoFrom": "Авто от {{amount}} руб.",
"members": "{{count}} участников",
"createTitle": "Создание группы скидок",
"editTitle": "Редактирование группы",
"stats": {
"total": "Всего групп",
"members": "Участников",
"autoAssign": "С авто-назначением"
},
"actions": {
"edit": "Редактировать",
"delete": "Удалить"
},
"confirm": {
"title": "Удалить группу?",
"text": "Группа будет удалена. Пользователи потеряют скидки этой группы.",
"cancel": "Отмена",
"delete": "Удалить"
},
"form": {
"name": "Название группы",
"namePlaceholder": "VIP клиенты",
"categoryDiscounts": "Скидки по категориям",
"periodDiscounts": "Скидки по периодам",
"add": "Добавить",
"periodHint": "Скидка применяется при покупке подписки на указанное кол-во дней",
"noPeriods": "Нет скидок по периодам",
"daysPlaceholder": "Дни",
"arrow": "дней →",
"autoAssign": "Авто-назначение при тратах от",
"rub": "руб.",
"autoAssignHint": "0 = не назначать автоматически",
"applyToAddons": "Применять к дополнительным услугам",
"cancel": "Отмена",
"saving": "Сохранение...",
"save": "Сохранить"
}
},
"users": {

View File

@@ -626,6 +626,7 @@
"payments": "支付",
"promoOffers": "促销优惠",
"promocodes": "促销码",
"promoGroups": "折扣组",
"remnawave": "RemnaWave",
"users": "用户"
},
@@ -647,6 +648,7 @@
"paymentsDesc": "支付验证",
"promoOffersDesc": "个性化折扣",
"promocodesDesc": "管理促销码",
"promoGroupsDesc": "用户折扣组",
"remnawaveDesc": "面板管理和统计",
"usersDesc": "管理机器人用户"
},
@@ -1388,6 +1390,62 @@
"deletePromocodeText": "促销码将被永久删除。",
"deleteGroupText": "该组将被删除。用户将失去该组的折扣。",
"deleteButton": "删除"
},
"validation": {
"codeRequired": "请输入促销码",
"balanceRequired": "奖金金额必须大于0",
"daysRequired": "天数必须大于0",
"groupRequired": "请选择折扣组",
"discountPercentInvalid": "折扣百分比必须在1到100之间",
"discountHoursRequired": "请指定折扣有效期(小时)"
}
},
"promoGroups": {
"title": "折扣组",
"subtitle": "管理用户折扣组",
"addGroup": "添加组",
"noGroups": "没有折扣组",
"default": "默认",
"servers": "服务器",
"traffic": "流量",
"devices": "设备",
"daysShort": "{{days}} 天",
"autoFrom": "自动 从 {{amount}} 卢布",
"members": "{{count}} 名成员",
"createTitle": "创建折扣组",
"editTitle": "编辑组",
"stats": {
"total": "组总数",
"members": "成员",
"autoAssign": "自动分配"
},
"actions": {
"edit": "编辑",
"delete": "删除"
},
"confirm": {
"title": "删除组?",
"text": "该组将被删除。用户将失去该组的折扣。",
"cancel": "取消",
"delete": "删除"
},
"form": {
"name": "组名称",
"namePlaceholder": "VIP客户",
"categoryDiscounts": "分类折扣",
"periodDiscounts": "期间折扣",
"add": "添加",
"periodHint": "购买指定天数订阅时应用折扣",
"noPeriods": "没有期间折扣",
"daysPlaceholder": "天",
"arrow": "天 →",
"autoAssign": "消费满额自动分配",
"rub": "卢布",
"autoAssignHint": "0 = 不自动分配",
"applyToAddons": "应用于附加服务",
"cancel": "取消",
"saving": "保存中...",
"save": "保存"
}
},
"users": {