arbret/frontend/app/components/PageLayout.tsx
counterweight d838d1be96
Step 4: Add admin UI page for pricing configuration
- Add pricing API functions to admin.ts
- Create admin pricing page with form and validation
- Add MANAGE_PRICING permission to auth context
- Add pricing to admin navigation
- Add translations for pricing page (en, ca, es)
- Update PageLayout and Header types for new page
2025-12-26 20:17:48 +01:00

66 lines
1.5 KiB
TypeScript

import { ReactNode } from "react";
import { Header } from "./Header";
import { LoadingState } from "./LoadingState";
import { ErrorDisplay } from "./ErrorDisplay";
import { layoutStyles } from "../styles/shared";
type PageId =
| "profile"
| "invites"
| "exchange"
| "trades"
| "admin-invites"
| "admin-availability"
| "admin-trades"
| "admin-price-history"
| "admin-pricing";
interface PageLayoutProps {
/** Current page ID for navigation highlighting */
currentPage: PageId;
/** Whether the page is loading (shows loading state) */
isLoading?: boolean;
/** Whether the user is authorized (hides page if false) */
isAuthorized?: boolean;
/** Error message to display */
error?: string | null;
/** Page content */
children: ReactNode;
/** Custom content wrapper style */
contentStyle?: React.CSSProperties;
}
/**
* Standard page layout component that handles common page structure:
* - Loading state
* - Authorization check
* - Header navigation
* - Error banner
* - Content wrapper
*/
export function PageLayout({
currentPage,
isLoading = false,
isAuthorized = true,
error,
children,
contentStyle,
}: PageLayoutProps) {
if (isLoading) {
return <LoadingState />;
}
if (!isAuthorized) {
return null;
}
return (
<main style={layoutStyles.main}>
<Header currentPage={currentPage} />
<div style={contentStyle || layoutStyles.contentCentered}>
<ErrorDisplay error={error} />
{children}
</div>
</main>
);
}