#13 完了
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user