mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
feat: add reset traffic toggle on tariff switch
- Add reset_traffic parameter to previewTariffSwitch and switchTariff API calls - Add reset_traffic_available/reset_traffic_default fields to TariffSwitchPreview type - Add toggle switch in tariff switch preview modal (shown when backend enables it) - Initialize toggle from server default (reset_traffic_default) - Pass reset_traffic flag on switch execution - Add translations for all 4 locales (ru, en, zh, fa)
This commit is contained in:
@@ -345,6 +345,7 @@ export const subscriptionApi = {
|
|||||||
// Preview tariff switch cost
|
// Preview tariff switch cost
|
||||||
previewTariffSwitch: async (
|
previewTariffSwitch: async (
|
||||||
tariffId: number,
|
tariffId: number,
|
||||||
|
resetTraffic?: boolean,
|
||||||
): Promise<{
|
): Promise<{
|
||||||
can_switch: boolean;
|
can_switch: boolean;
|
||||||
current_tariff_id: number | null;
|
current_tariff_id: number | null;
|
||||||
@@ -364,10 +365,14 @@ export const subscriptionApi = {
|
|||||||
base_upgrade_cost_kopeks?: number;
|
base_upgrade_cost_kopeks?: number;
|
||||||
discount_percent?: number;
|
discount_percent?: number;
|
||||||
discount_kopeks?: number;
|
discount_kopeks?: number;
|
||||||
|
// Traffic reset on switch
|
||||||
|
reset_traffic_available?: boolean;
|
||||||
|
reset_traffic_default?: boolean;
|
||||||
}> => {
|
}> => {
|
||||||
const response = await apiClient.post('/cabinet/subscription/tariff/switch/preview', {
|
const response = await apiClient.post('/cabinet/subscription/tariff/switch/preview', {
|
||||||
tariff_id: tariffId,
|
tariff_id: tariffId,
|
||||||
period_days: 30, // Default period for switch
|
period_days: 30,
|
||||||
|
...(resetTraffic !== undefined && { reset_traffic: resetTraffic }),
|
||||||
});
|
});
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
@@ -375,6 +380,7 @@ export const subscriptionApi = {
|
|||||||
// Switch to a different tariff
|
// Switch to a different tariff
|
||||||
switchTariff: async (
|
switchTariff: async (
|
||||||
tariffId: number,
|
tariffId: number,
|
||||||
|
resetTraffic?: boolean,
|
||||||
): Promise<{
|
): Promise<{
|
||||||
success: boolean;
|
success: boolean;
|
||||||
message: string;
|
message: string;
|
||||||
@@ -389,6 +395,7 @@ export const subscriptionApi = {
|
|||||||
const response = await apiClient.post('/cabinet/subscription/tariff/switch', {
|
const response = await apiClient.post('/cabinet/subscription/tariff/switch', {
|
||||||
tariff_id: tariffId,
|
tariff_id: tariffId,
|
||||||
period_days: 30,
|
period_days: 30,
|
||||||
|
...(resetTraffic !== undefined && { reset_traffic: resetTraffic }),
|
||||||
});
|
});
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -483,7 +483,9 @@
|
|||||||
"switched": "Tariff switched",
|
"switched": "Tariff switched",
|
||||||
"notEnoughBalance": "Insufficient balance",
|
"notEnoughBalance": "Insufficient balance",
|
||||||
"dailyPayment": "Daily payment",
|
"dailyPayment": "Daily payment",
|
||||||
"dailyChargeDescription": "Charged daily from your balance"
|
"dailyChargeDescription": "Charged daily from your balance",
|
||||||
|
"resetTraffic": "Reset traffic",
|
||||||
|
"resetTrafficHint": "Reset used traffic when switching tariff"
|
||||||
},
|
},
|
||||||
"switchTraffic": {
|
"switchTraffic": {
|
||||||
"title": "Change Traffic",
|
"title": "Change Traffic",
|
||||||
|
|||||||
@@ -378,7 +378,9 @@
|
|||||||
"remainingDays": "روزهای باقیمانده",
|
"remainingDays": "روزهای باقیمانده",
|
||||||
"switch": "تغییر",
|
"switch": "تغییر",
|
||||||
"title": "تغییر تعرفه",
|
"title": "تغییر تعرفه",
|
||||||
"upgradeCost": "هزینه ارتقا"
|
"upgradeCost": "هزینه ارتقا",
|
||||||
|
"resetTraffic": "بازنشانی ترافیک",
|
||||||
|
"resetTrafficHint": "بازنشانی ترافیک مصرفی هنگام تغییر تعرفه"
|
||||||
},
|
},
|
||||||
"promoGroup": {
|
"promoGroup": {
|
||||||
"yourGroup": "گروه شما: {{name}}",
|
"yourGroup": "گروه شما: {{name}}",
|
||||||
|
|||||||
@@ -506,7 +506,9 @@
|
|||||||
"switched": "Тариф изменён",
|
"switched": "Тариф изменён",
|
||||||
"notEnoughBalance": "Недостаточно средств",
|
"notEnoughBalance": "Недостаточно средств",
|
||||||
"dailyPayment": "Оплата за день",
|
"dailyPayment": "Оплата за день",
|
||||||
"dailyChargeDescription": "Списывается ежедневно с баланса"
|
"dailyChargeDescription": "Списывается ежедневно с баланса",
|
||||||
|
"resetTraffic": "Сбросить трафик",
|
||||||
|
"resetTrafficHint": "Обнулить использованный трафик при смене тарифа"
|
||||||
},
|
},
|
||||||
"switchTraffic": {
|
"switchTraffic": {
|
||||||
"title": "Изменить трафик",
|
"title": "Изменить трафик",
|
||||||
|
|||||||
@@ -378,7 +378,9 @@
|
|||||||
"remainingDays": "剩余天数",
|
"remainingDays": "剩余天数",
|
||||||
"switch": "切换",
|
"switch": "切换",
|
||||||
"title": "切换套餐",
|
"title": "切换套餐",
|
||||||
"upgradeCost": "升级费用"
|
"upgradeCost": "升级费用",
|
||||||
|
"resetTraffic": "重置流量",
|
||||||
|
"resetTrafficHint": "切换套餐时重置已使用流量"
|
||||||
},
|
},
|
||||||
"promoGroup": {
|
"promoGroup": {
|
||||||
"yourGroup": "您的组:{{name}}",
|
"yourGroup": "您的组:{{name}}",
|
||||||
|
|||||||
@@ -128,12 +128,14 @@ export default function SubscriptionPurchase() {
|
|||||||
|
|
||||||
// Tariff switch
|
// Tariff switch
|
||||||
const [switchTariffId, setSwitchTariffId] = useState<number | null>(null);
|
const [switchTariffId, setSwitchTariffId] = useState<number | null>(null);
|
||||||
|
const [resetTrafficOnSwitch, setResetTrafficOnSwitch] = useState(false);
|
||||||
|
|
||||||
// Auto-close all modals on success notification
|
// Auto-close all modals on success notification
|
||||||
const handleCloseAllModals = () => {
|
const handleCloseAllModals = () => {
|
||||||
setShowPurchaseForm(false);
|
setShowPurchaseForm(false);
|
||||||
setShowTariffPurchase(false);
|
setShowTariffPurchase(false);
|
||||||
setSwitchTariffId(null);
|
setSwitchTariffId(null);
|
||||||
|
setResetTrafficOnSwitch(false);
|
||||||
setSelectedTariff(null);
|
setSelectedTariff(null);
|
||||||
setSelectedTariffPeriod(null);
|
setSelectedTariffPeriod(null);
|
||||||
};
|
};
|
||||||
@@ -230,13 +232,21 @@ export default function SubscriptionPurchase() {
|
|||||||
enabled: !!switchTariffId,
|
enabled: !!switchTariffId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Initialize reset traffic toggle from server default
|
||||||
|
useEffect(() => {
|
||||||
|
if (switchPreview?.reset_traffic_default !== undefined) {
|
||||||
|
setResetTrafficOnSwitch(switchPreview.reset_traffic_default);
|
||||||
|
}
|
||||||
|
}, [switchPreview?.reset_traffic_default]);
|
||||||
|
|
||||||
// Tariff switch mutation
|
// Tariff switch mutation
|
||||||
const switchTariffMutation = useMutation({
|
const switchTariffMutation = useMutation({
|
||||||
mutationFn: (tariffId: number) => subscriptionApi.switchTariff(tariffId),
|
mutationFn: (tariffId: number) => subscriptionApi.switchTariff(tariffId, resetTrafficOnSwitch),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['subscription'] });
|
queryClient.invalidateQueries({ queryKey: ['subscription'] });
|
||||||
queryClient.invalidateQueries({ queryKey: ['purchase-options'] });
|
queryClient.invalidateQueries({ queryKey: ['purchase-options'] });
|
||||||
setSwitchTariffId(null);
|
setSwitchTariffId(null);
|
||||||
|
setResetTrafficOnSwitch(false);
|
||||||
navigate('/subscription', { replace: true });
|
navigate('/subscription', { replace: true });
|
||||||
},
|
},
|
||||||
onError: (error: unknown) => {
|
onError: (error: unknown) => {
|
||||||
@@ -250,6 +260,7 @@ export default function SubscriptionPurchase() {
|
|||||||
const targetTariff = tariffs.find((tariff) => tariff.id === switchTariffId);
|
const targetTariff = tariffs.find((tariff) => tariff.id === switchTariffId);
|
||||||
if (targetTariff) {
|
if (targetTariff) {
|
||||||
setSwitchTariffId(null);
|
setSwitchTariffId(null);
|
||||||
|
setResetTrafficOnSwitch(false);
|
||||||
setSelectedTariff(targetTariff);
|
setSelectedTariff(targetTariff);
|
||||||
setSelectedTariffPeriod(targetTariff.periods[0] || null);
|
setSelectedTariffPeriod(targetTariff.periods[0] || null);
|
||||||
setShowTariffPurchase(true);
|
setShowTariffPurchase(true);
|
||||||
@@ -598,6 +609,35 @@ export default function SubscriptionPurchase() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Reset traffic toggle */}
|
||||||
|
{switchPreview.reset_traffic_available && (
|
||||||
|
<label className="flex cursor-pointer items-center justify-between rounded-lg border border-dark-700/50 bg-dark-800/50 px-3 py-2.5">
|
||||||
|
<div>
|
||||||
|
<div className="text-sm font-medium text-dark-100">
|
||||||
|
{t('subscription.switchTariff.resetTraffic')}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-dark-400">
|
||||||
|
{t('subscription.switchTariff.resetTrafficHint')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
role="switch"
|
||||||
|
aria-checked={resetTrafficOnSwitch}
|
||||||
|
onClick={() => setResetTrafficOnSwitch((prev) => !prev)}
|
||||||
|
className={`relative h-6 w-11 flex-shrink-0 rounded-full transition-colors duration-200 ${
|
||||||
|
resetTrafficOnSwitch ? 'bg-accent-500' : 'bg-dark-600'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={`absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-white shadow transition-transform duration-200 ${
|
||||||
|
resetTrafficOnSwitch ? 'translate-x-5' : 'translate-x-0'
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
|
||||||
{!switchPreview.has_enough_balance &&
|
{!switchPreview.has_enough_balance &&
|
||||||
switchPreview.upgrade_cost_kopeks > 0 && (
|
switchPreview.upgrade_cost_kopeks > 0 && (
|
||||||
<InsufficientBalancePrompt
|
<InsufficientBalancePrompt
|
||||||
|
|||||||
@@ -143,6 +143,9 @@ export interface TariffSwitchPreview {
|
|||||||
base_upgrade_cost_kopeks?: number;
|
base_upgrade_cost_kopeks?: number;
|
||||||
discount_percent?: number;
|
discount_percent?: number;
|
||||||
discount_kopeks?: number;
|
discount_kopeks?: number;
|
||||||
|
// Traffic reset on switch
|
||||||
|
reset_traffic_available?: boolean;
|
||||||
|
reset_traffic_default?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RenewalOption {
|
export interface RenewalOption {
|
||||||
|
|||||||
Reference in New Issue
Block a user