fix(web): drop duplicate status — badge IS the editable trigger

The status column was rendering both a StatusBadge and a separate
EditableCell next to it, so 'done' showed twice in the same cell.
Adds a renderView prop to EditableCell so callers can override the
view-mode display; status now uses the badge as its visual, click-
to-edit behavior intact. Mobile card header drops its standalone
badge for the same reason — the body's Status row now shows the
badge inline.
This commit is contained in:
yiekheng 2026-05-03 08:13:51 +08:00
parent 6c984b6200
commit fe26878b38
2 changed files with 28 additions and 23 deletions

View File

@ -195,17 +195,15 @@ export default function AccountsTable({ initial, prefixPattern }: Props) {
/>
</td>
<td className="px-5 py-3 align-middle">
<div className="flex items-center gap-2">
<StatusBadge status={row.status} />
<EditableCell
value={row.status}
label={`status for ${row.username}`}
isCurrentlyEditing={editingKey === k("status")}
onEditStart={() => setEditingKey(k("status"))}
onEditEnd={() => setEditingKey(null)}
onSave={(v) => saveCell(row.username, "status", v)}
/>
</div>
<EditableCell
value={row.status}
label={`status for ${row.username}`}
isCurrentlyEditing={editingKey === k("status")}
onEditStart={() => setEditingKey(k("status"))}
onEditEnd={() => setEditingKey(null)}
onSave={(v) => saveCell(row.username, "status", v)}
renderView={(v) => <StatusBadge status={v} />}
/>
</td>
<td className="px-5 py-3 align-middle">
<EditableCell
@ -243,16 +241,13 @@ export default function AccountsTable({ initial, prefixPattern }: Props) {
<span className="font-mono text-base font-semibold text-zinc-900">
{row.username}
</span>
<div className="flex items-center gap-2">
<StatusBadge status={row.status} />
<DeleteButton
label={row.username}
onClick={() => {
setDeleteError(null);
setDeleteTarget(row.username);
}}
/>
</div>
<DeleteButton
label={row.username}
onClick={() => {
setDeleteError(null);
setDeleteTarget(row.username);
}}
/>
</div>
<dl className="mt-4 space-y-3 border-t border-zinc-100 pt-4">
<CardRow label="Password">
@ -273,6 +268,7 @@ export default function AccountsTable({ initial, prefixPattern }: Props) {
onEditStart={() => setEditingKey(k("status"))}
onEditEnd={() => setEditingKey(null)}
onSave={(v) => saveCell(row.username, "status", v)}
renderView={(v) => <StatusBadge status={v} />}
/>
</CardRow>
<CardRow label="Link">

View File

@ -9,6 +9,12 @@ type EditableCellProps = {
isCurrentlyEditing?: boolean;
onEditStart?: () => void;
onEditEnd?: () => void;
/**
* Override how the value is rendered in view mode. Use this to show
* something other than plain text (e.g., a status pill) clicking
* the rendered element still starts edit mode.
*/
renderView?: (value: string) => React.ReactNode;
};
export default function EditableCell({
@ -18,6 +24,7 @@ export default function EditableCell({
isCurrentlyEditing,
onEditStart,
onEditEnd,
renderView,
}: EditableCellProps) {
const [editing, setEditing] = useState(false);
const [draft, setDraft] = useState(value);
@ -75,10 +82,12 @@ export default function EditableCell({
type="button"
onClick={begin}
aria-label={label ? `Edit ${label}` : undefined}
className="group flex w-full min-w-0 items-start gap-2 -mx-2 rounded-md px-2 py-1 text-left font-mono text-[13px] text-zinc-900 transition-colors hover:bg-zinc-100/70 focus:outline-none focus-visible:ring-2 focus-visible:ring-zinc-900"
className="group flex w-full min-w-0 items-center gap-2 -mx-2 rounded-md px-2 py-1 text-left font-mono text-[13px] text-zinc-900 transition-colors hover:bg-zinc-100/70 focus:outline-none focus-visible:ring-2 focus-visible:ring-zinc-900"
>
<span className="min-w-0 flex-1 break-all">
{value || <em className="not-italic text-zinc-400"></em>}
{renderView
? renderView(value)
: value || <em className="not-italic text-zinc-400"></em>}
</span>
<span
aria-hidden="true"