mirror of
https://github.com/narrrl/holy-flavor-rater.git
synced 2026-11-04 17:07:01 +01:00
typed api
This commit is contained in:
1 parent
5219a66722
commit
fa37f8eb79
61 files changed
+2961
-2578
No files matched your search
@@ -0,0 +1,91 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import api from '../../lib/api';
|
||||
|
||||
const invalidateAdmin = (qc: ReturnType<typeof useQueryClient>) => {
|
||||
qc.invalidateQueries({ queryKey: ['adminStats'] });
|
||||
qc.invalidateQueries({ queryKey: ['adminUsers'] });
|
||||
qc.invalidateQueries({ queryKey: ['adminJobs'] });
|
||||
qc.invalidateQueries({ queryKey: ['adminConfig'] });
|
||||
};
|
||||
|
||||
export const useUpdateAdminConfig = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ key, value }: { key: string; value: unknown }) =>
|
||||
api.patch('admin-custom/config/', { [key]: value }),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['adminConfig'] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useTriggerJob = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (id: number) => api.post(`admin-custom/${id}/trigger_job/`),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['adminJobs'] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateJobSchedule = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ id, data }: { id: number; data: Record<string, unknown> }) =>
|
||||
api.patch(`admin-custom/${id}/update_job_schedule/`, data),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['adminJobs'] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useActivateBanner = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (id: number) => api.post(`banners/${id}/activate/`),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['banners'] });
|
||||
qc.invalidateQueries({ queryKey: ['activeBanner'] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useToggleBannerEnabled = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (id: number) => api.post(`banners/${id}/toggle_enabled/`),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['banners'] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useSendTestEmail = () =>
|
||||
useMutation({
|
||||
mutationFn: () => api.post('admin-custom/send_test_email/'),
|
||||
});
|
||||
|
||||
export const useToggleUserActive = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ id, isActive }: { id: string | number; isActive: boolean }) =>
|
||||
api.patch(`admin-custom/${id}/user_detail/`, { is_active: !isActive }),
|
||||
onSuccess: (_, vars) => {
|
||||
qc.invalidateQueries({ queryKey: ['adminUserDetail', String(vars.id)] });
|
||||
qc.invalidateQueries({ queryKey: ['adminUsers'] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteUser = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (id: string | number) => api.delete(`admin-custom/${id}/user_detail/`),
|
||||
onSuccess: (_, id) => {
|
||||
qc.invalidateQueries({ queryKey: ['adminUserDetail', String(id)] });
|
||||
qc.invalidateQueries({ queryKey: ['adminUsers'] });
|
||||
invalidateAdmin(qc);
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import api from '../../lib/api';
|
||||
import { queryKeys } from '../keys';
|
||||
|
||||
export interface UpdateFlavorInput {
|
||||
id: string | number;
|
||||
data: Record<string, unknown> | FormData;
|
||||
isFormData?: boolean;
|
||||
}
|
||||
|
||||
export const useUpdateFlavor = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ id, data, isFormData }: UpdateFlavorInput) =>
|
||||
api.patch(
|
||||
`flavors/${id}/`,
|
||||
data,
|
||||
isFormData ? { headers: { 'Content-Type': 'multipart/form-data' } } : undefined,
|
||||
),
|
||||
onSuccess: (_, vars) => {
|
||||
qc.invalidateQueries({ queryKey: queryKeys.flavorDetail(vars.id) });
|
||||
qc.invalidateQueries({ queryKey: queryKeys.flavorsAll() });
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import api from '../../lib/api';
|
||||
import { queryKeys } from '../keys';
|
||||
import type { Notification } from '../queries/useNotifications';
|
||||
|
||||
export const useMarkAllNotificationsRead = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: () => api.post('notifications/mark_all_read/'),
|
||||
onSuccess: () => {
|
||||
qc.setQueryData<Notification[]>(queryKeys.notifications(), (old) =>
|
||||
old?.map((n) => ({ ...n, is_read: true })),
|
||||
);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useMarkNotificationRead = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (id: number) => api.post(`notifications/${id}/mark_read/`),
|
||||
onSuccess: (_, id) => {
|
||||
qc.setQueryData<Notification[]>(queryKeys.notifications(), (old) =>
|
||||
old?.map((n) => (n.id === id ? { ...n, is_read: true } : n)),
|
||||
);
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import api from '../../lib/api';
|
||||
import { queryKeys } from '../keys';
|
||||
|
||||
const invalidateRatingViews = (qc: ReturnType<typeof useQueryClient>) => {
|
||||
qc.invalidateQueries({ queryKey: queryKeys.dashboard() });
|
||||
qc.invalidateQueries({ queryKey: queryKeys.publicProfileAll() });
|
||||
qc.invalidateQueries({ queryKey: queryKeys.flavorsAll() });
|
||||
qc.invalidateQueries({ queryKey: ['flavorDetail'] });
|
||||
qc.invalidateQueries({ queryKey: ['communityFeed'] });
|
||||
};
|
||||
|
||||
export interface UpdateRatingInput {
|
||||
id: number;
|
||||
score: number;
|
||||
comment: string | null;
|
||||
}
|
||||
|
||||
export const useUpdateRating = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ id, score, comment }: UpdateRatingInput) =>
|
||||
api.patch(`ratings/${id}/`, { score, comment }),
|
||||
onSuccess: () => invalidateRatingViews(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteRating = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (id: number) => api.delete(`ratings/${id}/`),
|
||||
onSuccess: () => invalidateRatingViews(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export interface CreateRatingInput {
|
||||
flavor: number;
|
||||
score: number;
|
||||
comment?: string | null;
|
||||
}
|
||||
|
||||
export const useCreateRating = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (input: CreateRatingInput) => api.post('ratings/', input),
|
||||
onSuccess: () => invalidateRatingViews(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export interface ReplyInput {
|
||||
ratingId: number;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export const useCreateReply = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ ratingId, text }: ReplyInput) =>
|
||||
api.post(`ratings/${ratingId}/reply/`, { text }),
|
||||
onSuccess: () => invalidateRatingViews(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteReply = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (replyId: number) => api.delete(`replies/${replyId}/`),
|
||||
onSuccess: () => invalidateRatingViews(qc),
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import api from '../../lib/api';
|
||||
import { queryKeys } from '../keys';
|
||||
|
||||
const invalidateRatingViews = (qc: ReturnType<typeof useQueryClient>) => {
|
||||
qc.invalidateQueries({ queryKey: queryKeys.dashboard() });
|
||||
qc.invalidateQueries({ queryKey: queryKeys.publicProfileAll() });
|
||||
qc.invalidateQueries({ queryKey: queryKeys.flavorsAll() });
|
||||
qc.invalidateQueries({ queryKey: ['flavorDetail'] });
|
||||
qc.invalidateQueries({ queryKey: ['communityFeed'] });
|
||||
};
|
||||
|
||||
export const useUpdateReply = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ replyId, text }: { replyId: number; text: string }) =>
|
||||
api.patch(`replies/${replyId}/`, { text }),
|
||||
onSuccess: () => invalidateRatingViews(qc),
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import api from '../../lib/api';
|
||||
|
||||
const invalidateMe = (qc: ReturnType<typeof useQueryClient>) => {
|
||||
qc.invalidateQueries({ queryKey: ['me'] });
|
||||
qc.invalidateQueries({ queryKey: ['currentUserLite'] });
|
||||
};
|
||||
|
||||
export const useUpdateAvatar = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('avatar', file);
|
||||
return api.post<{ avatar: string }>('users/update_avatar/', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
},
|
||||
onSuccess: () => invalidateMe(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdatePreferences = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (prefs: Record<string, unknown>) => api.patch('users/update_preferences/', prefs),
|
||||
onSuccess: () => invalidateMe(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateProfile = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (input: { username: string; email: string }) =>
|
||||
api.patch<{ message?: string }>('users/update_profile/', input),
|
||||
onSuccess: () => invalidateMe(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export const useConfirmEmail = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (code: string) => api.post<{ email: string }>('users/confirm_email/', { code }),
|
||||
onSuccess: () => invalidateMe(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export const useChangePassword = () =>
|
||||
useMutation({
|
||||
mutationFn: (input: { old_password: string; new_password: string }) =>
|
||||
api.post('users/change_password/', input),
|
||||
});
|
||||
|
||||
export const useRequestAccountDeletion = () =>
|
||||
useMutation({
|
||||
mutationFn: () => api.post('users/request_account_deletion/'),
|
||||
});
|
||||
|
||||
export const useConfirmAccountDeletion = () =>
|
||||
useMutation({
|
||||
mutationFn: (code: string) => api.post('users/confirm_account_deletion/', { code }),
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import api from '../../lib/api';
|
||||
import { queryKeys } from '../keys';
|
||||
|
||||
export const useFollowToggle = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ userId, currentlyFollowing }: { userId: number; currentlyFollowing: boolean }) =>
|
||||
api.post(`users/${userId}/${currentlyFollowing ? 'unfollow' : 'follow'}/`),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: queryKeys.publicProfileAll() });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useAddProfileComment = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ userId, text }: { userId: number; text: string }) =>
|
||||
api.post(`users/${userId}/add_comment/`, { text }),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: queryKeys.publicProfileAll() });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteProfileComment = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ userId, commentId }: { userId: number; commentId: number }) =>
|
||||
api.delete(`users/${userId}/delete_comment/${commentId}/`),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: queryKeys.publicProfileAll() });
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import api from '../../lib/api';
|
||||
|
||||
const invalidateTickets = (qc: ReturnType<typeof useQueryClient>) => {
|
||||
qc.invalidateQueries({ queryKey: ['tickets'] });
|
||||
};
|
||||
|
||||
export const useCreateTicket = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (input: { subject: string; description: string }) => api.post('tickets/', input),
|
||||
onSuccess: () => invalidateTickets(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export const useAddTicketMessage = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ ticketId, text }: { ticketId: number; text: string }) =>
|
||||
api.post(`tickets/${ticketId}/add_message/`, { text }),
|
||||
onSuccess: () => invalidateTickets(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateTicketStatus = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ ticketId, status }: { ticketId: number; status: string }) =>
|
||||
api.post(`tickets/${ticketId}/update_status/`, { status }),
|
||||
onSuccess: () => invalidateTickets(qc),
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteTicket = () => {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (ticketId: number) => api.delete(`tickets/${ticketId}/`),
|
||||
onSuccess: () => invalidateTickets(qc),
|
||||
});
|
||||
};
|
||||
Reference in new issue
Block a user