fix(courts): use club detail courts data instead of separate fetch
continuous-integration/drone/push Build is passing Details

Root cause: GET /admin/clubs/{id}/courts endpoint doesn't include
sport_variation nested structure, but GET /admin/clubs/{id} does.

Changes:
- Updated AdminClubDetail.courts to use Court[] type (includes sport_variation)
- ClubDetailTabs now passes courts + onUpdate callback to ClubCourtsTab
- ClubCourtsTab accepts courts as props instead of fetching separately
- Removed redundant getCourts() API call
- Removed debug logging

This fixes the court edit dropdown issue where sport variation wasn't
displaying because the data wasn't available from the courts endpoint.
master
Guillermo Pages 1 month ago
parent e21581dcd0
commit 86fa2a92e6

@ -205,7 +205,11 @@ export default function ClubDetailTabs({ clubId }: ClubDetailTabsProps) {
)} )}
{activeTab === 'courts' && ( {activeTab === 'courts' && (
<ClubCourtsTab clubId={clubId} /> <ClubCourtsTab
clubId={clubId}
courts={clubDetail.courts}
onUpdate={loadClubDetail}
/>
)} )}
</div> </div>
); );

@ -1,9 +1,8 @@
'use client'; 'use client';
import { useState, useEffect } from 'react'; import { useState } from 'react';
import { Loader2, AlertCircle, Plus, Edit, Trash2, AlertTriangle, X } from 'lucide-react'; import { Loader2, AlertCircle, Plus, Edit, Trash2, AlertTriangle, X } from 'lucide-react';
import { import {
getCourts,
createCourt, createCourt,
updateCourt, updateCourt,
deleteCourt, deleteCourt,
@ -15,11 +14,11 @@ import { formatTimestamp } from '@/src/types/courts';
interface ClubCourtsTabProps { interface ClubCourtsTabProps {
clubId: number; clubId: number;
courts: Court[];
onUpdate: () => void;
} }
export default function ClubCourtsTab({ clubId }: ClubCourtsTabProps) { export default function ClubCourtsTab({ clubId, courts, onUpdate }: ClubCourtsTabProps) {
const [courts, setCourts] = useState<Court[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
// Modal state // Modal state
@ -31,24 +30,6 @@ export default function ClubCourtsTab({ clubId }: ClubCourtsTabProps) {
const [selectedCourt, setSelectedCourt] = useState<Court | null>(null); const [selectedCourt, setSelectedCourt] = useState<Court | null>(null);
const [dependencies, setDependencies] = useState<CourtDependencies | null>(null); const [dependencies, setDependencies] = useState<CourtDependencies | null>(null);
useEffect(() => {
loadCourts();
}, [clubId]);
async function loadCourts() {
setLoading(true);
const result = await getCourts(clubId);
if (result.success) {
setCourts(result.data);
setError(null);
} else {
setError(result.error.detail);
}
setLoading(false);
}
function handleAdd() { function handleAdd() {
setShowAddModal(true); setShowAddModal(true);
} }
@ -88,20 +69,11 @@ export default function ClubCourtsTab({ clubId }: ClubCourtsTabProps) {
setDependencies(null); setDependencies(null);
} }
async function handleSuccess() { function handleSuccess() {
await loadCourts(); onUpdate(); // Trigger parent to refresh club detail (which includes courts)
closeModals(); closeModals();
} }
// Loading state
if (loading) {
return (
<div className="flex items-center justify-center py-20">
<Loader2 className="w-8 h-8 text-slate-600 animate-spin" />
</div>
);
}
// Error state // Error state
if (error && courts.length === 0) { if (error && courts.length === 0) {
return ( return (
@ -262,12 +234,6 @@ function CourtFormModal({ clubId, court, onClose, onSuccess }: CourtFormModalPro
const [fieldError, setFieldError] = useState(''); const [fieldError, setFieldError] = useState('');
const [sportVariationError, setSportVariationError] = useState(''); const [sportVariationError, setSportVariationError] = useState('');
// Debug: log the court data and extracted sport variation ID
useEffect(() => {
console.log('Court data:', court);
console.log('Extracted sport_variation_id:', initialSportVariationId);
}, [court]);
useEffect(() => { useEffect(() => {
async function loadSports() { async function loadSports() {
setLoadingSports(true); setLoadingSports(true);

@ -34,7 +34,7 @@ export interface AdminClubDetail {
name: string; name: string;
timezone: string; timezone: string;
}; };
courts: AdminCourt[]; courts: import('./courts').Court[];
slot_definitions: AdminSlotDefinition[]; slot_definitions: AdminSlotDefinition[];
upcoming_slots: AdminSlot[]; upcoming_slots: AdminSlot[];
provider: AdminProviderInfo; provider: AdminProviderInfo;
@ -43,6 +43,7 @@ export interface AdminClubDetail {
export interface AdminCourt { export interface AdminCourt {
court_id: number; court_id: number;
name: string; name: string;
// Deprecated: use Court type from courts.ts which includes sport_variation
} }
export interface AdminSlotDefinition { export interface AdminSlotDefinition {

Loading…
Cancel
Save