This commit is contained in:
2025-05-24 05:46:24 +09:00
parent db430cc426
commit 1b1392be4d
3 changed files with 50 additions and 21 deletions
+5 -2
View File
@@ -1,13 +1,16 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import axios from 'axios' import axios from 'axios'
import { Link, useNavigate } from 'react-router-dom' import { Link, useNavigate, useLocation } from 'react-router-dom'
import { API_BASE_URL } from '../config' import { API_BASE_URL } from '../config'
const TagSearch: React.FC = () => { const TagSearch: React.FC = () => {
const navigate = useNavigate () const navigate = useNavigate ()
const location = useLocation ()
const query = new URLSearchParams (location.search)
const tagsQuery = query.get ('tags') ?? ''
const [search, setSearch] = useState ('') const [search, setSearch] = useState (tagsQuery)
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter' && search.length > 0) if (e.key === 'Enter' && search.length > 0)
+41 -18
View File
@@ -4,15 +4,33 @@ import { Link } from 'react-router-dom'
import { API_BASE_URL } from '../config' import { API_BASE_URL } from '../config'
import TagSearch from './TagSearch' import TagSearch from './TagSearch'
type Tag = { id: number
name: string }
type TagByCategory = { [key: string]: Tag[] }
type OriginalTag = { id: number
name: string
category: string }
const tagNameMap: { [key: string]: string } = {
general: '一般',
deerjikist: 'ニジラー',
nico: 'ニコニコタグ' }
const TagSidebar: React.FC = () => { const TagSidebar: React.FC = () => {
const [tags, setTags] = useState<Array<{ id: number, name: string, category: string }>>([]) const [tags, setTags] = useState<TagByCategory> ({ })
useEffect(() => { useEffect(() => {
const fetchTags = async () => { const fetchTags = async () => {
try { try {
const response = await axios.get (`${API_BASE_URL}/tags`) const response = await axios.get (`${API_BASE_URL}/tags`)
setTags(response.data) const tagsTmp: TagByCategory = { }
for (const tag of response.data)
{
if (!(tag.category in tagsTmp))
tagsTmp[tag.category] = []
tagsTmp[tag.category].push ({ id: tag.id, name: tag.name })
}
setTags (tagsTmp)
} catch (error) { } catch (error) {
console.error('Failed to fetch tags:', error) console.error('Failed to fetch tags:', error)
} }
@@ -22,22 +40,27 @@ const TagSidebar: React.FC = () => {
}, []) }, [])
return ( return (
<div className="w-64 bg-gray-100 p-4 border-r border-gray-200 h-full"> <div className="w-64 bg-gray-100 p-4 border-r border-gray-200 h-full">
<TagSearch /> <TagSearch />
<ul> {['general', 'deerjikist', 'nico'].map (cat => (cat in tags) ? (
{tags.map (tag => ( <>
<li key={tag.id} className="mb-2"> <h2>{tagNameMap[cat]}</h2>
<Link <ul>
to={`/posts?${ (new URLSearchParams ({ tags: tag.name })).toString () }`} {tags[cat].map (tag => (
className="text-blue-600 hover:underline" <li key={tag.id} className="mb-2">
> <Link
{tag.name} to={`/posts?${ (new URLSearchParams ({ tags: tag.name })).toString () }`}
</Link> className="text-blue-600 hover:underline"
</li> >
))} {tag.name}
</ul> </Link>
</div> </li>
) ))}
</ul>
</>
) : <></>)}
</div>
)
} }
export default TagSidebar export default TagSidebar
+4 -1
View File
@@ -12,7 +12,10 @@ const PostPage = () => {
// const anyFlg = query.get ('match') === 'any' // const anyFlg = query.get ('match') === 'any'
const anyFlg = false const anyFlg = false
const tags = tagsQuery.split (' ').filter (e => e !== '') const tags = tagsQuery.split (' ').filter (e => e !== '')
document.title = `${ tags.join (anyFlg ? ' or ' : ' and ') } | ${ SITE_TITLE }` if (tags.length)
document.title = `${ tags.join (anyFlg ? ' or ' : ' and ') } | ${ SITE_TITLE }`
else
document.title = `${ SITE_TITLE } 〜 ぼざクリも、ぼざろ外も、外伝もあるんだよ`
useEffect(() => { useEffect(() => {
const fetchPosts = async () => { const fetchPosts = async () => {