mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-29 18:13:47 +00:00
Merge remote branch and add Quick Presets for theme colors
- Added Quick Presets section in AdminSettings with 8 predefined themes - Fixed ColorPicker overflow issues for small containers - Resolved merge conflicts keeping local theme implementation
This commit is contained in:
@@ -32,6 +32,7 @@ export default function Balance() {
|
||||
const [promocodeSuccess, setPromocodeSuccess] =
|
||||
useState<{ message: string; amount: number } | null>(null)
|
||||
const [transactionsPage, setTransactionsPage] = useState(1)
|
||||
const [isHistoryOpen, setIsHistoryOpen] = useState(false)
|
||||
|
||||
const { data: transactions, isLoading } = useQuery<PaginatedResponse<Transaction>>({
|
||||
queryKey: ['transactions', transactionsPage],
|
||||
@@ -122,7 +123,7 @@ export default function Balance() {
|
||||
<h1 className="text-2xl sm:text-3xl font-bold text-dark-50">{t('balance.title')}</h1>
|
||||
|
||||
{/* Balance Card */}
|
||||
<div className="card bg-gradient-to-br from-accent-500/10 to-transparent border-accent-500/20">
|
||||
<div className="bento-card bento-card-glow bg-gradient-to-br from-accent-500/10 to-transparent">
|
||||
<div className="text-sm text-dark-400 mb-2">{t('balance.currentBalance')}</div>
|
||||
<div className="text-4xl sm:text-5xl font-bold text-dark-50">
|
||||
{formatAmount(balanceData?.balance_rubles || 0)}
|
||||
@@ -131,7 +132,7 @@ export default function Balance() {
|
||||
</div>
|
||||
|
||||
{/* Promo Code Section */}
|
||||
<div className="card">
|
||||
<div className="bento-card">
|
||||
<h2 className="text-lg font-semibold text-dark-100 mb-4">{t('balance.promocode.title')}</h2>
|
||||
<div className="flex gap-3">
|
||||
<input
|
||||
@@ -168,7 +169,7 @@ export default function Balance() {
|
||||
|
||||
{/* Payment Methods */}
|
||||
{paymentMethods && paymentMethods.length > 0 && (
|
||||
<div className="card">
|
||||
<div className="bento-card">
|
||||
<h2 className="text-lg font-semibold text-dark-100 mb-4">{t('balance.topUpBalance')}</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
|
||||
{paymentMethods.map((method) => {
|
||||
@@ -181,10 +182,10 @@ export default function Balance() {
|
||||
key={method.id}
|
||||
disabled={!method.is_available}
|
||||
onClick={() => method.is_available && setSelectedMethod(method)}
|
||||
className={`p-4 rounded-xl border text-left transition-all ${
|
||||
className={`bento-card-hover p-4 text-left transition-all ${
|
||||
method.is_available
|
||||
? 'border-dark-700/50 hover:border-accent-500/50 bg-dark-800/30 cursor-pointer'
|
||||
: 'border-dark-800/30 bg-dark-900/30 opacity-50 cursor-not-allowed'
|
||||
? 'cursor-pointer'
|
||||
: 'opacity-50 cursor-not-allowed'
|
||||
}`}
|
||||
>
|
||||
<div className="font-semibold text-dark-100">{translatedName || method.name}</div>
|
||||
@@ -201,88 +202,104 @@ export default function Balance() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Transaction History */}
|
||||
<div className="card">
|
||||
<h2 className="text-lg font-semibold text-dark-100 mb-4">{t('balance.transactionHistory')}</h2>
|
||||
<div className="bento-card overflow-hidden">
|
||||
<button
|
||||
onClick={() => setIsHistoryOpen(!isHistoryOpen)}
|
||||
className="w-full flex items-center justify-between text-left"
|
||||
>
|
||||
<h2 className="text-lg font-semibold text-dark-100">{t('balance.transactionHistory')}</h2>
|
||||
<svg
|
||||
className={`w-5 h-5 text-dark-400 transition-transform duration-200 ${isHistoryOpen ? 'rotate-180' : ''}`}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{isLoading ? (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<div className="w-8 h-8 border-2 border-accent-500 border-t-transparent rounded-full animate-spin" />
|
||||
</div>
|
||||
) : transactions?.items && transactions.items.length > 0 ? (
|
||||
<div className="space-y-3">
|
||||
{transactions.items.map((tx) => {
|
||||
// API returns negative values for debits, positive for credits
|
||||
const isPositive = tx.amount_rubles >= 0
|
||||
const displayAmount = Math.abs(tx.amount_rubles)
|
||||
const sign = isPositive ? '+' : '-'
|
||||
const colorClass = isPositive ? 'text-success-400' : 'text-error-400'
|
||||
|
||||
return (
|
||||
<div
|
||||
key={tx.id}
|
||||
className="flex items-center justify-between p-4 rounded-xl bg-dark-800/30 border border-dark-700/30"
|
||||
>
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-3 mb-1">
|
||||
<span className={getTypeBadge(tx.type)}>
|
||||
{getTypeLabel(tx.type)}
|
||||
</span>
|
||||
<span className="text-xs text-dark-500">
|
||||
{new Date(tx.created_at).toLocaleDateString()}
|
||||
</span>
|
||||
</div>
|
||||
{tx.description && (
|
||||
<div className="text-sm text-dark-400">{tx.description}</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={`text-lg font-semibold ${colorClass}`}>
|
||||
{sign}{formatAmount(displayAmount)} {currencySymbol}
|
||||
</div>
|
||||
{isHistoryOpen && (
|
||||
<div className="mt-4">
|
||||
{isLoading ? (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<div className="w-8 h-8 border-2 border-accent-500 border-t-transparent rounded-full animate-spin" />
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center py-12">
|
||||
<div className="w-16 h-16 mx-auto mb-4 rounded-2xl bg-dark-800 flex items-center justify-center">
|
||||
<svg className="w-8 h-8 text-dark-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 18.75a60.07 60.07 0 0115.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75A.75.75 0 013 6h-.75m0 0v-.375c0-.621.504-1.125 1.125-1.125H20.25M2.25 6v9m18-10.5v.75c0 .414.336.75.75.75h.75m-1.5-1.5h.375c.621 0 1.125.504 1.125 1.125v9.75c0 .621-.504 1.125-1.125 1.125h-.375m1.5-1.5H21a.75.75 0 00-.75.75v.75m0 0H3.75m0 0h-.375a1.125 1.125 0 01-1.125-1.125V15m1.5 1.5v-.75A.75.75 0 003 15h-.75M15 10.5a3 3 0 11-6 0 3 3 0 016 0zm3 0h.008v.008H18V10.5zm-12 0h.008v.008H6V10.5z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-dark-400">{t('balance.noTransactions')}</div>
|
||||
</div>
|
||||
)}
|
||||
) : transactions?.items && transactions.items.length > 0 ? (
|
||||
<div className="space-y-3">
|
||||
{transactions.items.map((tx) => {
|
||||
const isPositive = tx.amount_rubles >= 0
|
||||
const displayAmount = Math.abs(tx.amount_rubles)
|
||||
const sign = isPositive ? '+' : '-'
|
||||
const colorClass = isPositive ? 'text-success-400' : 'text-error-400'
|
||||
|
||||
{transactions && transactions.pages > 1 && (
|
||||
<div className="mt-4 flex items-center gap-3 flex-wrap text-sm text-dark-500">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setTransactionsPage((prev) => Math.max(1, prev - 1))}
|
||||
disabled={transactions.page <= 1}
|
||||
className={`btn-secondary text-xs sm:text-sm flex-1 sm:flex-none min-w-[120px] ${
|
||||
transactions.page <= 1 ? 'opacity-50 cursor-not-allowed' : ''
|
||||
}`}
|
||||
>
|
||||
{t('common.back')}
|
||||
</button>
|
||||
<div className="flex-1 text-center">
|
||||
{t('balance.page', { current: transactions.page, total: transactions.pages })}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
setTransactionsPage((prev) =>
|
||||
transactions.pages ? Math.min(transactions.pages, prev + 1) : prev + 1
|
||||
)
|
||||
}
|
||||
disabled={transactions.page >= transactions.pages}
|
||||
className={`btn-secondary text-xs sm:text-sm flex-1 sm:flex-none min-w-[120px] ${
|
||||
transactions.page >= transactions.pages ? 'opacity-50 cursor-not-allowed' : ''
|
||||
}`}
|
||||
>
|
||||
{t('common.next')}
|
||||
</button>
|
||||
return (
|
||||
<div
|
||||
key={tx.id}
|
||||
className="flex items-center justify-between p-4 rounded-xl bg-dark-800/30 border border-dark-700/30"
|
||||
>
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-3 mb-1">
|
||||
<span className={getTypeBadge(tx.type)}>
|
||||
{getTypeLabel(tx.type)}
|
||||
</span>
|
||||
<span className="text-xs text-dark-500">
|
||||
{new Date(tx.created_at).toLocaleDateString()}
|
||||
</span>
|
||||
</div>
|
||||
{tx.description && (
|
||||
<div className="text-sm text-dark-400">{tx.description}</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={`text-lg font-semibold ${colorClass}`}>
|
||||
{sign}{formatAmount(displayAmount)} {currencySymbol}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center py-12">
|
||||
<div className="w-16 h-16 mx-auto mb-4 rounded-2xl bg-dark-800 flex items-center justify-center">
|
||||
<svg className="w-8 h-8 text-dark-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 18.75a60.07 60.07 0 0115.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75A.75.75 0 013 6h-.75m0 0v-.375c0-.621.504-1.125 1.125-1.125H20.25M2.25 6v9m18-10.5v.75c0 .414.336.75.75.75h.75m-1.5-1.5h.375c.621 0 1.125.504 1.125 1.125v9.75c0 .621-.504 1.125-1.125 1.125h-.375m1.5-1.5H21a.75.75 0 00-.75.75v.75m0 0H3.75m0 0h-.375a1.125 1.125 0 01-1.125-1.125V15m1.5 1.5v-.75A.75.75 0 003 15h-.75M15 10.5a3 3 0 11-6 0 3 3 0 016 0zm3 0h.008v.008H18V10.5zm-12 0h.008v.008H6V10.5z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-dark-400">{t('balance.noTransactions')}</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{transactions && transactions.pages > 1 && (
|
||||
<div className="mt-4 flex items-center gap-3 flex-wrap text-sm text-dark-500">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setTransactionsPage((prev) => Math.max(1, prev - 1))}
|
||||
disabled={transactions.page <= 1}
|
||||
className={`btn-secondary text-xs sm:text-sm flex-1 sm:flex-none min-w-[120px] ${
|
||||
transactions.page <= 1 ? 'opacity-50 cursor-not-allowed' : ''
|
||||
}`}
|
||||
>
|
||||
{t('common.back')}
|
||||
</button>
|
||||
<div className="flex-1 text-center">
|
||||
{t('balance.page', { current: transactions.page, total: transactions.pages })}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
setTransactionsPage((prev) =>
|
||||
transactions.pages ? Math.min(transactions.pages, prev + 1) : prev + 1
|
||||
)
|
||||
}
|
||||
disabled={transactions.page >= transactions.pages}
|
||||
className={`btn-secondary text-xs sm:text-sm flex-1 sm:flex-none min-w-[120px] ${
|
||||
transactions.page >= transactions.pages ? 'opacity-50 cursor-not-allowed' : ''
|
||||
}`}
|
||||
>
|
||||
{t('common.next')}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -86,8 +86,8 @@ export default function Contests() {
|
||||
|
||||
{/* Game Modal */}
|
||||
{selectedContest && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/60">
|
||||
<div className="card max-w-lg w-full max-h-[80vh] overflow-y-auto">
|
||||
<div className="fixed inset-0 z-[60] bg-black/70 backdrop-blur-sm flex items-center justify-center p-4">
|
||||
<div className="bento-card max-w-lg w-full max-h-[80vh] overflow-y-auto" onClick={e => e.stopPropagation()}>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h2 className="text-xl font-bold">{selectedContest.name}</h2>
|
||||
<button onClick={handleCloseGame} className="text-dark-400 hover:text-dark-200">
|
||||
|
||||
@@ -254,7 +254,7 @@ export default function Dashboard() {
|
||||
|
||||
{/* Subscription Status - Main Card */}
|
||||
{subscription && (
|
||||
<div className="card">
|
||||
<div className="bento-card">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h2 className="text-lg font-semibold text-dark-100">{t('subscription.status')}</h2>
|
||||
<span className={subscription.is_active ? 'badge-success' : 'badge-error'}>
|
||||
@@ -336,9 +336,9 @@ export default function Dashboard() {
|
||||
)}
|
||||
|
||||
{/* Stats Grid */}
|
||||
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<div className="bento-grid">
|
||||
{/* Balance */}
|
||||
<Link to="/balance" className="card-hover group" data-onboarding="balance">
|
||||
<Link to="/balance" className="bento-card-hover group" data-onboarding="balance">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className="text-dark-400 text-sm">{t('balance.currentBalance')}</span>
|
||||
<span className="text-dark-600 group-hover:text-accent-400 transition-colors">
|
||||
@@ -352,7 +352,7 @@ export default function Dashboard() {
|
||||
</Link>
|
||||
|
||||
{/* Subscription */}
|
||||
<Link to="/subscription" className="card-hover group" data-onboarding="subscription-status">
|
||||
<Link to="/subscription" className="bento-card-hover group" data-onboarding="subscription-status">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className="text-dark-400 text-sm">{t('subscription.title')}</span>
|
||||
<span className="text-dark-600 group-hover:text-accent-400 transition-colors">
|
||||
@@ -388,7 +388,7 @@ export default function Dashboard() {
|
||||
</Link>
|
||||
|
||||
{/* Referrals */}
|
||||
<Link to="/referral" className="card-hover group">
|
||||
<Link to="/referral" className="bento-card-hover group">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className="text-dark-400 text-sm">{t('referral.stats.totalReferrals')}</span>
|
||||
<span className="text-dark-600 group-hover:text-accent-400 transition-colors">
|
||||
@@ -403,7 +403,7 @@ export default function Dashboard() {
|
||||
</Link>
|
||||
|
||||
{/* Earnings */}
|
||||
<Link to="/referral" className="card-hover group">
|
||||
<Link to="/referral" className="bento-card-hover group">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className="text-dark-400 text-sm">{t('referral.stats.totalEarnings')}</span>
|
||||
<span className="text-dark-600 group-hover:text-accent-400 transition-colors">
|
||||
@@ -422,7 +422,7 @@ export default function Dashboard() {
|
||||
|
||||
{/* Trial Activation */}
|
||||
{hasNoSubscription && !trialLoading && trialInfo?.is_available && (
|
||||
<div className="card border-accent-500/30 bg-gradient-to-br from-accent-500/5 to-transparent">
|
||||
<div className="bento-card-glow border-accent-500/30 bg-gradient-to-br from-accent-500/5 to-transparent">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-12 h-12 rounded-xl bg-accent-500/20 flex items-center justify-center flex-shrink-0">
|
||||
<SparklesIcon />
|
||||
@@ -483,7 +483,7 @@ export default function Dashboard() {
|
||||
{wheelConfig?.is_enabled && (
|
||||
<Link
|
||||
to="/wheel"
|
||||
className="group card-hover flex items-center justify-between"
|
||||
className="group bento-card-hover flex items-center justify-between"
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
{/* Emoji */}
|
||||
@@ -504,7 +504,7 @@ export default function Dashboard() {
|
||||
)}
|
||||
|
||||
{/* Quick Actions */}
|
||||
<div className="card" data-onboarding="quick-actions">
|
||||
<div className="bento-card" data-onboarding="quick-actions">
|
||||
<h3 className="text-lg font-semibold text-dark-100 mb-4">{t('dashboard.quickActions')}</h3>
|
||||
<div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
|
||||
<Link to="/balance" className="btn-secondary justify-center text-center text-sm py-2.5">
|
||||
|
||||
@@ -166,7 +166,7 @@ export default function Info() {
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
{faqPages.map((faq: FaqPage) => (
|
||||
<div key={faq.id} className="card p-0 overflow-hidden">
|
||||
<div key={faq.id} className="bento-card p-0 overflow-hidden">
|
||||
<button
|
||||
onClick={() => toggleFaq(faq.id)}
|
||||
className="w-full px-4 py-3 flex items-center justify-between text-left hover:bg-dark-800/50 transition-colors"
|
||||
@@ -203,7 +203,7 @@ export default function Info() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="card prose prose-invert max-w-none">
|
||||
<div className="bento-card prose prose-invert max-w-none">
|
||||
<div dangerouslySetInnerHTML={{ __html: formatContent(rules.content) }} />
|
||||
{rules.updated_at && (
|
||||
<p className="text-sm text-dark-400 mt-6 pt-4 border-t border-dark-700">
|
||||
@@ -232,7 +232,7 @@ export default function Info() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="card prose prose-invert max-w-none">
|
||||
<div className="bento-card prose prose-invert max-w-none">
|
||||
<div dangerouslySetInnerHTML={{ __html: formatContent(privacy.content) }} />
|
||||
{privacy.updated_at && (
|
||||
<p className="text-sm text-dark-400 mt-6 pt-4 border-t border-dark-700">
|
||||
@@ -261,7 +261,7 @@ export default function Info() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="card prose prose-invert max-w-none">
|
||||
<div className="bento-card prose prose-invert max-w-none">
|
||||
<div dangerouslySetInnerHTML={{ __html: formatContent(offer.content) }} />
|
||||
{offer.updated_at && (
|
||||
<p className="text-sm text-dark-400 mt-6 pt-4 border-t border-dark-700">
|
||||
|
||||
@@ -97,7 +97,7 @@ export default function Profile() {
|
||||
<h1 className="text-2xl sm:text-3xl font-bold text-dark-50">{t('profile.title')}</h1>
|
||||
|
||||
{/* User Info Card */}
|
||||
<div className="card">
|
||||
<div className="bento-card">
|
||||
<h2 className="text-lg font-semibold text-dark-100 mb-6">{t('profile.accountInfo')}</h2>
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center py-3 border-b border-dark-800/50">
|
||||
@@ -126,7 +126,7 @@ export default function Profile() {
|
||||
</div>
|
||||
|
||||
{/* Email Section */}
|
||||
<div className="card">
|
||||
<div className="bento-card">
|
||||
<h2 className="text-lg font-semibold text-dark-100 mb-6">{t('profile.emailAuth')}</h2>
|
||||
|
||||
{user?.email ? (
|
||||
@@ -250,7 +250,7 @@ export default function Profile() {
|
||||
</div>
|
||||
|
||||
{/* Notification Settings */}
|
||||
<div className="card">
|
||||
<div className="bento-card">
|
||||
<h2 className="text-lg font-semibold text-dark-100 mb-6">{t('profile.notifications.title')}</h2>
|
||||
|
||||
{notificationsLoading ? (
|
||||
|
||||
@@ -144,8 +144,8 @@ export default function Referral() {
|
||||
</h1>
|
||||
|
||||
{/* Stats Cards */}
|
||||
<div className='grid grid-cols-2 sm:grid-cols-3 gap-4'>
|
||||
<div className='card'>
|
||||
<div className='bento-grid'>
|
||||
<div className='bento-card-hover'>
|
||||
<div className='text-sm text-dark-400'>
|
||||
{t('referral.stats.totalReferrals')}
|
||||
</div>
|
||||
@@ -155,7 +155,7 @@ export default function Referral() {
|
||||
{t('referral.stats.activeReferrals').toLowerCase()}
|
||||
</div>
|
||||
</div>
|
||||
<div className='card'>
|
||||
<div className='bento-card-hover'>
|
||||
<div className='text-sm text-dark-400'>
|
||||
{t('referral.stats.totalEarnings')}
|
||||
</div>
|
||||
@@ -163,7 +163,7 @@ export default function Referral() {
|
||||
{formatPositive(info?.total_earnings_rubles || 0)}
|
||||
</div>
|
||||
</div>
|
||||
<div className='card col-span-2 sm:col-span-1'>
|
||||
<div className='bento-card-hover col-span-2 sm:col-span-1'>
|
||||
<div className='text-sm text-dark-400'>
|
||||
{t('referral.stats.commissionRate')}
|
||||
</div>
|
||||
@@ -174,7 +174,7 @@ export default function Referral() {
|
||||
</div>
|
||||
|
||||
{/* Referral Link */}
|
||||
<div className='card'>
|
||||
<div className='bento-card'>
|
||||
<h2 className='text-lg font-semibold text-dark-100 mb-4'>
|
||||
{t('referral.yourLink')}
|
||||
</h2>
|
||||
@@ -217,7 +217,7 @@ export default function Referral() {
|
||||
|
||||
{/* Program Terms */}
|
||||
{terms && (
|
||||
<div className='card'>
|
||||
<div className='bento-card'>
|
||||
<h2 className='text-lg font-semibold text-dark-100 mb-4'>
|
||||
{t('referral.terms.title')}
|
||||
</h2>
|
||||
@@ -259,7 +259,7 @@ export default function Referral() {
|
||||
)}
|
||||
|
||||
{/* Referrals List */}
|
||||
<div className='card'>
|
||||
<div className='bento-card'>
|
||||
<h2 className='text-lg font-semibold text-dark-100 mb-4'>
|
||||
{t('referral.yourReferrals')}
|
||||
</h2>
|
||||
@@ -314,7 +314,7 @@ export default function Referral() {
|
||||
|
||||
{/* Earnings History */}
|
||||
{earnings?.items && earnings.items.length > 0 && (
|
||||
<div className='card'>
|
||||
<div className='bento-card'>
|
||||
<h2 className='text-lg font-semibold text-dark-100 mb-4'>
|
||||
{t('referral.earningsHistory')}
|
||||
</h2>
|
||||
|
||||
@@ -426,7 +426,7 @@ export default function Subscription() {
|
||||
|
||||
{/* Current Subscription */}
|
||||
{subscription ? (
|
||||
<div className="card">
|
||||
<div className="bento-card">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold text-dark-100">{t('subscription.currentPlan')}</h2>
|
||||
@@ -631,7 +631,7 @@ export default function Subscription() {
|
||||
|
||||
{/* Daily Subscription Pause */}
|
||||
{subscription && subscription.is_daily && !subscription.is_trial && (
|
||||
<div className="card">
|
||||
<div className="bento-card">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold text-dark-100">{t('subscription.pause.title')}</h2>
|
||||
@@ -730,7 +730,7 @@ export default function Subscription() {
|
||||
|
||||
{/* Additional Options (Buy Devices) */}
|
||||
{subscription && subscription.is_active && !subscription.is_trial && (
|
||||
<div className="card">
|
||||
<div className="bento-card">
|
||||
<h2 className="text-lg font-semibold text-dark-100 mb-4">Дополнительные опции</h2>
|
||||
|
||||
{/* Buy Devices */}
|
||||
@@ -1150,7 +1150,7 @@ export default function Subscription() {
|
||||
|
||||
{/* My Devices Section */}
|
||||
{subscription && (
|
||||
<div className="card">
|
||||
<div className="bento-card">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h2 className="text-lg font-semibold text-dark-100">{t('subscription.myDevices')}</h2>
|
||||
{devicesData && devicesData.devices.length > 0 && (
|
||||
@@ -1220,7 +1220,7 @@ export default function Subscription() {
|
||||
|
||||
{/* Tariffs Section - Combined Purchase/Extend/Switch like MiniApp */}
|
||||
{isTariffsMode && tariffs.length > 0 && (
|
||||
<div ref={tariffsCardRef} className="card">
|
||||
<div ref={tariffsCardRef} className="bento-card">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h2 className="text-lg font-semibold text-dark-100">
|
||||
{subscription?.is_daily && !subscription?.is_trial
|
||||
@@ -1375,10 +1375,10 @@ export default function Subscription() {
|
||||
return (
|
||||
<div
|
||||
key={tariff.id}
|
||||
className={`p-5 rounded-xl border text-left transition-all ${
|
||||
className={`bento-card-hover p-5 text-left transition-all ${
|
||||
isCurrentTariff
|
||||
? 'border-accent-500 bg-accent-500/10'
|
||||
: 'border-dark-700/50 bg-dark-800/30'
|
||||
? 'bento-card-glow border-accent-500'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start justify-between mb-3">
|
||||
@@ -1922,7 +1922,7 @@ export default function Subscription() {
|
||||
|
||||
{/* Purchase/Extend Section - Classic Mode */}
|
||||
{classicOptions && classicOptions.periods.length > 0 && (
|
||||
<div ref={tariffsCardRef} className="card">
|
||||
<div ref={tariffsCardRef} className="bento-card">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h2 className="text-lg font-semibold text-dark-100">
|
||||
{subscription && !subscription.is_trial ? t('subscription.extend') : t('subscription.getSubscription')}
|
||||
@@ -1984,10 +1984,10 @@ export default function Subscription() {
|
||||
setSelectedDevices(period.devices.current)
|
||||
}
|
||||
}}
|
||||
className={`p-4 rounded-xl border text-left transition-all relative ${
|
||||
className={`bento-card-hover p-4 text-left transition-all relative ${
|
||||
selectedPeriod?.id === period.id
|
||||
? 'border-accent-500 bg-accent-500/10'
|
||||
: 'border-dark-700/50 hover:border-dark-600 bg-dark-800/30'
|
||||
? 'bento-card-glow border-accent-500'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
{displayDiscount && displayDiscount > 0 && (
|
||||
@@ -2022,13 +2022,11 @@ export default function Subscription() {
|
||||
key={option.value}
|
||||
onClick={() => setSelectedTraffic(option.value)}
|
||||
disabled={!option.is_available}
|
||||
className={`p-4 rounded-xl border text-center transition-all relative ${
|
||||
className={`bento-card-hover p-4 text-center transition-all relative ${
|
||||
selectedTraffic === option.value
|
||||
? 'border-accent-500 bg-accent-500/10'
|
||||
: option.is_available
|
||||
? 'border-dark-700/50 hover:border-dark-600 bg-dark-800/30'
|
||||
: 'border-dark-800/30 bg-dark-900/30 opacity-50 cursor-not-allowed'
|
||||
}`}
|
||||
? 'bento-card-glow border-accent-500'
|
||||
: ''
|
||||
} ${!option.is_available ? 'opacity-50 cursor-not-allowed' : ''}`}
|
||||
>
|
||||
{promoTraffic.percent && (
|
||||
<div className="absolute -top-2 -right-2 px-2 py-0.5 bg-orange-500 text-white text-xs font-medium rounded-full">
|
||||
|
||||
@@ -385,7 +385,7 @@ export default function Support() {
|
||||
|
||||
return (
|
||||
<div className="max-w-md mx-auto mt-12">
|
||||
<div className="card text-center">
|
||||
<div className="bento-card text-center">
|
||||
<div className="w-16 h-16 mx-auto mb-4 rounded-2xl bg-dark-800 flex items-center justify-center">
|
||||
<svg className="w-8 h-8 text-dark-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M8.625 12a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H8.25m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H12m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0h-.375M21 12c0 4.556-4.03 8.25-9 8.25a9.764 9.764 0 01-2.555-.337A5.972 5.972 0 015.41 20.97a5.969 5.969 0 01-.474-.065 4.48 4.48 0 00.978-2.025c.09-.457-.133-.901-.467-1.226C3.93 16.178 3 14.189 3 12c0-4.556 4.03-8.25 9-8.25s9 3.694 9 8.25z" />
|
||||
@@ -454,7 +454,7 @@ export default function Support() {
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
{/* Tickets List */}
|
||||
<div className="lg:col-span-1 card">
|
||||
<div className="lg:col-span-1 bento-card">
|
||||
<h2 className="text-lg font-semibold text-dark-100 mb-4">{t('support.yourTickets')}</h2>
|
||||
|
||||
{isLoading ? (
|
||||
@@ -471,7 +471,7 @@ export default function Support() {
|
||||
setShowCreateForm(false)
|
||||
setReplyAttachment(null)
|
||||
}}
|
||||
className={`w-full text-left p-4 rounded-xl border transition-all ${
|
||||
className={`w-full text-left p-4 rounded-bento border transition-all ${
|
||||
selectedTicket?.id === ticket.id
|
||||
? 'border-accent-500 bg-accent-500/10'
|
||||
: 'border-dark-700/50 hover:border-dark-600 bg-dark-800/30'
|
||||
@@ -502,7 +502,7 @@ export default function Support() {
|
||||
</div>
|
||||
|
||||
{/* Ticket Detail / Create Form */}
|
||||
<div className="lg:col-span-2 card">
|
||||
<div className="lg:col-span-2 bento-card">
|
||||
{showCreateForm ? (
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold text-dark-100 mb-6">{t('support.createTicket')}</h2>
|
||||
|
||||
@@ -692,7 +692,7 @@ export default function Wheel() {
|
||||
|
||||
{/* Result Modal */}
|
||||
{showResultModal && spinResult && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/80 backdrop-blur-md animate-fade-in">
|
||||
<div className="fixed inset-0 z-[60] flex items-center justify-center p-4 bg-black/80 backdrop-blur-md animate-fade-in">
|
||||
<div
|
||||
className={`relative w-full max-w-md rounded-3xl p-8 text-center overflow-hidden ${
|
||||
spinResult.success
|
||||
|
||||
Reference in New Issue
Block a user