fix: abort old loads, stale sync state, warn before unsaved edits are lost

This commit is contained in:
lobo committed 2026-09-30 07:51:09 +02:00
1 parent cbafa3d540
commit 9ddc50f819
28 files changed
+753 -121

No files matched your search

+9 -7
View File
@@ -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();