mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-24 04:51:13 -05:00
Refactor: Implement API and cache improvements
This commit is contained in:
77
src/hooks/profile/useProfileUpdateMutation.ts
Normal file
77
src/hooks/profile/useProfileUpdateMutation.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { toast } from 'sonner';
|
||||
import { getErrorMessage } from '@/lib/errorHandler';
|
||||
import { useQueryInvalidation } from '@/lib/queryInvalidation';
|
||||
|
||||
interface ProfileUpdateParams {
|
||||
userId: string;
|
||||
updates: {
|
||||
display_name?: string;
|
||||
bio?: string;
|
||||
location_id?: string | null;
|
||||
website?: string | null;
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
export function useProfileUpdateMutation() {
|
||||
const queryClient = useQueryClient();
|
||||
const {
|
||||
invalidateUserProfile,
|
||||
invalidateProfileStats,
|
||||
invalidateProfileActivity,
|
||||
invalidateUserSearch
|
||||
} = useQueryInvalidation();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({ userId, updates }: ProfileUpdateParams) => {
|
||||
const { error } = await supabase
|
||||
.from('profiles')
|
||||
.update(updates)
|
||||
.eq('user_id', userId);
|
||||
|
||||
if (error) throw error;
|
||||
},
|
||||
onMutate: async ({ userId, updates }) => {
|
||||
// Cancel outgoing refetches
|
||||
await queryClient.cancelQueries({ queryKey: ['profile', userId] });
|
||||
|
||||
// Snapshot previous value
|
||||
const previousProfile = queryClient.getQueryData(['profile', userId]);
|
||||
|
||||
// Optimistically update
|
||||
queryClient.setQueryData(['profile', userId], (old: any) => ({
|
||||
...old,
|
||||
...updates,
|
||||
}));
|
||||
|
||||
return { previousProfile, userId };
|
||||
},
|
||||
onError: (error: unknown, _variables, context) => {
|
||||
// Rollback on error
|
||||
if (context?.previousProfile) {
|
||||
queryClient.setQueryData(['profile', context.userId], context.previousProfile);
|
||||
}
|
||||
|
||||
toast.error("Update Failed", {
|
||||
description: getErrorMessage(error),
|
||||
});
|
||||
},
|
||||
onSuccess: (_data, { userId, updates }) => {
|
||||
// Invalidate all related caches
|
||||
invalidateUserProfile(userId);
|
||||
invalidateProfileStats(userId);
|
||||
invalidateProfileActivity(userId);
|
||||
|
||||
// If display name changed, invalidate user search results
|
||||
if (updates.display_name) {
|
||||
invalidateUserSearch();
|
||||
}
|
||||
|
||||
toast.success("Profile Updated", {
|
||||
description: "Your changes have been saved.",
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
48
src/hooks/reports/useReportMutation.ts
Normal file
48
src/hooks/reports/useReportMutation.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
import { toast } from 'sonner';
|
||||
import { getErrorMessage } from '@/lib/errorHandler';
|
||||
import { useQueryInvalidation } from '@/lib/queryInvalidation';
|
||||
|
||||
interface ReportParams {
|
||||
entityType: 'review' | 'profile' | 'content_submission';
|
||||
entityId: string;
|
||||
reportType: string;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export function useReportMutation() {
|
||||
const { user } = useAuth();
|
||||
const queryClient = useQueryClient();
|
||||
const { invalidateModerationQueue, invalidateModerationStats } = useQueryInvalidation();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({ entityType, entityId, reportType, reason }: ReportParams) => {
|
||||
if (!user) throw new Error('Authentication required');
|
||||
|
||||
const { error } = await supabase.from('reports').insert({
|
||||
reporter_id: user.id,
|
||||
reported_entity_type: entityType,
|
||||
reported_entity_id: entityId,
|
||||
report_type: reportType,
|
||||
reason: reason?.trim() || null,
|
||||
});
|
||||
|
||||
if (error) throw error;
|
||||
},
|
||||
onSuccess: () => {
|
||||
invalidateModerationQueue();
|
||||
invalidateModerationStats();
|
||||
|
||||
toast.success("Report Submitted", {
|
||||
description: "Thank you for your report. We'll review it shortly.",
|
||||
});
|
||||
},
|
||||
onError: (error: unknown) => {
|
||||
toast.error("Error", {
|
||||
description: getErrorMessage(error),
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user