|
|
@@ -1,17 +1,21 @@ |
|
|
|
import axios from 'axios' |
|
|
|
import toCamel from 'camelcase-keys' |
|
|
|
import React, { useEffect, useState } from 'react' |
|
|
|
import { Helmet } from 'react-helmet' |
|
|
|
import { Link, useLocation } from 'react-router-dom' |
|
|
|
|
|
|
|
import TagSidebar from '@/components/TagSidebar' |
|
|
|
import WikiBody from '@/components/WikiBody' |
|
|
|
import TabGroup, { Tab } from '@/components/common/TabGroup' |
|
|
|
import MainArea from '@/components/layout/MainArea' |
|
|
|
import { API_BASE_URL, SITE_TITLE } from '@/config' |
|
|
|
|
|
|
|
import type { Post, Tag } from '@/types' |
|
|
|
import type { Post, Tag, WikiPage } from '@/types' |
|
|
|
|
|
|
|
|
|
|
|
export default () => { |
|
|
|
const [posts, setPosts] = useState<Post[]> ([]) |
|
|
|
const [wikiPage, setWikiPage] = useState<WikiPage | null> (null) |
|
|
|
|
|
|
|
const location = useLocation () |
|
|
|
const query = new URLSearchParams (location.search) |
|
|
@@ -21,21 +25,20 @@ export default () => { |
|
|
|
const tags = tagsQuery.split (' ').filter (e => e !== '') |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
const fetchPosts = async () => { |
|
|
|
try |
|
|
|
{ |
|
|
|
const res = await axios.get (`${ API_BASE_URL }/posts`, { |
|
|
|
params: { tags: tags.join (','), |
|
|
|
match: (anyFlg ? 'any' : 'all') } }) |
|
|
|
setPosts (res.data) |
|
|
|
} |
|
|
|
catch (error) |
|
|
|
{ |
|
|
|
console.error ('Failed to fetch posts:', error) |
|
|
|
setPosts ([]) |
|
|
|
} |
|
|
|
} |
|
|
|
fetchPosts() |
|
|
|
void (axios.get (`${ API_BASE_URL }/posts`, { |
|
|
|
params: { tags: tags.join (','), |
|
|
|
match: (anyFlg ? 'any' : 'all') } }) |
|
|
|
.then (res => setPosts (res.data)) |
|
|
|
.catch (err => { |
|
|
|
console.error ('Failed to fetch posts:', err) |
|
|
|
setPosts ([]) |
|
|
|
})) |
|
|
|
|
|
|
|
if (!(tags.length)) |
|
|
|
return |
|
|
|
void (axios.get (`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (tags.join (' ')) }`) |
|
|
|
.then (res => setWikiPage (toCamel (res.data, { deep: true }))) |
|
|
|
.catch (() => setWikiPage (null))) |
|
|
|
}, [location.search]) |
|
|
|
|
|
|
|
return ( |
|
|
@@ -49,16 +52,30 @@ export default () => { |
|
|
|
</Helmet> |
|
|
|
<TagSidebar posts={posts} /> |
|
|
|
<MainArea> |
|
|
|
<div className="flex flex-wrap gap-4 p-4"> |
|
|
|
{posts.map (post => ( |
|
|
|
<Link to={`/posts/${ post.id }`} |
|
|
|
key={post.id} |
|
|
|
className="w-40 h-40 overflow-hidden rounded-lg shadow-md hover:shadow-lg"> |
|
|
|
<img src={post.thumbnail ?? post.thumbnail_base} |
|
|
|
className="object-none w-full h-full" /> |
|
|
|
</Link> |
|
|
|
))} |
|
|
|
</div> |
|
|
|
<TabGroup key={wikiPage}> |
|
|
|
<Tab name="広場"> |
|
|
|
{posts.length |
|
|
|
? ( |
|
|
|
<div className="flex flex-wrap gap-4 p-4"> |
|
|
|
{posts.map (post => ( |
|
|
|
<Link to={`/posts/${ post.id }`} |
|
|
|
key={post.id} |
|
|
|
className="w-40 h-40 overflow-hidden rounded-lg shadow-md hover:shadow-lg"> |
|
|
|
<img src={post.thumbnail ?? post.thumbnail_base} |
|
|
|
className="object-none w-full h-full" /> |
|
|
|
</Link> |
|
|
|
))} |
|
|
|
</div>) |
|
|
|
: '広場には何もありませんよ.'} |
|
|
|
</Tab> |
|
|
|
{(wikiPage && wikiPage.body) && ( |
|
|
|
<Tab name="Wiki" init={!(posts.length)}> |
|
|
|
<WikiBody body={wikiPage.body} /> |
|
|
|
<div className="my-2"> |
|
|
|
<Link to={`/wiki/${ wikiPage.title }`}>Wiki を見る</Link> |
|
|
|
</div> |
|
|
|
</Tab>)} |
|
|
|
</TabGroup> |
|
|
|
</MainArea> |
|
|
|
</>) |
|
|
|
} |