mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
redesign: subscriptions list page — full width, grid layout, accent add button
- Remove max-w-lg constraint to match dashboard width - Grid layout: 2 columns on desktop, 1 on mobile - Move "Новый тариф" button to header row as accent-styled button - Larger empty state with more breathing room
This commit is contained in:
@@ -13,15 +13,15 @@ function EmptyState({ onBuy }: { onBuy: () => void }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="rounded-2xl border p-8 text-center"
|
className="rounded-2xl border p-10 text-center"
|
||||||
style={{ background: g.cardBg, borderColor: g.cardBorder }}
|
style={{ background: g.cardBg, borderColor: g.cardBorder }}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-2xl"
|
className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-2xl"
|
||||||
style={{ background: g.innerBg }}
|
style={{ background: g.innerBg }}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
className="h-7 w-7 opacity-40"
|
className="h-8 w-8 opacity-40"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
@@ -34,15 +34,15 @@ function EmptyState({ onBuy }: { onBuy: () => void }) {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 className="mb-1 text-lg font-semibold" style={{ color: g.text }}>
|
<h3 className="mb-2 text-xl font-semibold" style={{ color: g.text }}>
|
||||||
{t('subscriptions.empty', 'Нет подписок')}
|
{t('subscriptions.empty', 'Нет подписок')}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mb-5 text-sm" style={{ color: g.textSecondary }}>
|
<p className="mb-6 text-sm" style={{ color: g.textSecondary }}>
|
||||||
{t('subscriptions.emptyDesc', 'У вас пока нет активных подписок')}
|
{t('subscriptions.emptyDesc', 'У вас пока нет активных подписок')}
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
onClick={onBuy}
|
onClick={onBuy}
|
||||||
className="rounded-xl bg-accent-500 px-6 py-2.5 text-sm font-medium text-white transition-colors hover:bg-accent-600"
|
className="rounded-xl bg-accent-500 px-8 py-3 text-sm font-medium text-white transition-colors hover:bg-accent-600"
|
||||||
>
|
>
|
||||||
{t('subscriptions.buy', 'Купить подписку')}
|
{t('subscriptions.buy', 'Купить подписку')}
|
||||||
</button>
|
</button>
|
||||||
@@ -73,52 +73,65 @@ export default function Subscriptions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto max-w-lg space-y-4 p-4">
|
<div className="space-y-6">
|
||||||
<h1 className="text-2xl font-bold" style={{ color: g.text }}>
|
{/* Header */}
|
||||||
{t('subscriptions.title', 'Мои подписки')}
|
<div className="flex items-center justify-between">
|
||||||
</h1>
|
<h1 className="text-2xl font-bold" style={{ color: g.text }}>
|
||||||
|
{t('subscriptions.title', 'Мои подписки')}
|
||||||
|
</h1>
|
||||||
|
{!isLoading && subscriptions.length > 0 && (
|
||||||
|
<button
|
||||||
|
onClick={() => navigate('/subscription/purchase')}
|
||||||
|
className="flex items-center gap-1.5 rounded-xl px-4 py-2 text-sm font-medium transition-colors"
|
||||||
|
style={{
|
||||||
|
background: 'rgba(var(--color-accent-400), 0.1)',
|
||||||
|
color: 'rgb(var(--color-accent-400))',
|
||||||
|
border: '1px solid rgba(var(--color-accent-400), 0.2)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="h-4 w-4"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth={2.5}
|
||||||
|
>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
||||||
|
</svg>
|
||||||
|
{t('subscriptions.buyAnother', 'Новый тариф')}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Loading */}
|
||||||
{isLoading && (
|
{isLoading && (
|
||||||
<div className="space-y-3">
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||||
{[1, 2].map((i) => (
|
{[1, 2].map((i) => (
|
||||||
<div
|
<div
|
||||||
key={i}
|
key={i}
|
||||||
className="h-28 animate-pulse rounded-2xl"
|
className="h-36 animate-pulse rounded-2xl"
|
||||||
style={{ background: g.innerBg }}
|
style={{ background: g.innerBg }}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Empty state */}
|
||||||
{!isLoading && subscriptions.length === 0 && (
|
{!isLoading && subscriptions.length === 0 && (
|
||||||
<EmptyState onBuy={() => navigate('/subscription/purchase')} />
|
<EmptyState onBuy={() => navigate('/subscription/purchase')} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{subscriptions.map((sub) => (
|
{/* Subscription grid */}
|
||||||
<SubscriptionListCard
|
{subscriptions.length > 0 && (
|
||||||
key={sub.id}
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||||
subscription={sub}
|
{subscriptions.map((sub) => (
|
||||||
onClick={() => navigate(`/subscriptions/${sub.id}`)}
|
<SubscriptionListCard
|
||||||
/>
|
key={sub.id}
|
||||||
))}
|
subscription={sub}
|
||||||
|
onClick={() => navigate(`/subscriptions/${sub.id}`)}
|
||||||
{!isLoading && subscriptions.length > 0 && (
|
/>
|
||||||
<button
|
))}
|
||||||
onClick={() => navigate('/subscription/purchase')}
|
</div>
|
||||||
className="flex w-full items-center justify-center gap-2 rounded-2xl border border-dashed p-4 text-sm transition-all hover:border-accent-400/30 hover:opacity-80"
|
|
||||||
style={{ borderColor: g.cardBorder, color: g.textSecondary }}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
className="h-5 w-5"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth={2}
|
|
||||||
>
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
|
||||||
</svg>
|
|
||||||
{t('subscriptions.buyAnother', 'Купить ещё тариф')}
|
|
||||||
</button>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user