Files
message-inbox-web-frontend-sdk/apps/web/components/AppShell.tsx
T
2026-07-17 21:48:37 +05:30

74 lines
2.6 KiB
TypeScript

"use client";
import { useEffect } from "react";
import { usePathname } from "next/navigation";
import { useSdk } from "@lynkd/messaging-inbox-sdk";
import { useUi } from "@/lib/ui-state";
import clsx from "clsx";
import { WorkspaceRail } from "@/components/nav/WorkspaceRail";
import { Sidebar } from "@/components/nav/Sidebar";
import { ThreadPanel } from "@/components/message/ThreadPanel";
import { CommandPalette } from "@/components/overlays/CommandPalette";
import { NotificationsPanel } from "@/components/overlays/NotificationsPanel";
import { ProfileDrawer } from "@/components/overlays/ProfileDrawer";
import { ThemingPanel } from "@/components/overlays/ThemingPanel";
import { HuddleBar } from "@/components/overlays/HuddleBar";
import { Modals } from "@/components/overlays/Modals";
import { AiPanel } from "@/components/overlays/AiPanel";
import { Toaster } from "@/components/overlays/Toaster";
export function AppShell({ children }: { children: React.ReactNode }) {
const { loading } = useSdk();
const { thread, sidebarOpen, setSidebarOpen, sidebarCollapsed } = useUi();
const pathname = usePathname();
// close the mobile drawer whenever the route changes
useEffect(() => {
setSidebarOpen(false);
}, [pathname, setSidebarOpen]);
return (
<div className="flex h-[100dvh] w-full overflow-hidden bg-bg text-ink">
<WorkspaceRail />
<div
role={sidebarOpen ? "dialog" : undefined}
aria-modal={sidebarOpen ? true : undefined}
aria-hidden={!sidebarOpen ? true : undefined}
className={clsx(
"fixed inset-y-0 left-0 z-40 transition-transform md:static md:z-auto md:translate-x-0 md:!pointer-events-auto",
sidebarOpen ? "translate-x-0" : "pointer-events-none -translate-x-full md:pointer-events-auto",
sidebarCollapsed && "md:hidden",
)}
>
<Sidebar />
</div>
{sidebarOpen && <div className="fixed inset-0 z-30 bg-black/50 md:hidden" onClick={() => setSidebarOpen(false)} />}
<main className="flex min-w-0 flex-1">{loading ? <BootSkeleton /> : children}</main>
{thread && <ThreadPanel />}
<CommandPalette />
<NotificationsPanel />
<ProfileDrawer />
<ThemingPanel />
<HuddleBar />
<Modals />
<AiPanel />
<Toaster />
</div>
);
}
function BootSkeleton() {
return (
<div className="flex flex-1 items-center justify-center">
<div className="flex flex-col items-center gap-3 text-muted">
<div className="brand-mark h-10 w-10 animate-pulse rounded-card" />
<span className="text-[13px]">Loading workspace</span>
</div>
</div>
);
}