Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
103 lines
2.6 KiB
TypeScript
103 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import type { PaginationListColumnType } from '@/types'
|
|
import PaginatedList from '@/components/PaginatedList'
|
|
import AdminTableViewButton from '@/components/ui/AdminTableViewButton'
|
|
import Modal from '@/components/modals/Modal'
|
|
import { APP_ROUTES } from '@/constants/routes'
|
|
import { formatPersonName, coerceToString } from '@/helpers'
|
|
import { API_ROUTES } from '@/services/config'
|
|
import { formatIranianMobile, formatPersianDate } from '@/lib/formatters'
|
|
|
|
export interface GuestListItemRow {
|
|
id: string
|
|
listId: string
|
|
mobile: string
|
|
firstName: string | null
|
|
lastName: string | null
|
|
userId: string | null
|
|
note: string | null
|
|
createdAt: string
|
|
}
|
|
|
|
interface GuestListItemsModalProps {
|
|
isOpen: boolean
|
|
onOpenChange: (isOpen: boolean) => void
|
|
list: { id: string; name: string } | null
|
|
}
|
|
|
|
const columns: PaginationListColumnType[] = [
|
|
{
|
|
field: 'mobile',
|
|
label: 'موبایل',
|
|
filterable: false,
|
|
sortable: false,
|
|
},
|
|
{
|
|
field: 'firstName',
|
|
label: 'نام',
|
|
filterable: false,
|
|
sortable: true,
|
|
},
|
|
{
|
|
field: 'note',
|
|
label: 'یادداشت',
|
|
filterable: false,
|
|
sortable: false,
|
|
},
|
|
{
|
|
field: 'createdAt',
|
|
label: 'تاریخ افزودن',
|
|
filterable: false,
|
|
sortable: true,
|
|
},
|
|
{
|
|
field: 'actions',
|
|
label: 'عملیات',
|
|
},
|
|
]
|
|
|
|
const GuestListItemsModal = ({ isOpen, onOpenChange, list }: GuestListItemsModalProps) => (
|
|
<Modal
|
|
hideFooter
|
|
isOpen={isOpen}
|
|
size="3xl"
|
|
title={list ? `مخاطبین «${list.name}»` : 'مخاطبین لیست'}
|
|
onOpenChange={onOpenChange}
|
|
>
|
|
{list && (
|
|
<PaginatedList
|
|
key={list.id}
|
|
columns={columns}
|
|
url={API_ROUTES.GUEST_LISTS.ADMIN_ITEMS(list.id)}
|
|
>
|
|
{{
|
|
mobile: (_row, cellValue) => <span dir="ltr">{formatIranianMobile(cellValue)}</span>,
|
|
firstName: (row) => {
|
|
const item = row as unknown as GuestListItemRow
|
|
|
|
return formatPersonName(item.firstName, item.lastName)
|
|
},
|
|
note: (_row, cellValue) => (cellValue ? coerceToString(cellValue) : '—'),
|
|
createdAt: (_row, cellValue) => formatPersianDate(cellValue),
|
|
actions: (row) => {
|
|
const item = row as unknown as GuestListItemRow
|
|
|
|
if (!item.userId) return '—'
|
|
|
|
return (
|
|
<AdminTableViewButton
|
|
label="مشاهده کاربر"
|
|
mode="navigate"
|
|
to={APP_ROUTES.USER_DETAIL(item.userId)}
|
|
/>
|
|
)
|
|
},
|
|
}}
|
|
</PaginatedList>
|
|
)}
|
|
</Modal>
|
|
)
|
|
|
|
export default GuestListItemsModal
|