ぼざクリ タグ広場 https://hub.nizika.monster
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

74 lines
2.7 KiB

  1. import { useEffect, useState } from 'react'
  2. import { Helmet } from 'react-helmet'
  3. import { Link, useLocation, useParams, useNavigate } from 'react-router-dom'
  4. import ReactMarkdown from 'react-markdown'
  5. import axios from 'axios'
  6. import { API_BASE_URL, SITE_TITLE } from '@/config'
  7. import MainArea from '@/components/layout/MainArea'
  8. import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'
  9. import PageTitle from '@/components/common/PageTitle'
  10. import type { WikiPage } from '@/types'
  11. export default () => {
  12. const { title } = useParams ()
  13. const location = useLocation ()
  14. const navigate = useNavigate ()
  15. const [wikiPage, setWikiPage] = useState<WikiPage | null | undefined> (undefined)
  16. const query = new URLSearchParams (location.search)
  17. const version = query.get ('version')
  18. useEffect (() => {
  19. if (/^\d+$/.test (title))
  20. {
  21. void (axios.get (`${ API_BASE_URL }/wiki/${ title }`)
  22. .then (res => navigate (`/wiki/${ res.data.title }`, { replace: true })))
  23. return
  24. }
  25. void (axios.get (`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (title) }`, version && { params: { version } })
  26. .then (res => {
  27. setWikiPage (res.data)
  28. WikiIdBus.set (res.data.id)
  29. })
  30. .catch (() => setWikiPage (null)))
  31. }, [title, location.search])
  32. return (
  33. <MainArea>
  34. <Helmet>
  35. <title>{`${ title } Wiki | ${ SITE_TITLE }`}</title>
  36. </Helmet>
  37. {(wikiPage && version) && (
  38. <div className="text-sm flex gap-3 items-center justify-center border border-gray-700 rounded px-2 py-1 mb-4">
  39. {wikiPage.pred ? (
  40. <Link to={`/wiki/${ title }?version=${ wikiPage.pred }`}>
  41. &lt; 古
  42. </Link>) : <>(最古)</>}
  43. <span>{wikiPage.updated_at}</span>
  44. {wikiPage.succ ? (
  45. <Link to={`/wiki/${ title }?version=${ wikiPage.succ }`}>
  46. 新 &gt;
  47. </Link>) : <>(最新)</>}
  48. </div>)}
  49. <PageTitle>{title}</PageTitle>
  50. <div className="prose mx-auto p-4">
  51. {wikiPage === undefined ? 'Loading...' : (
  52. <>
  53. <ReactMarkdown components={{ a: (
  54. ({ href, children }) => (['/', '.'].some (e => href?.startsWith (e))
  55. ? <Link to={href!}>{children}</Link>
  56. : <a href={href} target="_blank" rel="noopener noreferrer">{children}</a>)) }}>
  57. {wikiPage?.body || `このページは存在しません。[新規作成してください](/wiki/new?title=${ title })。`}
  58. </ReactMarkdown>
  59. </>)}
  60. </div>
  61. </MainArea>)
  62. }