import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import type { CreateWishInput, UpdateWishInput } from '@family-wishlist/shared'; import { toast } from 'sonner'; import { wishesApi, type OwnerStatus } from './wishes.api'; import { ApiError } from '@/lib/api'; const LIST_KEY = (status: OwnerStatus) => ['wishes', status] as const; function invalidateAll(client: ReturnType): void { void client.invalidateQueries({ queryKey: ['wishes'] }); } function toastError(err: unknown, fallback = 'Something went wrong'): void { if (err instanceof ApiError) toast.error(err.message); else toast.error(fallback); } export function useWishes(status: OwnerStatus) { return useQuery({ queryKey: LIST_KEY(status), queryFn: () => wishesApi.list(status), staleTime: 10_000, }); } export function useCreateWish() { const client = useQueryClient(); return useMutation({ mutationFn: (input: CreateWishInput) => wishesApi.create(input), onSuccess: () => { invalidateAll(client); toast.success('Wish added'); }, onError: (err) => toastError(err), }); } export function useUpdateWish() { const client = useQueryClient(); return useMutation({ mutationFn: (vars: { id: string; input: UpdateWishInput }) => wishesApi.update(vars.id, vars.input), onSuccess: () => { invalidateAll(client); toast.success('Saved'); }, onError: (err) => toastError(err), }); } export function useArchiveWish() { const client = useQueryClient(); return useMutation({ mutationFn: (id: string) => wishesApi.archive(id), onSuccess: () => { invalidateAll(client); toast.success('Moved to archive'); }, onError: (err) => toastError(err), }); } export function useCompleteWish() { const client = useQueryClient(); return useMutation({ mutationFn: (id: string) => wishesApi.complete(id), onSuccess: () => { invalidateAll(client); toast.success('Marked as fulfilled'); }, onError: (err) => toastError(err), }); } export function useDeleteWish() { const client = useQueryClient(); return useMutation({ mutationFn: (id: string) => wishesApi.remove(id), onSuccess: () => { invalidateAll(client); toast.success('Moved to trash (30 days to restore)'); }, onError: (err) => toastError(err), }); } export function useRestoreWish() { const client = useQueryClient(); return useMutation({ mutationFn: (id: string) => wishesApi.restore(id), onSuccess: () => { invalidateAll(client); toast.success('Restored'); }, onError: (err) => toastError(err), }); } export function useDuplicateWish() { const client = useQueryClient(); return useMutation({ mutationFn: (id: string) => wishesApi.duplicate(id), onSuccess: () => { invalidateAll(client); toast.success('New wish created from the fulfilled one'); }, onError: (err) => toastError(err), }); } export function useUploadWishImage() { const client = useQueryClient(); return useMutation({ mutationFn: (vars: { id: string; file: File }) => wishesApi.uploadImage(vars.id, vars.file), onSuccess: () => { invalidateAll(client); toast.success('Image updated'); }, onError: (err) => toastError(err), }); } export function useRefreshOg() { const client = useQueryClient(); return useMutation({ mutationFn: (id: string) => wishesApi.refreshOg(id), onSuccess: () => { invalidateAll(client); toast.success('Image refreshed from link'); }, onError: (err) => toastError(err, 'Could not fetch image from link'), }); } export function useResetWishImage() { const client = useQueryClient(); return useMutation({ mutationFn: (id: string) => wishesApi.deleteImage(id), onSuccess: () => { invalidateAll(client); toast.success('Reset to default image'); }, onError: (err) => toastError(err), }); }