|
- import axios from 'axios'
- import toCamel from 'camelcase-keys'
- import { useEffect, useState } from 'react'
- import { Helmet } from 'react-helmet-async'
- import { Link, useLocation, useNavigate, useParams } from 'react-router-dom'
-
- import PostList from '@/components/PostList'
- 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 { API_BASE_URL, SITE_TITLE } from '@/config'
- import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'
-
- import type { Post, Tag, WikiPage } from '@/types'
-
-
- export default () => {
- const params = useParams ()
- const title = params.title ?? ''
-
- const location = useLocation ()
- const navigate = useNavigate ()
-
- const defaultTag = { name: title, category: 'general' } as Tag
-
- const [posts, setPosts] = useState<Post[]> ([])
- const [tag, setTag] = useState (defaultTag)
- const [wikiPage, setWikiPage] = useState<WikiPage | null | undefined> (undefined)
-
- const query = new URLSearchParams (location.search)
- const version = query.get ('version')
-
- useEffect (() => {
- if (/^\d+$/.test (title))
- {
- void (async () => {
- const res = await axios.get (`${ API_BASE_URL }/wiki/${ title }`)
- const data = res.data as WikiPage
- navigate (`/wiki/${ data.title }`, { replace: true })
- }) ()
-
- return
- }
-
- void (async () => {
- try
- {
- const res = await axios.get (
- `${ API_BASE_URL }/wiki/title/${ encodeURIComponent (title) }`,
- { params: version ? { version } : { } })
- const data = toCamel (res.data as any, { deep: true }) as WikiPage
- setWikiPage (data)
- WikiIdBus.set (data.id)
- }
- catch
- {
- setWikiPage (null)
- }
- }) ()
-
- void (async () => {
- try
- {
- const res = await axios.get (
- `${ API_BASE_URL }/posts?${ new URLSearchParams ({ tags: title,
- limit: '8' }) }`)
- const data = toCamel (res.data as any,
- { deep: true }) as { posts: Post[]
- nextCursor: string }
- setPosts (data.posts)
- }
- catch
- {
- setPosts ([])
- }
- }) ()
-
- void (async () => {
- try
- {
- const res = await axios.get (
- `${ API_BASE_URL }/tags/name/${ encodeURIComponent (title) }`)
- setTag (toCamel (res.data as any, { deep: true }) as Tag)
- }
- catch
- {
- setTag (defaultTag)
- }
- }) ()
-
- return () => WikiIdBus.set (null)
- }, [title, location.search])
-
- return (
- <MainArea>
- <Helmet>
- <title>{`${ title } Wiki | ${ SITE_TITLE }`}</title>
- </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 ? (
- <Link to={`/wiki/${ encodeURIComponent (title) }?version=${ wikiPage.pred }`}>
- < 古
- </Link>) : '(最古)'}
-
- <span>{wikiPage.updatedAt}</span>
-
- {wikiPage.succ ? (
- <Link to={`/wiki/${ encodeURIComponent (title) }?version=${ wikiPage.succ }`}>
- 新 >
- </Link>) : '(最新)'}
- </div>)}
-
- <PageTitle>
- <TagLink tag={tag}
- withWiki={false}
- withCount={false}
- {...(version && { to: `/wiki/${ encodeURIComponent (title) }` })} />
- </PageTitle>
- <div className="prose mx-auto p-4">
- {wikiPage === undefined
- ? 'Loading...'
- : <WikiBody body={wikiPage?.body || `このページは存在しません。[新規作成してください](/wiki/new?title=${ encodeURIComponent (title) })。`} />}
- </div>
-
- {(!(version) && posts.length > 0) && (
- <TabGroup>
- <Tab name="広場">
- <PostList posts={posts} />
- </Tab>
- </TabGroup>)}
- </MainArea>)
- }
|