79 lines
2.7 KiB
TypeScript
79 lines
2.7 KiB
TypeScript
import { Link } from 'react-router-dom'
|
||
import { Header } from '@widgets/header'
|
||
import { Footer } from '@widgets/footer'
|
||
import { TokenIcon } from '@shared/ui/TokenIcon'
|
||
import { ROUTES } from '@shared/config/routes'
|
||
import styles from './NotFoundPage.module.css'
|
||
|
||
/** Decorative coin set — purely visual, no live rates. */
|
||
const COINS = [
|
||
{ letter: '₿', color: '#f7931a' },
|
||
{ letter: 'Ξ', color: '#627eea' },
|
||
{ letter: '₮', color: '#26a17b' },
|
||
{ letter: '◎', color: '#9945ff' },
|
||
{ letter: '$', color: '#2775ca' },
|
||
{ letter: '₽', color: '#4a6dff' },
|
||
{ letter: 'Ʉ', color: '#00d4ff' },
|
||
]
|
||
|
||
/** Pre-baked rain layout so the scene looks the same on every render. */
|
||
const RAIN = [
|
||
{ left: 6, size: 34, delay: 0, duration: 7.5 },
|
||
{ left: 18, size: 26, delay: 2.1, duration: 9 },
|
||
{ left: 29, size: 44, delay: 4.3, duration: 6.5 },
|
||
{ left: 41, size: 22, delay: 1.2, duration: 10 },
|
||
{ left: 54, size: 38, delay: 3.4, duration: 8 },
|
||
{ left: 67, size: 28, delay: 0.6, duration: 9.5 },
|
||
{ left: 78, size: 48, delay: 2.8, duration: 7 },
|
||
{ left: 88, size: 24, delay: 5, duration: 8.5 },
|
||
{ left: 95, size: 32, delay: 1.7, duration: 9.2 },
|
||
]
|
||
|
||
export function NotFoundPage() {
|
||
return (
|
||
<>
|
||
<Header />
|
||
<main className={styles.page}>
|
||
<div className={styles.rain} aria-hidden="true">
|
||
{RAIN.map((coin, i) => {
|
||
const token = COINS[i % COINS.length]
|
||
return (
|
||
<span
|
||
key={i}
|
||
className={styles.drop}
|
||
style={{
|
||
left: `${coin.left}%`,
|
||
animationDelay: `${coin.delay}s`,
|
||
animationDuration: `${coin.duration}s`,
|
||
}}
|
||
>
|
||
<TokenIcon letter={token.letter} color={token.color} size={coin.size} />
|
||
</span>
|
||
)
|
||
})}
|
||
</div>
|
||
|
||
<div className={styles.content}>
|
||
<div className={styles.code} aria-hidden="true">
|
||
<span className={styles.digit}>4</span>
|
||
<span className={styles.coin}>
|
||
<TokenIcon letter="₿" color="#f7931a" size={140} />
|
||
</span>
|
||
<span className={styles.digit}>4</span>
|
||
</div>
|
||
|
||
<h1 className={styles.title}>Такой страницы не существует</h1>
|
||
<p className={styles.subtitle}>
|
||
Похоже, курс этого маршрута обнулился. Проверьте адрес или вернитесь на главную.
|
||
</p>
|
||
|
||
<Link to={ROUTES.HOME} className={styles.button}>
|
||
На главную
|
||
</Link>
|
||
</div>
|
||
</main>
|
||
<Footer />
|
||
</>
|
||
)
|
||
}
|