|
- import { Fragment, useEffect, useState } from 'react'
- import { Helmet } from 'react-helmet-async'
- import { useLocation } from 'react-router-dom'
-
- import nikumaru from '@/assets/fonts/nikumaru.otf'
- import PrefetchLink from '@/components/PrefetchLink'
- import TagLink from '@/components/TagLink'
- import PageTitle from '@/components/common/PageTitle'
- import SectionTitle from '@/components/common/SectionTitle'
- import SubsectionTitle from '@/components/common/SubsectionTitle'
- import MainArea from '@/components/layout/MainArea'
- import { SITE_TITLE } from '@/config'
- import { apiGet } from '@/lib/api'
-
- import type { FC } from 'react'
-
- import type { Material, Tag } from '@/types'
-
- type TagWithMaterial = Omit<Tag, 'children'> & {
- children: TagWithMaterial[]
- material: Material | null }
-
-
- const MaterialCard = ({ tag }: { tag: TagWithMaterial }) => {
- if (!(tag.material))
- return
-
- return (
- <PrefetchLink
- to={`/materials/${ tag.material.id }`}
- className="block w-40 h-40">
- <div
- className="w-full h-full overflow-hidden rounded-xl shadow
- text-center content-center text-4xl"
- style={{ fontFamily: 'Nikumaru' }}>
- {(tag.material.contentType && /image\/.*/.test (tag.material.contentType))
- ? <img src={tag.material.file || undefined}/>
- : <span>照会</span>}
- </div>
- </PrefetchLink>)
- }
-
-
- const MaterialListPage: FC = () => {
- const [loading, setLoading] = useState (false)
- const [tag, setTag] = useState<TagWithMaterial | null> (null)
-
- const location = useLocation ()
- const query = new URLSearchParams (location.search)
- const tagQuery = query.get ('tag') ?? ''
-
- useEffect (() => {
- if (!(tagQuery))
- {
- setTag (null)
- return
- }
-
- void (async () => {
- try
- {
- setLoading (true)
- setTag (
- await apiGet<TagWithMaterial> (
- `/tags/name/${ encodeURIComponent (tagQuery) }/materials`))
- }
- finally
- {
- setLoading (false)
- }
- }) ()
- }, [location.search, tagQuery])
-
- return (
- <MainArea>
- <Helmet>
- <style>
- {`
- @font-face
- {
- font-family: 'Nikumaru';
- src: url(${ nikumaru }) format('opentype');
- }`}
- </style>
- <title>{`${ tag ? `${ tag.name } 素材集` : '素材集' } | ${ SITE_TITLE }`}</title>
- </Helmet>
-
- {loading ? 'Loading...' : (
- tag
- ? (
- <>
- <PageTitle>
- <TagLink
- tag={tag}
- withWiki={false}
- withCount={false}
- to={tag.material
- ? `/materials/${ tag.material.id }`
- : `/materials?tag=${ encodeURIComponent (tag.name) }`}/>
- </PageTitle>
- {(!(tag.material) && tag.category !== 'meme') && (
- <div className="-mt-2">
- <PrefetchLink
- to={`/materials/new?tag=${ encodeURIComponent (tag.name) }`}>
- 追加
- </PrefetchLink>
- </div>)}
-
- <MaterialCard tag={tag}/>
-
- <div className="ml-2">
- {tag.children.map (c2 => (
- <Fragment key={c2.id}>
- <SectionTitle>
- <TagLink
- tag={c2}
- withWiki={false}
- withCount={false}
- to={`/materials?tag=${ encodeURIComponent (c2.name) }`}/>
- </SectionTitle>
- {(!(c2.material) && c2.category !== 'meme') && (
- <div className="-mt-4">
- <PrefetchLink
- to={`/materials/new?tag=${ encodeURIComponent (c2.name) }`}>
- 追加
- </PrefetchLink>
- </div>)}
-
- <MaterialCard tag={c2}/>
-
- <div className="ml-2">
- {c2.children.map (c3 => (
- <Fragment key={c3.id}>
- <SubsectionTitle>
- <TagLink
- tag={c3}
- withWiki={false}
- withCount={false}
- to={`/materials?tag=${ encodeURIComponent (c3.name) }`}/>
- </SubsectionTitle>
- {(!(c3.material) && c3.category !== 'meme') && (
- <div className="-mt-2">
- <PrefetchLink
- to={`/materials/new?tag=${
- encodeURIComponent (c3.name) }`}>
- 追加
- </PrefetchLink>
- </div>)}
-
- <MaterialCard tag={c3}/>
- </Fragment>))}
- </div>
- </Fragment>))}
- </div>
- </>)
- : (
- <>
- <p>左のリストから照会したいタグを選択してください。</p>
- <p>もしくは……</p>
- <ul>
- <li><PrefetchLink to="/materials/new">素材を新規追加する</PrefetchLink></li>
- {/* <li><a href="#">すべての素材をダウンロードする</a></li> */}
- </ul>
- </>))}
- </MainArea>)
- }
-
- export default MaterialListPage
|