From 5e0c49b205e232f7169bb14d5908af790589bf0a Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 22 Feb 2026 21:40:16 -0600 Subject: [PATCH] feat(web): add settings root index page with category cards Refs #466 Co-Authored-By: Claude Opus 4.6 --- .../src/app/(authenticated)/settings/page.tsx | 239 ++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 apps/web/src/app/(authenticated)/settings/page.tsx diff --git a/apps/web/src/app/(authenticated)/settings/page.tsx b/apps/web/src/app/(authenticated)/settings/page.tsx new file mode 100644 index 0000000..facf077 --- /dev/null +++ b/apps/web/src/app/(authenticated)/settings/page.tsx @@ -0,0 +1,239 @@ +"use client"; + +import { useState } from "react"; +import type { ReactElement, ReactNode } from "react"; +import Link from "next/link"; + +interface CategoryConfig { + title: string; + description: string; + href: string; + accent: string; + iconBg: string; + icon: ReactNode; +} + +interface SettingsCategoryCardProps { + category: CategoryConfig; +} + +function SettingsCategoryCard({ category }: SettingsCategoryCardProps): ReactElement { + const [hovered, setHovered] = useState(false); + + return ( + +
{ + setHovered(true); + }} + onMouseLeave={(): void => { + setHovered(false); + }} + style={{ + background: hovered ? "var(--surface-2)" : "var(--surface)", + border: `1px solid ${hovered ? category.accent : "var(--border)"}`, + borderRadius: "var(--r-lg)", + padding: 20, + transition: "background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease", + boxShadow: hovered ? "0 4px 16px rgba(0,0,0,0.2)" : "none", + cursor: "pointer", + display: "flex", + flexDirection: "column", + gap: 12, + height: "100%", + }} + > + {/* Icon well */} +
+ {category.icon} +
+ + {/* Title */} +
+ {category.title} +
+ + {/* Description */} +
+ {category.description} +
+ + {/* CTA */} +
+ Manage → +
+
+ + ); +} + +const categories: CategoryConfig[] = [ + { + title: "Credentials", + description: + "Securely store and manage API keys, tokens, and passwords used by agents and integrations.", + href: "/settings/credentials", + accent: "var(--ms-blue-400)", + iconBg: "rgba(47, 128, 255, 0.12)", + icon: ( + + ), + }, + { + title: "Domains", + description: + "Organize tasks and projects by life areas or functional domains within your workspace.", + href: "/settings/domains", + accent: "var(--ms-teal-400)", + iconBg: "rgba(20, 184, 166, 0.12)", + icon: ( + + ), + }, + { + title: "AI Personalities", + description: + "Customize how the AI assistant communicates \u2014 tone, formality, and response style.", + href: "/settings/personalities", + accent: "var(--ms-purple-400)", + iconBg: "rgba(139, 92, 246, 0.12)", + icon: ( + + ), + }, + { + title: "Workspaces", + description: + "Create and manage workspaces to organize projects and collaborate with your team.", + href: "/settings/workspaces", + accent: "var(--ms-amber-400)", + iconBg: "rgba(245, 158, 11, 0.12)", + icon: ( + + ), + }, +]; + +export default function SettingsPage(): ReactElement { + return ( +
+ {/* Page header */} +
+

+ Settings +

+

+ Configure your workspace, credentials, and preferences +

+
+ + {/* Category grid */} +
+ {categories.map((category) => ( + + ))} +
+
+ ); +}