admin/components/feedback/AdminState.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

53 lines
1.6 KiB
TypeScript

import type { ReactNode } from 'react'
import clsx from 'clsx'
import Button from '@/components/formElements/Button'
import CloseCircleIcon from '@/components/icons/CloseCircleIcon'
import FileQuestionIcon from '@/components/icons/FileQuestionIcon'
interface AdminStateProps {
actionLabel?: string
className?: string
description?: string
icon?: ReactNode
title: string
variant?: 'empty' | 'error'
onAction?: () => void
}
const AdminState = ({ actionLabel, className, description, icon, title, variant = 'empty', onAction }: AdminStateProps) => {
const isError = variant === 'error'
return (
<div
className={clsx('flex min-h-56 flex-col items-center justify-center px-5 py-10 text-center', className)}
role={isError ? 'alert' : 'status'}
>
<span
className={clsx(
'mb-4 flex size-14 items-center justify-center rounded-2xl border',
isError ? 'border-fourth-100 bg-fourth-100 text-fourth-900' : 'border-border bg-surface-secondary text-muted'
)}
>
{icon ?? (isError ? <CloseCircleIcon className="size-6" /> : <FileQuestionIcon className="size-7" />)}
</span>
<p className="text-sm font-bold text-foreground md:text-base">{title}</p>
{description ? <p className="mt-2 max-w-sm text-xs leading-6 text-muted">{description}</p> : null}
{actionLabel && onAction ? (
<Button
className="mt-4"
color={isError ? 'danger' : 'primary'}
size="sm"
variant="flat"
onClick={onAction}
>
{actionLabel}
</Button>
) : null}
</div>
)
}
export default AdminState