This commit is contained in:
2026-03-01 13:48:47 +09:00
parent f8d2d753fe
commit a088503272
5 changed files with 80 additions and 52 deletions
+18 -5
View File
@@ -3,13 +3,23 @@ import type { Category } from 'types'
export const LIGHT_COLOUR_SHADE = 800 export const LIGHT_COLOUR_SHADE = 800
export const DARK_COLOUR_SHADE = 300 export const DARK_COLOUR_SHADE = 300
export const CATEGORIES = ['deerjikist', export const CATEGORIES = [
'deerjikist',
'meme', 'meme',
'character', 'character',
'general', 'general',
'material', 'material',
'meta', 'meta',
'nico'] as const 'nico',
] as const
export const FETCH_POSTS_ORDER_FIELDS = [
'title',
'url',
'original_created_at',
'created_at',
'updated_at',
] as const
export const TAG_COLOUR = { export const TAG_COLOUR = {
deerjikist: 'rose', deerjikist: 'rose',
@@ -18,10 +28,13 @@ export const TAG_COLOUR = {
general: 'cyan', general: 'cyan',
material: 'orange', material: 'orange',
meta: 'yellow', meta: 'yellow',
nico: 'gray' } as const satisfies Record<Category, string> nico: 'gray',
} as const satisfies Record<Category, string>
export const USER_ROLES = ['admin', 'member', 'guest'] as const export const USER_ROLES = ['admin', 'member', 'guest'] as const
export const ViewFlagBehavior = { OnShowedDetail: 1, export const ViewFlagBehavior = {
OnShowedDetail: 1,
OnClickedLink: 2, OnClickedLink: 2,
NotAuto: 3 } as const NotAuto: 3,
} as const
+15 -18
View File
@@ -1,31 +1,28 @@
import { apiDelete, apiGet, apiPost } from '@/lib/api' import { apiDelete, apiGet, apiPost } from '@/lib/api'
import type { Post, PostTagChange } from '@/types' import type { FetchPostsParams, Post, PostTagChange } from '@/types'
export const fetchPosts = async ( export const fetchPosts = async (
{ url, title, tags, match, created_from, created_to, updated_from, { url, title, tags, match, createdFrom, createdTo, updatedFrom, updatedTo,
updated_to, original_created_from, original_created_to, page, limit }: { originalCreatedFrom, originalCreatedTo, page, limit, order }: FetchPostsParams
url?: string
title?: string
tags?: string
match?: 'all' | 'any'
created_from?: string
created_to?: string
updated_from?: string
updated_to?: string
original_created_from?: string
original_created_to?: string
page?: number
limit?: number },
): Promise<{ ): Promise<{
posts: Post[] posts: Post[]
count: number }> => count: number }> =>
await apiGet ('/posts', { params: { await apiGet ('/posts', { params: {
url, title, tags, match, created_from, created_to, updated_from, updated_to, ...(url && { url }),
original_created_from, original_created_to, ...(title && { title }),
...(tags && { tags }),
...(match && { match }),
...(createdFrom && { created_from: createdFrom }),
...(createdTo && { created_to: createdTo }),
...(updatedFrom && { updated_from: updatedFrom }),
...(updatedTo && { updated_to: updatedTo }),
...(originalCreatedFrom && { original_created_from: originalCreatedFrom }),
...(originalCreatedTo && { original_created_to: originalCreatedTo }),
...(page && { page }), ...(page && { page }),
...(limit && { limit }) } }) ...(limit && { limit }),
...(order && { order }) } })
export const fetchPost = async (id: string): Promise<Post> => await apiGet (`/posts/${ id }`) export const fetchPost = async (id: string): Promise<Post> => await apiGet (`/posts/${ id }`)
+3 -12
View File
@@ -1,17 +1,8 @@
import type { FetchPostsParams } from '@/types'
export const postsKeys = { export const postsKeys = {
root: ['posts'] as const, root: ['posts'] as const,
index: (p: { url?: string index: (p: FetchPostsParams) => ['posts', 'index', p] as const,
title?: string
tags?: string
match?: 'all' | 'any'
created_from?: string
created_to?: string
updated_from?: string
updated_to?: string
original_created_from?: string
original_created_to?: string
page?: number
limit?: number }) => ['posts', 'index', p] as const,
show: (id: string) => ['posts', id] as const, show: (id: string) => ['posts', id] as const,
related: (id: string) => ['related', id] as const, related: (id: string) => ['related', id] as const,
changes: (p: { id?: string; page: number; limit: number }) => changes: (p: { id?: string; page: number; limit: number }) =>
+13 -8
View File
@@ -18,7 +18,7 @@ import { postsKeys } from '@/lib/queryKeys'
import type { FC, ChangeEvent, FormEvent, KeyboardEvent } from 'react' import type { FC, ChangeEvent, FormEvent, KeyboardEvent } from 'react'
import type { Tag } from '@/types' import type { FetchPostsOrder, FetchPostsParams, Tag } from '@/types'
const setIf = (qs: URLSearchParams, k: string, v: string | null) => { const setIf = (qs: URLSearchParams, k: string, v: string | null) => {
@@ -49,11 +49,13 @@ export default (() => {
const qCreatedTo = query.get ('created_to') const qCreatedTo = query.get ('created_to')
const qUpdatedFrom = query.get ('updated_from') const qUpdatedFrom = query.get ('updated_from')
const qUpdatedTo = query.get ('updated_to') const qUpdatedTo = query.get ('updated_to')
const qOrder = (query.get ('order') || 'original_created_at:desc') as FetchPostsOrder
const [activeIndex, setActiveIndex] = useState (-1) const [activeIndex, setActiveIndex] = useState (-1)
const [createdFrom, setCreatedFrom] = useState (qCreatedFrom) const [createdFrom, setCreatedFrom] = useState (qCreatedFrom)
const [createdTo, setCreatedTo] = useState (qCreatedTo) const [createdTo, setCreatedTo] = useState (qCreatedTo)
const [matchType, setMatchType] = useState (qMatch ?? 'all') const [matchType, setMatchType] = useState (qMatch ?? 'all')
const [order, setOrder] = useState<FetchPostsOrder> ('original_created_at:desc')
const [originalCreatedFrom, setOriginalCreatedFrom] = useState (qOriginalCreatedFrom) const [originalCreatedFrom, setOriginalCreatedFrom] = useState (qOriginalCreatedFrom)
const [originalCreatedTo, setOriginalCreatedTo] = useState (qOriginalCreatedTo) const [originalCreatedTo, setOriginalCreatedTo] = useState (qOriginalCreatedTo)
const [suggestions, setSuggestions] = useState<Tag[]> ([]) const [suggestions, setSuggestions] = useState<Tag[]> ([])
@@ -64,16 +66,17 @@ export default (() => {
const [updatedTo, setUpdatedTo] = useState (qUpdatedTo) const [updatedTo, setUpdatedTo] = useState (qUpdatedTo)
const [url, setURL] = useState (qURL ?? '') const [url, setURL] = useState (qURL ?? '')
const keys = { const keys: FetchPostsParams = {
tags: qTags, match: qMatch, page, limit, tags: qTags, match: qMatch, page, limit,
...(qURL && { url: qURL }), ...(qURL && { url: qURL }),
...(qTitle && { title: qTitle }), ...(qTitle && { title: qTitle }),
...(qOriginalCreatedFrom && { original_created_from: qOriginalCreatedFrom }), ...(qOriginalCreatedFrom && { originalCreatedFrom: qOriginalCreatedFrom }),
...(qOriginalCreatedTo && { original_created_to: qOriginalCreatedTo }), ...(qOriginalCreatedTo && { originalCreatedTo: qOriginalCreatedTo }),
...(qCreatedFrom && { created_from: qCreatedFrom }), ...(qCreatedFrom && { createdFrom: qCreatedFrom }),
...(qCreatedTo && { created_to: qCreatedTo }), ...(qCreatedTo && { createdTo: qCreatedTo }),
...(qUpdatedFrom && { updated_from: qUpdatedFrom }), ...(qUpdatedFrom && { updatedFrom: qUpdatedFrom }),
...(qUpdatedTo && { updated_to: qUpdatedTo }) } ...(qUpdatedTo && { updatedTo: qUpdatedTo }),
...(qOrder && { order: qOrder }) }
const { data, isLoading: loading } = useQuery ({ const { data, isLoading: loading } = useQuery ({
queryKey: postsKeys.index (keys), queryKey: postsKeys.index (keys),
queryFn: () => fetchPosts (keys) }) queryFn: () => fetchPosts (keys) })
@@ -91,6 +94,7 @@ export default (() => {
setCreatedTo (qCreatedTo) setCreatedTo (qCreatedTo)
setUpdatedFrom (qUpdatedFrom) setUpdatedFrom (qUpdatedFrom)
setUpdatedTo (qUpdatedTo) setUpdatedTo (qUpdatedTo)
setOrder (qOrder)
document.querySelector ('table')?.scrollIntoView ({ behavior: 'smooth' }) document.querySelector ('table')?.scrollIntoView ({ behavior: 'smooth' })
}, [location.search]) }, [location.search])
@@ -160,6 +164,7 @@ export default (() => {
setIf (qs, 'updated_to', updatedTo) setIf (qs, 'updated_to', updatedTo)
qs.set ('match', matchType) qs.set ('match', matchType)
qs.set ('page', String ('1')) qs.set ('page', String ('1'))
qs.set ('order', order)
navigate (`${ location.pathname }?${ qs.toString () }`) navigate (`${ location.pathname }?${ qs.toString () }`)
} }
+23 -1
View File
@@ -1,9 +1,31 @@
import { CATEGORIES, USER_ROLES, ViewFlagBehavior } from '@/consts' import { CATEGORIES,
FETCH_POSTS_ORDER_FIELDS,
USER_ROLES,
ViewFlagBehavior } from '@/consts'
import type { ReactNode } from 'react' import type { ReactNode } from 'react'
export type Category = typeof CATEGORIES[number] export type Category = typeof CATEGORIES[number]
export type FetchPostsOrder = `${ FetchPostsOrderField }:${ 'asc' | 'desc' }`
export type FetchPostsOrderField = typeof FETCH_POSTS_ORDER_FIELDS[number]
export type FetchPostsParams = {
url?: string
title?: string
tags?: string
match?: 'all' | 'any'
createdFrom?: string
createdTo?: string
updatedFrom?: string
updatedTo?: string
originalCreatedFrom?: string
originalCreatedTo?: string
page?: number
limit?: number
order?: FetchPostsOrder }
export type Menu = MenuItem[] export type Menu = MenuItem[]
export type MenuItem = { export type MenuItem = {