Public Access
fix: abort old loads, stale sync state, warn before unsaved edits are lost
This commit is contained in:
1 parent
cbafa3d540
commit
9ddc50f819
28 files changed
+753
-121
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import {useCallback, useEffect, useRef, useState} from 'react';
|
||||
import {useCallback, useEffect, useState} from 'react';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import {Ban, ChevronLeft, ChevronRight, Loader2, Search, ShieldCheck, Trash2} from 'lucide-react';
|
||||
import {toast} from 'sonner';
|
||||
@@ -19,6 +19,7 @@ import {Input} from '@/components/ui/input';
|
||||
import {Label} from '@/components/ui/label';
|
||||
import PageContainer from '../components/PageContainer.jsx';
|
||||
import {deleteUser, fetchUsers, setUserBlocked} from '../utils/admin.js';
|
||||
import useAbortPrevious from '../hooks/useAbortPrevious.js';
|
||||
|
||||
const PAGE_SIZE = 20;
|
||||
const REFUSAL_KEY = {
|
||||
@@ -44,13 +45,13 @@ export default function AdminUsersPage() {
|
||||
const [typedEmail, setTypedEmail] = useState('');
|
||||
const [busy, setBusy] = useState(false);
|
||||
// Only the newest load may show its answer: a slow answer to an older search must not replace the list.
|
||||
const loadCount = useRef(0);
|
||||
const nextSignal = useAbortPrevious();
|
||||
|
||||
const load = useCallback(async () => {
|
||||
const current = ++loadCount.current;
|
||||
const signal = nextSignal();
|
||||
try {
|
||||
const response = await fetchUsers(search, page, PAGE_SIZE);
|
||||
if (current !== loadCount.current) return;
|
||||
const response = await fetchUsers(search, page, PAGE_SIZE, {signal});
|
||||
if (signal.aborted) return;
|
||||
if (response.status === 401) return;
|
||||
if (response.status === 403) {
|
||||
setStatus('forbidden');
|
||||
@@ -61,14 +62,15 @@ export default function AdminUsersPage() {
|
||||
return;
|
||||
}
|
||||
const data = await response.json();
|
||||
if (current !== loadCount.current) return;
|
||||
if (signal.aborted) return;
|
||||
setResult(data);
|
||||
setStatus('ready');
|
||||
} catch (err) {
|
||||
if (signal.aborted) return;
|
||||
console.error('Admin users error:', err);
|
||||
setStatus('error');
|
||||
}
|
||||
}, [search, page]);
|
||||
}, [nextSignal, search, page]);
|
||||
|
||||
useEffect(() => {
|
||||
load();
|
||||
|
||||
Reference in new issue
Block a user