@@ -184,7 +376,7 @@ export default function AccountSection() {
/>
)}
{mode === "server" && (
- editingDisplayName ? (
+ displayNameField.editing ? (
{ setDisplayNameInput(e.target.value); setDisplayNameError(""); }}
+ onChange={(e) => displayNameField.setInput(e.target.value)}
className="rounded-lg px-3 py-1.5 text-sm outline-hidden"
style={{ background: "var(--t-bg-input)", border: "1px solid var(--t-border)", color: "var(--t-text-primary)" }}
/>
- {displayNameError &&
{displayNameError}
}
+ {displayNameField.error &&
{displayNameField.error}
}
@@ -237,11 +417,7 @@ export default function AccountSection() {
icon="lucide:user"
label={t("settings.account.displayName.title")}
sub={displayName ?? "—"}
- onClick={() => {
- setDisplayNameInput(displayName ?? "");
- setDisplayNameError("");
- setEditingDisplayName(true);
- }}
+ onClick={() => displayNameField.start(displayName ?? "")}
/>
)
)}
diff --git a/src/components/settings/sections/VaultsSection.tsx b/src/components/settings/sections/VaultsSection.tsx
index bb96a2f5d..39fc7544b 100644
--- a/src/components/settings/sections/VaultsSection.tsx
+++ b/src/components/settings/sections/VaultsSection.tsx
@@ -23,7 +23,7 @@ import { runTeamAction } from "@/services/teamActionFeedback";
import { markTeamVaultLoadedAfterLocalActivation } from "@/services/teamVaultActivation";
import { openBillingCheckout } from "@/services/billingCheckout";
import { useTeamVaultStateStore } from "@/stores/teamVaultStateStore";
-import { useUserSearch } from "@/hooks/useUserSearch";
+import { useUserSearch, type UserSearchResult } from "@/hooks/useUserSearch";
// ─── Vault migration helpers ──────────────────────────────────────────────────
@@ -155,8 +155,6 @@ function MemberRoleBadges({ member, roles }: { member: TeamMember; roles: TeamRo
// ─── Invite search bar ────────────────────────────────────────────────────────
-interface SearchResult { user_id: string; display_name: string; public_key: string; }
-
function isValidEmail(s: string) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s);
}
@@ -179,7 +177,7 @@ function InviteBar({ teamId, existingIds, roles, canInvite, onMemberAdded }: {
const [sendingInvite, setSendingInvite] = useState(false);
const [success, setSuccess] = useState("");
const [error, setError] = useState("");
- const [buySeatsFor, setBuySeatsFor] = useState
(undefined);
+ const [buySeatsFor, setBuySeatsFor] = useState(undefined);
const isAtSeatLimit = seatAvailability(usedSeats, totalSeats).atLimit;
@@ -204,7 +202,7 @@ function InviteBar({ teamId, existingIds, roles, canInvite, onMemberAdded }: {
if (!canInvite) return null;
- const handleAdd = async (user: SearchResult) => {
+ const handleAdd = async (user: UserSearchResult) => {
if (isAtSeatLimit) { setBuySeatsFor(user); setOpen(false); return; }
setAdding(user.user_id);
setError(""); setSuccess("");
@@ -739,7 +737,7 @@ export function PrivateVaultMembersPanel({
const [adding, setAdding] = useState(null);
const [error, setError] = useState("");
- const handleAdd = async (user: SearchResult) => {
+ const handleAdd = async (user: UserSearchResult) => {
setAdding(user.user_id);
setError("");
try {
diff --git a/src/components/settings/sections/shared.tsx b/src/components/settings/sections/shared.tsx
index 8fd5af4f5..0a400a6e8 100644
--- a/src/components/settings/sections/shared.tsx
+++ b/src/components/settings/sections/shared.tsx
@@ -117,12 +117,13 @@ export function ActionItem({ icon, label, sub, danger, disabled, onClick }: {
);
}
-export function SettingsInput({ type = "text", placeholder, value, onChange, autoFocus }: {
+export function SettingsInput({ type = "text", placeholder, value, onChange, autoFocus, "aria-label": ariaLabel }: {
type?: string;
placeholder: string;
value: string;
onChange: (v: string) => void;
autoFocus?: boolean;
+ "aria-label"?: string;
}) {
return (
onChange(e.target.value)}
className="form-input w-full px-3 py-2 rounded-lg text-sm outline-hidden bg-(--t-bg-input) border border-(--t-border) text-(--t-text-primary)"
/>
diff --git a/src/components/shared/Toggle.tsx b/src/components/shared/Toggle.tsx
index f0c486c36..cb60aa202 100644
--- a/src/components/shared/Toggle.tsx
+++ b/src/components/shared/Toggle.tsx
@@ -2,14 +2,16 @@ interface ToggleProps {
checked: boolean;
onChange: (value: boolean) => void;
disabled?: boolean;
+ "aria-label"?: string;
}
-export function Toggle({ checked, onChange, disabled }: ToggleProps) {
+export function Toggle({ checked, onChange, disabled, "aria-label": ariaLabel }: ToggleProps) {
return (
,
@@ -395,6 +423,7 @@ function ActiveSharingView({
inviteSession,
invitedThisSession,
onInvite,
+ onUninvite,
onStop,
onUpgrade,
}: {
@@ -407,7 +436,8 @@ function ActiveSharingView({
tier: ShareTier;
inviteSession: InviteSession;
invitedThisSession: ReadonlySet