lolakd's picture
Создай полноценный frontend для проекта **LobsterTube** — полной копии YouTube, с современным дизайном, максимально приближённым к оригиналу YouTube (2025 года).
9f82044 verified
```typescript
import { Routes, Route } from 'react-router-dom'
import { useEffect } from 'react'
import { useAppDispatch, useAppSelector } from './hooks/redux'
import { fetchUser } from './store/slices/authSlice'
import { setTheme } from './store/slices/themeSlice'
// Layouts
import MainLayout from './components/layouts/MainLayout'
import AuthLayout from './components/layouts/AuthLayout'
// Pages
import HomePage from './pages/HomePage'
import WatchPage from './pages/WatchPage'
import ChannelPage from './pages/ChannelPage'
import SearchPage from './pages/SearchPage'
import UploadPage from './pages/UploadPage'
import LoginPage from './pages/LoginPage'
import RegisterPage from './pages/RegisterPage'
import NotFoundPage from './pages/NotFoundPage'
function App() {
const dispatch = useAppDispatch()
const { user, isLoading } = useAppSelector((state) => state.auth)
const { theme } = useAppSelector((state) => state.theme)
useEffect(() => {
// Initialize theme
const savedTheme = localStorage.getItem('theme') as 'light' | 'dark' || 'light'
dispatch(setTheme(savedTheme))
document.documentElement.classList.toggle('dark', savedTheme === 'dark')
// Check for existing token and fetch user
const token = localStorage.getItem('token')
if (token && !user) {
dispatch(fetchUser())
}
}, [dispatch, user])
useEffect(() => {
// Apply theme changes
document.documentElement.classList.toggle('dark', theme === 'dark')
localStorage.setItem('theme', theme)
}, [theme])
if (isLoading) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="animate-spin rounded-full h-32 w-32 border-b-2 border-youtube-red"></div>
</div>
)
}
return (
<div className="min-h-screen bg-youtube-light dark:bg-youtube-dark">
<Routes>
<Route path="/" element={<MainLayout />}>
<Route index element={<HomePage />} />
<Route path="watch/:id" element={<WatchPage />} />
<Route path="channel/:id" element={<ChannelPage />} />
<Route path="search" element={<SearchPage />} />
<Route path="upload" element={<UploadPage />} />
</Route>
<Route path="/auth" element={<AuthLayout />}>
<Route path="login" element={<LoginPage />} />
<Route path="register" element={<RegisterPage />} />
</Route>
<Route path="*" element={<NotFoundPage />} />
</Routes>
</div>
)
}
export default App
```
Теперь создам Redux store и slices: