fix: update facility detail types to match current API response shape
continuous-integration/drone/push Build is passing Details

The API now returns 'facility' with expanded address/settings fields instead of 'club', and slot types have been restructured to use flat properties instead of nested booking/meta objects.
master
Guillermo Pages 1 month ago
parent 4d9aeb9045
commit 94a1979201

@ -160,11 +160,11 @@ export default function AdminClubDetailComponent({ clubId }: AdminClubDetailProp
</div>
<div className="flex-1">
<h1 className="text-4xl font-bold text-slate-900 mb-3 tracking-tight">
{clubDetail.club.name}
{clubDetail.facility.name}
</h1>
<div className="flex items-center text-slate-600 space-x-2">
<MapPin className="w-5 h-5" />
<span className="text-lg font-medium">{clubDetail.club.timezone}</span>
<span className="text-lg font-medium">{clubDetail.facility.timezone}</span>
</div>
</div>
</div>

@ -160,10 +160,10 @@ export default function ClubDetailTabs({ clubId }: ClubDetailTabsProps) {
{/* Club Header */}
<div className="mb-8">
<h1 className="text-4xl font-bold text-slate-900 mb-2 tracking-tight">
{clubDetail.club.name}
{clubDetail.facility.name}
</h1>
<p className="text-lg text-slate-600 font-light">
{clubDetail.club.timezone}
{clubDetail.facility.timezone}
</p>
</div>

@ -185,10 +185,25 @@ export const MOCK_CLUBS: AdminClubsResponse = [
];
export const MOCK_CLUB_DETAIL: AdminClubDetail = {
club: {
facility: {
facility_id: 1,
name: 'Central Padel Geneva',
timezone: 'Europe/Zurich',
address: {
address_line_1: '123 Main Street',
address_line_2: null,
city: 'Geneva',
zip: '1200',
canton: 'GE',
country: 'Switzerland',
},
settings: {
contact: {
email: 'info@centralpadel.ch',
phone: '+41 22 123 45 67',
website: 'https://centralpadel.ch',
},
},
},
courts: [
{

@ -37,9 +37,9 @@ export async function getClubProfile(clubId: number): Promise<ApiResult<ClubProf
}
const responseData = await response.json();
// Backend returns { club: {...}, courts: [], provider: {...}, ... }
// Extract the club object
const data: ClubProfile = responseData.club;
// Backend returns { facility: {...}, courts: [], provider: {...}, ... }
// Extract the facility object
const data: ClubProfile = responseData.facility;
return { success: true, data };
} catch (error) {
return {

@ -27,12 +27,28 @@ export type AdminClubsResponse = AdminClub[];
/**
* GET /admin/facilities/{club_id} - Detailed facility view
* Based on VENUE_ADMIN_DESIGN.md and Access Avery correction 2025-11-05 12:14 UTC
* Updated: 2025-11-13 to match new API shape
*/
export interface AdminClubDetail {
club: {
facility: {
facility_id: number;
name: string;
timezone: string;
address: {
address_line_1: string | null;
address_line_2: string | null;
city: string | null;
zip: string | null;
canton: string | null;
country: string | null;
};
settings: {
contact: {
email: string | null;
phone: string | null;
website: string | null;
};
};
};
courts: import('./courts').Court[];
slot_definitions: AdminSlotDefinition[];
@ -55,39 +71,23 @@ export interface AdminSlotDefinition {
capacity: number;
valid_from: string; // Date string "YYYY-MM-DD"
valid_to: string | null; // Date string or null
rule: Record<string, any>; // Slot generation rules (JSONB)
created_at: string; // ISO 8601 timestamp
updated_at: string; // ISO 8601 timestamp
}
export interface AdminSlot {
slot_id: number; // slot_instance_id
slot_instance_id: number;
court_id: number;
court_name: string;
facility_id: number;
starts_at: string; // ISO 8601 timestamp
ends_at: string; // ISO 8601 timestamp
booking: AdminSlotBooking;
meta: AdminSlotMeta;
updated_at: string; // ISO 8601 timestamp
etag: string;
}
export interface AdminSlotBooking {
available: boolean; // Mapped from status
status: 'available' | 'pending' | 'booked' | 'cancelled';
capacity: number;
booked_count: number;
players: AdminPlayer[];
}
export interface AdminPlayer {
display_name: string;
app_user_id?: number; // Optional for guests
position: number;
is_guest: boolean;
}
export interface AdminSlotMeta {
tags?: string[]; // Optional annotations like ["maintenance"]
provider: 'local' | 'fairplay';
status: string; // e.g., "cancelled", "available", "booked"
display_status: string; // e.g., "cancelled"
reason?: string | null; // e.g., "materialiser_retired"
source: string; // e.g., "internal"
}
export interface AdminProviderInfo {

Loading…
Cancel
Save