ファイル
btrc-hub/frontend/src/pages/help/HelpChangesPage.tsx
T
みてるぞ e44887cf15 ヘルプを Wiki から分離 (#424) (#430)
画面上でのテストは完了.
移行にす早さが求められるので,準備ができたらマージする.

Reviewed-on: #430
Co-authored-by: miteruzo <miteruzo@naver.com>
2026-10-13 12:25:11 +09:00

120 行
4.1 KiB
TypeScript

import { useQuery } from '@tanstack/react-query'
import { useMemo } from 'react'
import { Helmet } from 'react-helmet-async'
import { useSearchParams } from 'react-router-dom'
import PrefetchLink from '@/components/PrefetchLink'
import PageTitle from '@/components/common/PageTitle'
import Pagination from '@/components/common/Pagination'
import MainArea from '@/components/layout/MainArea'
import { SITE_TITLE } from '@/config'
import { getHelpChanges, helpEditionDate } from '@/lib/help'
import { helpKeys } from '@/lib/queryKeys'
import { LIST_LIMIT_OPTIONS } from '@/lib/settings'
import { dateString } from '@/lib/utils'
import type { FC } from 'react'
const HelpChangesPage: FC = () => {
const [searchParams, setSearchParams] = useSearchParams ()
const identifier = searchParams.get ('identifier') ?? ''
const pageValue = searchParams.get ('page') ?? '1'
const pageNumber = Number (pageValue)
const requestedPage =
(/^[1-9]\d*$/.test (pageValue) && Number.isSafeInteger (pageNumber))
? pageNumber : 1
const limit = LIST_LIMIT_OPTIONS.find (
value => String (value) === searchParams.get ('limit')) ?? 20
const { data: changes = [], isLoading, error } = useQuery ({
queryKey: helpKeys.changes ('ja'),
queryFn: () => getHelpChanges ('ja'),
staleTime: Infinity })
const results = useMemo (() => identifier
? changes.filter (entry => entry.identifier === identifier)
: changes, [changes, identifier])
const totalPages = Math.ceil (results.length / limit)
const page = requestedPage <= Math.max (1, totalPages) ? requestedPage : 1
const pageResults = results.slice ((page - 1) * limit, page * limit)
const handleLimit = (value: string) => {
const next = new URLSearchParams (searchParams)
next.set ('limit', value)
next.set ('page', '1')
setSearchParams (next)
}
return (
<MainArea className="min-w-0 max-w-full">
<Helmet>
<title>{`ヘルプ改定履歴 | ${ SITE_TITLE }`}</title>
</Helmet>
<div className="flex flex-wrap items-center justify-between gap-3">
<PageTitle>ヘルプ改定履歴</PageTitle>
<label className="flex items-center gap-2 text-xs text-muted-foreground">
<span>件数</span>
<select value={limit} onChange={ev => handleLimit (ev.target.value)}
className="rounded border border-border bg-background px-2 py-1 text-sm
text-foreground">
{LIST_LIMIT_OPTIONS.map (value => (
<option key={value} value={value}>{value}</option>))}
</select>
</label>
</div>
{isLoading
? <p className="mt-4">読み込み中...</p>
: (error
? <p className="mt-4 text-red-600" role="alert">{error.message}</p>
: (
<div className="mt-4">
<div className="min-w-0 max-w-full overflow-x-auto">
<table className="table-auto w-full min-w-[900px] whitespace-nowrap
border-collapse">
<thead className="border-b-2 border-black dark:border-white">
<tr>
<th className="p-2 text-left">差分</th>
<th className="p-2 text-left">タイトル</th>
<th className="p-2 text-left">有効開始年月日</th>
</tr>
</thead>
<tbody>
{pageResults.map (entry => {
const path = `/help/${ encodeURIComponent (entry.identifier) }`
const diffQuery = new URLSearchParams ({
from: entry.pred ?? '', to: entry.edition })
const diffTo = `${ path }/diff?${ diffQuery.toString () }`
const updatedAt = helpEditionDate (entry.edition)
return (
<tr key={`${ entry.identifier }/${ entry.edition }`}
className="even:bg-gray-100 text-gray-900
dark:even:bg-gray-700 dark:text-gray-100">
<td className="p-2">
{entry.pred != null && (
<PrefetchLink to={diffTo}>
差分
</PrefetchLink>)}
</td>
<td className="p-2">
<PrefetchLink to={`${ path }?edition=${ entry.edition }`}>
{entry.title}
</PrefetchLink>
</td>
<td className="p-2">
{updatedAt != null && dateString (updatedAt, 'hour')}
</td>
</tr>)
})}
</tbody>
</table>
</div>
{totalPages > 0 && <Pagination page={page} totalPages={totalPages}/>}
</div>))}
</MainArea>)
}
export default HelpChangesPage