ぼざクリタグ広場 https://hub.nizika.monster
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

102 lines
3.2 KiB

  1. import { useQuery } from '@tanstack/react-query'
  2. import { Helmet } from 'react-helmet-async'
  3. import { useLocation } from 'react-router-dom'
  4. import TagLink from '@/components/TagLink'
  5. import PrefetchLink from '@/components/PrefetchLink'
  6. import PageTitle from '@/components/common/PageTitle'
  7. import Pagination from '@/components/common/Pagination'
  8. import MainArea from '@/components/layout/MainArea'
  9. import { SITE_TITLE } from '@/config'
  10. import { fetchPostChanges } from '@/lib/posts'
  11. import { postsKeys } from '@/lib/queryKeys'
  12. import { cn } from '@/lib/utils'
  13. import type { FC } from 'react'
  14. export default (() => {
  15. const location = useLocation ()
  16. const query = new URLSearchParams (location.search)
  17. const id = query.get ('id')
  18. const page = Number (query.get ('page') ?? 1)
  19. const limit = Number (query.get ('limit') ?? 20)
  20. // 投稿列の結合で使用
  21. let rowsCnt: number
  22. const { data, isLoading: loading } = useQuery ({
  23. queryKey: postsKeys.changes ({ ...(id && { id }), page, limit }),
  24. queryFn: () => fetchPostChanges ({ ...(id && { id }), page, limit }) })
  25. const changes = data?.changes ?? []
  26. const totalPages = data ? Math.ceil (data.count / limit) : 0
  27. return (
  28. <MainArea>
  29. <Helmet>
  30. <title>{`耕作履歴 | ${ SITE_TITLE }`}</title>
  31. </Helmet>
  32. <PageTitle>
  33. 耕作履歴
  34. {id && <>: 投稿 {<PrefetchLink to={`/posts/${ id }`}>#{id}</PrefetchLink>}</>}
  35. </PageTitle>
  36. {loading ? 'Loading...' : (
  37. <>
  38. <table className="table-auto w-full border-collapse">
  39. <thead className="border-b-2 border-black dark:border-white">
  40. <tr>
  41. <th className="p-2 text-left">投稿</th>
  42. <th className="p-2 text-left">変更</th>
  43. <th className="p-2 text-left">日時</th>
  44. </tr>
  45. </thead>
  46. <tbody>
  47. {changes.map ((change, i) => {
  48. let withPost = i === 0 || change.post.id !== changes[i - 1].post.id
  49. if (withPost)
  50. {
  51. rowsCnt = 1
  52. for (let j = i + 1;
  53. (j < changes.length
  54. && change.post.id === changes[j].post.id);
  55. ++j)
  56. ++rowsCnt
  57. }
  58. return (
  59. <tr key={`${ change.timestamp }-${ change.post.id }-${ change.tag.id }`}
  60. className={cn ('even:bg-gray-100 dark:even:bg-gray-700',
  61. withPost && 'border-t')}>
  62. {withPost && (
  63. <td className="align-top p-2 bg-white dark:bg-[#242424] border-r"
  64. rowSpan={rowsCnt}>
  65. <PrefetchLink to={`/posts/${ change.post.id }`}>
  66. <img src={change.post.thumbnail || change.post.thumbnailBase || undefined}
  67. alt={change.post.title || change.post.url}
  68. title={change.post.title || change.post.url || undefined}
  69. className="w-40"/>
  70. </PrefetchLink>
  71. </td>)}
  72. <td className="p-2">
  73. <TagLink tag={change.tag} withWiki={false} withCount={false}/>
  74. {`を${ change.changeType === 'add' ? '記載' : '消除' }`}
  75. </td>
  76. <td className="p-2">
  77. {change.user ? (
  78. <PrefetchLink to={`/users/${ change.user.id }`}>
  79. {change.user.name}
  80. </PrefetchLink>) : 'bot 操作'}
  81. <br/>
  82. {change.timestamp}
  83. </td>
  84. </tr>)
  85. })}
  86. </tbody>
  87. </table>
  88. <Pagination page={page} totalPages={totalPages}/>
  89. </>)}
  90. </MainArea>)
  91. }) satisfies FC