fix: user detail — separate request history sub selector, split mount effects

- Request history subscription selector no longer mutates shared
  activeSubscriptionId — uses independent requestHistorySubId state
- Request history reloads when subscription selector changes
- Split mount effect: loadPanelInfo in separate effect to avoid
  redundant loadUser calls when activeSubscriptionId changes
This commit is contained in:
Fringg
2026-04-29 06:22:38 +03:00
parent e1d2f8cee4
commit 853e1c9c84

View File

@@ -390,6 +390,7 @@ export default function AdminUserDetail() {
const [requestHistoryOffset, setRequestHistoryOffset] = useState(0); const [requestHistoryOffset, setRequestHistoryOffset] = useState(0);
const [requestHistoryTotal, setRequestHistoryTotal] = useState(0); const [requestHistoryTotal, setRequestHistoryTotal] = useState(0);
const [requestHistoryExpanded, setRequestHistoryExpanded] = useState(false); const [requestHistoryExpanded, setRequestHistoryExpanded] = useState(false);
const [requestHistorySubId, setRequestHistorySubId] = useState<number | null>(null);
const userId = id ? parseInt(id, 10) : null; const userId = id ? parseInt(id, 10) : null;
@@ -498,7 +499,7 @@ export default function AdminUserDetail() {
setRequestHistoryLoading(true); setRequestHistoryLoading(true);
const data = await adminUsersApi.getSubscriptionRequestHistory( const data = await adminUsersApi.getSubscriptionRequestHistory(
userId, userId,
activeSubscriptionId ?? undefined, requestHistorySubId ?? undefined,
offset, offset,
20, 20,
); );
@@ -511,7 +512,7 @@ export default function AdminUserDetail() {
setRequestHistoryLoading(false); setRequestHistoryLoading(false);
} }
}, },
[userId, activeSubscriptionId], [userId, requestHistorySubId],
); );
const loadNodeUsage = useCallback(async () => { const loadNodeUsage = useCallback(async () => {
@@ -606,8 +607,22 @@ export default function AdminUserDetail() {
return; return;
} }
loadUser(); loadUser();
}, [userId, loadUser, navigate]);
// Load panel info when subscription changes (separate from mount to avoid redundant loadUser)
useEffect(() => {
if (!userId || isNaN(userId)) return;
loadPanelInfo(); loadPanelInfo();
}, [userId, loadUser, loadPanelInfo, navigate]); }, [userId, loadPanelInfo]);
// Reload request history when the request-history subscription selector changes
useEffect(() => {
if (!requestHistoryExpanded || requestHistorySubId === null) return;
setRequestHistory([]);
setRequestHistoryOffset(0);
setRequestHistoryTotal(0);
loadRequestHistory(0);
}, [requestHistorySubId]); // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => { useEffect(() => {
if (activeTab === 'info') { if (activeTab === 'info') {
@@ -860,6 +875,7 @@ export default function AdminUserDetail() {
if (user && userSubscriptions.length > 0 && !hasAutoSelectedSub.current) { if (user && userSubscriptions.length > 0 && !hasAutoSelectedSub.current) {
const activeSub = userSubscriptions.find((s) => s.is_active) ?? userSubscriptions[0]; const activeSub = userSubscriptions.find((s) => s.is_active) ?? userSubscriptions[0];
setActiveSubscriptionId(activeSub.id); setActiveSubscriptionId(activeSub.id);
setRequestHistorySubId(activeSub.id);
hasAutoSelectedSub.current = true; hasAutoSelectedSub.current = true;
} }
}, [user, userSubscriptions]); }, [user, userSubscriptions]);
@@ -2511,13 +2527,9 @@ export default function AdminUserDetail() {
{userSubscriptions.length > 1 && ( {userSubscriptions.length > 1 && (
<div className="mb-3"> <div className="mb-3">
<select <select
value={activeSubscriptionId || ''} value={requestHistorySubId || ''}
onChange={(e) => { onChange={(e) => {
const subId = Number(e.target.value) || null; setRequestHistorySubId(Number(e.target.value) || null);
setActiveSubscriptionId(subId);
setRequestHistory([]);
setRequestHistoryOffset(0);
setRequestHistoryTotal(0);
}} }}
className="w-full rounded-lg border border-dark-600 bg-dark-700 px-3 py-2 text-sm text-dark-100" className="w-full rounded-lg border border-dark-600 bg-dark-700 px-3 py-2 text-sm text-dark-100"
> >