import { useQuery, useQueryClient } from '@tanstack/react-query' import { useSessionContext } from './supabase/useSessionContext' import { useSupabase } from './supabase/useSupabase' import { CollectionProps, ProfileProps } from '../types' function useProfile(database) { const { session } = useSessionContext() const user = session?.user const { data, isLoading, refetch } = useQuery(['profile', user?.id], { queryFn: async () => { if (!user?.id) return null const { data, error } = await database.from('profiles').select('*').eq('id', user.id).single() if (error) { // no rows - edge case of user being deleted if (error.code === 'PGRST116') { await database.auth.signOut() return null } throw new Error(error.message) } const profileData = data as ProfileProps if (typeof profileData.collection === 'string') { profileData.collection = JSON.parse(profileData.collection) as CollectionProps } return profileData }, }) return { data, isLoading, refetch } } export const useUser = () => { const { session, isLoading: isLoadingSession } = useSessionContext() const user = session?.user const database = useSupabase() const { data: profile, refetch, isLoading: isLoadingProfile } = useProfile(database) const queryClient = useQueryClient() const saveCardToMemberCollection = async (cardId: string, topicId: string) => { if (!user?.id) { alert('Please sign in to save this card to your account.') return } const { error } = await database.rpc('save_card_to_member_collection', { member_id: user.id, card_id: cardId, topic_id: topicId, }) if (error) throw new Error(error.message) queryClient.setQueryData(['profile', user.id], (oldData: ProfileProps | undefined) => { if (!oldData) return oldData const newCollection = { inbox: [...(oldData.collection?.inbox ?? []), cardId], lists: oldData.collection?.lists ?? [], posts: oldData.collection?.posts ?? [], } return { ...oldData, collection: newCollection, } }) } const unsaveCardFromMemberCollection = async (cardId: string, topicId: string) => { if (!user?.id) { alert('Please sign in to unsave this card from your account.') return } const { error } = await database.rpc('unsave_card_from_member_collection', { member_id: user.id, card_id: cardId, topic_id: topicId, }) if (error) throw new Error(error.message) queryClient.setQueryData(['profile', user.id], (oldData: ProfileProps | undefined) => { if (!oldData) return oldData const newCollection = { inbox: oldData.collection?.inbox?.filter((id) => id !== cardId) ?? [], lists: oldData.collection?.lists ?? [], posts: oldData.collection?.posts ?? [], } return { ...oldData, collection: newCollection } }) } const getCardsInMemberCollection = async () => { const cardIds = profile?.collection?.inbox?.reverse() || [] if (cardIds.length === 0) return [] const { data, error } = await database.from('cards').select('*').in('id', cardIds) if (error) throw new Error(error.message) return data } return { session, user, profile, updateProfile: () => refetch(), isLoadingSession, isLoadingProfile, isLoading: isLoadingSession || isLoadingProfile, saveCardToMemberCollection, unsaveCardFromMemberCollection, getCardsInMemberCollection, } }