728 lines
18 KiB
TypeScript
728 lines
18 KiB
TypeScript
// ============================================
|
|
// api/api_livreur.ts - LIVREUR API HELPERS
|
|
// ============================================
|
|
// ✅ Fonctions helper pour le dashboard livreur
|
|
// ✅ Utilise /api/v1/livreur/* endpoints
|
|
|
|
const API_URL = "/api/v1/livreur";
|
|
|
|
// ============================================
|
|
// 🔐 TYPES - LIVREUR
|
|
// ============================================
|
|
|
|
export interface DeliveryStatus {
|
|
status: "available" | "busy" | "offline";
|
|
current_command?: number;
|
|
last_update?: number;
|
|
}
|
|
|
|
export interface QueueInfo {
|
|
queue_size: number;
|
|
commands: any[];
|
|
}
|
|
|
|
export interface DeliveryItem {
|
|
id: number;
|
|
status: string;
|
|
adresse: string;
|
|
total_prix: number;
|
|
created_at: string;
|
|
updated_at: string;
|
|
eta?: string;
|
|
}
|
|
|
|
export interface ClientInfo {
|
|
username: string;
|
|
nom?: string;
|
|
prenom?: string;
|
|
telephone?: string;
|
|
}
|
|
|
|
export interface DeliveryDetails {
|
|
delivery: DeliveryItem;
|
|
client_info: ClientInfo;
|
|
}
|
|
|
|
export interface Alert {
|
|
id: number;
|
|
username: string;
|
|
status: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
// ============================================
|
|
// 🔐 GESTION JWT
|
|
// ============================================
|
|
|
|
/**
|
|
* ✅ Récupérer le token d'authentification
|
|
*/
|
|
const getAuthToken = (): string | null => {
|
|
return sessionStorage.getItem("admin_token");
|
|
};
|
|
|
|
export const isDeliveryAuthenticated = (): boolean => {
|
|
const token = sessionStorage.getItem("admin_token");
|
|
return !!token;
|
|
};
|
|
|
|
// ============================================
|
|
// 📊 STATUT DU LIVREUR
|
|
// ============================================
|
|
|
|
/**
|
|
* ✅ Récupérer le statut actuel du livreur
|
|
* GET /api/v1/livreur/status
|
|
*/
|
|
export const getMyStatus = async (): Promise<{
|
|
success: boolean;
|
|
status?: DeliveryStatus;
|
|
error?: string;
|
|
}> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log("🔍 [GET_MY_STATUS] Appel API");
|
|
|
|
const response = await fetch(`${API_URL}/status`, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [GET_MY_STATUS] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [GET_MY_STATUS] Réponse:", data);
|
|
|
|
return {
|
|
success: true,
|
|
status: data.status,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [GET_MY_STATUS] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ✅ Mettre à jour le statut du livreur
|
|
* POST /api/v1/livreur/status
|
|
*/
|
|
export const updateMyStatus = async (
|
|
status: "available" | "busy" | "offline",
|
|
): Promise<{ success: boolean; message?: string; error?: string }> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log("📝 [UPDATE_MY_STATUS] Appel API:", status);
|
|
|
|
const response = await fetch(`${API_URL}/update/status`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
body: JSON.stringify({ status }),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [UPDATE_MY_STATUS] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [UPDATE_MY_STATUS] Réponse:", data);
|
|
|
|
return {
|
|
success: true,
|
|
message: data.message,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [UPDATE_MY_STATUS] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
// ============================================
|
|
// 📦 QUEUE DU LIVREUR
|
|
// ============================================
|
|
|
|
/**
|
|
* ✅ Récupérer la queue de livraisons du livreur
|
|
* GET /api/v1/livreur/queue
|
|
*/
|
|
export const getMyQueue = async (): Promise<{
|
|
success: boolean;
|
|
queue_info?: QueueInfo;
|
|
error?: string;
|
|
}> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log("🔍 [GET_MY_QUEUE] Appel API");
|
|
|
|
const response = await fetch(`${API_URL}/queue`, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [GET_MY_QUEUE] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [GET_MY_QUEUE] Réponse:", data);
|
|
|
|
return {
|
|
success: true,
|
|
queue_info: data.queue_info,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [GET_MY_QUEUE] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
// ============================================
|
|
// 🚚 LIVRAISONS
|
|
// ============================================
|
|
|
|
/**
|
|
* ✅ Récupérer toutes les livraisons du livreur
|
|
* GET /api/v1/livreur/deliveries
|
|
*/
|
|
export const getMyDeliveries = async (): Promise<{
|
|
success: boolean;
|
|
deliveries?: DeliveryItem[];
|
|
error?: string;
|
|
}> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log("🔍 [GET_MY_DELIVERIES] Appel API");
|
|
|
|
const response = await fetch(`${API_URL}/deliveries`, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [GET_MY_DELIVERIES] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [GET_MY_DELIVERIES] Réponse:", data);
|
|
|
|
return {
|
|
success: true,
|
|
deliveries: data.deliveries || [],
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [GET_MY_DELIVERIES] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ✅ Récupérer les détails d'une livraison spécifique
|
|
* GET /api/v1/livreur/deliveries/:id
|
|
*/
|
|
export const getDeliveryDetails = async (
|
|
deliveryId: number,
|
|
): Promise<{
|
|
success: boolean;
|
|
delivery?: DeliveryDetails;
|
|
error?: string;
|
|
}> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log("🔍 [GET_DELIVERY_DETAILS] Appel API:", deliveryId);
|
|
|
|
const response = await fetch(`${API_URL}/deliveries/${deliveryId}`, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [GET_DELIVERY_DETAILS] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [GET_DELIVERY_DETAILS] Réponse:", data);
|
|
|
|
return {
|
|
success: true,
|
|
delivery: {
|
|
delivery: data.delivery,
|
|
client_info: data.client_info,
|
|
},
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [GET_DELIVERY_DETAILS] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ✅ Démarrer une livraison
|
|
* POST /api/v1/livreur/deliveries/:id/start
|
|
*/
|
|
export const startDelivery = async (
|
|
deliveryId: number,
|
|
latitude: number,
|
|
longitude: number,
|
|
): Promise<{ success: boolean; message?: string; error?: string }> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log("🚀 [START_DELIVERY] Appel API:", deliveryId);
|
|
|
|
const response = await fetch(
|
|
`${API_URL}/deliveries/${deliveryId}/start`,
|
|
{
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
body: JSON.stringify({ latitude, longitude }),
|
|
},
|
|
);
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [START_DELIVERY] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [START_DELIVERY] Réponse:", data);
|
|
|
|
return {
|
|
success: true,
|
|
message: data.message,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [START_DELIVERY] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ✅ Mettre à jour le statut d'une livraison
|
|
* PUT /api/v1/livreur/deliveries/:id/status
|
|
*/
|
|
export const updateDeliveryStatus = async (
|
|
deliveryId: number,
|
|
status: string,
|
|
latitude: number,
|
|
longitude: number,
|
|
): Promise<{ success: boolean; message?: string; error?: string }> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log(
|
|
"📝 [UPDATE_DELIVERY_STATUS] Appel API:",
|
|
deliveryId,
|
|
status,
|
|
);
|
|
|
|
const response = await fetch(
|
|
`${API_URL}/deliveries/${deliveryId}/status`,
|
|
{
|
|
method: "PUT",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
body: JSON.stringify({ status, latitude, longitude }),
|
|
},
|
|
);
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [UPDATE_DELIVERY_STATUS] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [UPDATE_DELIVERY_STATUS] Réponse:", data);
|
|
|
|
return {
|
|
success: true,
|
|
message: data.message,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [UPDATE_DELIVERY_STATUS] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
// ============================================
|
|
// 📍 POSITION GPS
|
|
// ============================================
|
|
|
|
/**
|
|
* ✅ Mettre à jour la position GPS du livreur
|
|
* POST /api/v1/livreur/location/update
|
|
*/
|
|
export const updateMyLocation = async (
|
|
latitude: number,
|
|
longitude: number,
|
|
): Promise<{
|
|
success: boolean;
|
|
message?: string;
|
|
status?: string;
|
|
error?: string;
|
|
}> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(`${API_URL}/location/update`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
body: JSON.stringify({ latitude, longitude }),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [UPDATE_MY_LOCATION] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
message: data.message,
|
|
status: data.status,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [UPDATE_MY_LOCATION] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ✅ Récupérer la position actuelle du livreur
|
|
* GET /api/v1/livreur/location
|
|
*/
|
|
export const getMyLocation = async (): Promise<{
|
|
success: boolean;
|
|
latitude?: number;
|
|
longitude?: number;
|
|
error?: string;
|
|
}> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(`${API_URL}/location`, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [GET_MY_LOCATION] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
latitude: data.latitude,
|
|
longitude: data.longitude,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [GET_MY_LOCATION] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
// ============================================
|
|
// 🚨 ALERTES POLICE
|
|
// ============================================
|
|
|
|
/**
|
|
* ✅ Déclencher une alerte police
|
|
* POST /api/v1/livreur/alert
|
|
*/
|
|
export const triggerPoliceAlert = async (): Promise<{
|
|
success: boolean;
|
|
alert_id?: number;
|
|
message?: string;
|
|
error?: string;
|
|
}> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log("🚨 [TRIGGER_POLICE_ALERT] Déclenchement alerte police");
|
|
|
|
const response = await fetch(`${API_URL}/alert`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [TRIGGER_POLICE_ALERT] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [TRIGGER_POLICE_ALERT] Alerte créée:", data);
|
|
|
|
return {
|
|
success: true,
|
|
alert_id: data.alert_id,
|
|
message: data.message,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [TRIGGER_POLICE_ALERT] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ✅ Mettre fin à une alerte
|
|
* DELETE /api/v1/livreur/alert/:id
|
|
*/
|
|
export const endAlert = async (
|
|
alertId: number,
|
|
): Promise<{
|
|
success: boolean;
|
|
message?: string;
|
|
error?: string;
|
|
}> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log("🔚 [END_ALERT] Terminer alerte:", alertId);
|
|
|
|
const response = await fetch(`${API_URL}/alert/${alertId}`, {
|
|
method: "DELETE",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [END_ALERT] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [END_ALERT] Alerte terminée:", data);
|
|
|
|
return {
|
|
success: true,
|
|
message: data.message,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [END_ALERT] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ✅ Récupérer toutes mes alertes
|
|
* GET /api/v1/livreur/alerts
|
|
*/
|
|
export const getMyAlerts = async (): Promise<{
|
|
success: boolean;
|
|
alerts?: Alert[];
|
|
count?: number;
|
|
error?: string;
|
|
}> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log("🔍 [GET_MY_ALERTS] Récupération alertes");
|
|
|
|
const response = await fetch(`${API_URL}/alerts`, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [GET_MY_ALERTS] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [GET_MY_ALERTS] Alertes récupérées:", data);
|
|
|
|
return {
|
|
success: true,
|
|
alerts: data.alerts || [],
|
|
count: data.count || 0,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [GET_MY_ALERTS] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ✅ Récupérer les détails d'une alerte
|
|
* GET /api/v1/livreur/alert/:id
|
|
*/
|
|
export const getAlertDetails = async (
|
|
alertId: number,
|
|
): Promise<{
|
|
success: boolean;
|
|
alert?: Alert;
|
|
error?: string;
|
|
}> => {
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
return { success: false, error: "Token non trouvé" };
|
|
}
|
|
|
|
try {
|
|
console.log("🔍 [GET_ALERT_DETAILS] Récupération alerte:", alertId);
|
|
|
|
const response = await fetch(`${API_URL}/alert/${alertId}`, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
console.error("❌ [GET_ALERT_DETAILS] Erreur API:", data);
|
|
return { success: false, error: data.error };
|
|
}
|
|
|
|
console.log("✅ [GET_ALERT_DETAILS] Alerte récupérée:", data);
|
|
|
|
return {
|
|
success: true,
|
|
alert: data.alert,
|
|
};
|
|
} catch (error) {
|
|
console.error("❌ [GET_ALERT_DETAILS] Erreur fetch:", error);
|
|
return { success: false, error: "Erreur réseau" };
|
|
}
|
|
};
|
|
|
|
// ============================================
|
|
// 🔄 EXPORT PAR DÉFAUT
|
|
// ============================================
|
|
|
|
export default {
|
|
// Statut
|
|
getMyStatus,
|
|
updateMyStatus,
|
|
|
|
// Queue
|
|
getMyQueue,
|
|
|
|
// Livraisons
|
|
getMyDeliveries,
|
|
getDeliveryDetails,
|
|
startDelivery,
|
|
updateDeliveryStatus,
|
|
|
|
// Position GPS
|
|
updateMyLocation,
|
|
getMyLocation,
|
|
|
|
// Alertes Police
|
|
triggerPoliceAlert,
|
|
endAlert,
|
|
getMyAlerts,
|
|
getAlertDetails,
|
|
};
|