feat: add court session and live courts API routes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ivan
2026-03-02 03:54:38 +00:00
parent f521eeb698
commit 09518c5335
3 changed files with 380 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { db } from '@/lib/db';
// GET /api/live - Get complete live court status
export async function GET(request: NextRequest) {
try {
const session = await getServerSession(authOptions);
if (!session?.user) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
);
}
const { searchParams } = new URL(request.url);
const siteId = searchParams.get('siteId');
// Build where clause for courts
const courtWhere: {
isActive: boolean;
site: { organizationId: string; id?: string };
} = {
isActive: true,
site: {
organizationId: session.user.organizationId,
},
};
if (siteId) {
courtWhere.site.id = siteId;
} else if (session.user.siteId) {
courtWhere.site.id = session.user.siteId;
}
const now = new Date();
const endOfHour = new Date(now.getTime() + 30 * 60 * 1000); // 30 minutes from now
// Get all courts with their active sessions AND current bookings
const courts = await db.court.findMany({
where: courtWhere,
include: {
sessions: {
where: { isActive: true },
include: {
client: { select: { id: true, firstName: true, lastName: true, phone: true } },
},
},
bookings: {
where: {
startTime: { lte: endOfHour },
endTime: { gte: now },
status: { in: ['CONFIRMED', 'PENDING'] },
},
include: {
client: { select: { id: true, firstName: true, lastName: true } },
},
},
site: { select: { id: true, name: true } },
},
orderBy: { displayOrder: 'asc' },
});
// Compute status for each court
const courtsWithStatus = courts.map((court) => {
let status: 'available' | 'active' | 'open-play' | 'booked';
if (court.sessions.length > 0) {
// Court has active sessions
if (court.isOpenPlay) {
status = 'open-play';
} else {
status = 'active';
}
} else if (court.bookings.length > 0) {
status = 'booked';
} else {
status = 'available';
}
return {
...court,
status,
};
});
return NextResponse.json(courtsWithStatus);
} catch (error) {
console.error('Error fetching live court status:', error);
return NextResponse.json(
{ error: 'Error fetching live court status' },
{ status: 500 }
);
}
}