Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
112 lines
3.3 KiB
TypeScript
112 lines
3.3 KiB
TypeScript
'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>
|
||
)
|
||
}
|