From 18e030c9b9fc3a730699733272c949c76aa9806b Mon Sep 17 00:00:00 2001 From: c0mrade Date: Tue, 26 May 2026 17:43:58 +0300 Subject: [PATCH] refactor(admin-user-detail): extract Referrals tab with own state + query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pulls the entire referrals tab into components/admin/userDetail/ ReferralsTab.tsx — state, useQuery, debounced search effects, click-outside listeners, mutation handlers, and the 295-line JSX block all live there now. The tab owns its referralsListQuery and calls onUserRefresh() (parent's loadUser) when a mutation needs to re-fetch the user object. Net to AdminUserDetail.tsx: down to 2902 lines (-479). Local 'actionLoading' inside the tab means referral-mutation clicks no longer dim balance/sync buttons. Same DOM, same handlers, same queryKey ['admin-user-referrals-list', userId]. --- .../admin/userDetail/ReferralsTab.tsx | 501 ++++++++++++++++++ src/pages/AdminUserDetail.tsx | 499 +---------------- 2 files changed, 511 insertions(+), 489 deletions(-) create mode 100644 src/components/admin/userDetail/ReferralsTab.tsx diff --git a/src/components/admin/userDetail/ReferralsTab.tsx b/src/components/admin/userDetail/ReferralsTab.tsx new file mode 100644 index 0000000..a745df3 --- /dev/null +++ b/src/components/admin/userDetail/ReferralsTab.tsx @@ -0,0 +1,501 @@ +import { useState, useEffect, useRef } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useQuery } from '@tanstack/react-query'; +import { useNavigate } from 'react-router'; +import { useCurrency } from '../../../hooks/useCurrency'; +import { useNotify } from '../../../platform/hooks/useNotify'; +import { adminUsersApi, type UserDetailResponse, type UserListItem } from '../../../api/adminUsers'; + +// ────────────────────────────────────────────────────────────────── +// Referrals tab — top-of-graph referrer + stats + referrals list, +// plus inline search/assign/remove flows. All state stays local; +// the parent only owns the user query and tells us when it refreshes. +// ────────────────────────────────────────────────────────────────── + +export interface ReferralsTabProps { + user: UserDetailResponse; + userId: number; + onUserRefresh: () => Promise | void; +} + +export function ReferralsTab({ user, userId, onUserRefresh }: ReferralsTabProps) { + const { t } = useTranslation(); + const { formatWithCurrency } = useCurrency(); + const navigate = useNavigate(); + const notify = useNotify(); + + // Referrals list — owned here, not in the parent. + const referralsListQuery = useQuery({ + queryKey: ['admin-user-referrals-list', userId] as const, + queryFn: () => adminUsersApi.getReferrals(userId, 0, 100), + enabled: !!userId, + }); + const referralsList = referralsListQuery.data?.users ?? []; + const referralsTotal = referralsListQuery.data?.total ?? 0; + const referralsListLoading = referralsListQuery.isFetching; + + // Action gating — local so other tabs' buttons aren't dimmed during a + // referral mutation here. + const [actionLoading, setActionLoading] = useState(false); + + // Inline referrer search dropdown + const [showReferrerSearch, setShowReferrerSearch] = useState(false); + const [referrerSearchQuery, setReferrerSearchQuery] = useState(''); + const [referrerSearchResults, setReferrerSearchResults] = useState([]); + const [referrerSearchLoading, setReferrerSearchLoading] = useState(false); + const referrerSearchRef = useRef(null); + + // Inline add-referral search dropdown + const [showAddReferral, setShowAddReferral] = useState(false); + const [addReferralSearchQuery, setAddReferralSearchQuery] = useState(''); + const [addReferralSearchResults, setAddReferralSearchResults] = useState([]); + const [addReferralSearchLoading, setAddReferralSearchLoading] = useState(false); + const addReferralSearchRef = useRef(null); + + // Debounced search for referrer + useEffect(() => { + if (referrerSearchQuery.length < 2 || !showReferrerSearch) { + setReferrerSearchResults([]); + setReferrerSearchLoading(false); + return; + } + setReferrerSearchLoading(true); + setReferrerSearchResults([]); + let cancelled = false; + const timer = setTimeout(async () => { + try { + const data = await adminUsersApi.getUsers({ search: referrerSearchQuery, limit: 10 }); + if (!cancelled) { + setReferrerSearchResults(data.users || []); + setReferrerSearchLoading(false); + } + } catch { + if (!cancelled) { + setReferrerSearchResults([]); + setReferrerSearchLoading(false); + } + } + }, 300); + return () => { + cancelled = true; + clearTimeout(timer); + }; + }, [referrerSearchQuery, showReferrerSearch]); + + // Close referrer dropdown on click outside + useEffect(() => { + const handleClickOutside = (e: MouseEvent) => { + if (referrerSearchRef.current && !referrerSearchRef.current.contains(e.target as Node)) { + setShowReferrerSearch(false); + setReferrerSearchQuery(''); + setReferrerSearchResults([]); + } + }; + if (showReferrerSearch) { + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + } + }, [showReferrerSearch]); + + // Debounced search for adding referral + useEffect(() => { + if (addReferralSearchQuery.length < 2 || !showAddReferral) { + setAddReferralSearchResults([]); + setAddReferralSearchLoading(false); + return; + } + setAddReferralSearchLoading(true); + setAddReferralSearchResults([]); + let cancelled = false; + const timer = setTimeout(async () => { + try { + const data = await adminUsersApi.getUsers({ search: addReferralSearchQuery, limit: 10 }); + if (!cancelled) { + setAddReferralSearchResults(data.users || []); + setAddReferralSearchLoading(false); + } + } catch { + if (!cancelled) { + setAddReferralSearchResults([]); + setAddReferralSearchLoading(false); + } + } + }, 300); + return () => { + cancelled = true; + clearTimeout(timer); + }; + }, [addReferralSearchQuery, showAddReferral]); + + // Close add-referral dropdown on click outside + useEffect(() => { + const handleClickOutside = (e: MouseEvent) => { + if ( + addReferralSearchRef.current && + !addReferralSearchRef.current.contains(e.target as Node) + ) { + setShowAddReferral(false); + setAddReferralSearchQuery(''); + setAddReferralSearchResults([]); + } + }; + if (showAddReferral) { + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + } + }, [showAddReferral]); + + // ─── Mutation handlers ─────────────────────────────────────────── + + const handleAssignReferrer = async (referrerId: number) => { + setActionLoading(true); + try { + await adminUsersApi.assignReferrer(userId, referrerId); + await onUserRefresh(); + setShowReferrerSearch(false); + setReferrerSearchQuery(''); + setReferrerSearchResults([]); + notify.success(t('admin.users.detail.referrals.referrerAssigned')); + } catch (error: unknown) { + const axiosErr = error as { response?: { data?: { detail?: string } } }; + notify.error(axiosErr?.response?.data?.detail || t('common.error')); + } finally { + setActionLoading(false); + } + }; + + const handleRemoveReferrer = async () => { + setActionLoading(true); + try { + await adminUsersApi.removeReferrer(userId); + await onUserRefresh(); + notify.success(t('admin.users.detail.referrals.referrerRemoved')); + } catch (error: unknown) { + const axiosErr = error as { response?: { data?: { detail?: string } } }; + notify.error(axiosErr?.response?.data?.detail || t('common.error')); + } finally { + setActionLoading(false); + } + }; + + const handleRemoveReferral = async (referralUserId: number) => { + setActionLoading(true); + try { + await adminUsersApi.removeReferral(userId, referralUserId); + await referralsListQuery.refetch(); + await onUserRefresh(); + notify.success(t('admin.users.detail.referrals.referralRemoved')); + } catch (error: unknown) { + const axiosErr = error as { response?: { data?: { detail?: string } } }; + notify.error(axiosErr?.response?.data?.detail || t('common.error')); + } finally { + setActionLoading(false); + } + }; + + const handleAddReferral = async (targetUserId: number) => { + setActionLoading(true); + try { + await adminUsersApi.assignReferrer(targetUserId, userId); + await referralsListQuery.refetch(); + await onUserRefresh(); + setShowAddReferral(false); + setAddReferralSearchQuery(''); + setAddReferralSearchResults([]); + notify.success(t('admin.users.detail.referrals.referralAdded')); + } catch (error: unknown) { + const axiosErr = error as { response?: { data?: { detail?: string } } }; + notify.error(axiosErr?.response?.data?.detail || t('common.error')); + } finally { + setActionLoading(false); + } + }; + + // ─── Render ────────────────────────────────────────────────────── + + return ( +
+ {/* Section 1: Who referred this user */} +
+

+ {t('admin.users.detail.referrals.referredBy')} +

+ + {user.referral.referred_by_id ? ( +
+ + +
+ ) : ( +
+ {showReferrerSearch ? ( +
+
+ setReferrerSearchQuery(e.target.value)} + placeholder={t('admin.users.detail.referrals.searchPlaceholder')} + className="flex-1 rounded-lg border border-dark-600 bg-dark-700 px-3 py-2.5 text-sm text-dark-100 placeholder-dark-500 focus:border-accent-500 focus:outline-none" + autoFocus + /> + +
+ {referrerSearchQuery.length >= 2 && referrerSearchResults.length > 0 && ( +
+ {referrerSearchResults + .filter((u) => u.id !== userId) + .map((u) => ( + + ))} + {referrerSearchResults.filter((u) => u.id !== userId).length === 0 && ( +
+ {t('admin.users.detail.referrals.noUsersFound')} +
+ )} +
+ )} + {referrerSearchQuery.length >= 2 && + !referrerSearchLoading && + referrerSearchResults.length === 0 && ( +
+ {t('admin.users.detail.referrals.noUsersFound')} +
+ )} +
+ ) : ( +
+ + {t('admin.users.detail.referrals.noReferrer')} + + +
+ )} +
+ )} +
+ + {/* Section 2: Referral stats */} +
+
+
+ {t('admin.users.detail.referrals.totalReferrals')} +
+
+ {user.referral.referrals_count} +
+
+
+
+ {t('admin.users.detail.referrals.totalEarnings')} +
+
+ {formatWithCurrency(user.referral.total_earnings_kopeks / 100)} +
+
+
+
+ {t('admin.users.detail.referrals.commission')} +
+
+ {user.referral.commission_percent != null + ? `${user.referral.commission_percent}%` + : t('admin.users.detail.referrals.default')} +
+
+
+
+ {t('admin.users.detail.referrals.referralCode')} +
+
+ {user.referral.referral_code} +
+
+
+ + {/* Section 3: Referrals list */} +
+
+

+ {t('admin.users.detail.referrals.referralsList')} ({referralsTotal}) +

+ {!showAddReferral && ( + + )} +
+ + {/* Add referral search */} + {showAddReferral && ( +
+
+ setAddReferralSearchQuery(e.target.value)} + placeholder={t('admin.users.detail.referrals.searchPlaceholder')} + className="flex-1 rounded-lg border border-dark-600 bg-dark-700 px-3 py-2.5 text-sm text-dark-100 placeholder-dark-500 focus:border-accent-500 focus:outline-none" + autoFocus + /> + +
+ {addReferralSearchQuery.length >= 2 && addReferralSearchResults.length > 0 && ( +
+ {addReferralSearchResults + .filter((u) => u.id !== userId && !referralsList.some((r) => r.id === u.id)) + .map((u) => ( + + ))} + {addReferralSearchResults.filter( + (u) => u.id !== userId && !referralsList.some((r) => r.id === u.id), + ).length === 0 && ( +
+ {t('admin.users.detail.referrals.noUsersFound')} +
+ )} +
+ )} + {addReferralSearchQuery.length >= 2 && + !addReferralSearchLoading && + addReferralSearchResults.length === 0 && ( +
+ {t('admin.users.detail.referrals.noUsersFound')} +
+ )} +
+ )} + + {referralsListLoading ? ( +
+
+
+ ) : referralsList.length === 0 ? ( +
+ {t('admin.users.detail.referrals.noReferrals')} +
+ ) : ( +
+ {referralsList.map((ref) => ( +
+ + +
+ ))} +
+ )} +
+
+ ); +} diff --git a/src/pages/AdminUserDetail.tsx b/src/pages/AdminUserDetail.tsx index 5c72d18..44891fa 100644 --- a/src/pages/AdminUserDetail.tsx +++ b/src/pages/AdminUserDetail.tsx @@ -25,6 +25,7 @@ import { promoOffersApi } from '../api/promoOffers'; import { AdminBackButton } from '../components/admin'; import { GiftsTab } from '../components/admin/userDetail/GiftsTab'; import { SyncTab } from '../components/admin/userDetail/SyncTab'; +import { ReferralsTab } from '../components/admin/userDetail/ReferralsTab'; import { createNumberInputHandler, toNumber } from '../utils/inputHelpers'; import { usePermissionStore } from '../store/permissions'; import { MessageMediaGrid } from '../components/tickets/MessageMediaGrid'; @@ -118,21 +119,8 @@ export default function AdminUserDetail() { const [referrals, setReferrals] = useState([]); const [referralsLoading, setReferralsLoading] = useState(false); - // Referrals tab state - const [referralsList, setReferralsList] = useState([]); - const [referralsTotal, setReferralsTotal] = useState(0); - const [referralsListLoading, setReferralsListLoading] = useState(false); - const [referrerSearchQuery, setReferrerSearchQuery] = useState(''); - const [showReferrerSearch, setShowReferrerSearch] = useState(false); - const [referrerSearchResults, setReferrerSearchResults] = useState([]); - const [referrerSearchLoading, setReferrerSearchLoading] = useState(false); - const referrerSearchRef = useRef(null); - // Add referral (bind someone as this user's referral) - const [showAddReferral, setShowAddReferral] = useState(false); - const [addReferralSearchQuery, setAddReferralSearchQuery] = useState(''); - const [addReferralSearchResults, setAddReferralSearchResults] = useState([]); - const [addReferralSearchLoading, setAddReferralSearchLoading] = useState(false); - const addReferralSearchRef = useRef(null); + // (Referrals-tab state, query, handlers, click-outside + debounced search + // effects moved into components/admin/userDetail/ReferralsTab.tsx) // Panel info & node usage const [panelInfo, setPanelInfo] = useState(null); @@ -278,11 +266,7 @@ export default function AdminUserDetail() { queryFn: () => adminUsersApi.getReferrals(userId as number, 0, 50), enabled: !!userId && !isNaN(userId) && activeTab === 'info', }); - const referralsListQuery = useQuery({ - queryKey: ['admin-user-referrals-list', userId] as const, - queryFn: () => adminUsersApi.getReferrals(userId as number, 0, 100), - enabled: !!userId && !isNaN(userId) && activeTab === 'referrals', - }); + // (referralsListQuery moved into ReferralsTab.tsx — the tab owns it now) const panelInfoQuery = useQuery({ queryKey: ['admin-user-panel-info', userId, activeSubscriptionId] as const, queryFn: () => adminUsersApi.getPanelInfo(userId as number, activeSubscriptionId ?? undefined), @@ -328,13 +312,7 @@ export default function AdminUserDetail() { if (referralsQuery.data) setReferrals(referralsQuery.data.users || []); setReferralsLoading(referralsQuery.isFetching); }, [referralsQuery.data, referralsQuery.isFetching]); - useEffect(() => { - if (referralsListQuery.data) { - setReferralsList(referralsListQuery.data.users || []); - setReferralsTotal(referralsListQuery.data.total || 0); - } - setReferralsListLoading(referralsListQuery.isFetching); - }, [referralsListQuery.data, referralsListQuery.isFetching]); + // (referralsListQuery sync moved into ReferralsTab.tsx) useEffect(() => { if (panelInfoQuery.data) setPanelInfo(panelInfoQuery.data); setPanelInfoLoading(panelInfoQuery.isFetching); @@ -388,13 +366,7 @@ export default function AdminUserDetail() { } }, []); - const loadReferralsList = useCallback( - async () => { - await referralsListQuery.refetch(); - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [referralsListQuery.refetch], - ); + // (loadReferralsList moved into ReferralsTab.tsx) const loadPanelInfo = useCallback( async () => { @@ -832,170 +804,8 @@ export default function AdminUserDetail() { } }; - // Referrals tab: assign referrer - const handleAssignReferrer = async (referrerId: number) => { - if (!userId) return; - setActionLoading(true); - try { - await adminUsersApi.assignReferrer(userId, referrerId); - await loadUser(); - setShowReferrerSearch(false); - setReferrerSearchQuery(''); - setReferrerSearchResults([]); - notify.success(t('admin.users.detail.referrals.referrerAssigned')); - } catch (error: unknown) { - const axiosErr = error as { response?: { data?: { detail?: string } } }; - notify.error(axiosErr?.response?.data?.detail || t('common.error')); - } finally { - setActionLoading(false); - } - }; - - // Referrals tab: remove referrer - const handleRemoveReferrer = async () => { - if (!userId) return; - setActionLoading(true); - try { - await adminUsersApi.removeReferrer(userId); - await loadUser(); - notify.success(t('admin.users.detail.referrals.referrerRemoved')); - } catch (error: unknown) { - const axiosErr = error as { response?: { data?: { detail?: string } } }; - notify.error(axiosErr?.response?.data?.detail || t('common.error')); - } finally { - setActionLoading(false); - } - }; - - // Referrals tab: remove a referral - const handleRemoveReferral = async (referralUserId: number) => { - if (!userId) return; - setActionLoading(true); - try { - await adminUsersApi.removeReferral(userId, referralUserId); - await loadReferralsList(); - await loadUser(); - notify.success(t('admin.users.detail.referrals.referralRemoved')); - } catch (error: unknown) { - const axiosErr = error as { response?: { data?: { detail?: string } } }; - notify.error(axiosErr?.response?.data?.detail || t('common.error')); - } finally { - setActionLoading(false); - } - }; - - // Add a referral: assign current user as referrer of selected user - const handleAddReferral = async (targetUserId: number) => { - if (!userId) return; - setActionLoading(true); - try { - await adminUsersApi.assignReferrer(targetUserId, userId); - await loadReferralsList(); - await loadUser(); - setShowAddReferral(false); - setAddReferralSearchQuery(''); - setAddReferralSearchResults([]); - notify.success(t('admin.users.detail.referrals.referralAdded')); - } catch (error: unknown) { - const axiosErr = error as { response?: { data?: { detail?: string } } }; - notify.error(axiosErr?.response?.data?.detail || t('common.error')); - } finally { - setActionLoading(false); - } - }; - - // Referrals tab: debounced user search for referrer assignment - useEffect(() => { - if (referrerSearchQuery.length < 2 || !showReferrerSearch) { - setReferrerSearchResults([]); - setReferrerSearchLoading(false); - return; - } - setReferrerSearchLoading(true); - setReferrerSearchResults([]); - let cancelled = false; - const timer = setTimeout(async () => { - try { - const data = await adminUsersApi.getUsers({ search: referrerSearchQuery, limit: 10 }); - if (!cancelled) { - setReferrerSearchResults(data.users || []); - setReferrerSearchLoading(false); - } - } catch { - if (!cancelled) { - setReferrerSearchResults([]); - setReferrerSearchLoading(false); - } - } - }, 300); - return () => { - cancelled = true; - clearTimeout(timer); - }; - }, [referrerSearchQuery, showReferrerSearch]); - - // Referrals tab: close search dropdown on click outside - useEffect(() => { - const handleClickOutside = (e: MouseEvent) => { - if (referrerSearchRef.current && !referrerSearchRef.current.contains(e.target as Node)) { - setShowReferrerSearch(false); - setReferrerSearchQuery(''); - setReferrerSearchResults([]); - } - }; - if (showReferrerSearch) { - document.addEventListener('mousedown', handleClickOutside); - return () => document.removeEventListener('mousedown', handleClickOutside); - } - }, [showReferrerSearch]); - - // Referrals tab: debounced search for adding referral - useEffect(() => { - if (addReferralSearchQuery.length < 2 || !showAddReferral) { - setAddReferralSearchResults([]); - setAddReferralSearchLoading(false); - return; - } - setAddReferralSearchLoading(true); - setAddReferralSearchResults([]); - let cancelled = false; - const timer = setTimeout(async () => { - try { - const data = await adminUsersApi.getUsers({ search: addReferralSearchQuery, limit: 10 }); - if (!cancelled) { - setAddReferralSearchResults(data.users || []); - setAddReferralSearchLoading(false); - } - } catch { - if (!cancelled) { - setAddReferralSearchResults([]); - setAddReferralSearchLoading(false); - } - } - }, 300); - return () => { - cancelled = true; - clearTimeout(timer); - }; - }, [addReferralSearchQuery, showAddReferral]); - - // Referrals tab: close add-referral dropdown on click outside - useEffect(() => { - const handleClickOutside = (e: MouseEvent) => { - if ( - addReferralSearchRef.current && - !addReferralSearchRef.current.contains(e.target as Node) - ) { - setShowAddReferral(false); - setAddReferralSearchQuery(''); - setAddReferralSearchResults([]); - } - }; - if (showAddReferral) { - document.addEventListener('mousedown', handleClickOutside); - return () => document.removeEventListener('mousedown', handleClickOutside); - } - }, [showAddReferral]); + // (Referrals-tab handlers + debounced search useEffects + click-outside + // useEffects moved into components/admin/userDetail/ReferralsTab.tsx) const handleResetTrial = async () => { if (!userId) return; @@ -3083,297 +2893,8 @@ export default function AdminUserDetail() { )} {/* Referrals Tab */} - {activeTab === 'referrals' && user && ( -
- {/* Section 1: Who referred this user */} -
-

- {t('admin.users.detail.referrals.referredBy')} -

- - {user.referral.referred_by_id ? ( -
- - -
- ) : ( -
- {showReferrerSearch ? ( -
-
- setReferrerSearchQuery(e.target.value)} - placeholder={t('admin.users.detail.referrals.searchPlaceholder')} - className="flex-1 rounded-lg border border-dark-600 bg-dark-700 px-3 py-2.5 text-sm text-dark-100 placeholder-dark-500 focus:border-accent-500 focus:outline-none" - autoFocus - /> - -
- {referrerSearchQuery.length >= 2 && referrerSearchResults.length > 0 && ( -
- {referrerSearchResults - .filter((u) => u.id !== userId) - .map((u) => ( - - ))} - {referrerSearchResults.filter((u) => u.id !== userId).length === 0 && ( -
- {t('admin.users.detail.referrals.noUsersFound')} -
- )} -
- )} - {referrerSearchQuery.length >= 2 && - !referrerSearchLoading && - referrerSearchResults.length === 0 && ( -
- {t('admin.users.detail.referrals.noUsersFound')} -
- )} -
- ) : ( -
- - {t('admin.users.detail.referrals.noReferrer')} - - -
- )} -
- )} -
- - {/* Section 2: Referral stats */} -
-
-
- {t('admin.users.detail.referrals.totalReferrals')} -
-
- {user.referral.referrals_count} -
-
-
-
- {t('admin.users.detail.referrals.totalEarnings')} -
-
- {formatWithCurrency(user.referral.total_earnings_kopeks / 100)} -
-
-
-
- {t('admin.users.detail.referrals.commission')} -
-
- {user.referral.commission_percent != null - ? `${user.referral.commission_percent}%` - : t('admin.users.detail.referrals.default')} -
-
-
-
- {t('admin.users.detail.referrals.referralCode')} -
-
- {user.referral.referral_code} -
-
-
- - {/* Section 3: Referrals list */} -
-
-

- {t('admin.users.detail.referrals.referralsList')} ({referralsTotal}) -

- {!showAddReferral && ( - - )} -
- - {/* Add referral search */} - {showAddReferral && ( -
-
- setAddReferralSearchQuery(e.target.value)} - placeholder={t('admin.users.detail.referrals.searchPlaceholder')} - className="flex-1 rounded-lg border border-dark-600 bg-dark-700 px-3 py-2.5 text-sm text-dark-100 placeholder-dark-500 focus:border-accent-500 focus:outline-none" - autoFocus - /> - -
- {addReferralSearchQuery.length >= 2 && addReferralSearchResults.length > 0 && ( -
- {addReferralSearchResults - .filter((u) => u.id !== userId && !referralsList.some((r) => r.id === u.id)) - .map((u) => ( - - ))} - {addReferralSearchResults.filter( - (u) => u.id !== userId && !referralsList.some((r) => r.id === u.id), - ).length === 0 && ( -
- {t('admin.users.detail.referrals.noUsersFound')} -
- )} -
- )} - {addReferralSearchQuery.length >= 2 && - !addReferralSearchLoading && - addReferralSearchResults.length === 0 && ( -
- {t('admin.users.detail.referrals.noUsersFound')} -
- )} -
- )} - - {referralsListLoading ? ( -
-
-
- ) : referralsList.length === 0 ? ( -
- {t('admin.users.detail.referrals.noReferrals')} -
- ) : ( -
- {referralsList.map((ref) => ( -
- - -
- ))} -
- )} -
-
+ {activeTab === 'referrals' && user && userId && ( + )}