refactor: align tariff builder with bot functionality

- Remove unused fields: custom_days, custom_traffic (bot doesn't use them)
- Add promo groups selection to tariff form
- Add API endpoint for fetching available promo groups
- Make traffic topup packages dynamic (add/remove any number)
- Fix stuck 0 in number inputs when clearing
- Add validation messages explaining why save button is blocked
- Match bot validation: name 2-50 chars, device_limit >= 1, tier_level 1-10
- Add missing i18n translations for new fields and validation errors
This commit is contained in:
c0mrade
2026-02-02 04:27:52 +03:00
parent 8cd95b84fb
commit d6edb659a3
6 changed files with 430 additions and 297 deletions

View File

@@ -1021,6 +1021,7 @@
"nameLabel": "نام تعرفه",
"nameExamplePeriod": "مثال: استاندارد",
"nameExampleDaily": "مثال: روزانه",
"nameHint": "۲ تا ۵۰ کاراکتر",
"descriptionLabel": "توضیحات",
"descriptionPlaceholder2": "توضیح مختصر تعرفه",
"trafficLimitLabel": "محدودیت ترافیک",
@@ -1037,8 +1038,12 @@
"addButton": "افزودن",
"noPeriodsHint": "هیچ دوره‌ای اضافه نشده. حداقل یک دوره اضافه کنید.",
"daysShort": "روز",
"serversTitle": "سرورها",
"serversTabHint": "سرورهای موجود در این تعرفه را انتخاب کنید.",
"noServersAvailable": "هیچ سروری در دسترس نیست",
"promoGroupsTitle": "گروه‌های تبلیغاتی",
"promoGroupsHint": "گروه‌های تبلیغاتی که به این تعرفه دسترسی دارند را انتخاب کنید. اگر هیچ‌کدام انتخاب نشود، همه دسترسی دارند.",
"noPromoGroups": "هیچ گروه تبلیغاتی وجود ندارد",
"extraDeviceTitle": "دستگاه‌های اضافی",
"devicePriceLabel": "قیمت دستگاه (30 روز):",
"devicePriceHint": "0 = خرید دستگاه در دسترس نیست",
@@ -1048,6 +1053,8 @@
"trafficMaxLimitLabel": "حداکثر محدودیت:",
"trafficLimitHint2": "(0 = بدون محدودیت)",
"trafficPackagesLabel": "بسته‌های ترافیک:",
"addPackageTitle": "افزودن بسته",
"noPackagesHint": "هیچ بسته‌ای اضافه نشده است. حداقل یک بسته اضافه کنید.",
"gbPackageUnit": "GB:",
"customDaysTitle": "تعداد روزهای سفارشی",
"customDaysDesc": "کاربر مدت اشتراک را انتخاب می‌کند",
@@ -1079,7 +1086,18 @@
"dailyPriceLabel": "قیمت روزانه",
"currencyPerDay": "₽/روز",
"dailyDeductionDesc": "هر روز از موجودی کاربر کسر می‌شود",
"dailyPriceRequired": "قیمت روزانه بزرگتر از 0 را وارد کنید"
"dailyPriceRequired": "قیمت روزانه بزرگتر از 0 را وارد کنید",
"cannotSave": "امکان ذخیره تعرفه وجود ندارد:",
"validation": {
"nameRequired": "نام تعرفه را وارد کنید",
"nameLength": "نام باید ۲ تا ۵۰ کاراکتر باشد",
"deviceLimitRequired": "تعداد دستگاه‌ها را مشخص کنید (حداقل ۱)",
"tierLevelInvalid": "سطح تعرفه باید بین ۱ تا ۱۰ باشد",
"fieldsRequired": "فیلدهای اجباری را پر کنید (دستگاه‌ها، سطح)",
"periodsRequired": "حداقل یک دوره اضافه کنید",
"dailyPriceRequired": "قیمت روزانه بزرگتر از 0 را وارد کنید",
"trafficPackagesRequired": "حداقل یک بسته ترافیک اضافه کنید (یا خرید ترافیک را غیرفعال کنید)"
}
},
"servers": {
"title": "مدیریت سرورها",