This commit is contained in:
2025-07-26 05:37:20 +09:00
parent de9bba5609
commit 2f3acc7584
3 changed files with 82 additions and 23 deletions
+22
View File
@@ -0,0 +1,22 @@
import { Link } from 'react-router-dom'
import type { Post } from '@/types'
type Props = { posts: Post[] }
export default ({ posts }: Props) => (
<div className="flex flex-wrap gap-6 p-4">
{posts.map ((post, i) => (
<Link to={`/posts/${ post.id }`}
key={i}
className="w-40 h-40 overflow-hidden rounded-lg shadow-md hover:shadow-lg">
<img src={post.thumbnail || post.thumbnailBase || undefined}
alt={post.title || post.url}
title={post.title || post.url || undefined}
loading="eager"
fetchPriority="high"
decoding="async"
className="object-none w-full h-full" />
</Link>))}
</div>)
+5 -18
View File
@@ -4,6 +4,7 @@ import { useEffect, useRef, useState } from 'react'
import { Helmet } from 'react-helmet-async' import { Helmet } from 'react-helmet-async'
import { Link, useLocation } from 'react-router-dom' import { Link, useLocation } from 'react-router-dom'
import PostList from '@/components/PostList'
import TagSidebar from '@/components/TagSidebar' import TagSidebar from '@/components/TagSidebar'
import WikiBody from '@/components/WikiBody' import WikiBody from '@/components/WikiBody'
import TabGroup, { Tab } from '@/components/common/TabGroup' import TabGroup, { Tab } from '@/components/common/TabGroup'
@@ -14,10 +15,10 @@ import type { Post, WikiPage } from '@/types'
export default () => { export default () => {
const [posts, setPosts] = useState<Post[]> ([])
const [wikiPage, setWikiPage] = useState<WikiPage | null> (null)
const [cursor, setCursor] = useState ('') const [cursor, setCursor] = useState ('')
const [loading, setLoading] = useState (false) const [loading, setLoading] = useState (false)
const [posts, setPosts] = useState<Post[]> ([])
const [wikiPage, setWikiPage] = useState<WikiPage | null> (null)
const loaderRef = useRef<HTMLDivElement | null> (null) const loaderRef = useRef<HTMLDivElement | null> (null)
@@ -25,7 +26,7 @@ export default () => {
setLoading (true) setLoading (true)
const res = await axios.get (`${ API_BASE_URL }/posts`, { const res = await axios.get (`${ API_BASE_URL }/posts`, {
params: { tags: tags.join (' '), params: { tags: tags.join (' '),
match: (anyFlg ? 'any' : 'all'), match: anyFlg ? 'any' : 'all',
...(withCursor ? { cursor } : { }) } }) ...(withCursor ? { cursor } : { }) } })
const data = toCamel (res.data as any, { deep: true }) as { posts: Post[] const data = toCamel (res.data as any, { deep: true }) as { posts: Post[]
nextCursor: string } nextCursor: string }
@@ -92,21 +93,7 @@ export default () => {
<TabGroup> <TabGroup>
<Tab name="広場"> <Tab name="広場">
{posts.length {posts.length
? ( ? <PostList posts={posts} />
<div className="flex flex-wrap gap-6 p-4">
{posts.map ((post, i) => (
<Link to={`/posts/${ post.id }`}
key={i}
className="w-40 h-40 overflow-hidden rounded-lg shadow-md hover:shadow-lg">
<img src={post.thumbnail || post.thumbnailBase || undefined}
alt={post.title || post.url}
title={post.title || post.url || undefined}
loading="eager"
fetchPriority="high"
decoding="async"
className="object-none w-full h-full" />
</Link>))}
</div>)
: !(loading) && '広場には何もありませんよ.'} : !(loading) && '広場には何もありませんよ.'}
{loading && 'Loading...'} {loading && 'Loading...'}
<div ref={loaderRef} className="h-12"></div> <div ref={loaderRef} className="h-12"></div>
+55 -5
View File
@@ -4,13 +4,16 @@ import { useEffect, useState } from 'react'
import { Helmet } from 'react-helmet-async' import { Helmet } from 'react-helmet-async'
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom' 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 WikiBody from '@/components/WikiBody'
import PageTitle from '@/components/common/PageTitle' import PageTitle from '@/components/common/PageTitle'
import TabGroup, { Tab } from '@/components/common/TabGroup'
import MainArea from '@/components/layout/MainArea' import MainArea from '@/components/layout/MainArea'
import { API_BASE_URL, SITE_TITLE } from '@/config' import { API_BASE_URL, SITE_TITLE } from '@/config'
import { WikiIdBus } from '@/lib/eventBus/WikiIdBus' import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'
import type { WikiPage } from '@/types' import type { Post, Tag, WikiPage } from '@/types'
export default () => { export default () => {
@@ -20,6 +23,10 @@ export default () => {
const location = useLocation () const location = useLocation ()
const navigate = useNavigate () 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 [wikiPage, setWikiPage] = useState<WikiPage | null | undefined> (undefined)
const query = new URLSearchParams (location.search) const query = new URLSearchParams (location.search)
@@ -33,14 +40,16 @@ export default () => {
const data = res.data as WikiPage const data = res.data as WikiPage
navigate (`/wiki/${ data.title }`, { replace: true }) navigate (`/wiki/${ data.title }`, { replace: true })
}) () }) ()
return return
} }
void (async () => { void (async () => {
try try
{ {
const res = await axios.get (`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (title) }`, const res = await axios.get (
{ params: { ...(version ? { version } : { }) } }) `${ API_BASE_URL }/wiki/title/${ encodeURIComponent (title) }`,
{ params: version ? { version } : { } })
const data = toCamel (res.data as any, { deep: true }) as WikiPage const data = toCamel (res.data as any, { deep: true }) as WikiPage
setWikiPage (data) setWikiPage (data)
WikiIdBus.set (data.id) WikiIdBus.set (data.id)
@@ -51,6 +60,36 @@ export default () => {
} }
}) () }) ()
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) return () => WikiIdBus.set (null)
}, [title, location.search]) }, [title, location.search])
@@ -59,6 +98,7 @@ export default () => {
<Helmet> <Helmet>
<title>{`${ title } Wiki | ${ SITE_TITLE }`}</title> <title>{`${ title } Wiki | ${ SITE_TITLE }`}</title>
</Helmet> </Helmet>
{(wikiPage && version) && ( {(wikiPage && version) && (
<div className="text-sm flex gap-3 items-center justify-center border border-gray-700 rounded px-2 py-1 mb-4"> <div className="text-sm flex gap-3 items-center justify-center border border-gray-700 rounded px-2 py-1 mb-4">
{wikiPage.pred ? ( {wikiPage.pred ? (
@@ -73,11 +113,21 @@ export default () => {
&gt; &gt;
</Link>) : <>()</>} </Link>) : <>()</>}
</div>)} </div>)}
<PageTitle>{title}</PageTitle>
<PageTitle>
<TagLink tag={tag} withWiki={false} withCount={false} />
</PageTitle>
<div className="prose mx-auto p-4"> <div className="prose mx-auto p-4">
{wikiPage === undefined {wikiPage === undefined
? 'Loading...' ? 'Loading...'
: <WikiBody body={wikiPage?.body || `このページは存在しません。[新規作成してください](/wiki/new?title=${ title })。`} />} : <WikiBody body={wikiPage?.body || `このページは存在しません。[新規作成してください](/wiki/new?title=${ encodeURIComponent (title) })。`} />}
</div> </div>
{posts.length > 0 && (
<TabGroup>
<Tab name="広場">
<PostList posts={posts} />
</Tab>
</TabGroup>)}
</MainArea>) </MainArea>)
} }