74 lines
2.8 KiB
TypeScript
74 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import { BarChart3, ClipboardList, FileText, ShieldCheck, TimerReset, Trophy, Users } from "lucide-react";
|
|
import Link from "next/link";
|
|
import { usePathname } from "next/navigation";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
const navItems = [
|
|
{ href: "/dashboard", label: "Dashboard", icon: BarChart3 },
|
|
{ href: "/roster", label: "Roster", icon: Users },
|
|
{ href: "/pitching", label: "Pitch Tracking", icon: TimerReset },
|
|
{ href: "/games", label: "Score Game", icon: FileText },
|
|
{ href: "/lineup", label: "Generate Lineup", icon: ClipboardList },
|
|
{ href: "/settings", label: "Pitching Rules", icon: ShieldCheck }
|
|
];
|
|
|
|
export function AppShell({
|
|
title,
|
|
subtitle,
|
|
children,
|
|
actions
|
|
}: {
|
|
title: string;
|
|
subtitle: string;
|
|
children: React.ReactNode;
|
|
actions?: React.ReactNode;
|
|
}) {
|
|
const pathname = usePathname();
|
|
|
|
return (
|
|
<div className="container py-3 md:py-6">
|
|
<header className="relative overflow-hidden rounded-[1.75rem] border bg-primary p-4 text-primary-foreground shadow-glow md:p-7">
|
|
<div className="pointer-events-none absolute inset-0 bg-hero-grid bg-[size:38px_38px] opacity-[0.08]" />
|
|
<div className="pointer-events-none absolute inset-x-0 top-0 h-24 bg-gradient-to-b from-white/10 to-transparent" />
|
|
<div className="relative flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
|
<div className="max-w-3xl">
|
|
<div className="mb-3 inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-3 py-1.5 text-xs font-medium text-white/80">
|
|
<Trophy className="h-4 w-4" />
|
|
Coach Connor's Lineup Lab
|
|
</div>
|
|
<h1 className="font-display text-3xl font-semibold leading-none tracking-tight md:text-5xl">{title}</h1>
|
|
<p className="mt-3 max-w-2xl text-sm text-white/70 md:text-base">{subtitle}</p>
|
|
</div>
|
|
{actions ? <div className="relative flex items-start">{actions}</div> : null}
|
|
</div>
|
|
</header>
|
|
|
|
<nav className="app-surface mt-3 flex flex-wrap gap-1.5 p-1.5">
|
|
{navItems.map((item) => {
|
|
const Icon = item.icon;
|
|
const active = pathname === item.href;
|
|
return (
|
|
<Link
|
|
key={item.href}
|
|
href={item.href}
|
|
className={cn(
|
|
"inline-flex items-center gap-2 rounded-full px-3 py-2 text-xs font-medium transition md:text-sm",
|
|
active
|
|
? "bg-primary text-primary-foreground shadow-panel"
|
|
: "text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
|
)}
|
|
>
|
|
<Icon className="h-4 w-4" />
|
|
{item.label}
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
|
|
<main className="mt-4 grid gap-4">{children}</main>
|
|
</div>
|
|
);
|
|
}
|