Admin AI assistant screen (mock 1o)
/settings/ai edits the household's AI settings: Provider and Model pill
dropdowns (model list from GET /settings/ai/models plus "Type a model
id"), the API key as its masked last four with a Replace sheet that PUTs
the key then verifies it ("Verified · Oct 1" or the verify error), the
Creativity (temperature) slider, the mono system prompt, Reset (confirms,
then reset-prompt) and Save changes (PATCHes only the edited fields).
A 400 from the endpoint lock says to remove the key before switching
provider; the sheet's Remove key does that.
Unsaved changes are guarded on leaving: the app now runs under a data
router (createBrowserRouter) so the page can use useBlocker, plus
beforeunload for reloads and closing the tab.
Adds the Select pill-dropdown primitive. The test helper declaredStyle
skips pseudo-element rules, which jsdom cannot match.
Maestro task: a0847bb7-54d0-4244-ab15-f82500d0fa7f
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import { useState, type ReactNode } from 'react'
|
||||
import { createMemoryRouter, RouterProvider } from 'react-router'
|
||||
|
||||
// InDataRouter renders children under a memory data router's splat route at
|
||||
// path, as main.tsx renders App, so pages that block navigation (useBlocker)
|
||||
// work in tests. The router is created once, on first render.
|
||||
export function InDataRouter({ path, children }: { path: string; children: ReactNode }) {
|
||||
const [router] = useState(() => createMemoryRouter([{ path: '*', element: children }], { initialEntries: [path] }))
|
||||
return <RouterProvider router={router} />
|
||||
}
|
||||
Reference in New Issue
Block a user