mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
Add files via upload
This commit is contained in:
@@ -7,6 +7,7 @@ import { subscriptionApi } from '../api/subscription'
|
||||
import { promoApi } from '../api/promo'
|
||||
import type { PurchaseSelection, PeriodOption, Tariff, TariffPeriod, ClassicPurchaseOptions } from '../types'
|
||||
import ConnectionModal from '../components/ConnectionModal'
|
||||
import InsufficientBalancePrompt from '../components/InsufficientBalancePrompt'
|
||||
import { useCurrency } from '../hooks/useCurrency'
|
||||
|
||||
// Helper to extract error message from axios/api errors
|
||||
@@ -772,9 +773,16 @@ export default function Subscription() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{devicePriceData && purchaseOptions && devicePriceData.total_price_kopeks && devicePriceData.total_price_kopeks > purchaseOptions.balance_kopeks && (
|
||||
<InsufficientBalancePrompt
|
||||
missingAmountKopeks={devicePriceData.total_price_kopeks - purchaseOptions.balance_kopeks}
|
||||
compact
|
||||
/>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={() => devicePurchaseMutation.mutate()}
|
||||
disabled={devicePurchaseMutation.isPending}
|
||||
disabled={devicePurchaseMutation.isPending || (devicePriceData?.total_price_kopeks && purchaseOptions && devicePriceData.total_price_kopeks > purchaseOptions.balance_kopeks)}
|
||||
className="btn-primary w-full py-3"
|
||||
>
|
||||
{devicePurchaseMutation.isPending ? (
|
||||
@@ -862,21 +870,36 @@ export default function Subscription() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
{selectedTrafficPackage && (
|
||||
<button
|
||||
onClick={() => trafficPurchaseMutation.mutate(selectedTrafficPackage)}
|
||||
disabled={trafficPurchaseMutation.isPending}
|
||||
className="btn-primary w-full py-3"
|
||||
>
|
||||
{trafficPurchaseMutation.isPending ? (
|
||||
<span className="flex items-center justify-center gap-2">
|
||||
<span className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" />
|
||||
</span>
|
||||
) : (
|
||||
`Купить ${selectedTrafficPackage} ГБ`
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
{selectedTrafficPackage && (() => {
|
||||
const selectedPkg = trafficPackages.find(p => p.gb === selectedTrafficPackage)
|
||||
const hasEnoughBalance = !selectedPkg || !purchaseOptions || selectedPkg.price_kopeks <= purchaseOptions.balance_kopeks
|
||||
const missingAmount = selectedPkg && purchaseOptions ? selectedPkg.price_kopeks - purchaseOptions.balance_kopeks : 0
|
||||
|
||||
return (
|
||||
<>
|
||||
{!hasEnoughBalance && missingAmount > 0 && (
|
||||
<InsufficientBalancePrompt
|
||||
missingAmountKopeks={missingAmount}
|
||||
compact
|
||||
className="mb-3"
|
||||
/>
|
||||
)}
|
||||
<button
|
||||
onClick={() => trafficPurchaseMutation.mutate(selectedTrafficPackage)}
|
||||
disabled={trafficPurchaseMutation.isPending || !hasEnoughBalance}
|
||||
className="btn-primary w-full py-3"
|
||||
>
|
||||
{trafficPurchaseMutation.isPending ? (
|
||||
<span className="flex items-center justify-center gap-2">
|
||||
<span className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" />
|
||||
</span>
|
||||
) : (
|
||||
`Купить ${selectedTrafficPackage} ГБ`
|
||||
)}
|
||||
</button>
|
||||
</>
|
||||
)
|
||||
})()}
|
||||
|
||||
{trafficPurchaseMutation.isError && (
|
||||
<div className="text-sm text-error-400 text-center">
|
||||
@@ -1050,9 +1073,10 @@ export default function Subscription() {
|
||||
</div>
|
||||
|
||||
{!switchPreview.has_enough_balance && switchPreview.upgrade_cost_kopeks > 0 && (
|
||||
<div className="text-sm text-error-400 bg-error-500/10 px-3 py-2 rounded-lg text-center">
|
||||
{t('subscription.switchTariff.notEnoughBalance')}: {switchPreview.missing_amount_label}
|
||||
</div>
|
||||
<InsufficientBalancePrompt
|
||||
missingAmountKopeks={switchPreview.missing_amount_kopeks}
|
||||
compact
|
||||
/>
|
||||
)}
|
||||
|
||||
<button
|
||||
@@ -1341,11 +1365,11 @@ export default function Subscription() {
|
||||
return (
|
||||
<div className="mt-6">
|
||||
{purchaseOptions && !hasEnoughBalance && (
|
||||
<div className="text-sm text-error-400 bg-error-500/10 px-4 py-3 rounded-lg text-center mb-4">
|
||||
{t('subscription.insufficientBalance', {
|
||||
missing: ((dailyPrice - purchaseOptions.balance_kopeks) / 100).toFixed(2)
|
||||
})}
|
||||
</div>
|
||||
<InsufficientBalancePrompt
|
||||
missingAmountKopeks={dailyPrice - purchaseOptions.balance_kopeks}
|
||||
compact
|
||||
className="mb-4"
|
||||
/>
|
||||
)}
|
||||
|
||||
<button
|
||||
@@ -1624,11 +1648,11 @@ export default function Subscription() {
|
||||
</div>
|
||||
|
||||
{purchaseOptions && !hasEnoughBalance && (
|
||||
<div className="text-sm text-error-400 bg-error-500/10 px-4 py-3 rounded-lg text-center mb-4">
|
||||
{t('subscription.insufficientBalance', {
|
||||
missing: ((totalPrice - purchaseOptions.balance_kopeks) / 100).toFixed(2)
|
||||
})}
|
||||
</div>
|
||||
<InsufficientBalancePrompt
|
||||
missingAmountKopeks={totalPrice - purchaseOptions.balance_kopeks}
|
||||
compact
|
||||
className="mb-4"
|
||||
/>
|
||||
)}
|
||||
|
||||
<button
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { wheelApi, type SpinResult, type SpinHistoryItem } from '../api/wheel'
|
||||
import FortuneWheel from '../components/wheel/FortuneWheel'
|
||||
import InsufficientBalancePrompt from '../components/InsufficientBalancePrompt'
|
||||
import { useCurrency } from '../hooks/useCurrency'
|
||||
|
||||
// Icons
|
||||
@@ -574,20 +575,21 @@ export default function Wheel() {
|
||||
|
||||
{/* Cannot spin hint */}
|
||||
{!config.can_spin && !isSpinning && (
|
||||
<div className="text-center p-4 rounded-xl bg-dark-800/50 border border-dark-700">
|
||||
<>
|
||||
{config.can_spin_reason === 'daily_limit_reached' ? (
|
||||
<p className="text-dark-400">{t('wheel.errors.dailyLimitReached')}</p>
|
||||
) : config.can_spin_reason === 'insufficient_balance' ? (
|
||||
<div className="space-y-1">
|
||||
<p className="text-warning-400 font-medium">{t('wheel.errors.insufficientBalance')}</p>
|
||||
<p className="text-dark-500 text-sm">
|
||||
{t('wheel.errors.topUpRequired')} ({formatAmount((config.required_balance_kopeks - config.user_balance_kopeks) / 100)} {currencySymbol})
|
||||
</p>
|
||||
<div className="text-center p-4 rounded-xl bg-dark-800/50 border border-dark-700">
|
||||
<p className="text-dark-400">{t('wheel.errors.dailyLimitReached')}</p>
|
||||
</div>
|
||||
) : config.can_spin_reason === 'insufficient_balance' ? (
|
||||
<InsufficientBalancePrompt
|
||||
missingAmountKopeks={config.required_balance_kopeks - config.user_balance_kopeks}
|
||||
/>
|
||||
) : (
|
||||
<p className="text-dark-400">{t('wheel.errors.cannotSpin')}</p>
|
||||
<div className="text-center p-4 rounded-xl bg-dark-800/50 border border-dark-700">
|
||||
<p className="text-dark-400">{t('wheel.errors.cannotSpin')}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user