feat(settings): /settings/export dynamic route wired into sidebar

The new `export` slug is now part of `SETTINGS_SECTION_SLUGS`, so the
dynamic `/settings/[section]/page.tsx` route picks it up via
`generateStaticParams()` and the existing 404-on-unknown guard. The
shell sidebar gains a Download-iconed entry between API and Advanced;
the placeholder fallback also learned the new icon so a future slug
addition can't crash type-checking.

The shell-test suite now expects ten sections (was nine) and asserts
that `/settings/export` is a real link in the rendered nav. Old
"advanced" copy already trimmed in the previous commit, so the export
entry is the new home for every "give me my data out" path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.7 committed 2026-05-09 23:51:33 +02:00
1 parent f1bd8014d8
commit a512650158
5 files changed
+19 -1

No files matched your search

+2
View File
@@ -7,6 +7,7 @@ import { AdvancedSection } from "@/components/settings/advanced-section";
import { AiSection } from "@/components/settings/ai-section";
import { ApiSection } from "@/components/settings/api-section";
import { DashboardSection } from "@/components/settings/dashboard-section";
import { ExportSection } from "@/components/settings/export-section";
import { IntegrationsSection } from "@/components/settings/integrations-section";
import { NotificationsSection } from "@/components/settings/notifications-section";
import { SectionPlaceholder } from "@/components/settings/section-placeholder";
@@ -45,6 +46,7 @@ const SECTION_COMPONENTS: Record<
dashboard: DashboardSection,
thresholds: ThresholdsSettingsSection,
api: ApiSection,
export: ExportSection,
advanced: AdvancedSection,
};
@@ -35,12 +35,15 @@ function renderShell(props: {
}
describe("SETTINGS_SECTION_SLUGS", () => {
it("declares exactly the nine sections agreed for v1.4.3", () => {
it("declares the ten sections agreed for v1.4.16", () => {
// Order matters — `generateStaticParams()` and the sidebar derive their
// ordering from this constant, so a reorder is a behaviour change.
// v1.4.3 split the dashboard panel: layout stays under `dashboard`,
// per-metric overrides moved to their own `thresholds` slug so it's
// a top-level entry in the settings nav.
// v1.4.16 phase B7 added the consolidated `export` section between
// `api` and `advanced` so every "give me my data out" path lives in
// one place.
expect([...SETTINGS_SECTION_SLUGS]).toEqual([
"account",
"integrations",
@@ -49,6 +52,7 @@ describe("SETTINGS_SECTION_SLUGS", () => {
"thresholds",
"ai",
"api",
"export",
"advanced",
"about",
]);
@@ -133,6 +137,9 @@ describe("<SettingsShell>", () => {
// The ampersand is HTML-escaped by React SSR — assert on the encoded
// form so we don't accidentally match a parser that double-escapes.
expect(html).toContain("API &amp; Tokens");
// v1.4.16 phase B7: the consolidated Export section is a top-level
// entry in the sidebar; the link must be present in both locales.
expect(html).toContain('href="/settings/export"');
expect(html).toContain("Advanced");
expect(html).toContain("About");
});
@@ -13,6 +13,7 @@
import {
Bell,
Download,
Info,
KeyRound,
LayoutDashboard,
@@ -36,6 +37,7 @@ const SLUG_ICON: Record<SettingsSectionSlug, LucideIcon> = {
thresholds: SlidersHorizontal,
ai: Sparkles,
api: KeyRound,
export: Download,
advanced: Settings2,
about: Info,
};
+1
View File
@@ -14,6 +14,7 @@ export const SETTINGS_SECTION_SLUGS = [
"thresholds",
"ai",
"api",
"export",
"advanced",
"about",
] as const;
@@ -19,6 +19,7 @@ import Link from "next/link";
import { usePathname } from "next/navigation";
import {
Bell,
Download,
Info,
KeyRound,
LayoutDashboard,
@@ -87,6 +88,11 @@ export const SETTINGS_SECTIONS: readonly SettingsSection[] = [
},
{ slug: "ai", titleKey: "settings.sections.ai.title", icon: Sparkles },
{ slug: "api", titleKey: "settings.sections.api.title", icon: KeyRound },
{
slug: "export",
titleKey: "settings.sections.export.title",
icon: Download,
},
{
slug: "advanced",
titleKey: "settings.sections.advanced.title",