"use client"; import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; import React, { useEffect, useState } from "react"; import { CurrencyToggle, MoodToggle } from "./currency-toggle"; import { apiFetch, clearAuth, getStoredUser } from "@/lib/api"; const navItems = [ { href: "/app", label: "Dashboard" }, { href: "/app/connect", label: "Accounts" }, { href: "/transactions", label: "Transactions" }, { href: "/rules", label: "Rules" }, { href: "/exports", label: "Exports" }, { href: "/tax", label: "Tax" }, { href: "/settings", label: "Settings" }, ]; type User = { id: string; email: string; fullName?: string | null; emailVerified?: boolean; twoFactorEnabled?: boolean; }; type SubscriptionData = { plan?: string; status?: string; }; type AppShellProps = { title: string; subtitle?: string; children: React.ReactNode; }; function initials(user: User): string { if (user.fullName) { const parts = user.fullName.trim().split(/\s+/); if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase(); return parts[0].slice(0, 2).toUpperCase(); } return user.email.slice(0, 2).toUpperCase(); } function displayName(user: User): string { return user.fullName?.trim() || user.email; } export function AppShell({ title, subtitle, children }: AppShellProps) { const pathname = usePathname(); const router = useRouter(); const [mobileOpen, setMobileOpen] = useState(false); const [user, setUser] = useState(getStoredUser()); const [planLabel, setPlanLabel] = useState("Free Plan"); useEffect(() => { // Fetch latest user profile apiFetch<{ user: User }>("/api/auth/me") .then((res) => { if (!res.error && res.data?.user) { setUser(res.data.user); } }) .catch(() => {}); // Fetch subscription plan apiFetch("/api/stripe/subscription") .then((res) => { if (!res.error && res.data?.plan) { const p = res.data.plan; setPlanLabel(p.charAt(0).toUpperCase() + p.slice(1) + " Plan"); } }) .catch(() => {}); }, []); const onLogout = async () => { const refreshToken = localStorage.getItem("ledgerone_refresh_token") ?? ""; try { await fetch("/api/auth/logout", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ refreshToken }), }); } catch {} clearAuth(); router.push("/login"); }; const NavLinks = () => ( <> {navItems.map((item) => { const isActive = pathname === item.href || (item.href !== "/app" && pathname.startsWith(item.href)); return ( setMobileOpen(false)} className={`flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-colors ${ isActive ? "bg-secondary text-foreground" : "text-muted-foreground hover:bg-secondary/50 hover:text-foreground" }`} > {item.label} ); })} ); return (
{/* Desktop Sidebar */} {/* Mobile overlay */} {mobileOpen && (
setMobileOpen(false)} /> )} {/* Mobile Sidebar drawer */} {/* Main Content */}
{/* Hamburger — mobile only */}

{title}

{subtitle &&

{subtitle}

}
{children}
); }