@@ -173,7 +173,7 @@ function AllGroupsTab({ allUsers, onRefresh, isMobile = false }) {
}
// ── Direct Messages tab ───────────────────────────────────────────────────────
-function DirectMessagesTab({ allUserGroups, onRefresh, refreshKey, isMobile = false }) {
+function DirectMessagesTab({ allUserGroups, onRefresh, refreshKey, isMobile = false, onIF, onIB }) {
const toast = useToast();
const [dms, setDms] = useState([]);
const [selected, setSelected] = useState(null);
@@ -248,7 +248,7 @@ function DirectMessagesTab({ allUserGroups, onRefresh, refreshKey, isMobile = fa
- setDmName(e.target.value)} placeholder="e.g. Coaches + Players" style={{ marginTop:6 }} autoComplete="new-password" />
+ setDmName(e.target.value)} placeholder="e.g. Coaches + Players" style={{ marginTop:6 }} autoComplete="new-password" onFocus={onIF} onBlur={onIB} />
@@ -282,7 +282,7 @@ function DirectMessagesTab({ allUserGroups, onRefresh, refreshKey, isMobile = fa
// ── U2U Restrictions tab ──────────────────────────────────────────────────────
-function U2URestrictionsTab({ allUserGroups, isMobile = false }) {
+function U2URestrictionsTab({ allUserGroups, isMobile = false, onIF, onIB }) {
const toast = useToast();
const [selectedGroup, setSelectedGroup] = useState(null);
const [blockedIds, setBlockedIds] = useState(new Set());
@@ -434,8 +434,8 @@ function U2URestrictionsTab({ allUserGroups, isMobile = false }) {
Allowed Groups ({otherGroups.length - blockedIds.size} of {otherGroups.length} allowed)
setSearch(e.target.value)} style={{ marginBottom:8 }}
- autoComplete="new-password" />
+ onChange={e = autoComplete="new-password"> setSearch(e.target.value)} style={{ marginBottom:8 }}
+ autoComplete="new-password" onFocus={onIF} onBlur={onIB} />
{loading ? (
@@ -515,7 +515,9 @@ export default function GroupManagerPage({ isMobile = false, onProfile, onHelp,
const [allUsers, setAllUsers] = useState([]);
const [allUserGroups, setAllUserGroups] = useState([]);
const [refreshKey, setRefreshKey] = useState(0);
- const keyboardOpen = useKeyboardOpen();
+ const [inputFocused, setInputFocused] = useState(false);
+ const onIF = () => setInputFocused(true);
+ const onIB = () => setInputFocused(false);
const onRefresh = () => setRefreshKey(k => k+1);
useEffect(() => {
@@ -559,7 +561,7 @@ export default function GroupManagerPage({ isMobile = false, onProfile, onHelp,
)}
{/* ── Right panel ── */}
-
+
{/* Mobile tab bar — only shown on mobile */}
{isMobile && (
@@ -573,14 +575,16 @@ export default function GroupManagerPage({ isMobile = false, onProfile, onHelp,
{/* Content */}
- {tab==='all' &&
}
- {tab==='dm' &&
}
- {tab==='u2u' &&
}
+ {tab==='all' &&
}
+ {tab==='dm' &&
}
+ {tab==='u2u' &&
}
- {/* Mobile footer — in-flow so it stays at bottom and never floats with keyboard */}
- {isMobile && (
-
+ {/* Mobile footer — fixed, hidden when any input is focused (keyboard open) */}
+ {isMobile && !inputFocused && (
+
+
+
)}
diff --git a/frontend/src/pages/HostAdmin.jsx b/frontend/src/pages/HostAdmin.jsx
index fa89022..34a39c3 100644
--- a/frontend/src/pages/HostAdmin.jsx
+++ b/frontend/src/pages/HostAdmin.jsx
@@ -417,7 +417,7 @@ function KeyEntry({ onSubmit }) {
placeholder="Host admin key" autoFocus
style={{ width: '100%', padding: '10px 12px', border: '1px solid #e0e0e0', borderRadius: 6,
fontSize: 14, outline: 'none', boxSizing: 'border-box', marginBottom: 12 }}
- />
+ autoComplete="new-password" />
Sign In
diff --git a/frontend/src/pages/UserManagerPage.jsx b/frontend/src/pages/UserManagerPage.jsx
index 81d4b5b..4d9ab64 100644
--- a/frontend/src/pages/UserManagerPage.jsx
+++ b/frontend/src/pages/UserManagerPage.jsx
@@ -108,7 +108,7 @@ function UserRow({ u, onUpdated }) {
setNameVal(e.target.value)}
onKeyDown={e => { if(e.key==='Enter') handleSaveName(); if(e.key==='Escape'){setEditName(false);setNameVal(u.name);} }}
- autoComplete="new-password" />
+ autoComplete="new-password" onFocus={onIF} onBlur={onIB} />
@@ -134,7 +134,7 @@ function UserRow({ u, onUpdated }) {
type="text" placeholder="New password (min 6)" value={resetPw}
onChange={e => setResetPw(e.target.value)}
onKeyDown={e => { if(e.key==='Enter') handleResetPw(); if(e.key==='Escape'){setShowReset(false);setResetPw('');} }}
- autoComplete="new-password" />
+ autoComplete="new-password" onFocus={onIF} onBlur={onIB} />