Initial Switch to V2. Completely Overhauled Backend, Frontend and General Structure.
This commit is contained in:
71
frontend/src/components/ui/PageHeader.jsx
Normal file
71
frontend/src/components/ui/PageHeader.jsx
Normal file
@@ -0,0 +1,71 @@
|
||||
// src/v2/components/ui/PageHeader.jsx
|
||||
// Standard page title block. Every page starts with this component.
|
||||
//
|
||||
// Props:
|
||||
// title — string (required) — main page heading
|
||||
// subtitle — string — muted description below the title
|
||||
// breadcrumbs — Array<{ label: string, href?: string }> — shown above the title
|
||||
// children — ReactNode — action buttons rendered top-right
|
||||
// className — extra classes on the wrapper
|
||||
//
|
||||
// Layout:
|
||||
// [breadcrumbs?]
|
||||
// [title] [children / actions →]
|
||||
// [subtitle?]
|
||||
//
|
||||
// Styles: src/v2/styles/components.css (.page-header*, .breadcrumbs*)
|
||||
|
||||
export default function PageHeader({
|
||||
title,
|
||||
subtitle,
|
||||
breadcrumbs,
|
||||
children,
|
||||
className = '',
|
||||
}) {
|
||||
return (
|
||||
<header className={`page-header ${className}`}>
|
||||
{/* Breadcrumb trail — only on detail pages */}
|
||||
{breadcrumbs?.length > 0 && (
|
||||
<nav aria-label="Breadcrumb" className="breadcrumbs">
|
||||
{breadcrumbs.map((crumb, i) => {
|
||||
const isLast = i === breadcrumbs.length - 1
|
||||
return (
|
||||
<span key={i} className="contents">
|
||||
{i > 0 && (
|
||||
<span className="breadcrumbs-sep" aria-hidden="true">
|
||||
/
|
||||
</span>
|
||||
)}
|
||||
{isLast || !crumb.href ? (
|
||||
<span
|
||||
className="breadcrumbs-current"
|
||||
aria-current={isLast ? 'page' : undefined}
|
||||
>
|
||||
{crumb.label}
|
||||
</span>
|
||||
) : (
|
||||
<a href={crumb.href}>{crumb.label}</a>
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
)}
|
||||
|
||||
{/* Title row */}
|
||||
<div className="page-header-row">
|
||||
<div className="min-w-0 flex-1">
|
||||
<h1 className="page-header-title">{title}</h1>
|
||||
{subtitle && (
|
||||
<p className="page-header-subtitle">{subtitle}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Action slot — top-right buttons */}
|
||||
{children && (
|
||||
<div className="page-header-actions">{children}</div>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user