diff --git a/apps/web/src/app/(dashboard)/settings/page.tsx b/apps/web/src/app/(dashboard)/settings/page.tsx new file mode 100644 index 0000000..cc6c925 --- /dev/null +++ b/apps/web/src/app/(dashboard)/settings/page.tsx @@ -0,0 +1,150 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { api } from '@/lib/api'; +import { useSession } from '@/lib/auth-client'; + +interface ProviderInfo { + name: string; + enabled: boolean; + modelCount: number; +} + +interface ModelInfo { + id: string; + name: string; + provider: string; + contextWindow: number; + reasoning: boolean; + cost: { input: number; output: number }; +} + +export default function SettingsPage(): React.ReactElement { + const { data: session } = useSession(); + const [providers, setProviders] = useState([]); + const [models, setModels] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + Promise.all([ + api('/api/providers').catch(() => []), + api('/api/providers/models').catch(() => []), + ]) + .then(([p, m]) => { + setProviders(p); + setModels(m); + }) + .finally(() => setLoading(false)); + }, []); + + return ( +
+

Settings

+ + {/* Profile */} +
+

Profile

+
+ {session?.user ? ( +
+ + + +
+ ) : ( +

Not signed in

+ )} +
+
+ + {/* Providers */} +
+

LLM Providers

+ {loading ? ( +

Loading providers...

+ ) : providers.length === 0 ? ( +
+

No providers configured

+
+ ) : ( +
+ {providers.map((p) => ( +
+
+

{p.name}

+

{p.modelCount} models available

+
+ + {p.enabled ? 'Active' : 'Disabled'} + +
+ ))} +
+ )} +
+ + {/* Models */} +
+

Available Models

+ {loading ? ( +

Loading models...

+ ) : models.length === 0 ? ( +
+

No models available

+
+ ) : ( +
+ + + + + + + + + + + {models.map((m) => ( + + + + + + + ))} + +
ModelProviderContextCost (in/out)
+ {m.name} + {m.reasoning && ( + reasoning + )} + {m.provider} + {(m.contextWindow / 1000).toFixed(0)}k + + ${m.cost.input} / ${m.cost.output} +
+
+ )} +
+
+ ); +} + +function Field({ label, value }: { label: string; value: string }): React.ReactElement { + return ( +
+ {label} + {value} +
+ ); +} diff --git a/docs/TASKS.md b/docs/TASKS.md index dc4feda..7728607 100644 --- a/docs/TASKS.md +++ b/docs/TASKS.md @@ -33,8 +33,8 @@ | P3-002 | done | Phase 3 | Auth pages — login, registration, SSO redirect | #83 | #27 | | P3-003 | done | Phase 3 | Chat UI — conversations, messages, streaming | #84 | #28 | | P3-004 | done | Phase 3 | Task management — list view + kanban board | #86 | #29 | -| P3-005 | in-progress | Phase 3 | Project & mission views — dashboard + PRD viewer | — | #30 | -| P3-006 | not-started | Phase 3 | Settings — provider config, profile, integrations | — | #31 | +| P3-005 | done | Phase 3 | Project & mission views — dashboard + PRD viewer | #87 | #30 | +| P3-006 | in-progress | Phase 3 | Settings — provider config, profile, integrations | — | #31 | | P3-007 | not-started | Phase 3 | Admin panel — user management, RBAC | — | #32 | | P3-008 | not-started | Phase 3 | Verify Phase 3 — web dashboard functional E2E | — | #33 | | P4-001 | not-started | Phase 4 | @mosaic/memory — preference + insight stores | — | #34 |