Sergey Krylov cfadb2adbe feat: migrate from react-router-dom to @tanstack/react-router (code-first)
- Create code-first route tree in src/app/routing/routeTree.tsx
- Replace ProtectedRoute with beforeLoad auth guards
- Add useSearchParamsCompat for URLSearchParams access
- Update App.tsx, layouts, and all page/widget imports
- Add frontend tooling: biome, prettier, env config
- Update all tests for TanStack Router compatibility
- Remove react-router-dom dependency, @tanstack/router-plugin
- Consolidate biome config at root level
2026-06-23 06:51:48 +03:00

143 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Link, Outlet, useNavigate } from '@tanstack/react-router'
import { useSession } from '@/entities/session'
import { SearchBar } from '@/widgets/search-bar'
export function AppLayout() {
const { isAuthenticated, user, logout } = useSession()
const navigate = useNavigate()
async function handleLogout() {
await logout()
navigate('/')
}
return (
<div style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column' }}>
<header
style={{
background: 'var(--color-surface)',
borderBottom: '1px solid #e0e0e0',
padding: '12px 24px',
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap',
gap: 24,
}}
>
<Link
to="/"
style={{
fontSize: 20,
fontWeight: 700,
color: 'var(--color-text)',
textDecoration: 'none',
}}
>
MoexVibe
</Link>
<div style={{ flex: '1 1 280px', minWidth: 220, maxWidth: 420 }}>
<SearchBar />
</div>
<Link
to="/portfolios"
style={{
fontSize: 14,
color: 'var(--color-text)',
textDecoration: 'none',
fontWeight: 500,
}}
>
Портфели
</Link>
<Link
to="/broker"
style={{
fontSize: 14,
color: 'var(--color-text)',
textDecoration: 'none',
fontWeight: 500,
}}
>
Брокер
</Link>
<Link
to="/screener"
style={{
fontSize: 14,
color: 'var(--color-text)',
textDecoration: 'none',
fontWeight: 500,
}}
>
Скринер
</Link>
<div
style={{
marginLeft: 'auto',
display: 'flex',
alignItems: 'center',
gap: 12,
flexWrap: 'wrap',
}}
>
{isAuthenticated ? (
<>
<Link
to="/profile"
style={{
fontSize: 14,
color: 'var(--color-text)',
textDecoration: 'none',
}}
>
{user?.name || user?.email}
</Link>
<button
onClick={handleLogout}
style={{
padding: '6px 16px',
background: 'transparent',
color: 'var(--color-text-secondary)',
border: '1px solid #e0e0e0',
borderRadius: 'var(--border-radius)',
fontSize: 14,
cursor: 'pointer',
}}
>
Выйти
</button>
</>
) : (
<Link
to="/login"
style={{
padding: '6px 16px',
background: 'var(--color-primary)',
color: '#fff',
textDecoration: 'none',
borderRadius: 'var(--border-radius)',
fontSize: 14,
fontWeight: 600,
}}
>
Войти
</Link>
)}
</div>
</header>
<main
style={{
flex: 1,
padding: 'clamp(16px, 4vw, 24px)',
maxWidth: 1200,
width: '100%',
margin: '0 auto',
}}
>
<Outlet />
</main>
</div>
)
}