From 94b9b9eb94d31d0cea8fb815b892f47d9a27a2e9 Mon Sep 17 00:00:00 2001 From: c0mrade Date: Thu, 26 Mar 2026 20:09:29 +0300 Subject: [PATCH] feat: tariff selector for trial subscription promo codes - Add tariff_id/tariff_name to PromoCode types - AdminPromocodeCreate: tariff dropdown for trial_subscription type - Shows default trial tariff or warns if none configured --- src/api/promocodes.ts | 4 +++ src/pages/AdminPromocodeCreate.tsx | 46 +++++++++++++++++++----------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/api/promocodes.ts b/src/api/promocodes.ts index cde1307..32e56b7 100644 --- a/src/api/promocodes.ts +++ b/src/api/promocodes.ts @@ -25,6 +25,8 @@ export interface PromoCode { valid_from: string; valid_until: string | null; promo_group_id: number | null; + tariff_id: number | null; + tariff_name: string | null; created_by: number | null; created_at: string; updated_at: string; @@ -63,6 +65,7 @@ export interface PromoCodeCreateRequest { is_active?: boolean; first_purchase_only?: boolean; promo_group_id?: number | null; + tariff_id?: number | null; } export interface PromoCodeUpdateRequest { @@ -76,6 +79,7 @@ export interface PromoCodeUpdateRequest { is_active?: boolean; first_purchase_only?: boolean; promo_group_id?: number | null; + tariff_id?: number | null; } // ============== PromoGroup Types ============== diff --git a/src/pages/AdminPromocodeCreate.tsx b/src/pages/AdminPromocodeCreate.tsx index c83ee49..19c03a1 100644 --- a/src/pages/AdminPromocodeCreate.tsx +++ b/src/pages/AdminPromocodeCreate.tsx @@ -61,6 +61,7 @@ export default function AdminPromocodeCreate() { const [firstPurchaseOnly, setFirstPurchaseOnly] = useState(false); const [validUntil, setValidUntil] = useState(''); const [promoGroupId, setPromoGroupId] = useState(null); + const [tariffId, setTariffId] = useState(null); // Fetch promo groups (for promo_group type) const { data: promoGroupsData } = useQuery({ @@ -104,6 +105,7 @@ export default function AdminPromocodeCreate() { setFirstPurchaseOnly(data.first_purchase_only || false); setValidUntil(data.valid_until ? data.valid_until.split('T')[0] : ''); setPromoGroupId(data.promo_group_id || null); + setTariffId(data.tariff_id || null); return data; }, []), }); @@ -147,6 +149,7 @@ export default function AdminPromocodeCreate() { first_purchase_only: firstPurchaseOnly, valid_until: validUntil ? new Date(validUntil).toISOString() : null, promo_group_id: type === 'promo_group' ? promoGroupId : null, + ...(type === 'trial_subscription' && tariffId ? { tariff_id: tariffId } : {}), }; if (isEdit) { @@ -312,24 +315,33 @@ export default function AdminPromocodeCreate() { )} {type === 'trial_subscription' && ( -
- {trialTariff ? ( -
- - {t('admin.promocodes.form.trialTariffInfo', 'Будет выдан тариф:')} - {' '} - {trialTariff.name} - - {' '} - ({trialTariff.traffic_limit_gb} GB, {trialTariff.device_limit}{' '} - {t('admin.promocodes.form.devices', 'устр.')}) - -
- ) : ( -
+
+ + + {!tariffId && !trialTariff && ( +
{t( - 'admin.promocodes.form.noTrialTariff', - '⚠️ Триальный тариф не настроен. Отметьте тариф как «доступен для триала» в настройках тарифов.', + 'admin.promocodes.form.noTrialTariffHint', + 'Выберите тариф или отметьте тариф как «доступен для триала» в настройках.', )}
)}