feat: signed-in state uses the shared OTM account menu (0.6.2)

Replace the ad-hoc "sign out" link next to the AI names toggle with
@otm/account-panel's OtmAccountMenu (avatar, OTM badge, Manage OTM
account, Sign out), and fold the "Sign in with OTM" helper line into
AiControls using the module's OTM_HELPER_LINE constant instead of a
hardcoded duplicate in Finder.tsx. Bumps @otm/account-panel 0.32.0 →
0.44.0 (already wired via .npmrc + transpilePackages for the
suggestions widget).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014LCQmFvKshyAJsE8C3B5ET
This commit is contained in:
2026-10-19 00:17:44 -05:00
co-authored by Claude Fable 5.1
parent 41e09d00d6
commit 4d1f7873ef
5 changed files with 56 additions and 34 deletions
+4 -4
View File
@@ -8,7 +8,7 @@
"name": "names-poweredbyotm", "name": "names-poweredbyotm",
"version": "0.6.1", "version": "0.6.1",
"dependencies": { "dependencies": {
"@otm/account-panel": "0.32.0", "@otm/account-panel": "^0.44.0",
"next": "^15.1.0", "next": "^15.1.0",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1" "react-dom": "18.3.1"
@@ -734,9 +734,9 @@
} }
}, },
"node_modules/@otm/account-panel": { "node_modules/@otm/account-panel": {
"version": "0.32.0", "version": "0.44.0",
"resolved": "https://git.poweredbyotm.com/api/packages/tonym/npm/%40otm%2Faccount-panel/-/0.32.0/account-panel-0.32.0.tgz", "resolved": "https://git.poweredbyotm.com/api/packages/tonym/npm/%40otm%2Faccount-panel/-/0.44.0/account-panel-0.44.0.tgz",
"integrity": "sha512-nWzVbaUC3Cv9awr8eTKB8XZv38GVXMnfXZPoqo6+jf+8GPHNwrpPjk0dtfV9wOq/FZyo686CF4CLoLBrRrh3nQ==", "integrity": "sha512-ule7EviLc5j7T9OFiknuL0oOv1hiV6D5Ph/7BwyP2PxbATXP8MIEAz0wz8bAupehWfFxrRGxfrIclWnRHynBIA==",
"peerDependencies": { "peerDependencies": {
"@stripe/react-stripe-js": ">=2", "@stripe/react-stripe-js": ">=2",
"@stripe/stripe-js": ">=3", "@stripe/stripe-js": ">=3",
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "names-poweredbyotm", "name": "names-poweredbyotm",
"version": "0.6.1", "version": "0.6.2",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev --port 3000", "dev": "next dev --port 3000",
@@ -10,7 +10,7 @@
"typecheck": "tsc --noEmit" "typecheck": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"@otm/account-panel": "0.32.0", "@otm/account-panel": "^0.44.0",
"next": "^15.1.0", "next": "^15.1.0",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1" "react-dom": "18.3.1"
+26 -8
View File
@@ -2,14 +2,21 @@
// The AI switch next to the generate button. Three states, one slot: // The AI switch next to the generate button. Three states, one slot:
// own key saved → "Use my Claude/Gemini key" (browser-direct path) // own key saved → "Use my Claude/Gemini key" (browser-direct path)
// signed in → "AI names" (platform gateway) + sign out // signed in → "AI names" (platform gateway) + the shared OTM account menu
// platform wired → "Sign in with OTM for AI names →" // platform wired → "Sign in with OTM" + the shared helper line
// none → nothing // none → nothing
// A saved key always wins over the platform path — see CLAUDE.md "AI — two paths". // A saved key always wins over the platform path — see CLAUDE.md "AI — two paths".
//
// The sign-in/account half rides @otm/account-panel's otm-login module so this
// app matches every other first-party app instead of a hand-rolled link +
// sign-out button. No OTM_LOGIN_CSS injection needed here — OtmAccountMenu
// carries its own (withStyles defaults true) and this app has no local
// accounts to theme-clash with.
import type { AiSettings } from "@/lib/ai"; import type { AiSettings } from "@/lib/ai";
import { otmSsoUrl } from "@/lib/otm"; import { otmSsoUrl } from "@/lib/otm";
import type { OtmAccount } from "@/hooks/useOtmSession"; import type { OtmAccount } from "@/hooks/useOtmSession";
import { OtmAccountMenu, OTM_HELPER_LINE } from "@otm/account-panel/otm-login";
const LABEL_STYLE = { display: "inline-flex", alignItems: "center", gap: 8, fontSize: 14, color: "var(--muted)" } as const; const LABEL_STYLE = { display: "inline-flex", alignItems: "center", gap: 8, fontSize: 14, color: "var(--muted)" } as const;
@@ -42,7 +49,8 @@ export function AiControls({
} }
if (platformAi && account) { if (platformAi && account) {
return ( return (
<label style={LABEL_STYLE} title={`Signed in as ${account.email}`}> <div style={{ display: "inline-flex", alignItems: "center", gap: 10 }}>
<label style={LABEL_STYLE}>
<input <input
type="checkbox" type="checkbox"
checked={usePlatformAi} checked={usePlatformAi}
@@ -50,24 +58,34 @@ export function AiControls({
style={{ width: "auto" }} style={{ width: "auto" }}
/> />
AI names AI names
<button type="button" className="linkish" onClick={onSignOut} title={`Sign out ${account.email}`}>
sign out
</button>
</label> </label>
<OtmAccountMenu
user={{ name: account.name, email: account.email }}
otm={{ linked: true }}
onSignOut={onSignOut}
/>
</div>
); );
} }
if (platformAi) { if (platformAi) {
// The lead (and only) action — this app has no local accounts, so there's // The lead (and only) action — this app has no local accounts, so there's
// no "other ways to sign in" to swap to. Styled as the house's one // no "other ways to sign in" to swap to. Styled as the house's one
// PRIMARY button, matching the shared first-party sign-in standard. // PRIMARY button, matching the shared first-party sign-in standard — the
// module's own `.otm-login__btn` is meant for its own card layout, not an
// inline control dropped into this app's plain CSS.
return ( return (
<span style={{ display: "inline-flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
<a <a
className="signin primary" className="signin primary"
href={otmSsoUrl("/")} href={otmSsoUrl("/")}
title="Free OTM account · adds AI-generated names" title="Free OTM account · adds AI-generated names"
> >
Sign in with OTM for AI names → Sign in with OTM
</a> </a>
<span className="hint signin-hint" style={{ margin: 0 }}>
{OTM_HELPER_LINE}
</span>
</span>
); );
} }
return null; return null;
+3 -6
View File
@@ -317,12 +317,9 @@ export default function Finder() {
onSignOut={signOut} onSignOut={signOut}
/> />
</div> </div>
{/* The "Sign in with OTM" helper line now lives inside AiControls
{platformAi && !account ? ( itself, next to the button, instead of as a second conditional
<p className="hint signin-hint"> block here — see AiControls.tsx. */}
Your OTM account — Face ID, Touch ID or a passkey works there.
</p>
) : null}
{aiOn ? ( {aiOn ? (
<div className="field brief"> <div className="field brief">
+8 -1
View File
@@ -2,7 +2,7 @@
// /changelog. Bump VERSION and prepend an entry when shipping a user-facing // /changelog. Bump VERSION and prepend an entry when shipping a user-facing
// change. Same convention as rpo. // change. Same convention as rpo.
export const VERSION = "0.6.1"; export const VERSION = "0.6.2";
export interface ChangelogEntry { export interface ChangelogEntry {
version: string; version: string;
@@ -11,6 +11,13 @@ export interface ChangelogEntry {
} }
export const CHANGELOG: ChangelogEntry[] = [ export const CHANGELOG: ChangelogEntry[] = [
{
version: "0.6.2",
date: "2026-10-19",
changes: [
"The signed-in state now shows the shared OTM account menu (avatar, OTM badge, Manage OTM account, Sign out) next to the AI names toggle, in place of a bare 'sign out' link — same module every other first-party app uses.",
],
},
{ {
version: "0.6.1", version: "0.6.1",
date: "2026-10-18", date: "2026-10-18",