import { Dialog } from '@base-ui/react/dialog'; import { useState } from 'react'; import { Button, buttonVariants } from '#/components/atoms/button.jsx'; import { Input } from '#/components/atoms/input.jsx'; import { Handle } from '#/components/molecules/handle.jsx'; import { account } from '#/lib/git.js'; import { beginSignIn } from '#/lib/oauth.js'; import { useSession } from '#/lib/session.jsx'; import { cn } from '#/lib/utils.js'; /** * The visitor's session, in the header: a sign-in affordance, or who they * are and the way out. * * The site's own account sits beside this and stays what it is, the identity * being browsed. This is the identity doing the browsing, on whichever server * holds it; signing in navigates to that server's consent page and back. * * The form asks in a dialog rather than in the header. Signing in is the one * thing on this page that leaves it, so it is worth a moment's attention and * room to say where the visitor is going and what fails when it does. The * header has room for neither: a form there widened the bar as it opened and * left an error to be read from a tooltip. */ export function SessionControls() { const { session, endSession } = useSession(); const [open, setOpen] = useState(false); const [identifier, setIdentifier] = useState(''); const [busy, setBusy] = useState(false); const [error, setError] = useState(''); if (session) { return ( ); } const submit = async (event) => { event.preventDefault(); setBusy(true); setError(''); try { await beginSignIn(identifier); } catch (err) { setError(err instanceof Error ? err.message : String(err)); setBusy(false); } }; return ( { setOpen(next); // A dialog closed part way through is reopened from the start, not // from whatever it was left saying. if (!next) { setError(''); setBusy(false); } }} > {/* The classes rather than the Button, the way a Link that should read as one takes them: the trigger is base-ui's own element and wants its own props on it. */} Sign in Sign in With your own atproto account, wherever it lives. Your server asks you to consent and sends you back here.
setIdentifier(event.target.value)} placeholder="your handle or DID" autoComplete="username" aria-label="Handle or DID" aria-invalid={error ? true : undefined} disabled={busy} /> {error &&

{error}

}
Cancel
{/* What signing in is for here, which is not obvious from a header button on somebody else's repository. */}

Your words are written to your own repo, never to {account.handle} 's. This repository decides whose it shows.

); }