Add admin portal
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { db } from '@/lib/prisma';
|
||||
|
||||
type ComplexStats = {
|
||||
id: string;
|
||||
complexName: string;
|
||||
complexSlug: string;
|
||||
city: string | null;
|
||||
planCode: string | null;
|
||||
planName: string | null;
|
||||
userCount: number;
|
||||
courtCount: number;
|
||||
totalBookings: number;
|
||||
avgBookingsPerDay: number;
|
||||
bookingsByStatus: {
|
||||
confirmed: number;
|
||||
cancelled: number;
|
||||
completed: number;
|
||||
noshow: number;
|
||||
};
|
||||
paymentStatus: 'active' | 'no_plan' | 'expired';
|
||||
};
|
||||
|
||||
export async function getComplexStatsList(): Promise<ComplexStats[]> {
|
||||
const complexes = await db.complex.findMany({
|
||||
include: {
|
||||
plan: true,
|
||||
users: true,
|
||||
courts: {
|
||||
include: {
|
||||
bookings: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return complexes.map((complex) => {
|
||||
const courtCount = complex.courts.length;
|
||||
const allBookings = complex.courts.flatMap((c) => c.bookings);
|
||||
|
||||
const bookingsByStatus = {
|
||||
confirmed: allBookings.filter((b) => b.status === 'CONFIRMED').length,
|
||||
cancelled: allBookings.filter((b) => b.status === 'CANCELLED').length,
|
||||
completed: allBookings.filter((b) => b.status === 'COMPLETED').length,
|
||||
noshow: allBookings.filter((b) => b.status === 'NOSHOW').length,
|
||||
};
|
||||
|
||||
const totalBookings = allBookings.length;
|
||||
|
||||
let avgBookingsPerDay = 0;
|
||||
if (allBookings.length > 0) {
|
||||
const dates = allBookings.map((b) => b.bookingDate);
|
||||
const minDate = new Date(Math.min(...dates.map((d) => d.getTime())));
|
||||
const daysDiff = Math.max(
|
||||
1,
|
||||
Math.ceil((Date.now() - minDate.getTime()) / (1000 * 60 * 60 * 24))
|
||||
);
|
||||
avgBookingsPerDay = Math.round((totalBookings / daysDiff) * 100) / 100;
|
||||
}
|
||||
|
||||
let paymentStatus: 'active' | 'no_plan' | 'expired' = 'no_plan';
|
||||
if (complex.plan) {
|
||||
paymentStatus = 'active';
|
||||
}
|
||||
|
||||
return {
|
||||
id: complex.id,
|
||||
complexName: complex.complexName,
|
||||
complexSlug: complex.complexSlug,
|
||||
city: complex.city,
|
||||
planCode: complex.planCode,
|
||||
planName: complex.plan?.name ?? null,
|
||||
userCount: complex.users.length,
|
||||
courtCount,
|
||||
totalBookings,
|
||||
avgBookingsPerDay,
|
||||
bookingsByStatus,
|
||||
paymentStatus,
|
||||
};
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user