|
- import { useQuery } from '@tanstack/react-query'
- import { useEffect, useMemo } from 'react'
- import { Helmet } from 'react-helmet-async'
- import { useLocation, useNavigate, useParams } from 'react-router-dom'
-
- import PostList from '@/components/PostList'
- import PrefetchLink from '@/components/PrefetchLink'
- import TagLink from '@/components/TagLink'
- import WikiBody from '@/components/WikiBody'
- import PageTitle from '@/components/common/PageTitle'
- import TabGroup, { Tab } from '@/components/common/TabGroup'
- import MainArea from '@/components/layout/MainArea'
- import { SITE_TITLE } from '@/config'
- import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'
- import { fetchPosts } from '@/lib/posts'
- import { postsKeys, tagsKeys, wikiKeys } from '@/lib/queryKeys'
- import { fetchTagByName } from '@/lib/tags'
- import { fetchWikiPage, fetchWikiPageByTitle } from '@/lib/wiki'
-
- import type { Tag } from '@/types'
-
-
- export default () => {
- const params = useParams ()
- const title = params.title ?? ''
-
- const location = useLocation ()
- const navigate = useNavigate ()
-
- const defaultTag = useMemo (() => ({ name: title, category: 'general' } as Tag), [title])
-
- const query = new URLSearchParams (location.search)
- const version = query.get ('version') || undefined
-
- const { data: wikiPage, isLoading: loading } = useQuery ({
- enabled: Boolean (title) && !(/^\d+$/.test (title)),
- queryKey: wikiKeys.show (title, { version }),
- queryFn: () => fetchWikiPageByTitle (title, { version }) })
-
- const effectiveTitle = wikiPage?.title ?? title
-
- const { data: tag } = useQuery ({
- enabled: Boolean (effectiveTitle),
- queryKey: tagsKeys.show (effectiveTitle),
- queryFn: () => fetchTagByName (effectiveTitle) })
-
- const { data } = useQuery ({
- enabled: Boolean (effectiveTitle) && !(version),
- queryKey: postsKeys.index ({ tags: effectiveTitle, match: 'all', page: 1, limit: 8 }),
- queryFn: () => fetchPosts ({ tags: effectiveTitle, match: 'all', page: 1, limit: 8 }) })
- const posts = data?.posts || []
-
- useEffect (() => {
- if (!(wikiPage))
- return
-
- WikiIdBus.set (wikiPage.id)
-
- if (wikiPage.title !== title)
- navigate (`/wiki/${ encodeURIComponent(wikiPage.title) }`, { replace: true })
-
- return () => WikiIdBus.set (null)
- }, [wikiPage, title, navigate])
-
- useEffect (() => {
- if (!(/^\d+$/.test (title)))
- return
-
- void (async () => {
- try
- {
- const data = await fetchWikiPage (title, { })
- navigate (`/wiki/${ encodeURIComponent(data.title) }`, { replace: true })
- }
- catch
- {
- ;
- }
- }) ()
- }, [title, navigate])
-
- return (
- <MainArea>
- <Helmet>
- <title>{`${ title } Wiki | ${ SITE_TITLE }`}</title>
- {!(wikiPage?.body) && <meta name="robots" content="noindex"/>}
- </Helmet>
-
- {(wikiPage && version) && (
- <div className="text-sm flex gap-3 items-center justify-center
- border border-gray-700 rounded px-2 py-1 mb-4">
- {wikiPage.pred ? (
- <PrefetchLink to={`/wiki/${ encodeURIComponent (title) }?version=${ wikiPage.pred }`}>
- < 古
- </PrefetchLink>) : '(最古)'}
-
- <span>{wikiPage.updatedAt}</span>
-
- {wikiPage.succ ? (
- <PrefetchLink to={`/wiki/${ encodeURIComponent (title) }?version=${ wikiPage.succ }`}>
- 新 >
- </PrefetchLink>) : '(最新)'}
- </div>)}
-
- <PageTitle>
- <TagLink tag={tag ?? defaultTag}
- withWiki={false}
- withCount={false}
- {...(version && { to: `/wiki/${ encodeURIComponent (title) }` })}/>
- </PageTitle>
- <div className="prose mx-auto p-4">
- {loading ? 'Loading...' : <WikiBody title={title} body={wikiPage?.body}/>}
- </div>
-
- {(!(version) && posts.length > 0) && (
- <TabGroup>
- <Tab name="広場">
- <PostList posts={posts}/>
- </Tab>
- </TabGroup>)}
- </MainArea>)
- }
|