mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 00:52:50 +00:00
197 lines
5.8 KiB
TypeScript
197 lines
5.8 KiB
TypeScript
import { apiClient } from '@/lib/api-client';
|
|
import { DashboardStats, RevenueData } from '@/types';
|
|
|
|
export const dashboardApi = {
|
|
getBackofficeStats: async () => {
|
|
const response = await apiClient.get<{
|
|
totalBookings: number;
|
|
totalNormalBookings: number;
|
|
totalPackageBookings: number;
|
|
totalTickets: number;
|
|
totalNormalTickets: number;
|
|
totalPackageTickets: number;
|
|
totalPassengers: number;
|
|
revenueByCurrency: { currency: string; totalMinor: number }[];
|
|
packageRevenueByCurrency: { currency: string; totalMinor: number }[];
|
|
}>('/dashboard/backoffice-stats');
|
|
return response;
|
|
},
|
|
|
|
getStats: async () => {
|
|
try {
|
|
// Fetch bookings and passengers data in parallel
|
|
const [bookingsRes, passengersRes] = await Promise.all([
|
|
apiClient.get<any>('/bookings?pageSize=1'),
|
|
apiClient.get<any>('/passengers?pageSize=1'),
|
|
]);
|
|
|
|
const bookingsTotal = bookingsRes?.meta?.total || 0;
|
|
const passengersTotal = passengersRes?.meta?.total || 0;
|
|
|
|
// Calculate revenue from confirmed bookings only
|
|
const confirmedRes = await apiClient.get<any>('/bookings?pageSize=1000&status=CONFIRMED');
|
|
const boardedRes = await apiClient.get<any>('/bookings?pageSize=1000&status=BOARDED');
|
|
const paidBookings = [
|
|
...(Array.isArray(confirmedRes) ? confirmedRes : confirmedRes?.items || []),
|
|
...(Array.isArray(boardedRes) ? boardedRes : boardedRes?.items || []),
|
|
];
|
|
const totalRevenue = paidBookings.reduce((sum: number, b: any) => sum + (b.totalMinor || 0), 0);
|
|
|
|
// Calculate average occupancy (placeholder - would need dedicated endpoint)
|
|
const occupancyRate = Math.floor(Math.random() * 100); // Replace with actual data
|
|
|
|
return {
|
|
totalBookings: bookingsTotal,
|
|
totalRevenue: totalRevenue,
|
|
totalPassengers: passengersTotal,
|
|
occupancyRate: occupancyRate,
|
|
totalTripsToday: 0,
|
|
activeTrips: 0,
|
|
cancelledBookings: 0,
|
|
averageTicketPrice: paidBookings.length > 0 ? Math.round(totalRevenue / paidBookings.length) : 0,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
totalBookings: 0,
|
|
totalRevenue: 0,
|
|
totalPassengers: 0,
|
|
occupancyRate: 0,
|
|
totalTripsToday: 0,
|
|
activeTrips: 0,
|
|
cancelledBookings: 0,
|
|
averageTicketPrice: 0,
|
|
};
|
|
}
|
|
},
|
|
|
|
getRevenueChart: async (days: number = 30) => {
|
|
try {
|
|
const response = await apiClient.get<RevenueData[]>(`/dashboard/revenue?days=${days}`);
|
|
return response;
|
|
} catch (error) {
|
|
return [];
|
|
}
|
|
},
|
|
|
|
getRecentBookings: async (limit: number = 10) => {
|
|
try {
|
|
const response = await apiClient.get<any>(`/bookings?pageSize=${limit}`);
|
|
// Extract items from paginated response
|
|
const bookings = Array.isArray(response) ? response : response?.items || [];
|
|
|
|
return bookings.map((booking: any) => ({
|
|
id: booking.id,
|
|
bookingRef: booking.bookingRef,
|
|
status: booking.status,
|
|
totalMinor: booking.totalMinor,
|
|
currency: booking.currency || 'ETB',
|
|
displayCurrency: booking.displayCurrency,
|
|
displayTotalMinor: booking.displayTotalMinor,
|
|
contactEmail: booking.contactEmail,
|
|
contactPhone: booking.contactPhone,
|
|
createdAt: booking.createdAt,
|
|
passenger: booking.passenger ? {
|
|
id: booking.passenger.id,
|
|
fullName: booking.passenger.fullName,
|
|
email: booking.passenger.email,
|
|
} : null,
|
|
schedule: booking.schedule,
|
|
paymentIntent: booking.paymentIntent,
|
|
}));
|
|
} catch (error) {
|
|
return [];
|
|
}
|
|
},
|
|
|
|
getTopAgents: async (limit: number = 5) => {
|
|
try {
|
|
const response = await apiClient.get<any[]>(`/agents/top?limit=${limit}`);
|
|
return response || [];
|
|
} catch (error) {
|
|
return [];
|
|
}
|
|
},
|
|
|
|
getOccupancyTrend: async (days: number = 7) => {
|
|
try {
|
|
const response = await apiClient.get<any[]>(`/dashboard/occupancy?days=${days}`);
|
|
return response || [];
|
|
} catch (error) {
|
|
return [];
|
|
}
|
|
},
|
|
|
|
getUpcomingTrips: async (limit: number = 5) => {
|
|
try {
|
|
const response = await apiClient.get<any[]>(`/schedules/upcoming?limit=${limit}`);
|
|
return response || [];
|
|
} catch (error) {
|
|
return [];
|
|
}
|
|
},
|
|
|
|
getPaymentMethods: async () => {
|
|
try {
|
|
const response = await apiClient.get<any[]>('/dashboard/payment-methods');
|
|
return response || [];
|
|
} catch (error) {
|
|
return [];
|
|
}
|
|
},
|
|
|
|
getPassengerStats: async () => {
|
|
try {
|
|
const response = await apiClient.get<any>('/dashboard/passenger-stats');
|
|
return response || {
|
|
totalPassengers: 0,
|
|
newPassengersToday: 0,
|
|
activePassengers: 0,
|
|
loyaltyPoints: 0,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
totalPassengers: 0,
|
|
newPassengersToday: 0,
|
|
activePassengers: 0,
|
|
loyaltyPoints: 0,
|
|
};
|
|
}
|
|
},
|
|
|
|
getTransactionSummary: async (days: number = 30) => {
|
|
try {
|
|
const response = await apiClient.get<any>(`/dashboard/transactions?days=${days}`);
|
|
return response || {
|
|
totalTransactions: 0,
|
|
successfulTransactions: 0,
|
|
failedTransactions: 0,
|
|
totalAmount: 0,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
totalTransactions: 0,
|
|
successfulTransactions: 0,
|
|
failedTransactions: 0,
|
|
totalAmount: 0,
|
|
};
|
|
}
|
|
},
|
|
|
|
getLiveMetrics: async () => {
|
|
try {
|
|
const response = await apiClient.get<any>('/dashboard/live-metrics');
|
|
return response || {
|
|
onlineUsers: 0,
|
|
activeBookings: 0,
|
|
activePayments: 0,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
onlineUsers: 0,
|
|
activeBookings: 0,
|
|
activePayments: 0,
|
|
};
|
|
}
|
|
},
|
|
};
|