|
|
@@ -1,6 +1,7 @@ |
|
|
|
|
|
import { useQuery } from '@tanstack/react-query' |
|
|
import { useState } from 'react' |
|
|
import { useState } from 'react' |
|
|
import { Helmet } from 'react-helmet-async' |
|
|
import { Helmet } from 'react-helmet-async' |
|
|
import { useLocation } from 'react-router-dom' |
|
|
|
|
|
|
|
|
import { useLocation, useNavigate } from 'react-router-dom' |
|
|
|
|
|
|
|
|
import PrefetchLink from '@/components/PrefetchLink' |
|
|
import PrefetchLink from '@/components/PrefetchLink' |
|
|
import TagLink from '@/components/TagLink' |
|
|
import TagLink from '@/components/TagLink' |
|
|
@@ -11,42 +12,56 @@ import Pagination from '@/components/common/Pagination' |
|
|
import MainArea from '@/components/layout/MainArea' |
|
|
import MainArea from '@/components/layout/MainArea' |
|
|
import { SITE_TITLE } from '@/config' |
|
|
import { SITE_TITLE } from '@/config' |
|
|
import { fetchPosts } from '@/lib/posts' |
|
|
import { fetchPosts } from '@/lib/posts' |
|
|
|
|
|
import { postsKeys } from '@/lib/queryKeys' |
|
|
|
|
|
|
|
|
import type { FC, FormEvent } from 'react' |
|
|
import type { FC, FormEvent } from 'react' |
|
|
|
|
|
|
|
|
import type { Post } from '@/types' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default (() => { |
|
|
export default (() => { |
|
|
const [createdFrom, setCreatedFrom] = useState<string | undefined> () |
|
|
|
|
|
const [createdTo, setCreatedTo] = useState<string | undefined> () |
|
|
|
|
|
const [matchType, setMatchType] = useState<'all' | 'any'> ('all') |
|
|
|
|
|
const [originalCreatedFrom, setOriginalCreatedFrom] = useState<string | undefined> () |
|
|
|
|
|
const [originalCreatedTo, setOriginalCreatedTo] = useState<string | undefined> () |
|
|
|
|
|
const [tagsStr, setTagsStr] = useState ('') |
|
|
|
|
|
const [title, setTitle] = useState ('') |
|
|
|
|
|
const [updatedFrom, setUpdatedFrom] = useState<string | undefined> () |
|
|
|
|
|
const [updatedTo, setUpdatedTo] = useState<string | undefined> () |
|
|
|
|
|
const [url, setURL] = useState ('') |
|
|
|
|
|
const [results, setResults] = useState<Post[]> ([]) |
|
|
|
|
|
const [totalPages, setTotalPages] = useState (0) |
|
|
|
|
|
|
|
|
const navigate = useNavigate () |
|
|
|
|
|
|
|
|
const location = useLocation () |
|
|
const location = useLocation () |
|
|
const query = new URLSearchParams (location.search) |
|
|
const query = new URLSearchParams (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 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) }) |
|
|
|
|
|
const results = data?.posts ?? [] |
|
|
|
|
|
const totalPages = data ? Math.ceil (data.count / limit) : 0 |
|
|
|
|
|
|
|
|
const search = async () => { |
|
|
const search = async () => { |
|
|
const tags = tagsStr.split (' ').filter (e => e !== '') |
|
|
|
|
|
const data = await fetchPosts ({ |
|
|
|
|
|
url, title, tags: tags.join (' '), match: matchType, |
|
|
|
|
|
created_from: createdFrom, created_to: createdTo, |
|
|
|
|
|
updated_from: updatedFrom, updated_to: updatedTo, |
|
|
|
|
|
original_created_from: originalCreatedFrom, |
|
|
|
|
|
original_created_to: originalCreatedTo, |
|
|
|
|
|
page, limit }) |
|
|
|
|
|
setResults (data.posts) |
|
|
|
|
|
setTotalPages (data ? Math.ceil (data.count / limit) : 0) |
|
|
|
|
|
|
|
|
const qs = new URLSearchParams (location.search) |
|
|
|
|
|
qs.set ('page', String ('1')) |
|
|
|
|
|
navigate (`${ location.pathname }?${ qs.toString () }`) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const handleSearch = (e: FormEvent) => { |
|
|
const handleSearch = (e: FormEvent) => { |
|
|
@@ -118,11 +133,11 @@ export default (() => { |
|
|
<Label>オリジナルの投稿日時</Label> |
|
|
<Label>オリジナルの投稿日時</Label> |
|
|
<DateTimeField |
|
|
<DateTimeField |
|
|
value={originalCreatedFrom ?? undefined} |
|
|
value={originalCreatedFrom ?? undefined} |
|
|
onChange={isoUTC => setOriginalCreatedFrom (isoUTC ?? undefined)}/> |
|
|
|
|
|
|
|
|
onChange={setOriginalCreatedFrom}/> |
|
|
<span className="mx-1">〜</span> |
|
|
<span className="mx-1">〜</span> |
|
|
<DateTimeField |
|
|
<DateTimeField |
|
|
value={originalCreatedTo ?? undefined} |
|
|
value={originalCreatedTo ?? undefined} |
|
|
onChange={isoUTC => setOriginalCreatedTo (isoUTC ?? undefined)}/> |
|
|
|
|
|
|
|
|
onChange={setOriginalCreatedTo}/> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
{/* 投稿日時 */} |
|
|
{/* 投稿日時 */} |
|
|
@@ -130,11 +145,11 @@ export default (() => { |
|
|
<Label>投稿日時</Label> |
|
|
<Label>投稿日時</Label> |
|
|
<DateTimeField |
|
|
<DateTimeField |
|
|
value={createdFrom ?? undefined} |
|
|
value={createdFrom ?? undefined} |
|
|
onChange={isoUTC => setCreatedFrom (isoUTC ?? undefined)}/> |
|
|
|
|
|
|
|
|
onChange={setCreatedFrom}/> |
|
|
<span className="mx-1">〜</span> |
|
|
<span className="mx-1">〜</span> |
|
|
<DateTimeField |
|
|
<DateTimeField |
|
|
value={createdTo ?? undefined} |
|
|
value={createdTo ?? undefined} |
|
|
onChange={isoUTC => setCreatedTo (isoUTC ?? undefined)}/> |
|
|
|
|
|
|
|
|
onChange={setCreatedTo}/> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
{/* 更新日時 */} |
|
|
{/* 更新日時 */} |
|
|
@@ -142,11 +157,11 @@ export default (() => { |
|
|
<Label>更新日時</Label> |
|
|
<Label>更新日時</Label> |
|
|
<DateTimeField |
|
|
<DateTimeField |
|
|
value={updatedFrom ?? undefined} |
|
|
value={updatedFrom ?? undefined} |
|
|
onChange={isoUTC => setUpdatedFrom (isoUTC ?? undefined)}/> |
|
|
|
|
|
|
|
|
onChange={setUpdatedFrom}/> |
|
|
<span className="mx-1">〜</span> |
|
|
<span className="mx-1">〜</span> |
|
|
<DateTimeField |
|
|
<DateTimeField |
|
|
value={updatedTo ?? undefined} |
|
|
value={updatedTo ?? undefined} |
|
|
onChange={isoUTC => setUpdatedTo (isoUTC ?? undefined)}/> |
|
|
|
|
|
|
|
|
onChange={setUpdatedTo}/> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
{/* 検索 */} |
|
|
{/* 検索 */} |
|
|
|