bug fixes
This commit is contained in:
@@ -741,12 +741,16 @@ export default function GroupManagerPage({ isMobile = false, onProfile, onHelp,
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Content */}
|
||||
<div style={{ flex:1, display:'flex', overflow: isMobile ? 'auto' : 'hidden', paddingBottom: isMobile ? 'calc(82px + env(safe-area-inset-bottom, 0px))' : 0 }}>
|
||||
{tab==='all' && <AllGroupsTab allUsers={allUsers} onRefresh={onRefresh} isMobile={isMobile} onIF={onIF} onIB={onIB} />}
|
||||
{tab==='dm' && <DirectMessagesTab allUserGroups={allUserGroups} onRefresh={onRefresh} refreshKey={refreshKey} isMobile={isMobile} onIF={onIF} onIB={onIB} />}
|
||||
{tab==='u2u' && <U2URestrictionsTab allUserGroups={allUserGroups} isMobile={isMobile} onIF={onIF} onIB={onIB} />}
|
||||
</div>
|
||||
{/* form wrapper suppresses Chrome Android's autofill chip bar; autoComplete="off"
|
||||
on individual inputs is ignored by Chrome but respected on the form element */}
|
||||
<form autoComplete="off" onSubmit={e => e.preventDefault()}>
|
||||
{/* Content */}
|
||||
<div style={{ flex:1, display:'flex', overflow: isMobile ? 'auto' : 'hidden', paddingBottom: isMobile ? 'calc(82px + env(safe-area-inset-bottom, 0px))' : 0 }}>
|
||||
{tab==='all' && <AllGroupsTab allUsers={allUsers} onRefresh={onRefresh} isMobile={isMobile} onIF={onIF} onIB={onIB} />}
|
||||
{tab==='dm' && <DirectMessagesTab allUserGroups={allUserGroups} onRefresh={onRefresh} refreshKey={refreshKey} isMobile={isMobile} onIF={onIF} onIB={onIB} />}
|
||||
{tab==='u2u' && <U2URestrictionsTab allUserGroups={allUserGroups} isMobile={isMobile} onIF={onIF} onIB={onIB} />}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/* Mobile footer — fixed, hidden when any input is focused (keyboard open) */}
|
||||
{isMobile && !inputFocused && (
|
||||
|
||||
@@ -621,32 +621,35 @@ export default function UserManagerPage({ isMobile = false, onProfile, onHelp, o
|
||||
)}
|
||||
|
||||
{/* Content */}
|
||||
<div style={{ flex:1, display:'flex', flexDirection:'column', overflow:'hidden', minHeight:0, background:'var(--background)' }}>
|
||||
{/* form wrapper suppresses Chrome Android's autofill chip bar; autoComplete="off"
|
||||
on individual inputs is ignored by Chrome but respected on the form element */}
|
||||
<form autoComplete="off" onSubmit={e => e.preventDefault()}>
|
||||
<div style={{ flex:1, display:'flex', flexDirection:'column', overflow:'hidden', minHeight:0, background:'var(--background)' }}>
|
||||
|
||||
{/* LIST VIEW */}
|
||||
{view === 'list' && (
|
||||
<>
|
||||
<div style={{ padding:'16px 16px 8px', flexShrink:0 }}>
|
||||
<input className="input" placeholder="Search users…" value={search} onChange={e => setSearch(e.target.value)}
|
||||
onFocus={onIF} onBlur={onIB}
|
||||
autoComplete="off" autoCorrect="off" spellCheck={false}
|
||||
style={{ width:'100%', maxWidth: isMobile ? '100%' : 400 }} />
|
||||
</div>
|
||||
<div style={{ flex:1, overflowY:'auto', padding:'0 16px', paddingBottom: isMobile ? 'calc(82px + env(safe-area-inset-bottom, 0px))' : 16, overscrollBehavior:'contain' }}>
|
||||
<div style={{ background:'var(--surface)', borderRadius:'var(--radius)', boxShadow:'var(--shadow-sm)', overflow:'hidden' }}>
|
||||
{loading ? (
|
||||
<div style={{ padding:48, textAlign:'center' }}><div className="spinner" /></div>
|
||||
) : loadError ? (
|
||||
<div style={{ padding:32, textAlign:'center', color:'var(--error)' }}>
|
||||
<div style={{ marginBottom:12 }}>⚠ {loadError}</div>
|
||||
<button className="btn btn-secondary btn-sm" onClick={load}>Retry</button>
|
||||
</div>
|
||||
) : filtered.length === 0 ? (
|
||||
<div style={{ padding:32, textAlign:'center', color:'var(--text-tertiary)', fontSize:14 }}>
|
||||
{search ? 'No users match your search.' : 'No users yet.'}
|
||||
</div>
|
||||
) : (
|
||||
filtered.map(u => <UserRow key={u.id} u={u} onUpdated={load} onEdit={goEdit} />)
|
||||
{/* LIST VIEW */}
|
||||
{view === 'list' && (
|
||||
<>
|
||||
<div style={{ padding:'16px 16px 8px', flexShrink:0 }}>
|
||||
<input className="input" placeholder="Search users…" value={search} onChange={e => setSearch(e.target.value)}
|
||||
onFocus={onIF} onBlur={onIB}
|
||||
autoComplete="off" autoCorrect="off" spellCheck={false}
|
||||
style={{ width:'100%', maxWidth: isMobile ? '100%' : 400 }} />
|
||||
</div>
|
||||
<div style={{ flex:1, overflowY:'auto', padding:'0 16px', paddingBottom: isMobile ? 'calc(82px + env(safe-area-inset-bottom, 0px))' : 16, overscrollBehavior:'contain' }}>
|
||||
<div style={{ background:'var(--surface)', borderRadius:'var(--radius)', boxShadow:'var(--shadow-sm)', overflow:'hidden' }}>
|
||||
{loading ? (
|
||||
<div style={{ padding:48, textAlign:'center' }}><div className="spinner" /></div>
|
||||
) : loadError ? (
|
||||
<div style={{ padding:32, textAlign:'center', color:'var(--error)' }}>
|
||||
<div style={{ marginBottom:12 }}>⚠ {loadError}</div>
|
||||
<button className="btn btn-secondary btn-sm" onClick={load}>Retry</button>
|
||||
</div>
|
||||
) : filtered.length === 0 ? (
|
||||
<div style={{ padding:32, textAlign:'center', color:'var(--text-tertiary)', fontSize:14 }}>
|
||||
{search ? 'No users match your search.' : 'No users yet.'}
|
||||
</div>
|
||||
) : (
|
||||
filtered.map(u => <UserRow key={u.id} u={u} onUpdated={load} onEdit={goEdit} />)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -677,6 +680,7 @@ export default function UserManagerPage({ isMobile = false, onProfile, onHelp, o
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/* Mobile footer — fixed, hidden when keyboard is up */}
|
||||
{isMobile && !inputFocused && (
|
||||
|
||||
Reference in New Issue
Block a user