feat: interactive page nav inside web app scaffolds

Each web app scaffold (shadcn, Mantine, HeroUI, Tremor) now has
clickable sidebar nav between Dashboard, Users, and Settings pages.
Dashboard shows stat cards + bar chart + activity feed. Users shows
a full data table with roles, status badges, and invite controls.
Settings shows form inputs and notification toggles — all styled to
each library's visual language.

Made-with: Cursor
This commit is contained in:
2026-03-02 13:22:24 -08:00
parent 54248887f1
commit 086047d177

View File

@@ -1,5 +1,7 @@
"use client"; "use client";
import { useState } from "react";
/** /**
* Design scaffolds — styled React mockups showing what each UI library * Design scaffolds — styled React mockups showing what each UI library
* looks like for a given surface. Used in the Design page preview area. * looks like for a given surface. Used in the Design page preview area.
@@ -12,63 +14,243 @@
// Shared mock data // Shared mock data
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
const NAV_ITEMS = ["Dashboard", "Projects", "Analytics", "Settings"];
const TABLE_ROWS = [ const TABLE_ROWS = [
{ name: "Alice Martin", email: "alice@co.com", status: "Active", date: "Jan 12" }, { name: "Alice Martin", email: "alice@co.com", role: "Admin", status: "Active", date: "Jan 12" },
{ name: "Ben Walsh", email: "ben@co.com", status: "Pending", date: "Jan 14" }, { name: "Ben Walsh", email: "ben@co.com", role: "Member", status: "Pending", date: "Jan 14" },
{ name: "Clara Kim", email: "clara@co.com", status: "Active", date: "Jan 15" }, { name: "Clara Kim", email: "clara@co.com", role: "Member", status: "Active", date: "Jan 15" },
{ name: "David Osei", email: "david@co.com", status: "Inactive", date: "Jan 16" }, { name: "David Osei", email: "david@co.com", role: "Viewer", status: "Inactive", date: "Jan 16" },
]; ];
type Page = "Dashboard" | "Users" | "Settings";
const PAGES: Page[] = ["Dashboard", "Users", "Settings"];
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// WEB APP scaffolds // WEB APP — shadcn
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function ShadcnDashboard() {
return (
<div className="flex-1 p-5 bg-zinc-50 overflow-auto">
<div className="grid grid-cols-3 gap-3 mb-4">
{["Total Revenue", "Active Users", "Conversions"].map((label, i) => (
<div key={label} className="bg-white rounded-lg border p-3">
<p className="text-[10px] text-zinc-500 mb-1">{label}</p>
<p className="text-lg font-bold text-zinc-900">{["$12,400", "2,841", "18.2%"][i]}</p>
<p className="text-[10px] text-zinc-400">+{[12, 8, 3][i]}% from last month</p>
</div>
))}
</div>
<div className="bg-white rounded-lg border mb-3">
<div className="px-4 py-3 border-b">
<span className="text-xs font-semibold text-zinc-700">Revenue</span>
</div>
<div className="p-4 flex items-end gap-1.5 h-24">
{[40,60,45,75,65,85,70,90,55,80,75,95].map((h,i)=>(
<div key={i} className="flex-1 rounded-sm" style={{ height:`${h}%`, background: i===11?"#18181b":"#e4e4e7" }} />
))}
</div>
</div>
<div className="bg-white rounded-lg border">
<div className="px-4 py-3 border-b"><span className="text-xs font-semibold text-zinc-700">Recent activity</span></div>
{TABLE_ROWS.slice(0,3).map(r=>(
<div key={r.name} className="flex items-center gap-3 px-4 py-2.5 border-b last:border-0">
<div className="w-6 h-6 rounded-full bg-zinc-200 shrink-0" />
<div className="flex-1"><p className="text-[11px] font-medium text-zinc-800">{r.name}</p><p className="text-[10px] text-zinc-400">{r.email}</p></div>
<span className={`px-1.5 py-0.5 rounded text-[9px] font-medium ${r.status==="Active"?"bg-zinc-100 text-zinc-700":"bg-zinc-50 text-zinc-400"}`}>{r.status}</span>
</div>
))}
</div>
</div>
);
}
function ShadcnUsers() {
return (
<div className="flex-1 p-5 bg-zinc-50 overflow-auto">
<div className="bg-white rounded-lg border">
<div className="px-4 py-3 border-b flex items-center justify-between">
<span className="text-xs font-semibold text-zinc-700">Team members</span>
<div className="flex gap-2">
<input className="h-7 px-2.5 rounded-md border border-zinc-200 text-[11px] outline-none w-32" placeholder="Search..." />
<div className="h-7 px-3 rounded-md bg-zinc-900 text-[11px] flex items-center text-white cursor-pointer">Invite</div>
</div>
</div>
<table className="w-full text-[11px]">
<thead><tr className="border-b bg-zinc-50">{["Name","Role","Status","Joined",""].map(h=><th key={h} className="px-4 py-2 text-left text-[10px] text-zinc-500 font-medium">{h}</th>)}</tr></thead>
<tbody>{TABLE_ROWS.map(r=>(
<tr key={r.name} className="border-b last:border-0 hover:bg-zinc-50">
<td className="px-4 py-2.5">
<div className="flex items-center gap-2"><div className="w-5 h-5 rounded-full bg-zinc-200" /><div><p className="font-medium text-zinc-800">{r.name}</p><p className="text-[10px] text-zinc-400">{r.email}</p></div></div>
</td>
<td className="px-4 py-2.5"><span className="px-1.5 py-0.5 rounded border border-zinc-200 text-[9px] text-zinc-600">{r.role}</span></td>
<td className="px-4 py-2.5"><span className={`px-1.5 py-0.5 rounded text-[9px] font-medium ${r.status==="Active"?"bg-zinc-900 text-white":r.status==="Pending"?"bg-zinc-100 text-zinc-600":"bg-zinc-50 text-zinc-400"}`}>{r.status}</span></td>
<td className="px-4 py-2.5 text-zinc-400">{r.date}</td>
<td className="px-4 py-2.5"><div className="h-6 px-2 rounded border border-zinc-200 text-[9px] flex items-center text-zinc-500 cursor-pointer w-fit">···</div></td>
</tr>
))}</tbody>
</table>
</div>
</div>
);
}
function ShadcnSettings() {
return (
<div className="flex-1 p-5 bg-zinc-50 overflow-auto">
<div className="bg-white rounded-lg border mb-3">
<div className="px-4 py-3 border-b"><span className="text-xs font-semibold text-zinc-700">General</span></div>
<div className="p-4 space-y-3">
{[{l:"Workspace name",v:"Acme Inc"},{l:"Slug",v:"acme-inc"},{l:"Email",v:"admin@acme.com"}].map(f=>(
<div key={f.l}>
<label className="text-[10px] font-medium text-zinc-600 block mb-1">{f.l}</label>
<input defaultValue={f.v} className="w-full h-8 px-3 rounded-md border border-zinc-200 text-[11px] outline-none focus:ring-1 focus:ring-zinc-900" />
</div>
))}
<div className="pt-1"><div className="h-7 px-3 rounded-md bg-zinc-900 text-[11px] inline-flex items-center text-white cursor-pointer">Save changes</div></div>
</div>
</div>
<div className="bg-white rounded-lg border">
<div className="px-4 py-3 border-b"><span className="text-xs font-semibold text-zinc-700">Notifications</span></div>
<div className="p-4 space-y-3">
{["Email digests","Push notifications","Security alerts","Product updates"].map((label,i)=>(
<div key={label} className="flex items-center justify-between">
<div><p className="text-[11px] font-medium text-zinc-700">{label}</p><p className="text-[10px] text-zinc-400">Receive {label.toLowerCase()}</p></div>
<div className={`w-8 h-4 rounded-full relative cursor-pointer transition-colors ${[true,false,true,false][i]?"bg-zinc-900":"bg-zinc-200"}`}>
<div className={`absolute top-0.5 w-3 h-3 rounded-full bg-white shadow transition-transform ${[true,false,true,false][i]?"translate-x-4":"translate-x-0.5"}`} />
</div>
</div>
))}
</div>
</div>
</div>
);
}
export function WebAppShadcn() { export function WebAppShadcn() {
const [page, setPage] = useState<Page>("Dashboard");
const NAV_ITEMS: { label: Page; icon: string }[] = [
{ label: "Dashboard", icon: "▦" },
{ label: "Users", icon: "◎" },
{ label: "Settings", icon: "⚙" },
];
return ( return (
<div className="flex h-full bg-white font-sans text-sm"> <div className="flex h-full bg-white font-sans text-sm">
{/* Sidebar */} <div className="w-44 border-r flex flex-col py-4 px-3 gap-1 bg-white shrink-0">
<div className="w-48 border-r flex flex-col py-4 px-3 gap-1 bg-white">
<div className="flex items-center gap-2 px-2 mb-4"> <div className="flex items-center gap-2 px-2 mb-4">
<div className="w-6 h-6 rounded bg-zinc-900" /> <div className="w-6 h-6 rounded bg-zinc-900" />
<span className="font-semibold text-zinc-900 text-xs">Acme Inc</span> <span className="font-semibold text-zinc-900 text-xs">Acme Inc</span>
</div> </div>
{NAV_ITEMS.map((item, i) => ( {NAV_ITEMS.map(({ label, icon }) => (
<div key={item} className={`flex items-center gap-2 px-2 py-1.5 rounded-md text-xs cursor-pointer ${i === 0 ? "bg-zinc-100 text-zinc-900 font-medium" : "text-zinc-500 hover:bg-zinc-50"}`}> <button key={label} onClick={() => setPage(label)}
<div className="w-3.5 h-3.5 rounded-sm bg-zinc-300" /> className={`flex items-center gap-2 px-2 py-1.5 rounded-md text-xs cursor-pointer w-full text-left ${page === label ? "bg-zinc-100 text-zinc-900 font-medium" : "text-zinc-500 hover:bg-zinc-50"}`}>
{item} <span className="text-[11px]">{icon}</span>{label}
</button>
))}
</div>
<div className="flex-1 flex flex-col min-w-0">
<div className="h-12 border-b flex items-center justify-between px-5 shrink-0">
<span className="font-semibold text-zinc-900 text-sm">{page}</span>
<div className="flex items-center gap-2">
<div className="h-7 px-3 rounded-md border border-zinc-200 text-[11px] flex items-center text-zinc-600">Export</div>
<div className="h-7 px-3 rounded-md bg-zinc-900 text-[11px] flex items-center text-white">+ New</div>
</div>
</div>
{page === "Dashboard" && <ShadcnDashboard />}
{page === "Users" && <ShadcnUsers />}
{page === "Settings" && <ShadcnSettings />}
</div>
</div>
);
}
function MantineDashboard() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f8f9fa" }}>
<div className="grid grid-cols-3 gap-3 mb-4">
{[{l:"Total Revenue",v:"$12,400",c:"#2f9e44"},{l:"Active Users",v:"2,841",c:"#228be6"},{l:"Conversions",v:"18.2%",c:"#e67700"}].map(item=>(
<div key={item.l} className="rounded-lg p-3" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<p className="text-[10px] mb-1" style={{ color:"#868e96" }}>{item.l}</p>
<p className="text-lg font-bold" style={{ color:"#212529" }}>{item.v}</p>
<p className="text-[10px]" style={{ color:item.c }}> trending up</p>
</div> </div>
))} ))}
</div> </div>
{/* Main */} <div className="rounded-lg mb-3" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<div className="flex-1 flex flex-col"> <div className="px-4 py-3" style={{ borderBottom:"1px solid #e9ecef" }}><span className="text-xs font-semibold" style={{ color:"#212529" }}>Monthly revenue</span></div>
<div className="h-12 border-b flex items-center justify-between px-5"> <div className="p-4 flex items-end gap-1.5 h-24">
<span className="font-semibold text-zinc-900 text-sm">Dashboard</span> {[40,60,45,75,65,85,70,90,55,80,75,95].map((h,i)=>(
<div className="flex items-center gap-2"> <div key={i} className="flex-1 rounded-sm" style={{ height:`${h}%`, background:i===11?"#228be6":"#d0ebff" }} />
<div className="h-7 px-3 rounded-md border border-zinc-200 text-[11px] flex items-center text-zinc-600">Export</div> ))}
<div className="h-7 px-3 rounded-md bg-zinc-900 text-[11px] flex items-center text-white">New project</div> </div>
</div>
<div className="rounded-lg" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #e9ecef" }}><span className="text-xs font-semibold" style={{ color:"#212529" }}>Recent</span></div>
{TABLE_ROWS.slice(0,3).map(r=>(
<div key={r.name} className="flex items-center gap-3 px-4 py-2.5" style={{ borderBottom:"1px solid #f1f3f5" }}>
<div className="w-6 h-6 rounded-full shrink-0" style={{ background:"#d0ebff" }} />
<div className="flex-1"><p className="text-[11px] font-semibold" style={{ color:"#212529" }}>{r.name}</p><p className="text-[10px]" style={{ color:"#868e96" }}>{r.email}</p></div>
<span className="px-1.5 py-0.5 rounded text-[9px] font-medium" style={r.status==="Active"?{background:"#d3f9d8",color:"#2f9e44"}:{background:"#f1f3f5",color:"#868e96"}}>{r.status}</span>
</div>
))}
</div>
</div>
);
}
function MantineUsers() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f8f9fa" }}>
<div className="rounded-lg" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<div className="px-4 py-3 flex items-center justify-between" style={{ borderBottom:"1px solid #e9ecef" }}>
<span className="text-xs font-semibold" style={{ color:"#212529" }}>Team members</span>
<div className="flex gap-2">
<input className="h-7 px-2.5 text-[11px] rounded" style={{ border:"1px solid #dee2e6", outline:"none", width:130 }} placeholder="Search members..." />
<button className="h-7 px-3 rounded text-[11px] font-medium text-white" style={{ background:"#228be6" }}>+ Invite</button>
</div> </div>
</div> </div>
<div className="flex-1 p-5 bg-zinc-50"> <table className="w-full text-[11px]">
<div className="grid grid-cols-3 gap-3 mb-4"> <thead><tr style={{ borderBottom:"1px solid #e9ecef", background:"#f8f9fa" }}>{["Member","Role","Status","Joined","Actions"].map(h=><th key={h} className="px-4 py-2 text-left text-[10px] font-semibold" style={{ color:"#868e96" }}>{h}</th>)}</tr></thead>
{["Total Revenue", "Active Users", "Conversions"].map((label, i) => ( <tbody>{TABLE_ROWS.map(r=>(
<div key={label} className="bg-white rounded-lg border p-3"> <tr key={r.name} style={{ borderBottom:"1px solid #f1f3f5" }}>
<p className="text-[10px] text-zinc-500 mb-1">{label}</p> <td className="px-4 py-2.5"><div className="flex items-center gap-2"><div className="w-6 h-6 rounded-full" style={{ background:"#d0ebff" }} /><div><p className="font-semibold" style={{ color:"#212529" }}>{r.name}</p><p style={{ color:"#868e96" }}>{r.email}</p></div></div></td>
<p className="text-lg font-bold text-zinc-900">{["$12,400", "2,841", "18.2%"][i]}</p> <td className="px-4 py-2.5"><span className="px-1.5 py-0.5 rounded text-[9px]" style={{ background:"#e7f5ff", color:"#1971c2" }}>{r.role}</span></td>
<p className="text-[10px] text-zinc-400">+{[12, 8, 3][i]}% from last month</p> <td className="px-4 py-2.5"><span className="px-1.5 py-0.5 rounded text-[9px] font-medium" style={r.status==="Active"?{background:"#d3f9d8",color:"#2f9e44"}:r.status==="Pending"?{background:"#fff3bf",color:"#e67700"}:{background:"#f1f3f5",color:"#868e96"}}>{r.status}</span></td>
</div> <td className="px-4 py-2.5" style={{ color:"#adb5bd" }}>{r.date}</td>
))} <td className="px-4 py-2.5"><button className="text-[10px] px-2 py-1 rounded" style={{ border:"1px solid #dee2e6", color:"#495057" }}>Manage</button></td>
</div> </tr>
<div className="bg-white rounded-lg border"> ))}</tbody>
<div className="px-4 py-3 border-b flex items-center justify-between"> </table>
<span className="text-xs font-semibold text-zinc-700">Recent activity</span> </div>
<div className="h-6 px-2 rounded border border-zinc-200 text-[10px] flex items-center text-zinc-500">Filter</div> </div>
);
}
function MantineSettings() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f8f9fa" }}>
<div className="rounded-lg mb-3" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #e9ecef" }}><span className="text-xs font-semibold" style={{ color:"#212529" }}>Workspace</span></div>
<div className="p-4 space-y-3">
{[{l:"Name",v:"Acme Inc"},{l:"Slug",v:"acme-inc"},{l:"Email",v:"admin@acme.com"}].map(f=>(
<div key={f.l}>
<label className="text-[10px] font-semibold block mb-1" style={{ color:"#495057" }}>{f.l}</label>
<input defaultValue={f.v} className="w-full h-8 px-3 rounded text-[11px]" style={{ border:"1px solid #dee2e6", outline:"none" }} />
</div> </div>
<table className="w-full text-[11px]"> ))}
<thead><tr className="border-b bg-zinc-50">{["Name","Email","Status","Date"].map(h=><th key={h} className="px-4 py-2 text-left text-[10px] text-zinc-500 font-medium">{h}</th>)}</tr></thead> <button className="h-8 px-4 rounded text-[11px] font-medium text-white" style={{ background:"#228be6" }}>Save</button>
<tbody>{TABLE_ROWS.map(r=><tr key={r.name} className="border-b last:border-0 hover:bg-zinc-50"><td className="px-4 py-2 font-medium text-zinc-800">{r.name}</td><td className="px-4 py-2 text-zinc-500">{r.email}</td><td className="px-4 py-2"><span className={`px-1.5 py-0.5 rounded text-[9px] font-medium ${r.status==="Active"?"bg-zinc-100 text-zinc-700":r.status==="Pending"?"bg-zinc-100 text-zinc-500":"bg-zinc-50 text-zinc-400"}`}>{r.status}</span></td><td className="px-4 py-2 text-zinc-400">{r.date}</td></tr>)}</tbody> </div>
</table> </div>
</div> <div className="rounded-lg" style={{ background:"#fff", border:"1px solid #e9ecef" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #e9ecef" }}><span className="text-xs font-semibold" style={{ color:"#212529" }}>Notifications</span></div>
<div className="p-4 space-y-3">
{["Email digests","Push notifications","Security alerts","Product updates"].map((label,i)=>(
<div key={label} className="flex items-center justify-between">
<div><p className="text-[11px] font-medium" style={{ color:"#212529" }}>{label}</p><p className="text-[10px]" style={{ color:"#868e96" }}>Get notified via {label.split(" ")[0].toLowerCase()}</p></div>
<div className="w-8 h-4 rounded-full relative cursor-pointer" style={{ background:[true,false,true,false][i]?"#228be6":"#dee2e6" }}>
<div className="absolute top-0.5 w-3 h-3 rounded-full bg-white shadow transition-transform" style={{ transform:[true,false,true,false][i]?"translateX(16px)":"translateX(2px)" }} />
</div>
</div>
))}
</div> </div>
</div> </div>
</div> </div>
@@ -76,48 +258,131 @@ export function WebAppShadcn() {
} }
export function WebAppMantine() { export function WebAppMantine() {
const [page, setPage] = useState<Page>("Dashboard");
const NAV: { label: Page; icon: string }[] = [
{ label: "Dashboard", icon: "▦" },
{ label: "Users", icon: "◎" },
{ label: "Settings", icon: "⚙" },
];
return ( return (
<div className="flex h-full font-sans text-sm" style={{ background: "#f8f9fa" }}> <div className="flex h-full font-sans text-sm" style={{ background: "#f8f9fa" }}>
<div className="w-48 flex flex-col py-4 px-3 gap-0.5" style={{ background: "#fff", borderRight: "1px solid #e9ecef" }}> <div className="w-44 flex flex-col py-4 px-3 gap-0.5 shrink-0" style={{ background: "#fff", borderRight: "1px solid #e9ecef" }}>
<div className="flex items-center gap-2 px-2 mb-4"> <div className="flex items-center gap-2 px-2 mb-4">
<div className="w-6 h-6 rounded" style={{ background: "#228be6" }} /> <div className="w-6 h-6 rounded" style={{ background: "#228be6" }} />
<span className="font-bold text-xs" style={{ color: "#1c7ed6" }}>Acme Inc</span> <span className="font-bold text-xs" style={{ color: "#1c7ed6" }}>Acme Inc</span>
</div> </div>
{NAV_ITEMS.map((item, i) => ( {NAV.map(({ label, icon }) => (
<div key={item} className="flex items-center gap-2 px-2 py-2 rounded text-xs cursor-pointer" style={i===0?{background:"#e7f5ff",color:"#1971c2",fontWeight:600}:{color:"#495057"}}> <button key={label} onClick={() => setPage(label)}
<div className="w-3.5 h-3.5 rounded-sm" style={{ background: i===0?"#74c0fc":"#ced4da" }} /> className="flex items-center gap-2 px-2 py-2 rounded text-xs cursor-pointer w-full text-left"
{item} style={page===label?{background:"#e7f5ff",color:"#1971c2",fontWeight:600}:{color:"#495057"}}>
<span>{icon}</span>{label}
</button>
))}
</div>
<div className="flex-1 flex flex-col min-w-0">
<div className="h-12 flex items-center justify-between px-5 shrink-0" style={{ background:"#fff", borderBottom:"1px solid #e9ecef" }}>
<span className="font-bold text-sm" style={{ color: "#212529" }}>{page}</span>
<div className="flex gap-2">
<button className="h-7 px-3 rounded text-[11px] font-medium" style={{ border:"1px solid #dee2e6", color:"#495057" }}>Export</button>
<button className="h-7 px-3 rounded text-[11px] font-medium text-white" style={{ background:"#228be6" }}>+ New</button>
</div>
</div>
{page === "Dashboard" && <MantineDashboard />}
{page === "Users" && <MantineUsers />}
{page === "Settings" && <MantineSettings />}
</div>
</div>
);
}
function HeroUIDashboard() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#fafafa" }}>
<div className="grid grid-cols-3 gap-3 mb-4">
{["Revenue","Users","Conversion"].map((label,i)=>(
<div key={label} className="rounded-2xl p-3" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<p className="text-[10px] mb-1" style={{ color:"#a1a1aa" }}>{label}</p>
<p className="text-lg font-bold" style={{ color:"#18181b" }}>{["$12,400","2,841","18.2%"][i]}</p>
<p className="text-[10px]" style={{ color:"#a855f7" }}>+{[12,8,3][i]}% this month</p>
</div> </div>
))} ))}
</div> </div>
<div className="flex-1 flex flex-col"> <div className="rounded-2xl mb-3" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<div className="h-12 flex items-center justify-between px-5" style={{ background:"#fff", borderBottom:"1px solid #e9ecef" }}> <div className="px-4 py-3" style={{ borderBottom:"1px solid #f4f4f5" }}><span className="text-xs font-semibold" style={{ color:"#18181b" }}>Revenue</span></div>
<span className="font-bold text-sm" style={{ color: "#212529" }}>Dashboard</span> <div className="p-4 flex items-end gap-1.5 h-24">
{[40,60,45,75,65,85,70,90,55,80,75,95].map((h,i)=>(
<div key={i} className="flex-1 rounded-md" style={{ height:`${h}%`, background:i===11?"linear-gradient(180deg,#a855f7,#ec4899)":"rgba(168,85,247,0.15)" }} />
))}
</div>
</div>
<div className="rounded-2xl" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #f4f4f5" }}><span className="text-xs font-semibold" style={{ color:"#18181b" }}>Recent activity</span></div>
{TABLE_ROWS.slice(0,3).map(r=>(
<div key={r.name} className="flex items-center gap-3 px-4 py-2.5" style={{ borderBottom:"1px solid #fafafa" }}>
<div className="w-7 h-7 rounded-full shrink-0" style={{ background:"linear-gradient(135deg,rgba(168,85,247,0.2),rgba(236,72,153,0.2))" }} />
<div className="flex-1"><p className="text-[11px] font-semibold" style={{ color:"#18181b" }}>{r.name}</p><p className="text-[10px]" style={{ color:"#a1a1aa" }}>{r.email}</p></div>
<span className="px-2 py-0.5 rounded-full text-[9px] font-semibold" style={r.status==="Active"?{background:"rgba(34,197,94,0.1)",color:"#16a34a"}:{background:"#f4f4f5",color:"#a1a1aa"}}>{r.status}</span>
</div>
))}
</div>
</div>
);
}
function HeroUIUsers() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#fafafa" }}>
<div className="rounded-2xl" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<div className="px-4 py-3 flex items-center justify-between" style={{ borderBottom:"1px solid #f4f4f5" }}>
<span className="text-xs font-semibold" style={{ color:"#18181b" }}>Team members</span>
<div className="flex gap-2"> <div className="flex gap-2">
<button className="h-7 px-3 rounded text-[11px] font-medium" style={{ border:"1px solid #dee2e6", color:"#495057" }}>Export</button> <input className="h-7 px-3 rounded-full text-[11px]" style={{ border:"1px solid #e4e4e7", outline:"none", width:130 }} placeholder="Search..." />
<button className="h-7 px-3 rounded text-[11px] font-medium text-white" style={{ background:"#228be6" }}>+ New project</button> <button className="h-7 px-3 rounded-full text-[11px] font-semibold text-white" style={{ background:"linear-gradient(135deg,#7c3aed,#ec4899)" }}>+ Invite</button>
</div> </div>
</div> </div>
<div className="flex-1 p-5"> <table className="w-full text-[11px]">
<div className="grid grid-cols-3 gap-3 mb-4"> <thead><tr style={{ borderBottom:"1px solid #f4f4f5" }}>{["Member","Role","Status","Joined",""].map(h=><th key={h} className="px-4 py-2.5 text-left text-[10px] font-medium" style={{ color:"#a1a1aa" }}>{h}</th>)}</tr></thead>
{["Total Revenue","Active Users","Conversions"].map((label,i)=>( <tbody>{TABLE_ROWS.map(r=>(
<div key={label} className="rounded-lg p-3" style={{ background:"#fff", border:"1px solid #e9ecef" }}> <tr key={r.name} style={{ borderBottom:"1px solid #fafafa" }}>
<p className="text-[10px] mb-1" style={{ color:"#868e96" }}>{label}</p> <td className="px-4 py-3"><div className="flex items-center gap-2.5"><div className="w-7 h-7 rounded-full" style={{ background:"linear-gradient(135deg,rgba(168,85,247,0.2),rgba(236,72,153,0.2))" }} /><div><p className="font-semibold" style={{ color:"#18181b" }}>{r.name}</p><p style={{ color:"#a1a1aa" }}>{r.email}</p></div></div></td>
<p className="text-lg font-bold" style={{ color:"#212529" }}>{["$12,400","2,841","18.2%"][i]}</p> <td className="px-4 py-3"><span className="px-2 py-0.5 rounded-full text-[9px]" style={{ background:"rgba(124,58,237,0.1)", color:"#7c3aed" }}>{r.role}</span></td>
<p className="text-[10px]" style={{ color:"#228be6" }}> {[12,8,3][i]}% this month</p> <td className="px-4 py-3"><span className="px-2 py-0.5 rounded-full text-[9px] font-semibold" style={r.status==="Active"?{background:"rgba(34,197,94,0.1)",color:"#16a34a"}:r.status==="Pending"?{background:"rgba(234,179,8,0.1)",color:"#a16207"}:{background:"#f4f4f5",color:"#a1a1aa"}}>{r.status}</span></td>
</div> <td className="px-4 py-3" style={{ color:"#d4d4d8" }}>{r.date}</td>
))} <td className="px-4 py-3"><button className="h-6 px-2.5 rounded-full text-[10px]" style={{ background:"rgba(124,58,237,0.08)", color:"#7c3aed" }}>Manage</button></td>
</div> </tr>
<div className="rounded-lg" style={{ background:"#fff", border:"1px solid #e9ecef" }}> ))}</tbody>
<div className="px-4 py-3 flex items-center justify-between" style={{ borderBottom:"1px solid #e9ecef" }}> </table>
<span className="text-xs font-semibold" style={{ color:"#212529" }}>Users</span> </div>
<input className="h-6 px-2 text-[10px] rounded" style={{ border:"1px solid #dee2e6", outline:"none", width:120 }} placeholder="Search..." /> </div>
);
}
function HeroUISettings() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#fafafa" }}>
<div className="rounded-2xl mb-3" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #f4f4f5" }}><span className="text-xs font-semibold" style={{ color:"#18181b" }}>Profile</span></div>
<div className="p-4 space-y-3">
{[{l:"Workspace name",v:"Acme Inc"},{l:"Slug",v:"acme-inc"},{l:"Email",v:"admin@acme.com"}].map(f=>(
<div key={f.l}>
<label className="text-[10px] font-semibold block mb-1" style={{ color:"#71717a" }}>{f.l}</label>
<input defaultValue={f.v} className="w-full h-8 px-3 rounded-xl text-[11px]" style={{ border:"1px solid #e4e4e7", outline:"none" }} />
</div> </div>
<table className="w-full text-[11px]"> ))}
<thead><tr style={{ borderBottom:"1px solid #e9ecef", background:"#f8f9fa" }}>{["Name","Email","Status","Date"].map(h=><th key={h} className="px-4 py-2 text-left text-[10px] font-semibold" style={{ color:"#868e96" }}>{h}</th>)}</tr></thead> <button className="h-8 px-4 rounded-full text-[11px] font-semibold text-white" style={{ background:"linear-gradient(135deg,#7c3aed,#ec4899)" }}>Save changes</button>
<tbody>{TABLE_ROWS.map(r=><tr key={r.name} style={{ borderBottom:"1px solid #f1f3f5" }}><td className="px-4 py-2 font-semibold" style={{ color:"#212529" }}>{r.name}</td><td className="px-4 py-2" style={{ color:"#868e96" }}>{r.email}</td><td className="px-4 py-2"><span className="px-1.5 py-0.5 rounded text-[9px] font-medium" style={r.status==="Active"?{background:"#d3f9d8",color:"#2f9e44"}:r.status==="Pending"?{background:"#fff3bf",color:"#e67700"}:{background:"#f1f3f5",color:"#868e96"}}>{r.status}</span></td><td className="px-4 py-2" style={{ color:"#adb5bd" }}>{r.date}</td></tr>)}</tbody> </div>
</table> </div>
</div> <div className="rounded-2xl" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}>
<div className="px-4 py-3" style={{ borderBottom:"1px solid #f4f4f5" }}><span className="text-xs font-semibold" style={{ color:"#18181b" }}>Notifications</span></div>
<div className="p-4 space-y-3">
{["Email digests","Push notifications","Security alerts","Product updates"].map((label,i)=>(
<div key={label} className="flex items-center justify-between">
<p className="text-[11px]" style={{ color:"#18181b" }}>{label}</p>
<div className="w-8 h-4 rounded-full relative cursor-pointer" style={{ background:[true,false,true,false][i]?"linear-gradient(135deg,#7c3aed,#ec4899)":"#e4e4e7" }}>
<div className="absolute top-0.5 w-3 h-3 rounded-full bg-white shadow" style={{ transform:[true,false,true,false][i]?"translateX(16px)":"translateX(2px)" }} />
</div>
</div>
))}
</div> </div>
</div> </div>
</div> </div>
@@ -125,98 +390,174 @@ export function WebAppMantine() {
} }
export function WebAppHeroUI() { export function WebAppHeroUI() {
const [page, setPage] = useState<Page>("Dashboard");
const NAV: { label: Page; icon: string }[] = [
{ label: "Dashboard", icon: "▦" },
{ label: "Users", icon: "◎" },
{ label: "Settings", icon: "⚙" },
];
return ( return (
<div className="flex h-full font-sans text-sm" style={{ background: "#fafafa" }}> <div className="flex h-full font-sans text-sm" style={{ background: "#fafafa" }}>
<div className="w-48 flex flex-col py-4 px-3 gap-1" style={{ background: "linear-gradient(180deg,#1a1a2e,#16213e)", color: "#fff" }}> <div className="w-44 flex flex-col py-4 px-3 gap-1 shrink-0" style={{ background: "linear-gradient(180deg,#1a1a2e,#16213e)", color: "#fff" }}>
<div className="flex items-center gap-2 px-2 mb-4"> <div className="flex items-center gap-2 px-2 mb-4">
<div className="w-6 h-6 rounded-full" style={{ background: "linear-gradient(135deg,#7c3aed,#ec4899)" }} /> <div className="w-6 h-6 rounded-full" style={{ background: "linear-gradient(135deg,#7c3aed,#ec4899)" }} />
<span className="font-bold text-xs text-white">Acme Inc</span> <span className="font-bold text-xs text-white">Acme Inc</span>
</div> </div>
{NAV_ITEMS.map((item, i) => ( {NAV.map(({ label, icon }) => (
<div key={item} className="flex items-center gap-2 px-2 py-2 rounded-xl text-xs cursor-pointer" style={i===0?{background:"rgba(124,58,237,0.3)",color:"#c084fc",fontWeight:600}:{color:"rgba(255,255,255,0.5)"}}> <button key={label} onClick={() => setPage(label)}
<div className="w-3.5 h-3.5 rounded-full" style={{ background: i===0?"#a855f7":"rgba(255,255,255,0.2)" }} /> className="flex items-center gap-2 px-2 py-2 rounded-xl text-xs cursor-pointer w-full text-left"
{item} style={page===label?{background:"rgba(124,58,237,0.3)",color:"#c084fc",fontWeight:600}:{color:"rgba(255,255,255,0.5)"}}>
<span>{icon}</span>{label}
</button>
))}
</div>
<div className="flex-1 flex flex-col min-w-0">
<div className="h-12 flex items-center justify-between px-5 bg-white shrink-0" style={{ borderBottom: "1px solid #f0f0f0" }}>
<span className="font-bold text-sm" style={{ background:"linear-gradient(90deg,#7c3aed,#ec4899)", WebkitBackgroundClip:"text", WebkitTextFillColor:"transparent" }}>{page}</span>
<div className="flex gap-2">
<button className="h-7 px-3 rounded-full text-[11px] font-medium" style={{ border:"1px solid #e4e4e7", color:"#71717a" }}>Export</button>
<button className="h-7 px-3 rounded-full text-[11px] font-semibold text-white" style={{ background:"linear-gradient(135deg,#7c3aed,#ec4899)" }}>+ New</button>
</div>
</div>
{page === "Dashboard" && <HeroUIDashboard />}
{page === "Users" && <HeroUIUsers />}
{page === "Settings" && <HeroUISettings />}
</div>
</div>
);
}
function TremorDashboard() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f9fafb" }}>
<div className="grid grid-cols-3 gap-3 mb-4">
{[{l:"Revenue",v:"$12,400",c:"#2563eb",bg:"#dbeafe",pct:65},{l:"Users",v:"2,841",c:"#7c3aed",bg:"#ede9fe",pct:48},{l:"Conversion",v:"18.2%",c:"#059669",bg:"#d1fae5",pct:72}].map(item=>(
<div key={item.l} className="rounded-xl p-3 bg-white" style={{ border:"1px solid #e5e7eb" }}>
<div className="flex items-center justify-between mb-2">
<p className="text-[10px] font-medium" style={{ color:"#6b7280" }}>{item.l}</p>
<div className="w-5 h-5 rounded" style={{ background:item.bg, display:"flex", alignItems:"center", justifyContent:"center" }}><div className="w-2 h-2 rounded-sm" style={{ background:item.c }} /></div>
</div>
<p className="text-lg font-bold" style={{ color:"#111827" }}>{item.v}</p>
<div className="mt-2 h-1.5 rounded-full" style={{ background:"#f3f4f6" }}><div className="h-full rounded-full" style={{ width:`${item.pct}%`, background:item.c }} /></div>
</div> </div>
))} ))}
</div> </div>
<div className="flex-1 flex flex-col"> <div className="bg-white rounded-xl p-4 mb-3" style={{ border:"1px solid #e5e7eb" }}>
<div className="h-12 flex items-center justify-between px-5 bg-white" style={{ borderBottom: "1px solid #f0f0f0" }}> <p className="text-xs font-semibold mb-3" style={{ color:"#111827" }}>Revenue over time</p>
<span className="font-bold text-sm" style={{ background:"linear-gradient(90deg,#7c3aed,#ec4899)", WebkitBackgroundClip:"text", WebkitTextFillColor:"transparent" }}>Dashboard</span> <div className="flex items-end gap-1.5 h-20">
<div className="flex gap-2"> {[40,65,55,80,70,90,75,85,60,95,80,100].map((h,i)=>(
<button className="h-7 px-3 rounded-full text-[11px] font-medium" style={{ border:"1px solid #e4e4e7", color:"#71717a" }}>Export</button> <div key={i} className="flex-1 rounded-t" style={{ height:`${h}%`, background:i===11?"#2563eb":"#dbeafe" }} />
<button className="h-7 px-3 rounded-full text-[11px] font-semibold text-white" style={{ background:"linear-gradient(135deg,#7c3aed,#ec4899)" }}>+ New project</button> ))}
</div>
</div> </div>
<div className="flex-1 p-5"> <div className="flex justify-between mt-1">
<div className="grid grid-cols-3 gap-3 mb-4"> {["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"].map(m=><span key={m} className="text-[8px]" style={{ color:"#9ca3af" }}>{m}</span>)}
{["Total Revenue","Active Users","Conversions"].map((label,i)=>( </div>
<div key={label} className="rounded-2xl p-3" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}> </div>
<p className="text-[10px] mb-1" style={{ color:"#a1a1aa" }}>{label}</p> <div className="bg-white rounded-xl p-3" style={{ border:"1px solid #e5e7eb" }}>
<p className="text-lg font-bold" style={{ color:"#18181b" }}>{["$12,400","2,841","18.2%"][i]}</p> {TABLE_ROWS.slice(0,3).map(r=>(
<p className="text-[10px]" style={{ color:"#a855f7" }}>+{[12,8,3][i]}% from last month</p> <div key={r.name} className="flex items-center gap-3 py-2 border-b last:border-0" style={{ borderColor:"#f3f4f6" }}>
</div> <div className="w-2 h-2 rounded-full" style={{ background:r.status==="Active"?"#059669":"#d1d5db" }} />
))} <span className="text-[11px] flex-1" style={{ color:"#111827" }}>{r.name}</span>
<span className="text-[10px]" style={{ color:"#6b7280" }}>{r.role}</span>
</div> </div>
<div className="rounded-2xl" style={{ background:"#fff", boxShadow:"0 2px 8px rgba(0,0,0,0.06)", border:"1px solid #f4f4f5" }}> ))}
<div className="px-4 py-3 flex items-center justify-between" style={{ borderBottom:"1px solid #f4f4f5" }}> </div>
<span className="text-xs font-semibold" style={{ color:"#18181b" }}>Recent activity</span> </div>
<button className="h-6 px-2.5 rounded-full text-[10px] font-medium" style={{ background:"rgba(124,58,237,0.1)", color:"#7c3aed" }}>View all</button> );
}
function TremorUsers() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f9fafb" }}>
<div className="grid grid-cols-2 gap-3 mb-4">
{[{l:"Total",v:"2,841",c:"#2563eb"},{l:"Active",v:"1,940",c:"#059669"},{l:"Pending",v:"647",c:"#d97706"},{l:"Inactive",v:"254",c:"#6b7280"}].map(s=>(
<div key={s.l} className="rounded-xl p-3 bg-white flex items-center gap-3" style={{ border:"1px solid #e5e7eb" }}>
<div className="w-8 h-8 rounded-full flex items-center justify-center" style={{ background:`${s.c}18` }}><div className="w-3 h-3 rounded-full" style={{ background:s.c }} /></div>
<div><p className="text-[10px]" style={{ color:"#6b7280" }}>{s.l}</p><p className="text-sm font-bold" style={{ color:"#111827" }}>{s.v}</p></div>
</div>
))}
</div>
<div className="bg-white rounded-xl" style={{ border:"1px solid #e5e7eb" }}>
<div className="px-4 py-3 flex items-center justify-between" style={{ borderBottom:"1px solid #f3f4f6" }}>
<span className="text-xs font-semibold" style={{ color:"#111827" }}>All users</span>
<input className="h-7 px-3 rounded-lg text-[11px]" style={{ border:"1px solid #e5e7eb", outline:"none", width:130 }} placeholder="Filter..." />
</div>
<table className="w-full text-[11px]">
<thead><tr style={{ borderBottom:"1px solid #f3f4f6" }}>{["Name","Role","Status","Date"].map(h=><th key={h} className="px-4 py-2 text-left text-[10px] font-medium" style={{ color:"#9ca3af" }}>{h}</th>)}</tr></thead>
<tbody>{TABLE_ROWS.map(r=>(
<tr key={r.name} style={{ borderBottom:"1px solid #f9fafb" }}>
<td className="px-4 py-2.5 font-medium" style={{ color:"#111827" }}>{r.name}</td>
<td className="px-4 py-2.5" style={{ color:"#6b7280" }}>{r.role}</td>
<td className="px-4 py-2.5"><div className="flex items-center gap-1.5"><div className="w-1.5 h-1.5 rounded-full" style={{ background:r.status==="Active"?"#059669":r.status==="Pending"?"#d97706":"#d1d5db" }} /><span style={{ color:"#374151" }}>{r.status}</span></div></td>
<td className="px-4 py-2.5" style={{ color:"#9ca3af" }}>{r.date}</td>
</tr>
))}</tbody>
</table>
</div>
</div>
);
}
function TremorSettings() {
return (
<div className="flex-1 p-5 overflow-auto" style={{ background:"#f9fafb" }}>
<div className="bg-white rounded-xl mb-3 p-4" style={{ border:"1px solid #e5e7eb" }}>
<p className="text-xs font-semibold mb-3" style={{ color:"#111827" }}>Workspace</p>
<div className="space-y-3">
{[{l:"Name",v:"Acme Inc"},{l:"Domain",v:"acme.com"},{l:"Timezone",v:"UTC-8"}].map(f=>(
<div key={f.l}>
<label className="text-[10px] font-medium block mb-1" style={{ color:"#6b7280" }}>{f.l}</label>
<input defaultValue={f.v} className="w-full h-8 px-3 rounded-lg text-[11px]" style={{ border:"1px solid #e5e7eb", outline:"none" }} />
</div> </div>
<table className="w-full text-[11px]"> ))}
<thead><tr style={{ borderBottom:"1px solid #f4f4f5" }}>{["Name","Email","Status","Date"].map(h=><th key={h} className="px-4 py-2 text-left text-[10px] font-medium" style={{ color:"#a1a1aa" }}>{h}</th>)}</tr></thead> <button className="h-8 px-4 rounded-lg text-[11px] font-medium text-white" style={{ background:"#2563eb" }}>Save</button>
<tbody>{TABLE_ROWS.map(r=><tr key={r.name} style={{ borderBottom:"1px solid #fafafa" }}><td className="px-4 py-2 font-semibold" style={{ color:"#18181b" }}>{r.name}</td><td className="px-4 py-2" style={{ color:"#a1a1aa" }}>{r.email}</td><td className="px-4 py-2"><span className="px-2 py-0.5 rounded-full text-[9px] font-semibold" style={r.status==="Active"?{background:"rgba(34,197,94,0.1)",color:"#16a34a"}:r.status==="Pending"?{background:"rgba(234,179,8,0.1)",color:"#a16207"}:{background:"#f4f4f5",color:"#a1a1aa"}}>{r.status}</span></td><td className="px-4 py-2" style={{ color:"#d4d4d8" }}>{r.date}</td></tr>)}</tbody>
</table>
</div>
</div> </div>
</div> </div>
<div className="bg-white rounded-xl p-4" style={{ border:"1px solid #e5e7eb" }}>
<p className="text-xs font-semibold mb-3" style={{ color:"#111827" }}>Alerts</p>
{["Email digests","Anomaly alerts","Weekly report","API warnings"].map((label,i)=>(
<div key={label} className="flex items-center justify-between py-2 border-b last:border-0" style={{ borderColor:"#f3f4f6" }}>
<p className="text-[11px]" style={{ color:"#374151" }}>{label}</p>
<div className="w-8 h-4 rounded-full relative" style={{ background:[true,true,false,true][i]?"#2563eb":"#e5e7eb" }}>
<div className="absolute top-0.5 w-3 h-3 rounded-full bg-white shadow" style={{ transform:[true,true,false,true][i]?"translateX(16px)":"translateX(2px)" }} />
</div>
</div>
))}
</div>
</div> </div>
); );
} }
export function WebAppTremor() { export function WebAppTremor() {
const [page, setPage] = useState<Page>("Dashboard");
const NAV: { label: Page; icon: string }[] = [
{ label: "Dashboard", icon: "▦" },
{ label: "Users", icon: "◎" },
{ label: "Settings", icon: "⚙" },
];
return ( return (
<div className="flex h-full font-sans text-sm bg-white"> <div className="flex h-full font-sans text-sm bg-white">
<div className="w-48 border-r flex flex-col py-4 px-3 gap-1" style={{ background:"#fff" }}> <div className="w-44 border-r flex flex-col py-4 px-3 gap-1 shrink-0" style={{ background:"#fff" }}>
<div className="flex items-center gap-2 px-2 mb-4"> <div className="flex items-center gap-2 px-2 mb-4">
<div className="w-6 h-6 rounded" style={{ background:"#3b82f6" }} /> <div className="w-6 h-6 rounded" style={{ background:"#3b82f6" }} />
<span className="font-bold text-xs" style={{ color:"#1e3a5f" }}>Acme Inc</span> <span className="font-bold text-xs" style={{ color:"#1e3a5f" }}>Acme Inc</span>
</div> </div>
{NAV_ITEMS.map((item, i) => ( {NAV.map(({ label, icon }) => (
<div key={item} className="flex items-center gap-2 px-2 py-2 rounded text-xs cursor-pointer" style={i===0?{background:"#eff6ff",color:"#1d4ed8",fontWeight:600}:{color:"#6b7280"}}> <button key={label} onClick={() => setPage(label)}
<div className="w-3.5 h-3.5 rounded" style={{ background:i===0?"#93c5fd":"#e5e7eb" }} /> className="flex items-center gap-2 px-2 py-2 rounded text-xs cursor-pointer w-full text-left"
{item} style={page===label?{background:"#eff6ff",color:"#1d4ed8",fontWeight:600}:{color:"#6b7280"}}>
</div> <span>{icon}</span>{label}
</button>
))} ))}
</div> </div>
<div className="flex-1 flex flex-col" style={{ background:"#f9fafb" }}> <div className="flex-1 flex flex-col min-w-0" style={{ background:"#f9fafb" }}>
<div className="h-12 flex items-center px-5 bg-white" style={{ borderBottom:"1px solid #e5e7eb" }}> <div className="h-12 flex items-center justify-between px-5 bg-white shrink-0" style={{ borderBottom:"1px solid #e5e7eb" }}>
<span className="font-bold text-sm" style={{ color:"#111827" }}>Overview</span> <span className="font-bold text-sm" style={{ color:"#111827" }}>{page}</span>
</div> <button className="h-7 px-3 rounded-lg text-[11px] font-medium text-white" style={{ background:"#2563eb" }}>+ New</button>
<div className="flex-1 p-5">
<div className="grid grid-cols-3 gap-3 mb-4">
{[{l:"Revenue",v:"$12,400",c:"#2563eb",bg:"#dbeafe"},{l:"Users",v:"2,841",c:"#7c3aed",bg:"#ede9fe"},{l:"Conversion",v:"18.2%",c:"#059669",bg:"#d1fae5"}].map(item=>(
<div key={item.l} className="rounded-xl p-3 bg-white" style={{ border:"1px solid #e5e7eb" }}>
<div className="flex items-center justify-between mb-2">
<p className="text-[10px] font-medium" style={{ color:"#6b7280" }}>{item.l}</p>
<div className="w-6 h-6 rounded" style={{ background:item.bg }}><div className="w-full h-full rounded flex items-center justify-center"><div className="w-2.5 h-2.5 rounded-sm" style={{ background:item.c }} /></div></div>
</div>
<p className="text-lg font-bold" style={{ color:"#111827" }}>{item.v}</p>
<div className="mt-2 h-1.5 rounded-full bg-gray-100"><div className="h-full rounded-full" style={{ width:`${[65,48,72][["Revenue","Users","Conversion"].indexOf(item.l)]}%`, background:item.c }} /></div>
</div>
))}
</div>
<div className="bg-white rounded-xl p-4" style={{ border:"1px solid #e5e7eb" }}>
<p className="text-xs font-semibold mb-3" style={{ color:"#111827" }}>Revenue over time</p>
<div className="flex items-end gap-1.5 h-24">
{[40,65,55,80,70,90,75,85,60,95,80,100].map((h,i)=>(
<div key={i} className="flex-1 rounded-t" style={{ height:`${h}%`, background:i===11?"#2563eb":"#dbeafe" }} />
))}
</div>
<div className="flex justify-between mt-1">
{["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"].map(m=><span key={m} className="text-[8px]" style={{ color:"#9ca3af" }}>{m}</span>)}
</div>
</div>
</div> </div>
{page === "Dashboard" && <TremorDashboard />}
{page === "Users" && <TremorUsers />}
{page === "Settings" && <TremorSettings />}
</div> </div>
</div> </div>
); );