// Slot Definition Types based on Backend API Contract // Contract: docs/owners/payloads/slot-definition-api-contract.md export type DayOfWeek = 0 | 1 | 2 | 3 | 4 | 5 | 6; // 0=Monday, 6=Sunday export interface SlotDefinitionRule { weekly: boolean; description?: string; } export interface SlotDefinitionRequest { court_id: number; dow: DayOfWeek; starts_at: string; // HH:MM:SS format duration_minutes: number; capacity: number; valid_from: string; // YYYY-MM-DD valid_to?: string; // YYYY-MM-DD, optional rule?: SlotDefinitionRule; } export interface SlotDefinition extends SlotDefinitionRequest { slot_definition_id: number; created_at: string; // ISO 8601 updated_at: string; // ISO 8601 updated_by_app_user_id: number; } export interface ValidationError { field: string; message: string; } export interface SlotDefinitionError { type: string; title: string; status: number; detail: string; code: string; errors?: ValidationError[]; } // Helper constants export const DAY_NAMES: Record = { 0: 'Monday', 1: 'Tuesday', 2: 'Wednesday', 3: 'Thursday', 4: 'Friday', 5: 'Saturday', 6: 'Sunday', }; export const DAY_NAMES_SHORT: Record = { 0: 'Mon', 1: 'Tue', 2: 'Wed', 3: 'Thu', 4: 'Fri', 5: 'Sat', 6: 'Sun', }; // Helper to format time for display export function formatTime(timeStr: string): string { // Convert HH:MM:SS to HH:MM return timeStr.substring(0, 5); } // Helper to format time for API export function formatTimeForAPI(timeStr: string): string { // Ensure HH:MM:SS format if (timeStr.length === 5) { return `${timeStr}:00`; } return timeStr; } // Helper to calculate end time export function calculateEndTime(startTime: string, durationMinutes: number): string { const [hours, minutes] = startTime.split(':').map(Number); const totalMinutes = hours * 60 + minutes + durationMinutes; const endHours = Math.floor(totalMinutes / 60); const endMinutes = totalMinutes % 60; return `${String(endHours).padStart(2, '0')}:${String(endMinutes).padStart(2, '0')}`; }