2026-01-28 16:00:56 +08:00
|
|
|
import { api } from "./client";
|
2026-02-04 15:25:04 +08:00
|
|
|
import type { AdminBounty, AdminPaymentEvent, AdminUser, AdminProduct, AdminComparisonTag, AdminComparisonTagItem, PaginatedResponse } from "../types";
|
2026-01-28 16:00:56 +08:00
|
|
|
|
|
|
|
|
export const adminApi = {
|
|
|
|
|
listUsers: () => api.get<PaginatedResponse<AdminUser>>("/admin/users/").then((r) => r.data),
|
2026-01-29 10:19:27 +08:00
|
|
|
updateUser: (id: number, data: { role?: string, is_active?: boolean }) =>
|
2026-01-28 16:00:56 +08:00
|
|
|
api.patch<AdminUser>(`/admin/users/${id}`, data).then((r) => r.data),
|
2026-01-29 10:19:27 +08:00
|
|
|
listCategories: () => api.get<PaginatedResponse<{ id: number, name: string }>>("/admin/categories/").then((r) => r.data),
|
|
|
|
|
listWebsites: () => api.get<PaginatedResponse<{ id: number, name: string }>>("/admin/websites/").then((r) => r.data),
|
|
|
|
|
listProducts: () => api.get<PaginatedResponse<{ id: number, name: string }>>("/admin/products/").then((r) => r.data),
|
2026-01-28 16:00:56 +08:00
|
|
|
listBounties: (status?: string) =>
|
|
|
|
|
api.get<PaginatedResponse<AdminBounty>>("/admin/bounties/", { params: { status } }).then((r) => r.data),
|
|
|
|
|
listDisputes: (status?: string) =>
|
2026-01-29 10:19:27 +08:00
|
|
|
api.get<PaginatedResponse<{ id: number, bounty_id: number, initiator_id: number, status: string, created_at: string }>>(
|
2026-01-28 16:00:56 +08:00
|
|
|
"/admin/disputes/",
|
|
|
|
|
{ params: { status } }
|
|
|
|
|
).then((r) => r.data),
|
|
|
|
|
listPayments: () => api.get<PaginatedResponse<AdminPaymentEvent>>("/admin/payments/").then((r) => r.data),
|
|
|
|
|
|
|
|
|
|
// Product review APIs
|
|
|
|
|
listPendingProducts: () =>
|
|
|
|
|
api.get<PaginatedResponse<AdminProduct>>("/admin/products/pending/").then((r) => r.data),
|
|
|
|
|
listAllProducts: (status?: string) =>
|
|
|
|
|
api.get<PaginatedResponse<AdminProduct>>("/admin/products/all/", { params: { status } }).then((r) => r.data),
|
2026-01-29 10:19:27 +08:00
|
|
|
reviewProduct: (productId: number, data: { approved: boolean, reject_reason?: string }) =>
|
2026-01-28 16:00:56 +08:00
|
|
|
api.post<AdminProduct>(`/admin/products/${productId}/review/`, data).then((r) => r.data),
|
2026-01-29 13:18:59 +08:00
|
|
|
updateProductImages: (productId: number, data: { images: string[]; image?: string }) =>
|
|
|
|
|
api.put<AdminProduct>(`/admin/products/${productId}/images/`, data).then((r) => r.data),
|
2026-02-04 15:25:04 +08:00
|
|
|
|
|
|
|
|
// Comparison tags
|
|
|
|
|
listComparisonTags: () => api.get<AdminComparisonTag[]>("/admin/compare-tags/").then((r) => r.data),
|
|
|
|
|
createComparisonTag: (data: { name: string; slug: string; description?: string; cover_image?: string; icon?: string; sort_order?: number; is_active?: boolean }) =>
|
|
|
|
|
api.post<AdminComparisonTag>("/admin/compare-tags/", data).then((r) => r.data),
|
|
|
|
|
updateComparisonTag: (tagId: number, data: { name?: string; slug?: string; description?: string; cover_image?: string; icon?: string; sort_order?: number; is_active?: boolean }) =>
|
|
|
|
|
api.patch<AdminComparisonTag>(`/admin/compare-tags/${tagId}`, data).then((r) => r.data),
|
|
|
|
|
deleteComparisonTag: (tagId: number) =>
|
|
|
|
|
api.delete<{ message: string }>(`/admin/compare-tags/${tagId}`).then((r) => r.data),
|
|
|
|
|
listComparisonTagItems: (tagId: number) =>
|
|
|
|
|
api.get<AdminComparisonTagItem[]>(`/admin/compare-tags/${tagId}/items/`).then((r) => r.data),
|
|
|
|
|
addComparisonTagItems: (tagId: number, data: { product_ids: number[]; sort_order?: number; is_pinned?: boolean }) =>
|
|
|
|
|
api.post<AdminComparisonTagItem[]>(`/admin/compare-tags/${tagId}/items/`, data).then((r) => r.data),
|
|
|
|
|
updateComparisonTagItem: (tagId: number, itemId: number, data: { sort_order?: number; is_pinned?: boolean }) =>
|
|
|
|
|
api.patch<AdminComparisonTagItem>(`/admin/compare-tags/${tagId}/items/${itemId}`, data).then((r) => r.data),
|
|
|
|
|
deleteComparisonTagItem: (tagId: number, itemId: number) =>
|
|
|
|
|
api.delete<{ message: string }>(`/admin/compare-tags/${tagId}/items/${itemId}`).then((r) => r.data),
|
|
|
|
|
|
|
|
|
|
// Price history backfill
|
|
|
|
|
backfillPriceHistory: (productIds?: number[]) =>
|
|
|
|
|
api.post<{ created: number; skipped: number }>("/admin/price-history/backfill/", { product_ids: productIds }).then((r) => r.data),
|
|
|
|
|
backfillTagPriceHistory: (tagId: number) =>
|
|
|
|
|
api.post<{ created: number; skipped: number }>(`/admin/compare-tags/${tagId}/backfill-history/`).then((r) => r.data),
|
|
|
|
|
recordPriceHistory: (data?: { product_ids?: number[]; force?: boolean }) =>
|
|
|
|
|
api.post<{ created: number; skipped: number }>("/admin/price-history/record/", data || {}).then((r) => r.data),
|
|
|
|
|
recordTagPriceHistory: (tagId: number, data?: { product_ids?: number[]; force?: boolean }) =>
|
|
|
|
|
api.post<{ created: number; skipped: number }>(`/admin/compare-tags/${tagId}/record-history/`, data || {}).then((r) => r.data),
|
2026-01-28 16:00:56 +08:00
|
|
|
};
|