refactor: remove all mock data flags and conditional logic
continuous-integration/drone/push Build is passing Details

Removed USE_MOCKS and USE_MOCK_DATA flags from all API client functions. All endpoints now call the real backend API directly without conditional mock data paths.

Changes:
- SlotDefinitionsComponent: removed mock flags from loadData() and loadDefinitions()
- materialisation.ts: removed mock conditionals from getMaterialisationStatus() and triggerMaterialisation()
- admin-clubs.ts: removed MaybeMock wrapper functions and USE_MOCK_DATA flag
- courts.ts: removed mock conditionals from all 7 CRUD functions

All API calls now go directly to https://api.playchoo.com backend.
master
Guillermo Pages 1 month ago
parent 45e859694b
commit 6b971d723b

@ -4,7 +4,7 @@ import { useState, useEffect } from 'react';
import { Calendar, Plus, Loader2, AlertCircle, Edit, Trash2, ArrowLeft } from 'lucide-react';
import Link from 'next/link';
import useTranslation from '@/src/hooks/useTranslation';
import { getSlotDefinitions, getMockSlotDefinitions, deleteSlotDefinition } from '@/src/lib/api/slot-definitions';
import { getSlotDefinitions, deleteSlotDefinition } from '@/src/lib/api/slot-definitions';
import type { SlotDefinition, SlotDefinitionError } from '@/src/types/slot-definitions';
import { DAY_NAMES, formatTime, calculateEndTime } from '@/src/types/slot-definitions';
import { getAdminClubDetail } from '@/src/lib/api/admin-clubs';
@ -38,18 +38,6 @@ export default function SlotDefinitionsComponent({ clubId }: SlotDefinitionsComp
setCourts(clubResult.data.courts);
}
// Use mock data for now (until backend is ready)
const USE_MOCKS = true;
if (USE_MOCKS) {
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 500));
setDefinitions(getMockSlotDefinitions());
setError(null);
setLoading(false);
return;
}
const result = await getSlotDefinitions(clubId);
if (result.success) {
setDefinitions(result.data);
@ -63,14 +51,6 @@ export default function SlotDefinitionsComponent({ clubId }: SlotDefinitionsComp
async function loadDefinitions() {
// Reload just definitions (for after create/edit/delete)
const USE_MOCKS = true;
if (USE_MOCKS) {
await new Promise(resolve => setTimeout(resolve, 300));
setDefinitions(getMockSlotDefinitions());
return;
}
const result = await getSlotDefinitions(clubId);
if (result.success) {
setDefinitions(result.data);

@ -198,35 +198,3 @@ export const MOCK_CLUB_DETAIL: AdminClubDetail = {
},
};
// ============================================================================
// Development Helper
// ============================================================================
/**
* Toggle to use mock data for local development
* Set to false once staging stubs are available
*/
const USE_MOCK_DATA = true;
/**
* Wrapper that returns mock or real data based on USE_MOCK_DATA flag
*/
export async function getAdminClubsMaybeMock(): Promise<AdminApiResult<AdminClubsResponse>> {
if (USE_MOCK_DATA && process.env.NODE_ENV === 'development') {
// Simulate network delay
await new Promise((resolve) => setTimeout(resolve, 500));
return { success: true, data: MOCK_CLUBS };
}
return getAdminClubs();
}
export async function getAdminClubDetailMaybeMock(
clubId: number
): Promise<AdminApiResult<AdminClubDetail>> {
if (USE_MOCK_DATA && process.env.NODE_ENV === 'development') {
// Simulate network delay
await new Promise((resolve) => setTimeout(resolve, 500));
return { success: true, data: MOCK_CLUB_DETAIL };
}
return getAdminClubDetail(clubId);
}

@ -29,17 +29,6 @@ type ApiResult<T> =
* Get club profile
*/
export async function getClubProfile(clubId: number): Promise<ApiResult<ClubProfile>> {
// Use mock data for now (until backend is ready)
const USE_MOCKS = false;
if (USE_MOCKS) {
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 300));
const mockProfile = getMockClubProfile(clubId);
return { success: true, data: mockProfile };
}
try {
const response = await fetch(`${API_BASE_URL}/admin/clubs/${clubId}`, {
method: 'GET',
@ -80,42 +69,6 @@ export async function updateClubProfile(
clubId: number,
request: ClubProfileUpdateRequest
): Promise<ApiResult<ClubProfile>> {
// Use mock data for now (until backend is ready)
const USE_MOCKS = false;
if (USE_MOCKS) {
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 500));
// Simple validation
if (!request.name || request.name.trim().length === 0) {
return {
success: false,
error: {
type: 'about:blank',
title: 'Validation Error',
status: 400,
detail: 'One or more fields failed validation',
code: 'validation_error',
errors: [
{
field: 'name',
message: 'Name is required',
},
],
},
};
}
const mockProfile: ClubProfile = {
...getMockClubProfile(clubId),
...request,
updated_at: new Date().toISOString(),
};
return { success: true, data: mockProfile };
}
try {
const response = await fetch(`${API_BASE_URL}/admin/clubs/${clubId}`, {
method: 'PATCH',
@ -151,17 +104,6 @@ export async function updateClubProfile(
* Get courts for a club
*/
export async function getCourts(clubId: number): Promise<ApiResult<Court[]>> {
// Use mock data for now (until backend is ready)
const USE_MOCKS = false;
if (USE_MOCKS) {
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 300));
const mockCourts = getMockCourts(clubId);
return { success: true, data: mockCourts };
}
try {
const response = await fetch(`${API_BASE_URL}/admin/clubs/${clubId}/courts`, {
method: 'GET',
@ -199,61 +141,6 @@ export async function createCourt(
clubId: number,
request: CourtRequest
): Promise<ApiResult<Court>> {
// Use mock data for now (until backend is ready)
const USE_MOCKS = false;
if (USE_MOCKS) {
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 500));
// Simple validation
if (!request.name || request.name.trim().length === 0) {
return {
success: false,
error: {
type: 'about:blank',
title: 'Validation Error',
status: 400,
detail: 'Court name is required',
code: 'validation_error',
errors: [
{
field: 'name',
message: 'Court name is required',
},
],
},
};
}
// Check for duplicate name (in mock data)
const existingCourts = getMockCourts(clubId);
if (existingCourts.some(c => c.name.toLowerCase() === request.name.trim().toLowerCase())) {
return {
success: false,
error: {
type: 'about:blank',
title: 'Duplicate Court Name',
status: 409,
detail: `A court with the name '${request.name}' already exists for this club`,
code: 'court_name_duplicate',
},
};
}
const newCourt: Court = {
court_id: Math.max(...existingCourts.map(c => c.court_id), 100) + 1,
name: request.name.trim(),
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
};
// Add to mock data (in-memory only)
mockCourtsData.push(newCourt);
return { success: true, data: newCourt };
}
try {
const response = await fetch(`${API_BASE_URL}/admin/clubs/${clubId}/courts`, {
method: 'POST',
@ -293,77 +180,6 @@ export async function updateCourt(
courtId: number,
request: CourtRequest
): Promise<ApiResult<Court>> {
// Use mock data for now (until backend is ready)
const USE_MOCKS = false;
if (USE_MOCKS) {
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 500));
// Simple validation
if (!request.name || request.name.trim().length === 0) {
return {
success: false,
error: {
type: 'about:blank',
title: 'Validation Error',
status: 400,
detail: 'Court name is required',
code: 'validation_error',
errors: [
{
field: 'name',
message: 'Court name is required',
},
],
},
};
}
// Check for duplicate name (excluding current court)
const existingCourts = getMockCourts(clubId);
if (existingCourts.some(c => c.court_id !== courtId && c.name.toLowerCase() === request.name.trim().toLowerCase())) {
return {
success: false,
error: {
type: 'about:blank',
title: 'Duplicate Court Name',
status: 409,
detail: `A court with the name '${request.name}' already exists for this club`,
code: 'court_name_duplicate',
},
};
}
const court = existingCourts.find(c => c.court_id === courtId);
if (!court) {
return {
success: false,
error: {
type: 'about:blank',
title: 'Court Not Found',
status: 404,
detail: 'Court not found',
code: 'court_not_found',
},
};
}
const updatedCourt: Court = {
...court,
name: request.name.trim(),
updated_at: new Date().toISOString(),
};
// Update in mock data (in-memory only)
const index = mockCourtsData.findIndex(c => c.court_id === courtId);
if (index !== -1) {
mockCourtsData[index] = updatedCourt;
}
return { success: true, data: updatedCourt };
}
try {
const response = await fetch(`${API_BASE_URL}/admin/clubs/${clubId}/courts/${courtId}`, {
method: 'PATCH',
@ -402,35 +218,6 @@ export async function getCourtDependencies(
clubId: number,
courtId: number
): Promise<ApiResult<CourtDependencies>> {
// Use mock data for now (until backend is ready)
const USE_MOCKS = false;
if (USE_MOCKS) {
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 300));
// Mock dependencies - first court has dependencies, others don't
const mockDeps: CourtDependencies = courtId === 101 ? {
court_id: courtId,
can_delete: false,
dependencies: {
slot_definitions: 12,
slot_instances_future: 34,
slot_instances_booked: 11,
},
} : {
court_id: courtId,
can_delete: true,
dependencies: {
slot_definitions: 0,
slot_instances_future: 0,
slot_instances_booked: 0,
},
};
return { success: true, data: mockDeps };
}
try {
const response = await fetch(`${API_BASE_URL}/admin/clubs/${clubId}/courts/${courtId}/dependencies`, {
method: 'GET',
@ -468,38 +255,6 @@ export async function deleteCourt(
clubId: number,
courtId: number
): Promise<ApiResult<void>> {
// Use mock data for now (until backend is ready)
const USE_MOCKS = false;
if (USE_MOCKS) {
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 500));
// Check dependencies first
const depsResult = await getCourtDependencies(clubId, courtId);
if (depsResult.success && !depsResult.data.can_delete) {
return {
success: false,
error: {
type: 'about:blank',
title: 'Court Has Dependencies',
status: 409,
detail: 'Cannot delete court because it is referenced by slot definitions or upcoming bookings',
code: 'court_has_dependencies',
dependencies: depsResult.data.dependencies,
},
};
}
// Remove from mock data (in-memory only)
const index = mockCourtsData.findIndex(c => c.court_id === courtId);
if (index !== -1) {
mockCourtsData.splice(index, 1);
}
return { success: true, data: undefined };
}
try {
const response = await fetch(`${API_BASE_URL}/admin/clubs/${clubId}/courts/${courtId}`, {
method: 'DELETE',

@ -28,17 +28,6 @@ type ApiResult<T> =
export async function getMaterialisationStatus(
clubId: number
): Promise<ApiResult<MaterialisationStatus>> {
// Use mock data for now (until backend is ready)
const USE_MOCKS = false;
if (USE_MOCKS) {
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 300));
const mockStatus = getMockMaterialisationStatus();
return { success: true, data: mockStatus };
}
try {
const response = await fetch(`${API_BASE_URL}/admin/clubs/${clubId}/materialisation-status`, {
method: 'GET',
@ -76,17 +65,6 @@ export async function triggerMaterialisation(
clubId: number,
request: MaterialisationTriggerRequest
): Promise<ApiResult<MaterialisationTriggerResponse>> {
// Use mock data for now (until backend is ready)
const USE_MOCKS = false;
if (USE_MOCKS) {
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 500));
const mockResponse = getMockTriggerResponse();
return { success: true, data: mockResponse };
}
try {
const response = await fetch(`${API_BASE_URL}/admin/clubs/${clubId}/slot-materialize`, {
method: 'POST',

Loading…
Cancel
Save