"use client";
import { useState } from "react";
import { ThemeColor, TABLE_ROWS, SHADCN_THEMES, MANTINE_THEMES, HEROUI_THEMES, TREMOR_THEMES } from "./types";
// Web App surface — shows a logged-in SaaS product: Dashboard, Users, Settings
// This is what the user's customers see after signing in.
type Page = "Dashboard" | "Users" | "Settings";
// ---------------------------------------------------------------------------
// Shared layout shell — nav + header are reused across libraries
// ---------------------------------------------------------------------------
function AppShell({
brand, navBg, navText, navItems, activePage, onNav, headerBg, header, children,
}: {
brand: string; navBg: string; navText: string;
navItems: { label: Page; icon: string }[];
activePage: Page; onNav: (p: Page) => void;
headerBg: string; header: React.ReactNode; children: React.ReactNode;
}) {
return (
{navItems.map(({ label, icon }) => (
))}
);
}
// ---------------------------------------------------------------------------
// shadcn/ui
// ---------------------------------------------------------------------------
export function WebAppShadcn({ themeColor }: { themeColor?: ThemeColor }) {
const [page, setPage] = useState("Dashboard");
const t = themeColor ?? SHADCN_THEMES[0];
const NAV = [{ label: "Dashboard" as Page, icon: "▦" }, { label: "Users" as Page, icon: "◎" }, { label: "Settings" as Page, icon: "⚙" }];
return (
{page}
>}
>
{page === "Dashboard" && (
{[["Total Revenue", "$12,400", "+12%"], ["Active Users", "2,841", "+8%"], ["Conversions", "18.2%", "+3%"]].map(([l, v, d]) => (
{l}
{v}
{d} from last month
))}
Revenue
{[40,60,45,75,65,85,70,90,55,80,75,95].map((h, i) => (
))}
{TABLE_ROWS.slice(0, 3).map(r => (
))}
)}
{page === "Users" && (
{TABLE_ROWS.map(r => (
{r.role}
{r.status}
{r.date}
))}
)}
{page === "Settings" && (
General
{[["Workspace name", "Acme Inc"], ["Slug", "acme-inc"], ["Email", "admin@acme.com"]].map(([l, v]) => (
))}
Save changes
)}
);
}
// ---------------------------------------------------------------------------
// Mantine
// ---------------------------------------------------------------------------
export function WebAppMantine({ themeColor }: { themeColor?: ThemeColor }) {
const [page, setPage] = useState("Dashboard");
const t = themeColor ?? MANTINE_THEMES[0];
const NAV = [{ label: "Dashboard" as Page, icon: "▦" }, { label: "Users" as Page, icon: "◎" }, { label: "Settings" as Page, icon: "⚙" }];
return (
{page}
>}
>
{page === "Dashboard" && (
{[["Total Revenue", "$12,400", "#2f9e44"], ["Active Users", "2,841", "#228be6"], ["Conversions", "18.2%", "#e67700"]].map(([l, v, c]) => (
))}
Monthly revenue
{[40,60,45,75,65,85,70,90,55,80,75,95].map((h, i) => (
))}
{TABLE_ROWS.slice(0, 3).map(r => (
))}
)}
{page === "Users" && (
Team members
{TABLE_ROWS.map(r => (
))}
)}
{page === "Settings" && (
Workspace
{[["Name", "Acme Inc"], ["Slug", "acme-inc"], ["Email", "admin@acme.com"]].map(([l, v]) => (
))}
)}
);
}
// ---------------------------------------------------------------------------
// HeroUI
// ---------------------------------------------------------------------------
export function WebAppHeroUI({ themeColor }: { themeColor?: ThemeColor }) {
const [page, setPage] = useState("Dashboard");
const t = themeColor ?? HEROUI_THEMES[0];
const NAV = [{ label: "Dashboard" as Page, icon: "▦" }, { label: "Users" as Page, icon: "◎" }, { label: "Settings" as Page, icon: "⚙" }];
return (
{page}
>}
>
{page === "Dashboard" && (
{[["Revenue", "$12,400"], ["Users", "2,841"], ["Conversion", "18.2%"]].map(([l, v]) => (
))}
{[40,60,45,75,65,85,70,90,55,80,75,95].map((h, i) => (
))}
)}
{page === "Users" && (
Team
{TABLE_ROWS.map(r => (
))}
)}
{page === "Settings" && (
Profile
{[["Workspace", "Acme Inc"], ["Slug", "acme-inc"], ["Email", "admin@acme.com"]].map(([l, v]) => (
))}
)}
);
}
// ---------------------------------------------------------------------------
// Tremor (analytics/data-heavy)
// ---------------------------------------------------------------------------
export function WebAppTremor({ themeColor }: { themeColor?: ThemeColor }) {
const [page, setPage] = useState("Dashboard");
const t = themeColor ?? TREMOR_THEMES[0];
const NAV = [{ label: "Dashboard" as Page, icon: "▦" }, { label: "Users" as Page, icon: "◎" }, { label: "Settings" as Page, icon: "⚙" }];
return (
{page}
>}
>
{page === "Dashboard" && (
{[{ l: "Revenue", v: "$12,400", c: t.primary, pct: 65 }, { l: "Users", v: "2,841", c: "#7c3aed", pct: 48 }, { l: "Conversion", v: "18.2%", c: "#059669", pct: 72 }].map(item => (
))}
Revenue over time
{[40,65,55,80,70,90,75,85,60,95,80,100].map((h, i) => (
))}
)}
{page === "Users" && (
All users
{TABLE_ROWS.map(r => (
))}
)}
{page === "Settings" && (
Workspace
{[["Name", "Acme Inc"], ["Domain", "acme.com"], ["Timezone", "UTC-8"]].map(([l, v]) => (
))}
)}
);
}
export { SHADCN_THEMES, MANTINE_THEMES, HEROUI_THEMES, TREMOR_THEMES };