52 lines
1.3 KiB
TypeScript
52 lines
1.3 KiB
TypeScript
import type { ReactNode } from 'react'
|
|
|
|
interface AdminCollapsibleCardProps {
|
|
title: string
|
|
subtitle?: string
|
|
hint?: string
|
|
previewUrl?: string
|
|
children: ReactNode
|
|
open?: boolean
|
|
className?: string
|
|
}
|
|
|
|
/**
|
|
* Reusable collapsible card for admin forms.
|
|
* Replaces the repeated <details>/<summary> pattern throughout AdminPage.
|
|
*/
|
|
export function AdminCollapsibleCard({
|
|
title,
|
|
subtitle,
|
|
hint = 'Expand to edit',
|
|
previewUrl,
|
|
children,
|
|
open = false,
|
|
className = '',
|
|
}: AdminCollapsibleCardProps) {
|
|
return (
|
|
<details className={`admin-collapsible-card ${className}`.trim()} open={open}>
|
|
<summary className="admin-collapsible-summary">
|
|
<div>
|
|
<strong>{title}</strong>
|
|
{subtitle && <p>{subtitle}</p>}
|
|
</div>
|
|
<div className="admin-collapsible-actions">
|
|
{previewUrl && (
|
|
<a
|
|
href={previewUrl}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="btn-admin-secondary"
|
|
onClick={e => e.stopPropagation()}
|
|
>
|
|
Preview
|
|
</a>
|
|
)}
|
|
<span className="admin-collapsible-hint">{hint}</span>
|
|
</div>
|
|
</summary>
|
|
<div className="admin-collapsible-body">{children}</div>
|
|
</details>
|
|
)
|
|
}
|