admin/components/paginated-list/PaginatedListPagination.tsx
alisaza e1eaf5eff5 feat: initial ghabilee-admin backoffice app
Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js
app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
2026-09-05 13:12:59 +03:30

112 lines
3.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import type { Selection } from '@/types/heroui'
import { Pagination } from '@/components/heroui/Pagination'
import Button from '@/components/formElements/Button'
import Input from '@/components/formElements/Input'
import AngleLeftIcon from '@/components/icons/AngleLeftIcon'
import { FIELD_RADIUS, FIELD_WRAPPER } from '@/constants/formFieldStyles'
export const ROWS_PER_PAGE_OPTIONS = [20, 30, 45, 50, 100].map((value) => ({
code: String(value),
name: `${value} ردیف`,
}))
interface Props {
dataLength: number
page: number
pages: number
rowsPerPage: number
selectedKeys: Selection
selectionMode: 'single' | 'multiple' | 'none'
totalItems: number
onNextPage: () => void
onPageChange: (page: number) => void
onPreviousPage: () => void
onRowsPerPageChange: (rowsPerPage: number) => void
}
export default function PaginatedListPagination({
dataLength,
page,
pages,
rowsPerPage,
selectedKeys,
selectionMode,
totalItems,
onNextPage,
onPageChange,
onPreviousPage,
onRowsPerPageChange,
}: Props) {
return (
<div className="flex flex-col items-center justify-between gap-3 border-t border-secondary-40 bg-secondary-50/60 px-4 py-3 lg:flex-row">
{selectionMode !== 'none' && (
<div className="flex items-center gap-2 text-nowrap text-small text-default-400">
<span>{selectedKeys === 'all' ? 'تمامی سطرها انتخاب شدند' : `${selectedKeys.size} تا از ${dataLength} انتخاب شدند`}</span>
<span>|</span>
<span>تعداد کل: {dataLength}</span>
</div>
)}
{!!rowsPerPage && (
<div className="flex w-full items-center gap-2 text-nowrap text-xs text-secondary-30 lg:w-auto">
<span>نمایش </span>
<Input
ariaLabel="تعداد ردیف در صفحه"
className="min-w-[7rem]"
generalType="select"
inputWrapper={FIELD_WRAPPER}
isClearable={false}
name="rowsPerPage"
radius={FIELD_RADIUS}
selectKey="code"
selectOptions={ROWS_PER_PAGE_OPTIONS}
selectValue="name"
size="sm"
value={String(rowsPerPage)}
variant="bordered"
onValueChange={(next) => {
onRowsPerPageChange(Number(next))
}}
/>
<span>از {totalItems}</span>
</div>
)}
{!!page && !!pages && !!rowsPerPage && (
<Pagination
isCompact
showControls
showShadow
className="max-w-full overflow-x-auto"
color="primary"
page={page}
total={pages}
onChange={onPageChange}
/>
)}
<div className="hidden w-[30%] justify-end gap-2 lg:flex">
<Button
color="default"
disabled={page === 1}
iconStart={<AngleLeftIcon className="size-6 rotate-180 text-text" />}
size="sm"
variant="flat"
onClick={onPreviousPage}
>
قبلی
</Button>
<Button
color="default"
disabled={page === pages}
iconEnd={<AngleLeftIcon className="size-6 text-text" />}
size="sm"
variant="flat"
onClick={onNextPage}
>
بعدی
</Button>
</div>
</div>
)
}