| @@ -1,5 +1,5 @@ | |||||
| import { useQuery } from '@tanstack/react-query' | import { useQuery } from '@tanstack/react-query' | ||||
| import { useState } from 'react' | |||||
| import { useEffect, useMemo, useState } from 'react' | |||||
| import { Helmet } from 'react-helmet-async' | import { Helmet } from 'react-helmet-async' | ||||
| import { useLocation, useNavigate } from 'react-router-dom' | import { useLocation, useNavigate } from 'react-router-dom' | ||||
| @@ -17,49 +17,89 @@ import { postsKeys } from '@/lib/queryKeys' | |||||
| import type { FC, FormEvent } from 'react' | import type { FC, FormEvent } from 'react' | ||||
| const setIf = (qs: URLSearchParams, k: string, v: string | null) => { | |||||
| const t = v?.trim () | |||||
| if (t) | |||||
| qs.set (k, t) | |||||
| } | |||||
| export default (() => { | export default (() => { | ||||
| const location = useLocation () | |||||
| const navigate = useNavigate () | const navigate = useNavigate () | ||||
| const location = useLocation () | |||||
| const query = new URLSearchParams (location.search) | |||||
| const query = useMemo (() => new URLSearchParams (location.search), | |||||
| [location.search]) | |||||
| const page = Number (query.get ('page') ?? 1) | const page = Number (query.get ('page') ?? 1) | ||||
| const limit = Number (query.get ('limit') ?? 20) | const limit = Number (query.get ('limit') ?? 20) | ||||
| const [createdFrom, setCreatedFrom] = | |||||
| useState<string | null> (query.get ('created_from')) | |||||
| const [createdTo, setCreatedTo] = | |||||
| useState<string | null> (query.get ('created_to')) | |||||
| const [matchType, setMatchType] = | |||||
| useState<'all' | 'any'> ((query.get ('match') as 'all' | 'any' | null) ?? 'all') | |||||
| const [originalCreatedFrom, setOriginalCreatedFrom] = | |||||
| useState<string | null> (query.get ('original_created_from')) | |||||
| const [originalCreatedTo, setOriginalCreatedTo] = | |||||
| useState<string | null> (query.get ('original_created_to')) | |||||
| const [tagsStr, setTagsStr] = useState (query.get ('tags') ?? '') | |||||
| const [title, setTitle] = useState (query.get ('title') ?? '') | |||||
| const [updatedFrom, setUpdatedFrom] = | |||||
| useState<string | null> (query.get ('updated_from')) | |||||
| const [updatedTo, setUpdatedTo] = | |||||
| useState<string | null> (query.get ('updated_to')) | |||||
| const [url, setURL] = useState (query.get ('url') ?? '') | |||||
| const qURL = query.get ('url') | |||||
| const qTitle = query.get ('title') | |||||
| const qTags = query.get ('tags') ?? '' | |||||
| const qMatch: 'all' | 'any' = query.get ('match') === 'any' ? 'any' : 'all' | |||||
| const qOriginalCreatedFrom = query.get ('original_created_from') | |||||
| const qOriginalCreatedTo = query.get ('original_created_to') | |||||
| const qCreatedFrom = query.get ('created_from') | |||||
| const qCreatedTo = query.get ('created_to') | |||||
| const qUpdatedFrom = query.get ('updated_from') | |||||
| const qUpdatedTo = query.get ('updated_to') | |||||
| const [createdFrom, setCreatedFrom] = useState (qCreatedFrom) | |||||
| const [createdTo, setCreatedTo] = useState (qCreatedTo) | |||||
| const [matchType, setMatchType] = useState (qMatch ?? 'all') | |||||
| const [originalCreatedFrom, setOriginalCreatedFrom] = useState (qOriginalCreatedFrom) | |||||
| const [originalCreatedTo, setOriginalCreatedTo] = useState (qOriginalCreatedTo) | |||||
| const [tagsStr, setTagsStr] = useState (qTags) | |||||
| const [title, setTitle] = useState (qTitle ?? '') | |||||
| const [updatedFrom, setUpdatedFrom] = useState (qUpdatedFrom) | |||||
| const [updatedTo, setUpdatedTo] = useState (qUpdatedTo) | |||||
| const [url, setURL] = useState (qURL ?? '') | |||||
| const keys = { | const keys = { | ||||
| tags: tagsStr, match: matchType, page, limit, | |||||
| ...(url && { url }), | |||||
| ...(title && { title }), | |||||
| ...(originalCreatedFrom && { original_created_from: originalCreatedFrom }), | |||||
| ...(originalCreatedTo && { original_created_to: originalCreatedTo }), | |||||
| ...(createdFrom && { created_from: createdFrom }), | |||||
| ...(createdTo && { created_to: createdTo }), | |||||
| ...(updatedFrom && { updated_from: updatedFrom }), | |||||
| ...(updatedTo && { updated_to: updatedTo }) } | |||||
| const { data, /* isLoading: loading */ } = useQuery ({ | |||||
| queryKey: postsKeys.index (keys), queryFn: () => fetchPosts (keys) }) | |||||
| tags: qTags, match: qMatch, page, limit, | |||||
| ...(qURL && { url: qURL }), | |||||
| ...(qTitle && { title: qTitle }), | |||||
| ...(qOriginalCreatedFrom && { original_created_from: qOriginalCreatedFrom }), | |||||
| ...(qOriginalCreatedTo && { original_created_to: qOriginalCreatedTo }), | |||||
| ...(qCreatedFrom && { created_from: qCreatedFrom }), | |||||
| ...(qCreatedTo && { created_to: qCreatedTo }), | |||||
| ...(qUpdatedFrom && { updated_from: qUpdatedFrom }), | |||||
| ...(qUpdatedTo && { updated_to: qUpdatedTo }) } | |||||
| const { data, isLoading: loading } = useQuery ({ | |||||
| queryKey: postsKeys.index (keys), | |||||
| queryFn: () => fetchPosts (keys) }) | |||||
| const results = data?.posts ?? [] | const results = data?.posts ?? [] | ||||
| const totalPages = data ? Math.ceil (data.count / limit) : 0 | const totalPages = data ? Math.ceil (data.count / limit) : 0 | ||||
| useEffect (() => { | |||||
| setURL (qURL ?? '') | |||||
| setTitle (qTitle ?? '') | |||||
| setTagsStr (qTags ?? '') | |||||
| setMatchType (qMatch ?? 'all') | |||||
| setOriginalCreatedFrom (qOriginalCreatedFrom) | |||||
| setOriginalCreatedTo (qOriginalCreatedTo) | |||||
| setCreatedFrom (qCreatedFrom) | |||||
| setCreatedTo (qCreatedTo) | |||||
| setUpdatedFrom (qUpdatedFrom) | |||||
| setUpdatedTo (qUpdatedTo) | |||||
| document.getElementsByTagName ('main')![0].scroll (0, 0) | |||||
| }, [location.search]) | |||||
| const search = async () => { | const search = async () => { | ||||
| const qs = new URLSearchParams (location.search) | |||||
| const qs = new URLSearchParams () | |||||
| setIf (qs, 'tags', tagsStr) | |||||
| setIf (qs, 'url', url) | |||||
| setIf (qs, 'title', title) | |||||
| setIf (qs, 'original_created_from', originalCreatedFrom) | |||||
| setIf (qs, 'original_created_to', originalCreatedTo) | |||||
| setIf (qs, 'created_from', createdFrom) | |||||
| setIf (qs, 'created_to', createdTo) | |||||
| setIf (qs, 'updated_from', updatedFrom) | |||||
| setIf (qs, 'updated_to', updatedTo) | |||||
| qs.set ('match', matchType) | |||||
| qs.set ('page', String ('1')) | qs.set ('page', String ('1')) | ||||
| navigate (`${ location.pathname }?${ qs.toString () }`) | navigate (`${ location.pathname }?${ qs.toString () }`) | ||||
| } | } | ||||
| @@ -175,7 +215,7 @@ export default (() => { | |||||
| </form> | </form> | ||||
| </div> | </div> | ||||
| {results.length > 0 && ( | |||||
| {loading ? 'Loading...' : (results.length > 0 ? ( | |||||
| <div className="mt-4"> | <div className="mt-4"> | ||||
| <div className="overflow-x-auto"> | <div className="overflow-x-auto"> | ||||
| <table className="w-full min-w-[1200px] table-fixed border-collapse"> | <table className="w-full min-w-[1200px] table-fixed border-collapse"> | ||||
| @@ -241,6 +281,6 @@ export default (() => { | |||||
| </div> | </div> | ||||
| <Pagination page={page} totalPages={totalPages}/> | <Pagination page={page} totalPages={totalPages}/> | ||||
| </div>)} | |||||
| </div>) : '結果ないよ(笑)')} | |||||
| </MainArea>) | </MainArea>) | ||||
| }) satisfies FC | }) satisfies FC | ||||