Procházet zdrojové kódy

feat: implmenet users and posts pagination

Mohammad Mahdi Salimi před 1 měsícem
rodič
revize
f149558419

+ 10 - 2
src/features/posts/components/posts-table.tsx

@@ -21,15 +21,22 @@ import {
 import { DataTablePagination, DataTableToolbar } from '@/components/data-table'
 import { DataTableBulkActions } from './data-table-bulk-actions'
 import { postsColumns as columns } from './posts-columns'
-import { type Post } from '@/types/posts.types'
+import type { Post } from '@/types/posts.types'
+import type { Pagination } from '@/types/common.types'
 
 type DataTableProps = {
   data: Post[]
+  paginationData?: Pagination
   search: Record<string, unknown>
   navigate: NavigateFn
 }
 
-export function PostsTable({ data, search, navigate }: DataTableProps) {
+export function PostsTable({
+  data,
+  paginationData,
+  search,
+  navigate,
+}: DataTableProps) {
   // Local UI-only states
   const [rowSelection, setRowSelection] = useState({})
   const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
@@ -70,6 +77,7 @@ export function PostsTable({ data, search, navigate }: DataTableProps) {
       columnFilters,
       columnVisibility,
     },
+    pageCount: paginationData?.last_page ?? -1,
     manualPagination: true,
     manualFiltering: true,
     manualSorting: true,

+ 11 - 2
src/features/posts/index.tsx

@@ -16,8 +16,12 @@ export function Posts() {
   const search = route.useSearch()
   const navigate = route.useNavigate()
 
-  const { data, isLoading } = usePosts({ page: 1, per_page: 10 })
+  const { data, isLoading } = usePosts({
+    page: search.page ?? 1,
+    per_page: search.pageSize ?? 10,
+  })
   const posts = data?.data?.posts
+  const paginationInfo = data?.data?.pagination
 
   return (
     <PostsProvider>
@@ -40,7 +44,12 @@ export function Posts() {
         {isLoading ? (
           <div>در حال دریافت...</div>
         ) : (
-          <PostsTable data={posts ?? []} search={search} navigate={navigate} />
+          <PostsTable
+            data={posts ?? []}
+            paginationData={paginationInfo}
+            search={search}
+            navigate={navigate}
+          />
         )}
       </Main>
 

+ 9 - 1
src/features/users/components/users-table.tsx

@@ -22,14 +22,21 @@ import { DataTablePagination, DataTableToolbar } from '@/components/data-table'
 import { DataTableBulkActions } from './data-table-bulk-actions'
 import { usersColumns as columns } from './users-columns'
 import { type User } from '@/types/users.types'
+import { type Pagination } from '@/types/common.types'
 
 type DataTableProps = {
   data: User[]
+  paginationData?: Pagination
   search: Record<string, unknown>
   navigate: NavigateFn
 }
 
-export function UsersTable({ data, search, navigate }: DataTableProps) {
+export function UsersTable({
+  data,
+  paginationData,
+  search,
+  navigate,
+}: DataTableProps) {
   // Local UI-only states
   const [rowSelection, setRowSelection] = useState({})
   const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
@@ -70,6 +77,7 @@ export function UsersTable({ data, search, navigate }: DataTableProps) {
       columnFilters,
       columnVisibility,
     },
+    pageCount: paginationData?.last_page ?? -1,
     manualPagination: true,
     manualFiltering: true,
     manualSorting: true,

+ 15 - 2
src/features/users/index.tsx

@@ -17,8 +17,12 @@ export function Users() {
   const search = route.useSearch()
   const navigate = route.useNavigate()
 
-  const { data } = useUsers({ page: 1, per_page: 10 })
+  const { data, isLoading } = useUsers({
+    page: search.page ?? 1,
+    per_page: search.pageSize ?? 10,
+  })
   const users = data?.data.users
+  const paginationInfo = data?.data?.pagination
 
   return (
     <UsersProvider>
@@ -39,7 +43,16 @@ export function Users() {
           </div>
           <UsersPrimaryButtons />
         </div>
-        <UsersTable data={users ?? []} search={search} navigate={navigate} />
+        {isLoading ? (
+          <div>در حال دریافت...</div>
+        ) : (
+          <UsersTable
+            data={users ?? []}
+            paginationData={paginationInfo}
+            search={search}
+            navigate={navigate}
+          />
+        )}
       </Main>
 
       <UsersDialogs />

+ 8 - 1
src/routes/_authenticated/posts/index.tsx

@@ -1,6 +1,13 @@
-import { Posts } from '@/features/posts'
+import z from 'zod'
 import { createFileRoute } from '@tanstack/react-router'
+import { Posts } from '@/features/posts'
+
+const postsSearchSchema = z.object({
+  page: z.coerce.number().optional().catch(1),
+  pageSize: z.coerce.number().optional().catch(10),
+})
 
 export const Route = createFileRoute('/_authenticated/posts/')({
+  validateSearch: postsSearchSchema,
   component: Posts,
 })

+ 2 - 2
src/routes/_authenticated/users/index.tsx

@@ -3,8 +3,8 @@ import { createFileRoute } from '@tanstack/react-router'
 import { Users } from '@/features/users'
 
 const usersSearchSchema = z.object({
-  page: z.number().optional().catch(1),
-  pageSize: z.number().optional().catch(10),
+  page: z.coerce.number().optional().catch(1),
+  pageSize: z.coerce.number().optional().catch(10),
   // Facet filters
   status: z
     .array(

+ 18 - 0
src/types/common.types.ts

@@ -3,6 +3,24 @@ export interface PaginationParams {
   per_page?: number
 }
 
+export interface Links {
+  first: string
+  last: string
+  prev: null
+  next: string
+}
+
+export interface Pagination {
+  current_page: number
+  last_page: number
+  per_page: number
+  total: number
+  from: number
+  to: number
+  has_more_pages: boolean
+  links: Links
+}
+
 export type ApiResponse<T> = {
   success: boolean
   message: string

+ 1 - 17
src/types/posts.types.ts

@@ -1,20 +1,4 @@
-export interface Pagination {
-  current_page: number
-  last_page: number
-  per_page: number
-  total: number
-  from: number
-  to: number
-  has_more_pages: boolean
-  links: Links
-}
-
-export interface Links {
-  first: string
-  last: string
-  prev: null
-  next: string
-}
+import type { Pagination } from './common.types'
 
 export interface Post {
   id: number

+ 3 - 1
src/types/users.types.ts

@@ -1,3 +1,5 @@
+import type { Pagination } from './common.types'
+
 export interface User {
   id: number
   is_me: boolean
@@ -42,7 +44,7 @@ export interface GetUserResponse {
   message: string
   data: {
     users: User[]
-    meta?: UsersListMeta
+    pagination: Pagination
   }
 }