From a5d0d2253eceaad8bec56d9e98286564c010d48b Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Thu, 30 Oct 2025 18:36:45 +0000 Subject: [PATCH] Refactor: Use RPC for user data --- src/components/moderation/ReassignDialog.tsx | 8 +++---- src/components/moderation/ReportsQueue.tsx | 16 ++++++------- src/components/moderation/UserRoleManager.tsx | 18 ++++++++++---- src/lib/systemActivityService.ts | 24 +++++++++---------- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/components/moderation/ReassignDialog.tsx b/src/components/moderation/ReassignDialog.tsx index 68998e87..b88558ad 100644 --- a/src/components/moderation/ReassignDialog.tsx +++ b/src/components/moderation/ReassignDialog.tsx @@ -69,10 +69,10 @@ export function ReassignDialog({ const userIds = roles.map((r) => r.user_id); - const { data: profiles, error: profilesError } = await supabase - .from('profiles') - .select('user_id, username, display_name') - .in('user_id', userIds); + const { data: allProfiles, error: profilesError } = await supabase + .rpc('get_users_with_emails'); + + const profiles = allProfiles?.filter(p => userIds.includes(p.user_id)); if (profilesError) throw profilesError; diff --git a/src/components/moderation/ReportsQueue.tsx b/src/components/moderation/ReportsQueue.tsx index f9f9b013..b1c37461 100644 --- a/src/components/moderation/ReportsQueue.tsx +++ b/src/components/moderation/ReportsQueue.tsx @@ -190,11 +190,11 @@ export const ReportsQueue = forwardRef((props, ref) => { // Get unique reporter IDs const reporterIds = [...new Set((data || []).map(r => r.reporter_id))]; - // Fetch reporter profiles - const { data: profiles } = await supabase - .from('profiles') - .select('user_id, username, display_name') - .in('user_id', reporterIds); + // Fetch reporter profiles with emails (for admins) + const { data: allProfiles } = await supabase + .rpc('get_users_with_emails'); + + const profiles = allProfiles?.filter(p => reporterIds.includes(p.user_id)); const profileMap = new Map(profiles?.map(p => [p.user_id, p]) || []); @@ -219,10 +219,8 @@ export const ReportsQueue = forwardRef((props, ref) => { profileIds.length > 0 ? supabase - .from('profiles') - .select('user_id, username, display_name') - .in('user_id', profileIds) - .then(({ data }) => data || []) + .rpc('get_users_with_emails') + .then(({ data }) => data?.filter(p => profileIds.includes(p.user_id)) || []) : Promise.resolve([]), submissionIds.length > 0 diff --git a/src/components/moderation/UserRoleManager.tsx b/src/components/moderation/UserRoleManager.tsx index a2da0684..ee3c8853 100644 --- a/src/components/moderation/UserRoleManager.tsx +++ b/src/components/moderation/UserRoleManager.tsx @@ -85,10 +85,12 @@ export function UserRoleManager() { // Get unique user IDs const userIds = [...new Set((data || []).map(r => r.user_id))]; - // Fetch user profiles + // Fetch user profiles with emails (for admins) const { - data: profiles - } = await supabase.from('profiles').select('user_id, username, display_name').in('user_id', userIds); + data: allProfiles + } = await supabase.rpc('get_users_with_emails'); + + const profiles = allProfiles?.filter(p => userIds.includes(p.user_id)); const profileMap = new Map(profiles?.map(p => [p.user_id, p]) || []); // Combine data with profiles @@ -113,9 +115,15 @@ export function UserRoleManager() { } try { const { - data, + data: allUsers, error - } = await supabase.from('profiles').select('user_id, username, display_name').or(`username.ilike.%${search}%,display_name.ilike.%${search}%`).limit(10); + } = await supabase.rpc('get_users_with_emails'); + + // Filter by search term + const data = allUsers?.filter(user => + user.username.toLowerCase().includes(search.toLowerCase()) || + user.display_name?.toLowerCase().includes(search.toLowerCase()) + ).slice(0, 10); if (error) throw error; // Filter out users who already have roles diff --git a/src/lib/systemActivityService.ts b/src/lib/systemActivityService.ts index 50707a11..f0f45a4b 100644 --- a/src/lib/systemActivityService.ts +++ b/src/lib/systemActivityService.ts @@ -768,10 +768,10 @@ export async function fetchSystemActivities( const uniqueUserIds = [...new Set(filteredActivities.map(a => a.actor_id).filter(Boolean))] as string[]; if (uniqueUserIds.length > 0) { - const { data: profiles } = await supabase - .from('profiles') - .select('user_id, username, display_name, avatar_url') - .in('user_id', uniqueUserIds); + const { data: allProfiles } = await supabase + .rpc('get_users_with_emails'); + + const profiles = allProfiles?.filter(p => uniqueUserIds.includes(p.user_id)); if (profiles) { const profileMap = new Map(profiles.map(p => [p.user_id, p])); @@ -797,10 +797,10 @@ export async function fetchSystemActivities( .filter(Boolean) as string[]; if (targetUserIds.length > 0) { - const { data: targetProfiles } = await supabase - .from('profiles') - .select('user_id, username') - .in('user_id', targetUserIds); + const { data: allTargetProfiles } = await supabase + .rpc('get_users_with_emails'); + + const targetProfiles = allTargetProfiles?.filter(p => targetUserIds.includes(p.user_id)); if (targetProfiles) { const targetProfileMap = new Map(targetProfiles.map(p => [p.user_id, p])); @@ -826,10 +826,10 @@ export async function fetchSystemActivities( .filter(Boolean) as string[]; if (accountUserIds.length > 0) { - const { data: accountProfiles } = await supabase - .from('profiles') - .select('user_id, username') - .in('user_id', accountUserIds); + const { data: allAccountProfiles } = await supabase + .rpc('get_users_with_emails'); + + const accountProfiles = allAccountProfiles?.filter(p => accountUserIds.includes(p.user_id)); if (accountProfiles) { const accountProfileMap = new Map(accountProfiles.map(p => [p.user_id, p]));