This commit is contained in:
@@ -8,6 +8,7 @@ import type {
|
||||
DeliveryPerson,
|
||||
DeliveryPersonsStats,
|
||||
Alert,
|
||||
MonthlyStats,
|
||||
} from "./types";
|
||||
|
||||
const V2 = `${API_BASE_URL}/api/v2`;
|
||||
@@ -126,7 +127,13 @@ export interface DailyDetail {
|
||||
categories: DailyCategoryDetail[];
|
||||
}
|
||||
|
||||
export type StatSection = "commandes" | "revenus" | "produits" | "heures" | "jours" | "doses";
|
||||
export type StatSection =
|
||||
| "commandes"
|
||||
| "revenus"
|
||||
| "produits"
|
||||
| "heures"
|
||||
| "jours"
|
||||
| "doses";
|
||||
|
||||
export interface AdminStats {
|
||||
summary: StatsSummary;
|
||||
@@ -150,8 +157,12 @@ export const getAdminStats = async (): Promise<AdminStats> => {
|
||||
return data;
|
||||
};
|
||||
|
||||
export const resetAdminStats = async (section: StatSection): Promise<{ success: boolean; reset_at: string }> => {
|
||||
const { data } = await apiClient.post(`${V2}/admin/protected/stats/reset/${section}`);
|
||||
export const resetAdminStats = async (
|
||||
section: StatSection,
|
||||
): Promise<{ success: boolean; reset_at: string }> => {
|
||||
const { data } = await apiClient.post(
|
||||
`${V2}/admin/protected/stats/reset/${section}`,
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -273,9 +284,17 @@ export const validateCommand = async (commandId: number) => {
|
||||
`${V2}/admin/protected/orders/${commandId}/force-validate`,
|
||||
{ command_id: commandId },
|
||||
);
|
||||
const validated = (data.validated ?? []) as { command_id: number; points_awarded: number }[];
|
||||
const points = validated.find((v) => v.command_id === commandId)?.points_awarded ?? 0;
|
||||
return { success: true, points_awarded: points, validated_count: data.validated_count ?? 0 };
|
||||
const validated = (data.validated ?? []) as {
|
||||
command_id: number;
|
||||
points_awarded: number;
|
||||
}[];
|
||||
const points =
|
||||
validated.find((v) => v.command_id === commandId)?.points_awarded ?? 0;
|
||||
return {
|
||||
success: true,
|
||||
points_awarded: points,
|
||||
validated_count: data.validated_count ?? 0,
|
||||
};
|
||||
};
|
||||
|
||||
export const proposeAddressChangeAdmin = async (
|
||||
@@ -300,7 +319,6 @@ export const notifyClientToDescend = async (commandId: number) => {
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// ============================================
|
||||
|
||||
export const getAvailableDeliveryPersons = async () => {
|
||||
@@ -335,8 +353,17 @@ export const getDeliveryPersonDetails = async (username: string) => {
|
||||
return data.deliveryman || data;
|
||||
};
|
||||
|
||||
export const getLivreurRatings = async (username: string): Promise<{
|
||||
ratings: { id: number; order_id: number; client_username: string; rating: number; comment: string; created_at: string }[];
|
||||
export const getLivreurRatings = async (
|
||||
username: string,
|
||||
): Promise<{
|
||||
ratings: {
|
||||
id: number;
|
||||
order_id: number;
|
||||
client_username: string;
|
||||
rating: number;
|
||||
comment: string;
|
||||
created_at: string;
|
||||
}[];
|
||||
average: number;
|
||||
count: number;
|
||||
}> => {
|
||||
@@ -963,7 +990,9 @@ export const reorderCategoriesAdmin = async (
|
||||
ids: number[],
|
||||
): Promise<{ success: boolean; error?: string }> => {
|
||||
try {
|
||||
await apiClient.put(`${V2}/admin/protected/categories/reorder`, { ids });
|
||||
await apiClient.put(`${V2}/admin/protected/categories/reorder`, {
|
||||
ids,
|
||||
});
|
||||
return { success: true };
|
||||
} catch (error: any) {
|
||||
return {
|
||||
@@ -1223,3 +1252,15 @@ export const updateSettings = async (
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const getAdminStatsByMonth = async (
|
||||
month?: string,
|
||||
): Promise<MonthlyStats> => {
|
||||
const { data } = await apiClient.get(
|
||||
`${V2}/admin/protected/stats/monthly`,
|
||||
{
|
||||
params: month ? { month } : undefined,
|
||||
},
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -72,7 +72,7 @@ export interface Alert {
|
||||
export interface DeliveryPerson {
|
||||
id: number;
|
||||
username: string;
|
||||
status: 'available' | 'busy' | 'offline';
|
||||
status: "available" | "busy" | "offline";
|
||||
location: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
@@ -102,15 +102,25 @@ export interface Product {
|
||||
category: string;
|
||||
stock: number;
|
||||
unit: string;
|
||||
prices?: Array<{ id?: number; quantity: number; price: number; active_price?: boolean }>;
|
||||
media?: Array<{ url: string; type: string; id?: number; created_at?: string }>;
|
||||
prices?: Array<{
|
||||
id?: number;
|
||||
quantity: number;
|
||||
price: number;
|
||||
active_price?: boolean;
|
||||
}>;
|
||||
media?: Array<{
|
||||
url: string;
|
||||
type: string;
|
||||
id?: number;
|
||||
created_at?: string;
|
||||
}>;
|
||||
coming_soon?: boolean;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
}
|
||||
|
||||
export interface DeliveryStatus {
|
||||
status: 'available' | 'busy' | 'offline';
|
||||
status: "available" | "busy" | "offline";
|
||||
current_command?: number;
|
||||
last_update?: number;
|
||||
}
|
||||
@@ -164,3 +174,21 @@ export interface MapLinks {
|
||||
apple_maps: string;
|
||||
openstreetmap: string;
|
||||
}
|
||||
|
||||
export interface MonthlyDayStat {
|
||||
day: string; // "2026-06-05"
|
||||
label: string; // "05/06"
|
||||
count: number;
|
||||
revenue: number;
|
||||
quantity: number;
|
||||
}
|
||||
export interface MonthlyStatsSummary {
|
||||
total_orders: number;
|
||||
total_revenue: number;
|
||||
total_quantity: number;
|
||||
}
|
||||
export interface MonthlyStats {
|
||||
month: string; // "2026-06"
|
||||
summary: MonthlyStatsSummary;
|
||||
by_day: MonthlyDayStat[];
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user