diff --git a/src/components/ConnectionModal.tsx b/src/components/ConnectionModal.tsx index 68cd8de..58662e6 100644 --- a/src/components/ConnectionModal.tsx +++ b/src/components/ConnectionModal.tsx @@ -386,8 +386,11 @@ export default function ConnectionModal({ onClose }: ConnectionModalProps) { // Main view return ( - {/* Header - app selector */} -
+
+

{t('subscription.connection.title')}

+
+ +
-
- {/* Payment options */} - {hasOptions && method.options && ( -
- {method.options.map((opt) => ( - - ))} -
- )} - - {/* Amount input */} -
- setAmount(e.target.value)} - placeholder={`${formatAmount(minRubles, 0)} – ${formatAmount(maxRubles, 0)}`} - className="w-full h-12 px-4 pr-12 text-lg font-semibold bg-dark-800 border border-dark-700 rounded-xl text-dark-100 placeholder:text-dark-500 focus:outline-none focus:border-accent-500" - autoComplete="off" - /> - - {currencySymbol} - -
- - {/* Quick amounts */} +
{quickAmounts.length > 0 && ( -
+
{quickAmounts.map((a) => { const val = getQuickValue(a) + const isSelected = amount === val + return ( - + + {formatAmount(a, 0)} + + + {currencySymbol} + + ) })}
)} - {/* Error */} - {error && ( -
{error}
+
+
+ + + {formatAmount(minRubles, 0)} – {formatAmount(maxRubles, 0)} {currencySymbol} + +
+ +
+
+
+ setAmount(e.target.value)} + placeholder="0" + className="w-full h-14 pl-5 pr-12 text-2xl font-bold bg-transparent text-dark-50 placeholder:text-dark-600 focus:outline-none" + autoComplete="off" + /> +
+ + {currencySymbol} + +
+
+
+
+ + {hasOptions && method.options && ( +
+ +
+ {method.options.map((opt) => { + const isSelected = selectedOption === opt.id + return ( + + ) + })} +
+
+ )} + + {error && ( +
+
+ + + +
+

{error}

+
)} - {/* Submit */}
@@ -285,3 +340,4 @@ export default function TopUpModal({ method, onClose, initialAmountRubles }: Top } return modalContent } + diff --git a/src/data/colorPresets.ts b/src/data/colorPresets.ts index f272f23..0cee321 100644 --- a/src/data/colorPresets.ts +++ b/src/data/colorPresets.ts @@ -7,7 +7,6 @@ export interface ColorPreset { description: string descriptionRu: string colors: ThemeColors - // Preview colors for the card preview: { background: string accent: string @@ -28,10 +27,10 @@ export const COLOR_PRESETS: ColorPreset[] = [ darkSurface: '#0f172a', darkText: '#f1f5f9', darkTextSecondary: '#94a3b8', - lightBackground: '#f8fafc', + lightBackground: '#f1f5f9', lightSurface: '#ffffff', lightText: '#0f172a', - lightTextSecondary: '#64748b', + lightTextSecondary: '#475569', success: '#22c55e', warning: '#f59e0b', error: '#ef4444', @@ -56,7 +55,7 @@ export const COLOR_PRESETS: ColorPreset[] = [ darkTextSecondary: '#64748b', lightBackground: '#f0fdf4', lightSurface: '#ffffff', - lightText: '#052e16', + lightText: '#14532d', lightTextSecondary: '#166534', success: '#22c55e', warning: '#eab308', @@ -82,8 +81,8 @@ export const COLOR_PRESETS: ColorPreset[] = [ darkTextSecondary: '#a1a1aa', lightBackground: '#faf5ff', lightSurface: '#ffffff', - lightText: '#1e1b29', - lightTextSecondary: '#6b21a8', + lightText: '#3b0764', + lightTextSecondary: '#581c87', success: '#22c55e', warning: '#f59e0b', error: '#ef4444', @@ -108,8 +107,8 @@ export const COLOR_PRESETS: ColorPreset[] = [ darkTextSecondary: '#a3a3a3', lightBackground: '#fff7ed', lightSurface: '#ffffff', - lightText: '#1c1917', - lightTextSecondary: '#c2410c', + lightText: '#7c2d12', + lightTextSecondary: '#9a3412', success: '#22c55e', warning: '#f59e0b', error: '#ef4444', @@ -135,7 +134,7 @@ export const COLOR_PRESETS: ColorPreset[] = [ lightBackground: '#f0fdfa', lightSurface: '#ffffff', lightText: '#134e4a', - lightTextSecondary: '#0f766e', + lightTextSecondary: '#115e59', success: '#22c55e', warning: '#f59e0b', error: '#ef4444', @@ -158,18 +157,122 @@ export const COLOR_PRESETS: ColorPreset[] = [ darkSurface: '#0f172a', darkText: '#f1f5f9', darkTextSecondary: '#94a3b8', - lightBackground: '#F7E7CE', - lightSurface: '#FEF9F0', - lightText: '#1F1A12', - lightTextSecondary: '#7D6B48', + lightBackground: '#fefce8', + lightSurface: '#ffffff', + lightText: '#713f12', + lightTextSecondary: '#92400e', success: '#22c55e', warning: '#f59e0b', error: '#ef4444', }, preview: { - background: '#F7E7CE', + background: '#0a0f1a', accent: '#b8860b', - text: '#1F1A12', + text: '#f1f5f9', + }, + }, + { + id: 'quantum-teal', + name: 'Quantum Teal', + nameRu: 'Квантовый бирюзовый', + description: 'Bio-synthetic, futuristic fintech', + descriptionRu: 'Био-синтетический, футуристичный финтех', + colors: { + accent: '#0d9488', + darkBackground: '#0f172a', + darkSurface: '#1e293b', + darkText: '#f1f5f9', + darkTextSecondary: '#94a3b8', + lightBackground: '#f0fdfa', + lightSurface: '#ffffff', + lightText: '#134e4a', + lightTextSecondary: '#0f766e', + success: '#22c55e', + warning: '#f59e0b', + error: '#ef4444', + }, + preview: { + background: '#0f172a', + accent: '#0d9488', + text: '#f1f5f9', + }, + }, + { + id: 'cosmic-violet', + name: 'Cosmic Violet', + nameRu: 'Космический фиолет', + description: 'Digital lavender, wellness vibes', + descriptionRu: 'Цифровая лаванда, атмосфера спокойствия', + colors: { + accent: '#7c3aed', + darkBackground: '#0b0d10', + darkSurface: '#18181b', + darkText: '#f4f4f5', + darkTextSecondary: '#a1a1aa', + lightBackground: '#faf5ff', + lightSurface: '#ffffff', + lightText: '#3b0764', + lightTextSecondary: '#5b21b6', + success: '#22c55e', + warning: '#f59e0b', + error: '#ef4444', + }, + preview: { + background: '#0b0d10', + accent: '#7c3aed', + text: '#f4f4f5', + }, + }, + { + id: 'solar-coral', + name: 'Solar Coral', + nameRu: 'Солнечный коралл', + description: 'Hyper-coral, high energy social', + descriptionRu: 'Гипер-коралловый, энергия соцсетей', + colors: { + accent: '#ea580c', + darkBackground: '#18181b', + darkSurface: '#27272a', + darkText: '#fafafa', + darkTextSecondary: '#a1a1aa', + lightBackground: '#fff7ed', + lightSurface: '#ffffff', + lightText: '#7c2d12', + lightTextSecondary: '#9a3412', + success: '#22c55e', + warning: '#f59e0b', + error: '#ef4444', + }, + preview: { + background: '#18181b', + accent: '#ea580c', + text: '#fafafa', + }, + }, + { + id: 'frost-blue', + name: 'Frost Blue', + nameRu: 'Морозный синий', + description: 'Liquid chrome, enterprise trust', + descriptionRu: 'Жидкий хром, корпоративное доверие', + colors: { + accent: '#0284c7', + darkBackground: '#0b0d10', + darkSurface: '#1e293b', + darkText: '#f1f5f9', + darkTextSecondary: '#94a3b8', + lightBackground: '#f0f9ff', + lightSurface: '#ffffff', + lightText: '#0c4a6e', + lightTextSecondary: '#075985', + success: '#22c55e', + warning: '#f59e0b', + error: '#ef4444', + }, + preview: { + background: '#0b0d10', + accent: '#0284c7', + text: '#f1f5f9', }, }, ] diff --git a/src/pages/Balance.tsx b/src/pages/Balance.tsx index eb8b5c2..6e0c10e 100644 --- a/src/pages/Balance.tsx +++ b/src/pages/Balance.tsx @@ -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>({ queryKey: ['transactions', transactionsPage], @@ -201,88 +202,104 @@ export default function Balance() {
)} - {/* Transaction History */} -
-

{t('balance.transactionHistory')}

+
+ - {isLoading ? ( -
-
-
- ) : transactions?.items && transactions.items.length > 0 ? ( -
- {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 ( -
-
-
- - {getTypeLabel(tx.type)} - - - {new Date(tx.created_at).toLocaleDateString()} - -
- {tx.description && ( -
{tx.description}
- )} -
-
- {sign}{formatAmount(displayAmount)} {currencySymbol} -
+ {isHistoryOpen && ( +
+ {isLoading ? ( +
+
- ) - })} -
- ) : ( -
-
- - - -
-
{t('balance.noTransactions')}
-
- )} + ) : transactions?.items && transactions.items.length > 0 ? ( +
+ {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 && ( -
- -
- {t('balance.page', { current: transactions.page, total: transactions.pages })} -
- + return ( +
+
+
+ + {getTypeLabel(tx.type)} + + + {new Date(tx.created_at).toLocaleDateString()} + +
+ {tx.description && ( +
{tx.description}
+ )} +
+
+ {sign}{formatAmount(displayAmount)} {currencySymbol} +
+
+ ) + })} +
+ ) : ( +
+
+ + + +
+
{t('balance.noTransactions')}
+
+ )} + + {transactions && transactions.pages > 1 && ( +
+ +
+ {t('balance.page', { current: transactions.page, total: transactions.pages })} +
+ +
+ )}
)}