- Refactored layout structure in multiple components to enhance consistency and maintainability by introducing outer and inner wrapper classes. - Updated the `MonthNavHeader` component for shared month navigation functionality, improving code reuse. - Adjusted padding and margin properties in various components to ensure a cohesive design and better responsiveness. - Removed unnecessary padding from certain elements to streamline the layout and improve visual clarity.
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
/**
|
|
* Shared full-screen state layout for fallback screens (access denied, not-found, error).
|
|
* Uses content-safe, app tokens, and consistent spacing so all fallback screens look like the same app.
|
|
*/
|
|
|
|
"use client";
|
|
|
|
export interface FullScreenStateShellProps {
|
|
/** Main heading (e.g. "Access denied", "Page not found"). */
|
|
title: React.ReactNode;
|
|
/** Optional description or message below the title. */
|
|
description?: React.ReactNode;
|
|
/** Optional extra content (e.g. server detail, secondary text). */
|
|
children?: React.ReactNode;
|
|
/** Primary action (Button or Link). */
|
|
primaryAction: React.ReactNode;
|
|
/** Wrapper role. Default "alert" for error/denied states. */
|
|
role?: "alert" | "status";
|
|
/** Optional extra class names for the wrapper. */
|
|
className?: string;
|
|
}
|
|
|
|
const OUTER_CLASS =
|
|
"content-safe flex min-h-[var(--tg-viewport-stable-height,100vh)] flex-col items-center justify-center gap-4 bg-background text-foreground";
|
|
const INNER_CLASS = "mx-auto w-full max-w-[var(--max-width-app)] px-3 flex flex-col items-center gap-4";
|
|
|
|
/**
|
|
* Full-screen centered shell with title, optional description, and primary action.
|
|
* Use for access denied, not-found, and in-app error boundary screens.
|
|
*/
|
|
export function FullScreenStateShell({
|
|
title,
|
|
description,
|
|
children,
|
|
primaryAction,
|
|
role = "alert",
|
|
className,
|
|
}: FullScreenStateShellProps) {
|
|
return (
|
|
<div
|
|
className={className ? `${OUTER_CLASS} ${className}` : OUTER_CLASS}
|
|
role={role}
|
|
>
|
|
<div className={INNER_CLASS}>
|
|
<h1 className="text-xl font-semibold">{title}</h1>
|
|
{description != null && (
|
|
<p className="text-center text-muted-foreground">{description}</p>
|
|
)}
|
|
{children}
|
|
{primaryAction}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|