Files
ai_web/frontend/src/hooks/useApi.ts
ddrwode fc0679b199 haha
2026-02-02 13:48:11 +08:00

931 lines
27 KiB
TypeScript

/**
* React Query hooks for API calls
*/
import { keepPreviousData, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useDebouncedValue } from "@/hooks/useDebouncedValue";
import {
authApi,
categoryApi,
websiteApi,
productApi,
bountyApi,
favoriteApi,
notificationApi,
paymentApi,
adminApi,
friendApi,
setAccessToken,
setRefreshToken,
clearRefreshToken,
searchApi,
type User,
type Bounty,
type BountyApplication,
type BountyComment,
type BountyDelivery,
type BountyDispute,
type BountyReview,
type BountyExtensionRequest,
type Favorite,
type FavoriteTag,
type PriceMonitor,
type Notification,
type NotificationPreference,
} from '@/lib/api';
const shortStaleTime = 30 * 1000;
const staticStaleTime = 5 * 60 * 1000;
// ==================== Auth Hooks ====================
export function useMe() {
return useQuery({
queryKey: ['auth', 'me'],
queryFn: authApi.me,
retry: false,
refetchOnWindowFocus: false,
staleTime: shortStaleTime,
});
}
export function useLogin() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ openId, password }: { openId: string; password: string }) =>
authApi.login({ open_id: openId, password }),
onSuccess: (data) => {
// Store tokens
setAccessToken(data.access_token);
setRefreshToken(data.refresh_token);
// Refetch user data
queryClient.invalidateQueries({ queryKey: ['auth', 'me'] });
},
});
}
export function useRegister() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ openId, password, name, email }: { openId: string; password: string; name?: string; email?: string }) =>
authApi.register({ open_id: openId, password, name, email }),
onSuccess: (data) => {
setAccessToken(data.access_token);
setRefreshToken(data.refresh_token);
queryClient.invalidateQueries({ queryKey: ['auth', 'me'] });
},
});
}
export function useLogout() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: authApi.logout,
onSuccess: () => {
setAccessToken(null);
clearRefreshToken();
queryClient.setQueryData(['auth', 'me'], null);
queryClient.invalidateQueries({ queryKey: ['auth'] });
},
});
}
export function useUpdateMe() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: authApi.updateMe,
onSuccess: (data) => {
queryClient.setQueryData(['auth', 'me'], data);
},
});
}
export function useChangePassword() {
return useMutation({
mutationFn: authApi.changePassword,
});
}
// ==================== Friends Hooks ====================
export function useFriends(options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['friends'],
queryFn: friendApi.list,
staleTime: shortStaleTime,
enabled: options?.enabled !== false,
});
}
export function useIncomingFriendRequests(options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['friends', 'requests', 'incoming'],
queryFn: friendApi.incoming,
staleTime: shortStaleTime,
enabled: options?.enabled !== false,
});
}
export function useOutgoingFriendRequests(options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['friends', 'requests', 'outgoing'],
queryFn: friendApi.outgoing,
staleTime: shortStaleTime,
enabled: options?.enabled !== false,
});
}
/** 仅请求待处理好友数量,用于角标(不拉完整列表) */
export function useIncomingFriendRequestCount(options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['friends', 'requests', 'incoming', 'count'],
queryFn: () => friendApi.incomingCount(),
staleTime: shortStaleTime,
enabled: options?.enabled !== false,
});
}
export function useSendFriendRequest() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: { receiver_id: number }) => friendApi.sendRequest(data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['friends', 'requests'] });
},
});
}
export function useAcceptFriendRequest() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (requestId: number) => friendApi.acceptRequest(requestId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['friends'] });
queryClient.invalidateQueries({ queryKey: ['friends', 'requests'] });
},
});
}
export function useRejectFriendRequest() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (requestId: number) => friendApi.rejectRequest(requestId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['friends', 'requests'] });
},
});
}
export function useCancelFriendRequest() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (requestId: number) => friendApi.cancelRequest(requestId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['friends', 'requests'] });
},
});
}
export function useSearchUsers(q: string, limit?: number) {
const debouncedQuery = useDebouncedValue(q, 300);
return useQuery({
queryKey: ['friends', 'search', debouncedQuery, limit],
queryFn: () => friendApi.searchUsers(debouncedQuery, limit),
enabled: !!debouncedQuery.trim(),
staleTime: shortStaleTime,
});
}
// ==================== Category Hooks ====================
export function useCategories(options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['categories'],
queryFn: categoryApi.list,
staleTime: staticStaleTime,
enabled: options?.enabled !== false,
});
}
export function useCategoryBySlug(slug: string) {
return useQuery({
queryKey: ['categories', slug],
queryFn: () => categoryApi.getBySlug(slug),
enabled: !!slug,
staleTime: staticStaleTime,
});
}
// ==================== Website Hooks ====================
export function useWebsites(params?: { category_id?: number; is_verified?: boolean; page?: number }) {
return useQuery({
queryKey: ['websites', params],
queryFn: () => websiteApi.list(params),
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
});
}
export function useWebsite(id: number) {
return useQuery({
queryKey: ['websites', id],
queryFn: () => websiteApi.get(id),
enabled: !!id,
staleTime: shortStaleTime,
});
}
// ==================== Product Hooks ====================
export function useProducts(params?: { category_id?: number; search?: string; page?: number; min_price?: number; max_price?: number; sort_by?: string }) {
return useQuery({
queryKey: ['products', params],
queryFn: () => productApi.list(params),
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
});
}
export function useRecommendedProducts(limit = 8) {
return useQuery({
queryKey: ['products', 'recommendations', limit],
queryFn: () => productApi.recommendations(limit),
staleTime: shortStaleTime,
});
}
export function useProduct(id: number) {
return useQuery({
queryKey: ['products', id],
queryFn: () => productApi.get(id),
enabled: !!id,
staleTime: shortStaleTime,
});
}
export function useProductWithPrices(id: number) {
return useQuery({
queryKey: ['products', id, 'prices'],
queryFn: () => productApi.getWithPrices(id),
enabled: !!id,
staleTime: shortStaleTime,
});
}
export function useProductSearch(q: string, params?: { page?: number; category_id?: number; user_id?: string; min_price?: number; max_price?: number; sort_by?: string }) {
const debouncedQuery = useDebouncedValue(q, 300);
return useQuery({
queryKey: ['products', 'search', debouncedQuery, params],
queryFn: () => productApi.search({ q: debouncedQuery, ...params }),
enabled: !!debouncedQuery.trim(),
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
});
}
// ==================== Bounty Hooks ====================
export function useBounties(params?: { status?: string; publisher_id?: number; acceptor_id?: number; page?: number }) {
return useQuery({
queryKey: ['bounties', params],
queryFn: () => bountyApi.list(params),
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
});
}
export function useBounty(id: number) {
return useQuery({
queryKey: ['bounties', id],
queryFn: () => bountyApi.get(id),
enabled: !!id,
staleTime: shortStaleTime,
});
}
export function useBountySearch(q: string, page?: number) {
const debouncedQuery = useDebouncedValue(q, 300);
return useQuery({
queryKey: ['bounties', 'search', debouncedQuery, page],
queryFn: () => bountyApi.search(debouncedQuery, page),
enabled: !!debouncedQuery.trim(),
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
});
}
export function useMyPublishedBounties(page?: number) {
return useQuery({
queryKey: ['bounties', 'my-published', page],
queryFn: () => bountyApi.myPublished(page),
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
});
}
export function useMyAcceptedBounties(page?: number) {
return useQuery({
queryKey: ['bounties', 'my-accepted', page],
queryFn: () => bountyApi.myAccepted(page),
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
});
}
export function useCreateBounty() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: bountyApi.create,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['bounties'] });
},
});
}
export function useUpdateBounty() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: number; data: Parameters<typeof bountyApi.update>[1] }) =>
bountyApi.update(id, data),
onSuccess: (_, { id }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', id] });
queryClient.invalidateQueries({ queryKey: ['bounties'] });
},
});
}
export function useCancelBounty() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: bountyApi.cancel,
onSuccess: (_, id) => {
queryClient.invalidateQueries({ queryKey: ['bounties', id] });
queryClient.invalidateQueries({ queryKey: ['bounties'] });
},
});
}
export function useCompleteBounty() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: bountyApi.complete,
onSuccess: (_, id) => {
queryClient.invalidateQueries({ queryKey: ['bounties', id] });
queryClient.invalidateQueries({ queryKey: ['bounties'] });
},
});
}
// Bounty Applications
export function useBountyApplications(bountyId: number) {
return useQuery({
queryKey: ['bounties', bountyId, 'applications'],
queryFn: () => bountyApi.listApplications(bountyId),
enabled: !!bountyId,
});
}
export function useMyBountyApplication(bountyId: number) {
return useQuery({
queryKey: ['bounties', bountyId, 'my-application'],
queryFn: () => bountyApi.myApplication(bountyId),
enabled: !!bountyId,
});
}
export function useSubmitApplication() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ bountyId, data }: { bountyId: number; data: { message?: string } }) =>
bountyApi.submitApplication(bountyId, data),
onSuccess: (_, { bountyId }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'applications'] });
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'my-application'] });
},
});
}
export function useAcceptApplication() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ bountyId, applicationId }: { bountyId: number; applicationId: number }) =>
bountyApi.acceptApplication(bountyId, applicationId),
onSuccess: (_, { bountyId }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId] });
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'applications'] });
},
});
}
// Bounty Comments
export function useBountyComments(bountyId: number) {
return useQuery({
queryKey: ['bounties', bountyId, 'comments'],
queryFn: () => bountyApi.listComments(bountyId),
enabled: !!bountyId,
});
}
export function useCreateComment() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ bountyId, data }: { bountyId: number; data: { content: string; parent_id?: number } }) =>
bountyApi.createComment(bountyId, data),
onSuccess: (_, { bountyId }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'comments'] });
},
});
}
// Bounty Deliveries
export function useDeliveries(bountyId: number, enabled = true) {
return useQuery({
queryKey: ['bounties', bountyId, 'deliveries'],
queryFn: () => bountyApi.listDeliveries(bountyId),
enabled: !!bountyId && enabled,
});
}
export function useSubmitDelivery() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ bountyId, data }: { bountyId: number; data: { content: string; attachment_url?: string } }) =>
bountyApi.submitDelivery(bountyId, data),
onSuccess: (_, { bountyId }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'deliveries'] });
},
});
}
export function useReviewDelivery() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ bountyId, deliveryId, accept }: { bountyId: number; deliveryId: number; accept: boolean }) =>
bountyApi.reviewDelivery(bountyId, deliveryId, accept),
onSuccess: (_, { bountyId }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'deliveries'] });
},
});
}
// Bounty Disputes
export function useDisputes(bountyId: number, enabled = true) {
return useQuery({
queryKey: ['bounties', bountyId, 'disputes'],
queryFn: () => bountyApi.listDisputes(bountyId),
enabled: !!bountyId && enabled,
});
}
export function useCreateDispute() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ bountyId, data }: { bountyId: number; data: { reason: string; evidence_url?: string } }) =>
bountyApi.createDispute(bountyId, data),
onSuccess: (_, { bountyId }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'disputes'] });
},
});
}
export function useResolveDispute() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ bountyId, disputeId, data }: { bountyId: number; disputeId: number; data: { resolution: string; accepted: boolean } }) =>
bountyApi.resolveDispute(bountyId, disputeId, data),
onSuccess: (_, { bountyId }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'disputes'] });
},
});
}
// Bounty Reviews
export function useBountyReviews(bountyId: number, enabled = true) {
return useQuery({
queryKey: ['bounties', bountyId, 'reviews'],
queryFn: () => bountyApi.listReviews(bountyId),
enabled: !!bountyId && enabled,
});
}
export function useCreateReview() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ bountyId, data }: { bountyId: number; data: { reviewee_id: number; rating: number; comment?: string } }) =>
bountyApi.createReview(bountyId, data),
onSuccess: (_, { bountyId }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'reviews'] });
},
});
}
// Bounty Extensions
export function useExtensionRequests(bountyId: number, enabled = true) {
return useQuery({
queryKey: ['bounties', bountyId, 'extensions'],
queryFn: () => bountyApi.listExtensions(bountyId),
enabled: !!bountyId && enabled,
});
}
export function useCreateExtensionRequest() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ bountyId, data }: { bountyId: number; data: { proposed_deadline: string; reason?: string } }) =>
bountyApi.createExtension(bountyId, data),
onSuccess: (_, { bountyId }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'extensions'] });
},
});
}
export function useReviewExtensionRequest() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ bountyId, requestId, approve }: { bountyId: number; requestId: number; approve: boolean }) =>
bountyApi.reviewExtension(bountyId, requestId, approve),
onSuccess: (_, { bountyId }) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId, 'extensions'] });
},
});
}
// ==================== Favorites Hooks ====================
export function useFavorites(params?: { tag_id?: number; page?: number }, options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['favorites', params],
queryFn: () => favoriteApi.list(params),
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
enabled: options?.enabled !== false,
});
}
export function useFavorite(id: number) {
return useQuery({
queryKey: ['favorites', id],
queryFn: () => favoriteApi.get(id),
enabled: !!id,
staleTime: shortStaleTime,
});
}
export function useCheckFavorite(productId: number, websiteId: number) {
return useQuery({
queryKey: ['favorites', 'check', productId, websiteId],
queryFn: () => favoriteApi.check(productId, websiteId),
enabled: !!productId && !!websiteId,
staleTime: shortStaleTime,
});
}
export function useAddFavorite() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: favoriteApi.add,
onSuccess: (_, data) => {
queryClient.invalidateQueries({ queryKey: ['favorites'] });
queryClient.invalidateQueries({ queryKey: ['favorites', 'check', data.product_id, data.website_id] });
},
});
}
export function useRemoveFavorite() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: favoriteApi.remove,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['favorites'] });
},
});
}
// Favorite Tags
export function useFavoriteTags() {
return useQuery({
queryKey: ['favorites', 'tags'],
queryFn: favoriteApi.listTags,
staleTime: staticStaleTime,
});
}
export function useCreateFavoriteTag() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: favoriteApi.createTag,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['favorites', 'tags'] });
},
});
}
export function useUpdateFavoriteTag() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: number; data: Parameters<typeof favoriteApi.updateTag>[1] }) =>
favoriteApi.updateTag(id, data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['favorites', 'tags'] });
},
});
}
export function useDeleteFavoriteTag() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: favoriteApi.deleteTag,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['favorites', 'tags'] });
queryClient.invalidateQueries({ queryKey: ['favorites'] });
},
});
}
// Price Monitor
export function usePriceMonitor(favoriteId: number) {
return useQuery({
queryKey: ['favorites', favoriteId, 'monitor'],
queryFn: () => favoriteApi.getMonitor(favoriteId),
enabled: !!favoriteId,
});
}
export function usePriceHistory(favoriteId: number, page?: number) {
return useQuery({
queryKey: ['favorites', favoriteId, 'monitor', 'history', page],
queryFn: () => favoriteApi.getMonitorHistory(favoriteId, page),
enabled: !!favoriteId,
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
});
}
export function useCreatePriceMonitor() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ favoriteId, data }: { favoriteId: number; data: Parameters<typeof favoriteApi.createMonitor>[1] }) =>
favoriteApi.createMonitor(favoriteId, data),
onSuccess: (_, { favoriteId }) => {
queryClient.invalidateQueries({ queryKey: ['favorites', favoriteId, 'monitor'] });
},
});
}
export function useUpdatePriceMonitor() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ favoriteId, data }: { favoriteId: number; data: Parameters<typeof favoriteApi.updateMonitor>[1] }) =>
favoriteApi.updateMonitor(favoriteId, data),
onSuccess: (_, { favoriteId }) => {
queryClient.invalidateQueries({ queryKey: ['favorites', favoriteId, 'monitor'] });
},
});
}
export function useRefreshPriceMonitor() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (favoriteId: number) => favoriteApi.refreshMonitor(favoriteId),
onSuccess: (_, favoriteId) => {
queryClient.invalidateQueries({ queryKey: ['favorites', favoriteId, 'monitor'] });
queryClient.invalidateQueries({ queryKey: ['favorites', favoriteId, 'monitor', 'history'] });
},
});
}
export function useAllPriceMonitors(page?: number) {
return useQuery({
queryKey: ['favorites', 'monitors', 'all', page],
queryFn: () => favoriteApi.listAllMonitors(page),
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
});
}
// ==================== Notification Hooks ====================
export function useNotifications(params?: { is_read?: boolean; type?: string; start?: string; end?: string; page?: number }, options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['notifications', params],
queryFn: () => notificationApi.list(params),
staleTime: shortStaleTime,
placeholderData: keepPreviousData,
enabled: options?.enabled !== false,
});
}
export function useGlobalSearch(q: string, limit = 10) {
const debouncedQuery = useDebouncedValue(q, 300);
return useQuery({
queryKey: ['search', debouncedQuery, limit],
queryFn: () => searchApi.global(debouncedQuery, limit),
enabled: !!debouncedQuery.trim(),
staleTime: shortStaleTime,
});
}
export function useUnreadNotificationCount(options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['notifications', 'unread-count'],
queryFn: notificationApi.unreadCount,
staleTime: shortStaleTime,
enabled: options?.enabled !== false,
});
}
export function useMarkNotificationAsRead() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: notificationApi.markAsRead,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['notifications'] });
},
});
}
export function useMarkAllNotificationsAsRead() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: notificationApi.markAllAsRead,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['notifications'] });
},
});
}
export function useNotificationPreferences(options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['notifications', 'preferences'],
queryFn: notificationApi.getPreferences,
staleTime: shortStaleTime,
enabled: options?.enabled !== false,
});
}
export function useUpdateNotificationPreferences() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: { enable_bounty?: boolean; enable_price_alert?: boolean; enable_system?: boolean }) =>
notificationApi.updatePreferences(data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['notifications', 'preferences'] });
},
});
}
// ==================== Payment Hooks ====================
export function useConnectStatus() {
return useQuery({
queryKey: ['payments', 'connect', 'status'],
queryFn: paymentApi.getConnectStatus,
});
}
export function useCreateEscrow() {
return useMutation({
mutationFn: paymentApi.createEscrow,
});
}
export function useSetupConnectAccount() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ returnUrl, refreshUrl }: { returnUrl: string; refreshUrl: string }) =>
paymentApi.setupConnectAccount(returnUrl, refreshUrl),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['payments', 'connect'] });
},
});
}
export function useReleasePayout() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: paymentApi.releasePayout,
onSuccess: (_, bountyId) => {
queryClient.invalidateQueries({ queryKey: ['bounties', bountyId] });
},
});
}
// ==================== Admin Hooks ====================
export function useAdminUsers() {
return useQuery({
queryKey: ['admin', 'users'],
queryFn: adminApi.listUsers,
staleTime: shortStaleTime,
});
}
export function useUpdateAdminUser() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, data }: { id: number; data: { role?: string; is_active?: boolean } }) =>
adminApi.updateUser(id, data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'users'] });
},
});
}
export function useAdminBounties(status?: string) {
return useQuery({
queryKey: ['admin', 'bounties', status],
queryFn: () => adminApi.listBounties(status),
staleTime: shortStaleTime,
});
}
export function useAdminPayments() {
return useQuery({
queryKey: ['admin', 'payments'],
queryFn: adminApi.listPayments,
staleTime: shortStaleTime,
});
}
export function useAdminDisputes(status?: string) {
return useQuery({
queryKey: ['admin', 'disputes', status],
queryFn: () => adminApi.listDisputes(status),
staleTime: shortStaleTime,
});
}
export function useAdminPendingProducts() {
return useQuery({
queryKey: ['admin', 'products', 'pending'],
queryFn: adminApi.listPendingProducts,
staleTime: shortStaleTime,
});
}
export function useAdminAllProducts(status?: string) {
return useQuery({
queryKey: ['admin', 'products', 'all', status],
queryFn: () => adminApi.listAllProducts(status),
staleTime: shortStaleTime,
});
}
export function useReviewProduct() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ productId, data }: { productId: number; data: { approved: boolean; reject_reason?: string } }) =>
adminApi.reviewProduct(productId, data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'products'] });
},
});
}
export function useUpdateAdminProductImages() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ productId, data }: { productId: number; data: { images: string[]; image?: string } }) =>
adminApi.updateProductImages(productId, data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'products'] });
},
});
}
// ==================== My Products Hooks ====================
export function useMyProducts(status?: string, options?: { enabled?: boolean }) {
return useQuery({
queryKey: ['products', 'my', status],
queryFn: () => productApi.myProducts(status),
staleTime: shortStaleTime,
enabled: options?.enabled !== false,
});
}