import type { AccountPair } from './useJellyfinData'; import { ArrowLeftRight, CircleSlash, KeyRound, Loader2, UserPlus, Users } from 'lucide-react'; import { useJellyfinAccounts } from './useJellyfinData'; // Who exists on each side, shown side by side. // // The reason this is worth a screen: provisioning is invisible. Connecting a server can create accounts, // adopt accounts, and leave accounts alone, and until now the only record of which happened was a JSON // field in a response nobody reads and rows in a table nobody can see. An owner asking "did it work" had // no way to find out except to open Jellyfin and count. // // Four states, and each one means something different: // // linked a row in `jellyfin_accounts` says these are the same person // matchable the names fold to the same thing but nothing is recorded — what connecting WOULD adopt // Officer only no Jellyfin account, and no name that matches one — what connecting WOULD create // Jellyfin only somebody with no Officer account. Never touched, and that is deliberate: an absence // in Officer is indistinguishable from a list that has not been told about them yet. // this connection the admin account Officer signs in as. It has to be its own state: the owner is // excluded from the provisionable list on purpose, so without this their own account // appears on the Jellyfin side with nothing opposite it and gets labelled as belonging // to nobody — which is what the owner saw, next to their own name. const TONE = { connection: 'text-sky-600', linked: 'text-emerald-600', matchable: 'text-amber-600', officer: 'text-muted-foreground', jellyfin: 'text-muted-foreground', } as const; const stateOf = (p: AccountPair) => { if (p.isConnection) return { key: 'connection' as const, label: 'the account Officer connects with' }; if (p.linked && p.jellyfin) return { key: 'linked' as const, label: p.adopted ? 'linked (adopted)' : 'linked' }; if (p.linked) return { key: 'matchable' as const, label: 'linked, but the Jellyfin account is gone' }; if (p.matchable) return { key: 'matchable' as const, label: 'names match — not linked yet' }; if (p.officer) return { key: 'officer' as const, label: 'no Jellyfin account' }; return { key: 'jellyfin' as const, label: 'not an Officer account' }; }; const Cell = ({ name, sub, muted }: { name: string | null; sub?: string | null; muted?: boolean }) => name ? (
{name}
{sub ?
{sub}
: null}
) : (
—
); export const AccountsSection = ({ serverId }: { serverId: number | null }) => { const { data, isLoading, error } = useJellyfinAccounts(serverId); if (serverId === null) return null; return (

Accounts

{data?.known ? ( {data.counts.linked} linked · {data.counts.officerOnly} Officer only · {data.counts.jellyfinOnly} Jellyfin only ) : null}
{isLoading ? (

reading both sides…

) : null} {/* Distinct from "there are none". Not knowing means the platform has not sent the account list, or this server could not be reached — rendering an empty table for either would state something false about the server. */} {error || (data && !data.known) ? (

{data && !data.known ? data.reason : 'could not read the accounts on this server'}

) : null} {data?.known ? (
Officer Jellyfin
{data.pairs.map((pair) => { const state = stateOf(pair); return (
{state.key === 'connection' ? ( ) : state.key === 'linked' || state.key === 'matchable' ? ( ) : ( )}
{state.label}
); })}
) : null}

Connecting a server links accounts whose usernames match, creates the ones Officer has and Jellyfin does not, and never touches a Jellyfin account with no Officer user — an absence here is indistinguishable from someone the list has not been told about yet.

); };