mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
feat: add WebBackButton to all sub-pages, widen renew page layout
- New WebBackButton component: visible on web, hidden in Telegram (native back button handles navigation there) - Added to: Subscription detail, SubscriptionPurchase, RenewSubscription - RenewSubscription: removed max-w-lg, grid layout for period cards
This commit is contained in:
32
src/components/WebBackButton.tsx
Normal file
32
src/components/WebBackButton.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { Link } from 'react-router';
|
||||
import { usePlatform } from '../platform';
|
||||
import { BackIcon } from './icons';
|
||||
|
||||
interface WebBackButtonProps {
|
||||
to: string;
|
||||
replace?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Back button visible only on web platform.
|
||||
* Hidden in Telegram Mini App — native back button handles navigation there.
|
||||
*/
|
||||
export function WebBackButton({ to, replace, className }: WebBackButtonProps) {
|
||||
const { platform } = usePlatform();
|
||||
|
||||
if (platform === 'telegram') return null;
|
||||
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
replace={replace}
|
||||
className={
|
||||
className ||
|
||||
'flex h-10 w-10 items-center justify-center rounded-xl border border-dark-700 bg-dark-800 transition-colors hover:border-dark-600'
|
||||
}
|
||||
>
|
||||
<BackIcon />
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { getGlassColors } from '../utils/glassTheme';
|
||||
import { useCurrency } from '../hooks/useCurrency';
|
||||
import { useHaptic } from '../platform';
|
||||
import InsufficientBalancePrompt from '../components/InsufficientBalancePrompt';
|
||||
import { WebBackButton } from '../components/WebBackButton';
|
||||
|
||||
export default function RenewSubscription() {
|
||||
const { subscriptionId } = useParams<{ subscriptionId: string }>();
|
||||
@@ -97,17 +98,20 @@ export default function RenewSubscription() {
|
||||
const missingAmount = insufficientMatch ? Number(insufficientMatch[1]) : null;
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-lg space-y-5 p-4">
|
||||
<div className="space-y-5">
|
||||
{/* Title */}
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold" style={{ color: g.text }}>
|
||||
{t('subscription.extend', 'Продлить подписку')}
|
||||
</h1>
|
||||
{subscription?.tariff_name && (
|
||||
<p className="mt-1 text-sm" style={{ color: g.textSecondary }}>
|
||||
{subscription.tariff_name}
|
||||
</p>
|
||||
)}
|
||||
<div className="flex items-center gap-3">
|
||||
<WebBackButton to={`/subscriptions/${subId}`} />
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold" style={{ color: g.text }}>
|
||||
{t('subscription.extend', 'Продлить подписку')}
|
||||
</h1>
|
||||
{subscription?.tariff_name && (
|
||||
<p className="mt-1 text-sm" style={{ color: g.textSecondary }}>
|
||||
{subscription.tariff_name}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Balance */}
|
||||
@@ -134,7 +138,7 @@ export default function RenewSubscription() {
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||
{options.map((option) => {
|
||||
const isSelected = selectedPeriod === option.period_days;
|
||||
const canAfford = balanceKopeks >= option.price_kopeks;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate, useParams } from 'react-router';
|
||||
import { subscriptionApi } from '../api/subscription';
|
||||
import { WebBackButton } from '../components/WebBackButton';
|
||||
import TrafficProgressBar from '../components/dashboard/TrafficProgressBar';
|
||||
import { HoverBorderGradient } from '../components/ui/hover-border-gradient';
|
||||
import { useTrafficZone } from '../hooks/useTrafficZone';
|
||||
@@ -480,12 +481,15 @@ export default function Subscription() {
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Page title — native Telegram back button handles navigation */}
|
||||
<h1 className="text-2xl font-bold text-dark-50 sm:text-3xl">
|
||||
{isMultiTariff && subscription?.tariff_name
|
||||
? subscription.tariff_name
|
||||
: t('subscription.title')}
|
||||
</h1>
|
||||
{/* Page title */}
|
||||
<div className="flex items-center gap-3">
|
||||
<WebBackButton to="/subscriptions" />
|
||||
<h1 className="text-2xl font-bold text-dark-50 sm:text-3xl">
|
||||
{isMultiTariff && subscription?.tariff_name
|
||||
? subscription.tariff_name
|
||||
: t('subscription.title')}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Current Subscription */}
|
||||
{subscription ? (
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useNavigate, useSearchParams } from 'react-router';
|
||||
import { AxiosError } from 'axios';
|
||||
import { subscriptionApi } from '../api/subscription';
|
||||
import { promoApi } from '../api/promo';
|
||||
import { WebBackButton } from '../components/WebBackButton';
|
||||
import { getGlassColors } from '../utils/glassTheme';
|
||||
import { useTheme } from '../hooks/useTheme';
|
||||
import type {
|
||||
@@ -407,16 +408,21 @@ export default function SubscriptionPurchase() {
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Header — native Telegram back button handles navigation */}
|
||||
<h1 className="text-2xl font-bold text-dark-50 sm:text-3xl">
|
||||
{isMultiTariff && !subscriptionId
|
||||
? t('subscription.newTariff', 'Новый тариф')
|
||||
: !isMultiTariff && subscription?.is_daily && !subscription?.is_trial
|
||||
? t('subscription.switchTariff.title')
|
||||
: subscription && !subscription.is_trial
|
||||
? t('subscription.extend')
|
||||
: t('subscription.getSubscription')}
|
||||
</h1>
|
||||
{/* Header */}
|
||||
<div className="flex items-center gap-3">
|
||||
<WebBackButton
|
||||
to={subscriptionId ? `/subscriptions/${subscriptionId}` : '/subscriptions'}
|
||||
/>
|
||||
<h1 className="text-2xl font-bold text-dark-50 sm:text-3xl">
|
||||
{isMultiTariff && !subscriptionId
|
||||
? t('subscription.newTariff', 'Новый тариф')
|
||||
: !isMultiTariff && subscription?.is_daily && !subscription?.is_trial
|
||||
? t('subscription.switchTariff.title')
|
||||
: subscription && !subscription.is_trial
|
||||
? t('subscription.extend')
|
||||
: t('subscription.getSubscription')}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Tariffs Section */}
|
||||
{isTariffsMode && tariffs.length > 0 && (
|
||||
|
||||
Reference in New Issue
Block a user