17.05.2026 funny
This commit is contained in:
@@ -26,9 +26,8 @@ export function RouterProvider() {
|
|||||||
<Route path={ROUTES.REGISTER} element={<RegisterPage />} />
|
<Route path={ROUTES.REGISTER} element={<RegisterPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path={ROUTES.CONVERTER} element={<ConverterPage />} />
|
|
||||||
|
|
||||||
<Route element={<ProtectedRoute />}>
|
<Route element={<ProtectedRoute />}>
|
||||||
|
<Route path={ROUTES.CONVERTER} element={<ConverterPage />} />
|
||||||
<Route path={ROUTES.WALLET} element={<WalletPage />} />
|
<Route path={ROUTES.WALLET} element={<WalletPage />} />
|
||||||
<Route path={ROUTES.SWAP} element={<SwapPage />} />
|
<Route path={ROUTES.SWAP} element={<SwapPage />} />
|
||||||
<Route path={ROUTES.BRIDGE} element={<BridgePage />} />
|
<Route path={ROUTES.BRIDGE} element={<BridgePage />} />
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { useMe } from '@features/auth'
|
import { useMe } from '@features/auth'
|
||||||
|
import { usePortfolio } from '@features/wallet'
|
||||||
|
import { ROUTES } from '@shared/config/routes'
|
||||||
import { Button, FormField } from '@shared/ui'
|
import { Button, FormField } from '@shared/ui'
|
||||||
import { WalletHeader } from '@widgets/wallet-header'
|
import { WalletHeader } from '@widgets/wallet-header'
|
||||||
import { ProfileAvatar, ProfileSection } from '@widgets/profile'
|
import { ProfileAvatar, ProfileSection } from '@widgets/profile'
|
||||||
@@ -6,11 +9,19 @@ import styles from './ProfilePage.module.css'
|
|||||||
|
|
||||||
export function ProfilePage() {
|
export function ProfilePage() {
|
||||||
const { data } = useMe()
|
const { data } = useMe()
|
||||||
|
const { data: portfolio, isLoading: isPortfolioLoading } = usePortfolio()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
const capitalize = (s: string) => (s ? s[0].toUpperCase() + s.slice(1).toLowerCase() : '')
|
||||||
const fullName = data
|
const fullName = data
|
||||||
? [data.last_name, data.first_name, data.middle_name].filter(Boolean).join(' ')
|
? [data.last_name, data.first_name, data.middle_name].filter(Boolean).map(capitalize).join(' ')
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
|
const userBalance =
|
||||||
|
isPortfolioLoading || !portfolio || portfolio.totalUsd == null
|
||||||
|
? '$—'
|
||||||
|
: `$${portfolio.totalUsd.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.page}>
|
<div className={styles.page}>
|
||||||
<WalletHeader />
|
<WalletHeader />
|
||||||
@@ -24,8 +35,8 @@ export function ProfilePage() {
|
|||||||
<ProfileAvatar />
|
<ProfileAvatar />
|
||||||
<div className={styles.userInfo}>
|
<div className={styles.userInfo}>
|
||||||
<span className={styles.userName}>{fullName}</span>
|
<span className={styles.userName}>{fullName}</span>
|
||||||
<span className={styles.userBalance}>$245.00</span>
|
<span className={styles.userBalance}>{userBalance}</span>
|
||||||
<span className={styles.userBalanceRub}>≈ 22 340,50 ₽</span>
|
{/* <span className={styles.userBalanceRub}>≈ 22 340,50 ₽</span> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -66,7 +77,7 @@ export function ProfilePage() {
|
|||||||
<span className={styles.mnemonicIcon}>🔑</span>
|
<span className={styles.mnemonicIcon}>🔑</span>
|
||||||
<span className={styles.mnemonicText}>Сид-фраза из 12 слов для восстановления кошелька</span>
|
<span className={styles.mnemonicText}>Сид-фраза из 12 слов для восстановления кошелька</span>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="danger">⚠ Показать мнемонику</Button>
|
<Button variant="danger" onClick={() => navigate(ROUTES.SEED_PHRASE)}>⚠ Показать мнемонику</Button>
|
||||||
</div>
|
</div>
|
||||||
</ProfileSection>
|
</ProfileSection>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export function ConverterSection() {
|
|||||||
>
|
>
|
||||||
КУПИТЬ
|
КУПИТЬ
|
||||||
</button>
|
</button>
|
||||||
<button
|
{/* <button
|
||||||
type="button"
|
type="button"
|
||||||
disabled
|
disabled
|
||||||
className={styles.tab}
|
className={styles.tab}
|
||||||
@@ -69,7 +69,7 @@ export function ConverterSection() {
|
|||||||
onClick={() => c.setMode('sell')}
|
onClick={() => c.setMode('sell')}
|
||||||
>
|
>
|
||||||
ПРОДАТЬ
|
ПРОДАТЬ
|
||||||
</button>
|
</button> */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.field}>
|
<div className={styles.field}>
|
||||||
@@ -141,7 +141,7 @@ export function ConverterSection() {
|
|||||||
type="button"
|
type="button"
|
||||||
className={styles.payBtn}
|
className={styles.payBtn}
|
||||||
onClick={handlePay}
|
onClick={handlePay}
|
||||||
disabled={!rubTotal || isPending}
|
disabled={!rubTotal || isPending || !c.agreed}
|
||||||
>
|
>
|
||||||
{isPending ? 'Обработка...' : 'Оплатить'}
|
{isPending ? 'Обработка...' : 'Оплатить'}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -7,14 +7,21 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'
|
|||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { logout } from '@features/auth/api/registrationApi'
|
import { logout } from '@features/auth/api/registrationApi'
|
||||||
import { AUTH_QUERY_KEY, useMe } from '@features/auth'
|
import { AUTH_QUERY_KEY, useMe } from '@features/auth'
|
||||||
|
import { usePrices } from '@features/wallet'
|
||||||
import { tokenStore } from '@shared/api/tokenStore'
|
import { tokenStore } from '@shared/api/tokenStore'
|
||||||
import { Notification } from '@shared/ui'
|
import { Notification } from '@shared/ui'
|
||||||
|
|
||||||
const TICKERS = [
|
const TICKER_SYMBOLS = ['BTC', 'ETH', 'SOL']
|
||||||
{ symbol: 'BTC', price: '$66,916.00', change: 0.12, },
|
|
||||||
{ symbol: 'ETH', price: '$2,053.97', change: -0.12 },
|
const capitalize = (s: string) => (s ? s[0].toUpperCase() + s.slice(1).toLowerCase() : '')
|
||||||
{ symbol: 'SOL', price: '$163.84', change: -1.57 },
|
|
||||||
]
|
function formatPrice(value: number | null | undefined): string {
|
||||||
|
if (value == null) return '$—'
|
||||||
|
if (value >= 1) {
|
||||||
|
return `$${value.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
|
||||||
|
}
|
||||||
|
return `$${value.toLocaleString('en-US', { minimumFractionDigits: 4, maximumFractionDigits: 6 })}`
|
||||||
|
}
|
||||||
|
|
||||||
export function WalletHeader() {
|
export function WalletHeader() {
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
@@ -23,7 +30,10 @@ export function WalletHeader() {
|
|||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const { data: me } = useMe()
|
const { data: me } = useMe()
|
||||||
const fullName = me ? `${me.first_name} ${me.middle_name}`.trim() : ''
|
const { data: prices } = usePrices(TICKER_SYMBOLS)
|
||||||
|
const fullName = me
|
||||||
|
? [me.first_name, me.middle_name].filter(Boolean).map(capitalize).join(' ')
|
||||||
|
: ''
|
||||||
|
|
||||||
const { mutate: logoutMutate } = useMutation({
|
const { mutate: logoutMutate } = useMutation({
|
||||||
mutationFn: logout,
|
mutationFn: logout,
|
||||||
@@ -57,13 +67,10 @@ export function WalletHeader() {
|
|||||||
<img src={logo} alt="ЭКСА" />
|
<img src={logo} alt="ЭКСА" />
|
||||||
</a>
|
</a>
|
||||||
<div className={styles.ticker}>
|
<div className={styles.ticker}>
|
||||||
{TICKERS.map(({ symbol, price, change }) => (
|
{TICKER_SYMBOLS.map((symbol) => (
|
||||||
<div key={symbol} className={styles.tick}>
|
<div key={symbol} className={styles.tick}>
|
||||||
<b>{symbol}</b>
|
<b>{symbol}</b>
|
||||||
<span>{price}</span>
|
<span>{formatPrice(prices?.[symbol]?.usd)}</span>
|
||||||
<span className={change >= 0 ? styles.up : styles.dn}>
|
|
||||||
{change >= 0 ? '+' : ''}{change}%
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user