diff options
Diffstat (limited to 'apps/web/lib/queries/use-highlight-mutations.ts')
| -rw-r--r-- | apps/web/lib/queries/use-highlight-mutations.ts | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/apps/web/lib/queries/use-highlight-mutations.ts b/apps/web/lib/queries/use-highlight-mutations.ts new file mode 100644 index 0000000..0e228c8 --- /dev/null +++ b/apps/web/lib/queries/use-highlight-mutations.ts @@ -0,0 +1,132 @@ +"use client" + +import { useMutation, useQueryClient } from "@tanstack/react-query" +import { createSupabaseBrowserClient } from "@/lib/supabase/client" +import { queryKeys } from "./query-keys" +import { notify } from "@/lib/notify" + +interface CreateHighlightParameters { + entryIdentifier: string + highlightedText: string + textOffset: number + textLength: number + textPrefix: string + textSuffix: string + note?: string | null + color?: string +} + +export function useCreateHighlight() { + const supabaseClient = createSupabaseBrowserClient() + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: async (parameters: CreateHighlightParameters) => { + const { + data: { user }, + } = await supabaseClient.auth.getUser() + + if (!user) throw new Error("Not authenticated") + + const { data, error } = await supabaseClient + .from("user_highlights") + .insert({ + user_id: user.id, + entry_id: parameters.entryIdentifier, + highlighted_text: parameters.highlightedText, + text_offset: parameters.textOffset, + text_length: parameters.textLength, + text_prefix: parameters.textPrefix, + text_suffix: parameters.textSuffix, + note: parameters.note ?? null, + color: parameters.color ?? "yellow", + }) + .select("id") + .single() + + if (error) throw error + + return data.id as string + }, + onSuccess: (_data, variables) => { + queryClient.invalidateQueries({ + queryKey: queryKeys.highlights.forEntry(variables.entryIdentifier), + }) + queryClient.invalidateQueries({ queryKey: queryKeys.highlights.all }) + queryClient.invalidateQueries({ queryKey: queryKeys.userProfile.all }) + notify("text highlighted") + }, + onError: (error: Error) => { + notify( + error.message.includes("limit") + ? "highlight limit reached for your plan" + : "failed to create highlight" + ) + }, + }) +} + +export function useUpdateHighlightNote() { + const supabaseClient = createSupabaseBrowserClient() + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: async ({ + highlightIdentifier, + note, + }: { + highlightIdentifier: string + note: string | null + entryIdentifier: string + }) => { + const { error } = await supabaseClient + .from("user_highlights") + .update({ note }) + .eq("id", highlightIdentifier) + + if (error) throw error + }, + onSuccess: (_data, variables) => { + queryClient.invalidateQueries({ + queryKey: queryKeys.highlights.forEntry(variables.entryIdentifier), + }) + queryClient.invalidateQueries({ queryKey: queryKeys.highlights.all }) + notify("note updated") + }, + onError: () => { + notify("failed to update note") + }, + }) +} + +export function useDeleteHighlight() { + const supabaseClient = createSupabaseBrowserClient() + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: async ({ + highlightIdentifier, + }: { + highlightIdentifier: string + entryIdentifier: string + }) => { + const { error } = await supabaseClient + .from("user_highlights") + .delete() + .eq("id", highlightIdentifier) + + if (error) throw error + }, + onSuccess: (_data, variables) => { + queryClient.invalidateQueries({ + queryKey: queryKeys.highlights.forEntry(variables.entryIdentifier), + }) + queryClient.invalidateQueries({ queryKey: queryKeys.highlights.all }) + queryClient.invalidateQueries({ queryKey: queryKeys.userProfile.all }) + notify("highlight removed") + }, + onError: () => { + notify("failed to remove highlight") + }, + }) +} |