Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import type { PropsWithChildren, ReactNode } from 'react'
|
|
|
|
import clsx from 'clsx'
|
|
|
|
type AdminFormSectionProps = PropsWithChildren<{
|
|
className?: string
|
|
contained?: boolean
|
|
description?: ReactNode
|
|
title: ReactNode
|
|
}>
|
|
|
|
export function AdminFormSection({ children, className, contained = true, description, title }: AdminFormSectionProps) {
|
|
return (
|
|
<section className={clsx(contained && 'admin-surface p-4', className)}>
|
|
<header className="flex items-start gap-3 border-b border-secondary-40 pb-3">
|
|
<span
|
|
aria-hidden
|
|
className="mt-2 size-2 shrink-0 rounded-full bg-primary-600 ring-4 ring-primary-50"
|
|
/>
|
|
<div>
|
|
<h2 className="text-sm font-bold text-secondary-10 sm:text-base">{title}</h2>
|
|
{description ? <p className="mt-1 text-xs leading-5 text-secondary-30">{description}</p> : null}
|
|
</div>
|
|
</header>
|
|
<div className="mt-5">{children}</div>
|
|
</section>
|
|
)
|
|
}
|
|
|
|
type AdminFormActionsProps = PropsWithChildren<{
|
|
className?: string
|
|
helper?: ReactNode
|
|
sticky?: boolean
|
|
}>
|
|
|
|
export function AdminFormActions({ children, className, helper, sticky = false }: AdminFormActionsProps) {
|
|
return (
|
|
<footer
|
|
className={clsx(
|
|
'flex flex-col-reverse gap-3 rounded-2xl border border-secondary-40 bg-white/95 p-3 shadow-[0_-4px_20px_rgba(51,58,68,0.04)] backdrop-blur sm:flex-row sm:items-center sm:justify-between sm:px-4',
|
|
sticky && 'sticky bottom-3 z-20',
|
|
className
|
|
)}
|
|
>
|
|
{helper ? <p className="text-xs leading-5 text-secondary-30">{helper}</p> : <span />}
|
|
<div className="flex flex-wrap items-center gap-2">{children}</div>
|
|
</footer>
|
|
)
|
|
}
|