Files
memer/frontend/src/hooks/useMemes.ts
2026-03-28 22:12:53 -05:00

154 lines
3.9 KiB
TypeScript

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api, type ListParams } from '../api/client';
export function useCollections() {
return useQuery({
queryKey: ['collections'],
queryFn: () => api.collections.list(),
staleTime: 30_000,
});
}
export function useCreateCollection() {
const qc = useQueryClient();
return useMutation({
mutationFn: (name: string) => api.collections.create(name),
onSuccess: () => qc.invalidateQueries({ queryKey: ['collections'] }),
});
}
export function useRenameCollection() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ id, name }: { id: number; name: string }) => api.collections.rename(id, name),
onSuccess: () => qc.invalidateQueries({ queryKey: ['collections'] }),
});
}
export function useDeleteCollection() {
const qc = useQueryClient();
return useMutation({
mutationFn: (id: number) => api.collections.delete(id),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['collections'] });
qc.invalidateQueries({ queryKey: ['memes'] });
},
});
}
export function useMoveMeme() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ id, collection_id }: { id: string; collection_id: number }) =>
api.memes.move(id, collection_id),
onSuccess: (_, vars) => {
qc.invalidateQueries({ queryKey: ['memes'] });
qc.invalidateQueries({ queryKey: ['meme', vars.id] });
qc.invalidateQueries({ queryKey: ['collections'] });
},
});
}
export function useMemes(params: ListParams = {}) {
return useQuery({
queryKey: ['memes', params],
queryFn: () => api.memes.list(params),
});
}
export function useMeme(id: string | null) {
return useQuery({
queryKey: ['meme', id],
queryFn: () => api.memes.get(id!),
enabled: !!id,
});
}
export function useTags() {
return useQuery({
queryKey: ['tags'],
queryFn: () => api.tags.list(),
});
}
export function useUploadMeme() {
const qc = useQueryClient();
return useMutation({
mutationFn: (formData: FormData) => api.memes.upload(formData),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['memes'] });
qc.invalidateQueries({ queryKey: ['tags'] });
},
});
}
export function useUpdateMeme() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({ id, ...body }: { id: string; title?: string; description?: string; tags?: string[] }) =>
api.memes.update(id, body),
onSuccess: (_, vars) => {
qc.invalidateQueries({ queryKey: ['memes'] });
qc.invalidateQueries({ queryKey: ['meme', vars.id] });
qc.invalidateQueries({ queryKey: ['tags'] });
},
});
}
export function useDeleteMeme() {
const qc = useQueryClient();
return useMutation({
mutationFn: (id: string) => api.memes.delete(id),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['memes'] });
qc.invalidateQueries({ queryKey: ['tags'] });
},
});
}
export function useAdminStats() {
return useQuery({
queryKey: ['admin', 'stats'],
queryFn: () => api.admin.stats(),
staleTime: 30_000,
});
}
export function useReindexStatus() {
return useQuery({
queryKey: ['admin', 'reindex-status'],
queryFn: () => api.admin.reindexStatus(),
staleTime: 0,
});
}
export function useReindex() {
const qc = useQueryClient();
return useMutation({
mutationFn: () => api.admin.reindex(),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['admin', 'reindex-status'] });
qc.invalidateQueries({ queryKey: ['memes'] });
},
});
}
export function useRescaleMeme() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({
id,
...body
}: {
id: string;
width?: number;
height?: number;
quality?: number;
label?: string;
}) => api.memes.rescale(id, body),
onSuccess: (_, vars) => {
qc.invalidateQueries({ queryKey: ['meme', vars.id] });
},
});
}