fleetlens 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/apps/web/.next/BUILD_ID +1 -1
- package/app/apps/web/.next/app-path-routes-manifest.json +9 -0
- package/app/apps/web/.next/build-manifest.json +6 -6
- package/app/apps/web/.next/prerender-manifest.json +3 -3
- package/app/apps/web/.next/routes-manifest.json +62 -0
- package/app/apps/web/.next/server/app/_global-error/page/build-manifest.json +3 -3
- package/app/apps/web/.next/server/app/_global-error.html +1 -1
- package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_not-found/page/build-manifest.json +3 -3
- package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/api/ask/route.js +3 -2
- package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/events/route.js +1 -0
- package/app/apps/web/.next/server/app/api/events/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/insights/months-index/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/insights/months-index/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/insights/months-index/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/insights/months-index/route.js +7 -0
- package/app/apps/web/.next/server/app/api/insights/months-index/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/insights/months-index/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/insights/months-index/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route.js +6 -0
- package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/insights/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/insights/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/insights/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/insights/route.js +8 -0
- package/app/apps/web/.next/server/app/api/insights/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/insights/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/insights/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/insights/saved/[key]/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/insights/saved/[key]/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/insights/saved/[key]/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/insights/saved/[key]/route.js +6 -0
- package/app/apps/web/.next/server/app/api/insights/saved/[key]/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/insights/saved/[key]/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/insights/saved/[key]/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/insights/saved/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/insights/saved/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/insights/saved/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/insights/saved/route.js +6 -0
- package/app/apps/web/.next/server/app/api/insights/saved/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/insights/saved/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/insights/saved/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/insights/weeks-index/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/insights/weeks-index/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/insights/weeks-index/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/insights/weeks-index/route.js +7 -0
- package/app/apps/web/.next/server/app/api/insights/weeks-index/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/insights/weeks-index/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/insights/weeks-index/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/insights/[key]/page/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/insights/[key]/page/build-manifest.json +17 -0
- package/app/apps/web/.next/server/app/insights/[key]/page/next-font-manifest.json +6 -0
- package/app/apps/web/.next/server/app/insights/[key]/page/react-loadable-manifest.json +1 -0
- package/app/apps/web/.next/server/app/insights/[key]/page/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/insights/[key]/page.js +16 -0
- package/app/apps/web/.next/server/app/insights/[key]/page.js.map +5 -0
- package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/insights/page/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/insights/page/build-manifest.json +17 -0
- package/app/apps/web/.next/server/app/insights/page/next-font-manifest.json +6 -0
- package/app/apps/web/.next/server/app/insights/page/react-loadable-manifest.json +1 -0
- package/app/apps/web/.next/server/app/insights/page/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/insights/page.js +16 -0
- package/app/apps/web/.next/server/app/insights/page.js.map +5 -0
- package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/insights/print/[key]/page/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/insights/print/[key]/page/build-manifest.json +17 -0
- package/app/apps/web/.next/server/app/insights/print/[key]/page/next-font-manifest.json +6 -0
- package/app/apps/web/.next/server/app/insights/print/[key]/page/react-loadable-manifest.json +1 -0
- package/app/apps/web/.next/server/app/insights/print/[key]/page/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/insights/print/[key]/page.js +16 -0
- package/app/apps/web/.next/server/app/insights/print/[key]/page.js.map +5 -0
- package/app/apps/web/.next/server/app/insights/print/[key]/page.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/insights/print/[key]/page_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/page/build-manifest.json +3 -3
- package/app/apps/web/.next/server/app/page.js +1 -1
- package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/parallelism/page/build-manifest.json +3 -3
- package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page/build-manifest.json +3 -3
- package/app/apps/web/.next/server/app/projects/[slug]/page.js +1 -2
- package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/page/build-manifest.json +3 -3
- package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page/build-manifest.json +3 -3
- package/app/apps/web/.next/server/app/sessions/[id]/page.js +1 -2
- package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/page/build-manifest.json +3 -3
- package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/usage/page/build-manifest.json +3 -3
- package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app-paths-manifest.json +9 -0
- package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_insights_months-index_route_actions_0~h~zci.js +3 -0
- package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_insights_saved_[key]_route_actions_0a5j9yw.js +3 -0
- package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_insights_weeks-index_route_actions_0hh-1c7.js +3 -0
- package/app/apps/web/.next/server/chunks/{[externals]__0rv9ct5._.js → [externals]__0_xztrf._.js} +2 -2
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0.hmj0z._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__01h_g-p._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nh-z10._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0op9af~._.js +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0ri7q~r._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0rr1~~x._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0s0gv.0._.js +3 -0
- package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_insights_pdf_[key]_route_actions_0lu-lnx.js +3 -0
- package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_insights_route_actions_0h8l5lz.js +3 -0
- package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_insights_saved_route_actions_13rlblw.js +3 -0
- package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_00t2xj6.js +68 -0
- package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0sgyieh._.js → node_modules_next_dist_esm_build_templates_app-route_0ck.78s.js} +5 -5
- package/app/apps/web/.next/server/chunks/packages_parser_dist_fs_0bc7ptm.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__00z7zlm._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__08.d5ia._.js +12 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0b323~k._.js +8 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0euu8sa._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0gio_ck._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0gx-4qa._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0w52fbc._.js +3 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0z45d0g._.js +49 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__13itnvx._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/_0r~__0v._.js +12 -0
- package/app/apps/web/.next/server/chunks/ssr/_0xies90._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_insights_[key]_page_actions_0_z2~e_.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_insights_page_actions_0zjdm~n.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_insights_print_[key]_page_actions_0a853fw.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_06j3c.0._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_insight-report_tsx_13q2a-c._.js +12 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_insights-view_tsx_11730ta._.js +6 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0-lmm4p._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0nqz8dw._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_0t-hj0x._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0vz7_px.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_10cdrh2.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_12n1lw_.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0-jvt~a._.js +1 -1
- package/app/apps/web/.next/server/functions-config-manifest.json +7 -1
- package/app/apps/web/.next/server/middleware-build-manifest.js +6 -6
- package/app/apps/web/.next/server/pages/500.html +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/app/apps/web/.next/static/chunks/03_7xtpi9sv4g.js +4 -0
- package/app/apps/web/.next/static/chunks/08c1pcrocqq5s.js +6 -0
- package/app/apps/web/.next/static/chunks/0e-wrhqh4h3r5.js +2 -0
- package/app/apps/web/.next/static/chunks/0i7er7_bfab36.js +10 -0
- package/app/apps/web/.next/static/chunks/0ipytyi01h0ta.js +1 -0
- package/app/apps/web/.next/static/chunks/0u-n8fz-ms.ee.js +6 -0
- package/app/apps/web/.next/static/chunks/137uw2-qbro07.js +31 -0
- package/app/apps/web/.next/static/chunks/{0p1lpoh02zh8h.js → 15w5_bct86ut6.js} +3 -3
- package/app/apps/web/.next/static/chunks/{turbopack-17n9y8y0h4q9f.js → turbopack-169w-1._23ra_.js} +1 -1
- package/app/apps/web/app/api/insights/months-index/route.ts +80 -0
- package/app/apps/web/app/api/insights/pdf/[key]/route.ts +45 -0
- package/app/apps/web/app/api/insights/route.ts +508 -0
- package/app/apps/web/app/api/insights/saved/[key]/route.ts +11 -0
- package/app/apps/web/app/api/insights/saved/route.ts +9 -0
- package/app/apps/web/app/api/insights/weeks-index/route.ts +95 -0
- package/app/apps/web/app/insights/[key]/page.tsx +59 -0
- package/app/apps/web/app/insights/page.tsx +7 -0
- package/app/apps/web/app/insights/print/[key]/page.tsx +73 -0
- package/app/apps/web/app/sessions/[id]/session-view.tsx +450 -21
- package/app/apps/web/components/insight-report.tsx +1031 -0
- package/app/apps/web/components/insights-view.tsx +647 -0
- package/app/apps/web/components/live-refresher.tsx +11 -2
- package/app/apps/web/components/sidebar.tsx +8 -0
- package/app/apps/web/eslint.config.mjs +2 -0
- package/app/apps/web/lib/ai/chrome-pdf.ts +64 -0
- package/app/apps/web/lib/ai/insights-prompt.ts +71 -0
- package/app/apps/web/lib/ai/saved-reports.ts +83 -0
- package/app/apps/web/lib/date-range.ts +11 -2
- package/app/apps/web/lib/use-live-events.ts +7 -2
- package/app/apps/web/package.json +3 -2
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +2852 -11
- package/dist/index.js +3091 -268
- package/package.json +5 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__05lbtny._.js +0 -12
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ms7h0~._.js +0 -8
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0p~g4m6._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0wvzyl7._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/_0ph19-k._.js +0 -12
- package/app/apps/web/.next/server/chunks/ssr/_0u29mdd._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/node_modules_0i2xw~e._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0.knjn.._.js +0 -3
- package/app/apps/web/.next/static/chunks/0257pdz1-imal.js +0 -2
- package/app/apps/web/.next/static/chunks/08983lz4~hffx.js +0 -6
- package/app/apps/web/.next/static/chunks/0qmh881w772ef.js +0 -31
- package/app/apps/web/.next/static/chunks/0wdga7zbwvg70.js +0 -1
- package/app/apps/web/.next/static/chunks/14q3xsfpkvuef.js +0 -6
- /package/app/apps/web/.next/static/{0fPDRTdMQ-Y62h6fHNJXL → 95-RytHk7ZQtfpZj5BLST}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{0fPDRTdMQ-Y62h6fHNJXL → 95-RytHk7ZQtfpZj5BLST}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{0fPDRTdMQ-Y62h6fHNJXL → 95-RytHk7ZQtfpZj5BLST}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getSavedReport } from "@/lib/ai/saved-reports";
|
|
2
|
+
|
|
3
|
+
export const dynamic = "force-dynamic";
|
|
4
|
+
export const runtime = "nodejs";
|
|
5
|
+
|
|
6
|
+
export async function GET(_req: Request, ctx: { params: Promise<{ key: string }> }) {
|
|
7
|
+
const { key } = await ctx.params;
|
|
8
|
+
const report = await getSavedReport(key);
|
|
9
|
+
if (!report) return Response.json({ error: "not found" }, { status: 404 });
|
|
10
|
+
return Response.json({ report });
|
|
11
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weeks index — drives the week picker in /insights.
|
|
3
|
+
*
|
|
4
|
+
* Returns the last N calendar weeks (Mon-Sun, newest first) with:
|
|
5
|
+
* - isoweek + period label
|
|
6
|
+
* - session count observed in that window (raw SessionMeta filter)
|
|
7
|
+
* - in_progress flag for this week
|
|
8
|
+
* - saved_key when a report exists on disk
|
|
9
|
+
* - archetype_label + sessions_used from the saved report, for display
|
|
10
|
+
*/
|
|
11
|
+
import { listSessions } from "@claude-lens/parser/fs";
|
|
12
|
+
import { calendarWeek, priorCalendarWeek } from "@claude-lens/parser";
|
|
13
|
+
import { listSavedReports, type SavedReportMeta } from "@/lib/ai/saved-reports";
|
|
14
|
+
|
|
15
|
+
export const dynamic = "force-dynamic";
|
|
16
|
+
export const runtime = "nodejs";
|
|
17
|
+
|
|
18
|
+
type WeekRow = {
|
|
19
|
+
iso_week: number;
|
|
20
|
+
start: string; // "2026-04-13"
|
|
21
|
+
end: string;
|
|
22
|
+
label: string; // "Apr 13 – Apr 19"
|
|
23
|
+
sessions: number;
|
|
24
|
+
in_progress: boolean;
|
|
25
|
+
saved_key: string | null;
|
|
26
|
+
archetype_label?: string;
|
|
27
|
+
sessions_used?: number;
|
|
28
|
+
prs?: number;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function isoDay(d: Date): string {
|
|
32
|
+
const y = d.getFullYear();
|
|
33
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
34
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
35
|
+
return `${y}-${m}-${day}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function isoWeekNo(d: Date): number {
|
|
39
|
+
const t = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
|
|
40
|
+
t.setUTCDate(t.getUTCDate() + 4 - (t.getUTCDay() || 7));
|
|
41
|
+
const yearStart = new Date(Date.UTC(t.getUTCFullYear(), 0, 1));
|
|
42
|
+
return Math.ceil((((t.getTime() - yearStart.getTime()) / 86_400_000) + 1) / 7);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function label(start: Date, end: Date): string {
|
|
46
|
+
const fmt = (d: Date) => d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
47
|
+
return `${fmt(start)} – ${fmt(end)}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function GET(req: Request) {
|
|
51
|
+
const url = new URL(req.url);
|
|
52
|
+
const count = Math.min(26, Math.max(1, parseInt(url.searchParams.get("count") ?? "12", 10)));
|
|
53
|
+
|
|
54
|
+
const [metas, saved] = await Promise.all([listSessions({ limit: 10000 }), listSavedReports()]);
|
|
55
|
+
const savedByKey = new Map<string, SavedReportMeta>(saved.map((s) => [s.key, s]));
|
|
56
|
+
|
|
57
|
+
const current = calendarWeek();
|
|
58
|
+
const prior = priorCalendarWeek();
|
|
59
|
+
|
|
60
|
+
const weeks: WeekRow[] = [];
|
|
61
|
+
for (let i = 0; i < count; i++) {
|
|
62
|
+
let start: Date, end: Date, in_progress: boolean;
|
|
63
|
+
if (i === 0) {
|
|
64
|
+
start = current.start; end = current.end; in_progress = true;
|
|
65
|
+
} else {
|
|
66
|
+
const offset = (i - 1) * 7;
|
|
67
|
+
start = new Date(prior.start); start.setDate(prior.start.getDate() - offset);
|
|
68
|
+
end = new Date(prior.end); end.setDate(prior.end.getDate() - offset);
|
|
69
|
+
in_progress = false;
|
|
70
|
+
}
|
|
71
|
+
const startMs = start.getTime();
|
|
72
|
+
const endMs = new Date(end).setHours(23, 59, 59, 999);
|
|
73
|
+
const sessions = metas.filter((m) => {
|
|
74
|
+
if (!m.firstTimestamp) return false;
|
|
75
|
+
const t = Date.parse(m.firstTimestamp);
|
|
76
|
+
return !Number.isNaN(t) && t >= startMs && t <= endMs;
|
|
77
|
+
}).length;
|
|
78
|
+
const startKey = isoDay(start);
|
|
79
|
+
const savedMeta = savedByKey.get(`week-${startKey}`);
|
|
80
|
+
weeks.push({
|
|
81
|
+
iso_week: isoWeekNo(start),
|
|
82
|
+
start: startKey,
|
|
83
|
+
end: isoDay(end),
|
|
84
|
+
label: label(start, end),
|
|
85
|
+
sessions,
|
|
86
|
+
in_progress,
|
|
87
|
+
saved_key: savedMeta ? savedMeta.key : null,
|
|
88
|
+
archetype_label: savedMeta?.archetype_label,
|
|
89
|
+
sessions_used: savedMeta?.sessions_used,
|
|
90
|
+
prs: savedMeta?.prs,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return Response.json({ weeks });
|
|
95
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Saved-report viewer. Deep-linkable, bookmarkable, server-rendered.
|
|
3
|
+
*
|
|
4
|
+
* /insights → history + picker (client-state machine)
|
|
5
|
+
* /insights/[key] → this page — reads the saved JSON off disk
|
|
6
|
+
* /insights/print/[key] → headless-Chrome target for PDF export
|
|
7
|
+
*/
|
|
8
|
+
import Link from "next/link";
|
|
9
|
+
import { notFound } from "next/navigation";
|
|
10
|
+
import { ArrowLeft } from "lucide-react";
|
|
11
|
+
import { InsightReport } from "@/components/insight-report";
|
|
12
|
+
import { getSavedReport } from "@/lib/ai/saved-reports";
|
|
13
|
+
|
|
14
|
+
export const dynamic = "force-dynamic";
|
|
15
|
+
|
|
16
|
+
export default async function SavedInsightPage({
|
|
17
|
+
params,
|
|
18
|
+
}: { params: Promise<{ key: string }> }) {
|
|
19
|
+
const { key } = await params;
|
|
20
|
+
const report = await getSavedReport(key);
|
|
21
|
+
if (!report) notFound();
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div>
|
|
25
|
+
<div className="no-print" style={topNavStyle}>
|
|
26
|
+
<Link href="/insights" style={backBtnStyle}>
|
|
27
|
+
<ArrowLeft size={12} /> Reports
|
|
28
|
+
</Link>
|
|
29
|
+
<span style={{ fontSize: 11, color: "var(--af-text-tertiary)", fontFamily: "var(--font-mono)" }}>
|
|
30
|
+
saved · key: {key}
|
|
31
|
+
</span>
|
|
32
|
+
</div>
|
|
33
|
+
<InsightReport data={report} savedKey={key} />
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const topNavStyle: React.CSSProperties = {
|
|
39
|
+
maxWidth: 980,
|
|
40
|
+
margin: "0 auto",
|
|
41
|
+
padding: "16px 44px 0",
|
|
42
|
+
display: "flex",
|
|
43
|
+
alignItems: "center",
|
|
44
|
+
gap: 12,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const backBtnStyle: React.CSSProperties = {
|
|
48
|
+
display: "inline-flex",
|
|
49
|
+
alignItems: "center",
|
|
50
|
+
gap: 6,
|
|
51
|
+
padding: "7px 12px",
|
|
52
|
+
border: "1px solid var(--af-border)",
|
|
53
|
+
borderRadius: 8,
|
|
54
|
+
background: "var(--af-surface)",
|
|
55
|
+
color: "var(--af-text)",
|
|
56
|
+
fontSize: 12,
|
|
57
|
+
fontWeight: 500,
|
|
58
|
+
textDecoration: "none",
|
|
59
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Print-mode rendering target for `/api/insights/pdf/[key]`.
|
|
3
|
+
*
|
|
4
|
+
* Server-renders the saved report with the sidebar and floating widgets
|
|
5
|
+
* hidden, light theme forced, and print-optimised spacing. Chrome headless
|
|
6
|
+
* points at this URL when generating the PDF.
|
|
7
|
+
*/
|
|
8
|
+
import { notFound } from "next/navigation";
|
|
9
|
+
import { InsightReport } from "@/components/insight-report";
|
|
10
|
+
import { getSavedReport } from "@/lib/ai/saved-reports";
|
|
11
|
+
|
|
12
|
+
export const dynamic = "force-dynamic";
|
|
13
|
+
|
|
14
|
+
export default async function PrintInsightPage({
|
|
15
|
+
params,
|
|
16
|
+
}: { params: Promise<{ key: string }> }) {
|
|
17
|
+
const { key } = await params;
|
|
18
|
+
const report = await getSavedReport(key);
|
|
19
|
+
if (!report) notFound();
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div data-theme="light" data-print-mode="true" style={{ background: "white" }}>
|
|
23
|
+
<style>{`
|
|
24
|
+
/* Neutralise the root-layout viewport lock so content paginates freely. */
|
|
25
|
+
html, body {
|
|
26
|
+
height: auto !important;
|
|
27
|
+
min-height: 0 !important;
|
|
28
|
+
overflow: visible !important;
|
|
29
|
+
background: white !important;
|
|
30
|
+
margin: 0 !important;
|
|
31
|
+
padding: 0 !important;
|
|
32
|
+
}
|
|
33
|
+
body > div[style*="height: 100vh"],
|
|
34
|
+
body > div[style*="height:100vh"] {
|
|
35
|
+
display: block !important;
|
|
36
|
+
height: auto !important;
|
|
37
|
+
min-height: 0 !important;
|
|
38
|
+
}
|
|
39
|
+
main {
|
|
40
|
+
flex: none !important;
|
|
41
|
+
padding: 0 !important;
|
|
42
|
+
margin: 0 !important;
|
|
43
|
+
width: 100% !important;
|
|
44
|
+
min-height: 0 !important;
|
|
45
|
+
overflow: visible !important;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Hide everything that isn't the report itself. */
|
|
49
|
+
aside, [data-sidebar], .af-sidebar,
|
|
50
|
+
[data-live-refresher], .af-live-widget,
|
|
51
|
+
nav[aria-label="Main"], header[data-app-header] { display: none !important; }
|
|
52
|
+
.no-print { display: none !important; }
|
|
53
|
+
|
|
54
|
+
/* Report layout tuned for letter paper. */
|
|
55
|
+
.report-root {
|
|
56
|
+
max-width: none !important;
|
|
57
|
+
margin: 0 !important;
|
|
58
|
+
padding: 36px 48px 48px !important;
|
|
59
|
+
color: var(--af-text) !important;
|
|
60
|
+
}
|
|
61
|
+
.report-root section { page-break-inside: auto; }
|
|
62
|
+
.report-root section > header,
|
|
63
|
+
.report-root [role="heading"],
|
|
64
|
+
.report-root h1, .report-root h2, .report-root h3 {
|
|
65
|
+
page-break-after: avoid;
|
|
66
|
+
break-after: avoid;
|
|
67
|
+
}
|
|
68
|
+
@page { size: letter; margin: 0.4in; }
|
|
69
|
+
`}</style>
|
|
70
|
+
<InsightReport data={report} />
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|