Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
'use client'
|
|
|
|
import Button from '@/components/formElements/Button'
|
|
import EyeIcon from '@/components/icons/EyeIcon'
|
|
|
|
type AdminTableViewButtonProps = {
|
|
/** Accessible label, e.g. «مشاهده کاربر» */
|
|
label: string
|
|
disabled?: boolean
|
|
isLoading?: boolean
|
|
} & (
|
|
| {
|
|
/** Client-side navigation to a real detail route. */
|
|
mode: 'navigate'
|
|
to: string
|
|
onClick?: never
|
|
}
|
|
| {
|
|
/** Opens a same-page modal (with its own fetch) instead of navigating. */
|
|
mode: 'open-detail'
|
|
onClick: () => void
|
|
to?: never
|
|
}
|
|
)
|
|
|
|
/**
|
|
* Canonical admin-table “view details” control.
|
|
* Use only in the `actions` column — never as a cell-content stand-in for names/titles.
|
|
*
|
|
* Callers must declare exactly one of two interaction models via `mode`:
|
|
* - `mode: 'navigate'` — routes to a real detail page via `to`. Used by most tables. In 7 of
|
|
* these navigate cases (`payments`, `bookings`, `sms-messages`, `withdrawal-requests`,
|
|
* `identity-verifications`, `audit-logs` → the admin user, `user-reports` → the reported
|
|
* user) the destination is a *related entity's* detail page rather than the row's own,
|
|
* because those row types (payments, bookings, SMS messages, audit-log entries, identity
|
|
* verifications, user reports) have no dedicated detail route of their own — the user's
|
|
* detail page is the most useful place to send the admin instead. This is an intentional,
|
|
* audited product decision, not a bug — do not "fix" these to point at a nonexistent
|
|
* own-entity route.
|
|
* - `mode: 'open-detail'` — opens a local `Modal` that does its own fetch, instead of
|
|
* navigating (e.g. `settlements/page.tsx`, `guest-lists/page.tsx`).
|
|
*/
|
|
const AdminTableViewButton = (props: AdminTableViewButtonProps) => {
|
|
const { label, disabled, isLoading } = props
|
|
const to = props.mode === 'navigate' ? props.to : undefined
|
|
const onClick = props.mode === 'open-detail' ? props.onClick : undefined
|
|
|
|
return (
|
|
<Button
|
|
iconOnly
|
|
aria-label={label}
|
|
color="warning"
|
|
disabled={disabled}
|
|
isLoading={isLoading}
|
|
size="sm"
|
|
to={to}
|
|
variant="flat"
|
|
onClick={onClick}
|
|
>
|
|
<EyeIcon className="size-4" />
|
|
</Button>
|
|
)
|
|
}
|
|
|
|
export default AdminTableViewButton
|