|
- import { AnimatePresence, LayoutGroup } from 'framer-motion'
- import { useEffect, useState } from 'react'
- import { BrowserRouter,
- Navigate,
- Route,
- Routes,
- useLocation } from 'react-router-dom'
-
- import RouteBlockerOverlay from '@/components/RouteBlockerOverlay'
- import TopNav from '@/components/TopNav'
- import { Toaster } from '@/components/ui/toaster'
- import { apiPost, isApiError } from '@/lib/api'
- import NicoTagListPage from '@/pages/tags/NicoTagListPage'
- import NotFound from '@/pages/NotFound'
- import PostDetailPage from '@/pages/posts/PostDetailPage'
- import PostHistoryPage from '@/pages/posts/PostHistoryPage'
- import PostListPage from '@/pages/posts/PostListPage'
- import PostNewPage from '@/pages/posts/PostNewPage'
- import ServiceUnavailable from '@/pages/ServiceUnavailable'
- import SettingPage from '@/pages/users/SettingPage'
- import WikiDetailPage from '@/pages/wiki/WikiDetailPage'
- import WikiDiffPage from '@/pages/wiki/WikiDiffPage'
- import WikiEditPage from '@/pages/wiki/WikiEditPage'
- import WikiHistoryPage from '@/pages/wiki/WikiHistoryPage'
- import WikiNewPage from '@/pages/wiki/WikiNewPage'
- import WikiSearchPage from '@/pages/wiki/WikiSearchPage'
-
- import type { Dispatch, FC, SetStateAction } from 'react'
-
- import type { User } from '@/types'
-
-
- const RouteTransitionWrapper = ({ user, setUser }: {
- user: User | null
- setUser: Dispatch<SetStateAction<User | null>> }) => {
- const location = useLocation ()
-
- return (
- <LayoutGroup id="gallery-shared">
- <AnimatePresence mode="wait">
- <Routes location={location} key={location.pathname}>
- <Route path="/" element={<Navigate to="/posts" replace/>}/>
- <Route path="/posts" element={<PostListPage/>}/>
- <Route path="/posts/new" element={<PostNewPage user={user}/>}/>
- <Route path="/posts/:id" element={<PostDetailRoute user={user}/>}/>
- <Route path="/posts/changes" element={<PostHistoryPage/>}/>
- <Route path="/tags/nico" element={<NicoTagListPage user={user}/>}/>
- <Route path="/wiki" element={<WikiSearchPage/>}/>
- <Route path="/wiki/:title" element={<WikiDetailPage/>}/>
- <Route path="/wiki/new" element={<WikiNewPage user={user}/>}/>
- <Route path="/wiki/:id/edit" element={<WikiEditPage user={user}/>}/>
- <Route path="/wiki/:id/diff" element={<WikiDiffPage/>}/>
- <Route path="/wiki/changes" element={<WikiHistoryPage/>}/>
- <Route path="/users/settings" element={<SettingPage user={user} setUser={setUser}/>}/>
- <Route path="/settings" element={<Navigate to="/users/settings" replace/>}/>
- <Route path="*" element={<NotFound/>}/>
- </Routes>
- </AnimatePresence>
- </LayoutGroup>)
- }
-
-
- const PostDetailRoute = ({ user }: { user: User | null }) => {
- const location = useLocation ()
- const key = location.pathname
- return <PostDetailPage key={key} user={user}/>
- }
-
-
- export default (() => {
- const [user, setUser] = useState<User | null> (null)
- const [status, setStatus] = useState (200)
-
- useEffect (() => {
- const createUser = async () => {
- const data = await apiPost<{ code: string; user: User }> ('/users')
- if (data.code)
- {
- localStorage.setItem ('user_code', data.code)
- setUser (data.user)
- }
- }
-
- const code = localStorage.getItem ('user_code')
- if (code)
- {
- void (async () => {
- try
- {
- const data = await apiPost<{ valid: boolean; user: User }> ('/users/verify', { code })
- if (data.valid)
- setUser (data.user)
- else
- await createUser ()
- }
- catch (err)
- {
- if (isApiError (err))
- setStatus (err.response?.status ?? 200)
- }
- }) ()
- }
- else
- createUser ()
- }, [])
-
- switch (status)
- {
- case 503:
- return <ServiceUnavailable/>
- }
-
- return (
- <>
- <RouteBlockerOverlay/>
- <BrowserRouter>
- <div className="flex flex-col h-screen w-screen">
- <TopNav user={user}/>
- <RouteTransitionWrapper user={user} setUser={setUser}/>
- </div>
- <Toaster/>
- </BrowserRouter>
- </>)
- }) satisfies FC
|