Components: - DashboardShell — main layout combining sidebar + topbar + content area - Sidebar — collapsible nav with sections, badges, active state, auto-settings link - TopBar — user avatar/menu, notifications bell, sign out, custom actions - ProfilePage — avatar, name/email form, loading/error/success states - BillingPage — current plan card, status badge, trial info, plan comparison grid - SettingsPage — section-based layout with empty state Features: - NavItem[] or NavSection[] for flat or grouped navigation - ShellFeatures toggle: profile, billing, settings, notifications, themeToggle - ShellUser with avatar, role, initials fallback - onNavigate callback for SPA routers (Next.js, etc.) - Collapsible sidebar with toggle button - All styled via --bl-shell-* CSS custom properties with fallbacks - 41 tests covering all components
72 lines
1.8 KiB
TypeScript
72 lines
1.8 KiB
TypeScript
import type { ReactNode } from 'react';
|
|
import type { SettingsPageProps } from './types.js';
|
|
|
|
export function SettingsPage({ productName, sections = [] }: SettingsPageProps): ReactNode {
|
|
return (
|
|
<div data-testid="bl-shell-settings-page" style={{ maxWidth: 700 }}>
|
|
<h1
|
|
style={{
|
|
fontSize: 24,
|
|
fontWeight: 700,
|
|
marginBottom: 24,
|
|
color: 'var(--color-foreground, #111827)',
|
|
}}
|
|
>
|
|
Settings
|
|
</h1>
|
|
|
|
{sections.length === 0 && (
|
|
<div
|
|
data-testid="bl-settings-empty"
|
|
style={{
|
|
padding: 32,
|
|
textAlign: 'center',
|
|
color: 'var(--color-muted-foreground, #6b7280)',
|
|
fontSize: 14,
|
|
}}
|
|
>
|
|
No settings configured for {productName}.
|
|
</div>
|
|
)}
|
|
|
|
{sections.map((section, i) => (
|
|
<div
|
|
key={i}
|
|
data-testid={`bl-settings-section-${i}`}
|
|
style={{
|
|
padding: 24,
|
|
borderRadius: 12,
|
|
border: '1px solid var(--bl-shell-border, var(--color-border, #e5e7eb))',
|
|
marginBottom: 16,
|
|
background: 'var(--color-surface, #fff)',
|
|
}}
|
|
>
|
|
<h2
|
|
style={{
|
|
fontSize: 16,
|
|
fontWeight: 600,
|
|
marginBottom: 4,
|
|
color: 'var(--color-foreground, #111827)',
|
|
}}
|
|
>
|
|
{section.title}
|
|
</h2>
|
|
{section.description && (
|
|
<p
|
|
style={{
|
|
fontSize: 14,
|
|
color: 'var(--color-muted-foreground, #6b7280)',
|
|
marginBottom: 16,
|
|
marginTop: 0,
|
|
}}
|
|
>
|
|
{section.description}
|
|
</p>
|
|
)}
|
|
<div>{section.content}</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|