Files
claudemesh/apps/web/src/app/[locale]/dashboard/(user)/layout.tsx
Alejandro Gutiérrez 43e429f204
Some checks failed
CI / Lint (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Broker tests (Postgres) (push) Has been cancelled
CI / Docker build (linux/amd64) (push) Has been cancelled
feat(workspace): claudemesh me notifications + dashboard parity
ships v0.4.0 phase 3.

api: GET /v1/me/notifications aggregates the mesh.notification
table across every joined mesh in a 7-day window (?since=iso
overrides, ?include=all surfaces already-read). returns sender +
topic + mesh context plus a 240-char snippet for v1 plaintext
messages or raw ciphertext for v2 (the dashboard topic-key cache
decrypts client-side).

cli (1.12.0): claudemesh me notifications — terse unread feed
with @ dot, --all to include read, --since for custom window.

web: /dashboard/notifications mirrors the cli view in card form,
adds a notifications entry to the dashboard sidebar between
topics and invites. each card links straight to the topic chat.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 02:35:57 +01:00

85 lines
1.8 KiB
TypeScript

import { redirect } from "next/navigation";
import { Icons } from "@turbostarter/ui-web/icons";
import { SidebarProvider } from "@turbostarter/ui-web/sidebar";
import { pathsConfig } from "~/config/paths";
import { getSession } from "~/lib/auth/server";
import { DashboardInset } from "~/modules/common/layout/dashboard/inset";
import { DashboardSidebar } from "~/modules/common/layout/dashboard/sidebar";
/**
* Dashboard sidebar menu configuration.
*/
const menu = [
{
label: "platform",
items: [
{
title: "dashboard",
href: pathsConfig.dashboard.user.index,
icon: Icons.Atom,
},
{
title: "meshes",
href: pathsConfig.dashboard.user.meshes.index,
icon: Icons.Share,
},
{
title: "topics",
href: pathsConfig.dashboard.user.topics,
icon: Icons.MessageSquare,
},
{
title: "notifications",
href: pathsConfig.dashboard.user.notifications,
icon: Icons.Bell,
},
{
title: "invites",
href: pathsConfig.dashboard.user.invites,
icon: Icons.Link,
},
],
},
{
label: "manage",
items: [
{
title: "account",
href: pathsConfig.dashboard.user.settings.index,
icon: Icons.Settings,
},
],
},
{
label: "dev",
items: [
{
title: "demos",
href: pathsConfig.demo.index,
icon: Icons.LayoutDashboard,
},
],
},
];
export default async function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
const { user } = await getSession();
if (!user) {
return redirect(pathsConfig.auth.login);
}
return (
<SidebarProvider>
<DashboardSidebar user={user} menu={menu} />
<DashboardInset>{children}</DashboardInset>
</SidebarProvider>
);
}