Implement tasks 25, 26 + completion visibility setting

Task 25: Multiple dashboards — dashboards table + migration, /d/[slug]
route, root redirect, dashboard tabs in nav with create/rename/delete/
set-default. Task 26: Editable dashboard — react-grid-layout drag/resize
editor, widget picker modal with per-widget configurator auto-generated
from default config, save/reset server actions with Zod validation.

Completion visibility: server-side per-user setting (hours) replaces
localStorage timer; queries filter completed items by updatedAt cutoff;
Settings page dropdown persists preference via server action.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ginnoir
2026-05-06 15:52:59 -05:00
co-authored by Claude Sonnet 4.6
parent 2ad9521ef9
commit d5a8bf9d95
27 changed files with 1646 additions and 237 deletions
+10 -3
View File
@@ -6,8 +6,9 @@ import { AppNav } from "@/components/app-nav";
import "@/modules"; // registers all module manifests
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { eq } from "drizzle-orm";
import { users } from "@/modules/_core/schema";
import { asc, eq } from "drizzle-orm";
import { dashboards, users } from "@/modules/_core/schema";
import type { DashboardMeta } from "@/app/d/actions";
import { getQuickAdds } from "@/modules/_core";
import { QuickAddProvider } from "@/components/quick-add-provider";
import { QuickAddSheet } from "@/components/quick-add-sheet";
@@ -40,6 +41,7 @@ export default async function RootLayout({
}) {
let theme = "default";
let themeMode = "system";
let userDashboards: DashboardMeta[] = [];
const session = await auth();
if (session?.user?.id) {
@@ -52,6 +54,11 @@ export default async function RootLayout({
theme = row.theme;
themeMode = row.themeMode;
}
userDashboards = await db
.select({ id: dashboards.id, name: dashboards.name, slug: dashboards.slug, isDefault: dashboards.isDefault, position: dashboards.position })
.from(dashboards)
.where(eq(dashboards.userId, session.user.id))
.orderBy(asc(dashboards.position), asc(dashboards.createdAt));
}
// For system mode we can't know the preference on the server — the inline
@@ -71,7 +78,7 @@ export default async function RootLayout({
</head>
<body className="min-h-screen">
<QuickAddProvider actions={quickAdds}>
<AppNav />
<AppNav dashboards={userDashboards} />
<main>{children}</main>
<QuickAddSheet />
<CommandPalette />