agent: LoginFlow — one card, matching Dropdown's popup visual language
mara: "reuse the popup component for the login, the floating separate panels should be one card" — the old markup's .agent-status-overlay > * rule boxed every direct-child <p>/<form> separately, a faithful port of app.js's el().append()-per-line but not what a hand-authored component should do. Wraps each state's content in one .login-card div instead, styled to match Dropdown's .ui-dropdown (@hive/shared) background/border/radius/shadow values exactly, so this reads as the same popup family as every other floating surface in the app rather than a one-off. Not the Dropdown component itself — its options.map render is menu-item-shaped, not a fit for a login form + output pane. agent.css's .agent-status-overlay > * rule is untouched (app.js's still-live markup depends on it verbatim until the index.html cutover) — .login-card coexists with it rather than editing it, correctly overriding on equal specificity since main.css loads after agent.css.
This commit is contained in:
parent
ae94fff5af
commit
b56696d898
2 changed files with 43 additions and 8 deletions
25
frontend/packages/agent/src/components/LoginFlow.css
Normal file
25
frontend/packages/agent/src/components/LoginFlow.css
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/* .login-card — one elevated-surface card for the whole login-recovery
|
||||
overlay, replacing the old markup's per-`<p>`/`<form>` boxing
|
||||
(`agent.css`'s `.agent-status-overlay > *`, still needed there
|
||||
verbatim since app.js's still-live markup depends on it until the
|
||||
index.html cutover — this file coexists with it rather than editing
|
||||
it). Same visual language as `Dropdown`'s `.ui-dropdown`
|
||||
(`@hive/shared/dropdown/Dropdown.css`) — background/border/radius/
|
||||
shadow values match exactly, so this reads as the same "popup" family
|
||||
as every other floating surface in the app, just laid out as a static
|
||||
block instead of an anchored, position:absolute menu (that part of
|
||||
`Dropdown` is specific to hanging under a trigger and doesn't apply
|
||||
here — `.agent-status-overlay` already centres this card itself). */
|
||||
.login-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.6em;
|
||||
background: var(--bg-elev);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.5em;
|
||||
box-shadow: 0 0.4em 1em rgba(0, 0, 0, 0.35);
|
||||
padding: 1em 1.2em;
|
||||
}
|
||||
.login-card > * {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
@ -3,13 +3,23 @@
|
|||
// as real functional UI, not just a status label: an agent whose
|
||||
// credentials got rotated (or hit `/logout`) has NO other way back
|
||||
// online, so this is load-bearing, not cosmetic. Reuses agent.css's
|
||||
// existing `.agent-status-overlay`/`.status-needs-login`/`.btn-login`/
|
||||
// `.loginform`/`.loginform-reveal` rules verbatim (same class names as
|
||||
// the old markup) — no component-local CSS needed, matching Header.tsx's
|
||||
// same reuse pattern.
|
||||
// `.status-needs-login`/`.btn-login`/`.loginform`/`.loginform-reveal`
|
||||
// rules verbatim (same class names as the old markup).
|
||||
//
|
||||
// mara (screenshot review): "reuse the popup component for the login,
|
||||
// the floating separate panels should be one card." The old markup's
|
||||
// `.agent-status-overlay > *` rule boxed every direct-child `<p>`/
|
||||
// `<form>` separately (a fine translation of `el().append()`-per-line,
|
||||
// but not what a hand-authored component should do) — this renders one
|
||||
// `.login-card` instead, styled with the same "elevated surface" look
|
||||
// `Dropdown`'s `.ui-dropdown` already established (`@hive/shared/
|
||||
// dropdown/Dropdown.css`), not `Dropdown` itself (its `options.map`
|
||||
// render is menu-item-shaped, not a generic content container — not a
|
||||
// fit for a login form + output pane).
|
||||
import { useState } from 'preact/hooks';
|
||||
import type { SessionView } from '../types.js';
|
||||
import { postLoginStart, postLoginCode, postLoginCancel } from '../lib/loginAction.js';
|
||||
import './LoginFlow.css';
|
||||
|
||||
function LoginIdle({ onStarted }: { onStarted: () => void }) {
|
||||
const [busy, setBusy] = useState(false);
|
||||
|
|
@ -27,7 +37,7 @@ function LoginIdle({ onStarted }: { onStarted: () => void }) {
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="login-card">
|
||||
<p class="status-needs-login">◌ NEEDS L0G1N</p>
|
||||
<p>
|
||||
No Claude session in <code>~/.claude/</code>. The harness is up but the turn loop is
|
||||
|
|
@ -43,7 +53,7 @@ function LoginIdle({ onStarted }: { onStarted: () => void }) {
|
|||
Spawns <code>claude auth login</code> over plain stdio pipes. The OAuth URL will appear
|
||||
here when claude emits it; paste the resulting code back into the form below.
|
||||
</p>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +89,7 @@ function LoginInProgress({ session, onDone }: { session: SessionView | null; onD
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="login-card">
|
||||
<p class="status-needs-login">◌ L0G1N 1N PR0GRESS</p>
|
||||
{session?.url ? (
|
||||
<>
|
||||
|
|
@ -136,7 +146,7 @@ function LoginInProgress({ session, onDone }: { session: SessionView | null; onD
|
|||
{error ? <p class="meta">error: {error}</p> : null}
|
||||
<h3>output</h3>
|
||||
<pre class="diff">{session?.output || ''}</pre>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue