"use client"; import { useState, useEffect } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Building2, MapPin, Users, Clock, DollarSign, Save, Plus, Pencil, Trash2, X, } from "lucide-react"; interface Site { id: string; name: string; address: string; phone: string | null; openTime: string; closeTime: string; isActive: boolean; } interface Court { id: string; name: string; type: string; hourlyRate: number; peakHourlyRate: number | null; status: string; siteId: string; site?: { name: string }; isOpenPlay?: boolean; } interface User { id: string; email: string; firstName: string; lastName: string; role: string; isActive: boolean; site?: { name: string } | null; } export default function SettingsPage() { const [activeTab, setActiveTab] = useState("organization"); const [loading, setLoading] = useState(false); const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null); // Organization state const [orgName, setOrgName] = useState("SmashPoint Demo"); const [orgEmail, setOrgEmail] = useState("info@smashpoint.com"); const [orgPhone, setOrgPhone] = useState("+52 555 123 4567"); const [currency, setCurrency] = useState("MXN"); const [timezone, setTimezone] = useState("America/Mexico_City"); // Sites state const [sites, setSites] = useState([]); const [loadingSites, setLoadingSites] = useState(true); const [editingSite, setEditingSite] = useState(null); const [showSiteForm, setShowSiteForm] = useState(false); // Courts state const [courts, setCourts] = useState([]); const [loadingCourts, setLoadingCourts] = useState(true); const [editingCourt, setEditingCourt] = useState(null); const [showCourtForm, setShowCourtForm] = useState(false); // Users state const [users, setUsers] = useState([]); const [loadingUsers, setLoadingUsers] = useState(true); useEffect(() => { fetchSites(); fetchCourts(); fetchUsers(); }, []); const fetchSites = async () => { try { const res = await fetch("/api/sites"); if (res.ok) { const data = await res.json(); setSites(data.data || []); } } catch (error) { console.error("Error fetching sites:", error); } finally { setLoadingSites(false); } }; const fetchCourts = async () => { try { const res = await fetch("/api/courts"); if (res.ok) { const data = await res.json(); // Courts API returns array directly, map pricePerHour to hourlyRate for frontend const courtsArray = Array.isArray(data) ? data : data.data || []; setCourts(courtsArray.map((c: Record) => ({ ...c, hourlyRate: c.pricePerHour ?? c.hourlyRate, }))); } } catch (error) { console.error("Error fetching courts:", error); } finally { setLoadingCourts(false); } }; const fetchUsers = async () => { try { const res = await fetch("/api/users"); if (res.ok) { const data = await res.json(); setUsers(data.data || []); } } catch (error) { console.error("Error fetching users:", error); } finally { setLoadingUsers(false); } }; const handleSaveOrganization = async () => { setLoading(true); // Simulate save await new Promise((resolve) => setTimeout(resolve, 500)); setMessage({ type: "success", text: "Settings saved successfully" }); setLoading(false); setTimeout(() => setMessage(null), 3000); }; const handleSaveSite = async (site: Partial) => { setLoading(true); try { const method = editingSite ? "PUT" : "POST"; const url = editingSite ? `/api/sites/${editingSite.id}` : "/api/sites"; const res = await fetch(url, { method, headers: { "Content-Type": "application/json" }, body: JSON.stringify(site), }); if (res.ok) { setMessage({ type: "success", text: editingSite ? "Site updated" : "Site created" }); fetchSites(); setShowSiteForm(false); setEditingSite(null); } else { setMessage({ type: "error", text: "Error saving site" }); } } catch (error) { setMessage({ type: "error", text: "Connection error" }); } finally { setLoading(false); setTimeout(() => setMessage(null), 3000); } }; const handleSaveCourt = async (court: Partial) => { setLoading(true); try { const method = editingCourt ? "PUT" : "POST"; const url = editingCourt ? `/api/courts/${editingCourt.id}` : "/api/courts"; const res = await fetch(url, { method, headers: { "Content-Type": "application/json" }, body: JSON.stringify(court), }); if (res.ok) { setMessage({ type: "success", text: editingCourt ? "Court updated" : "Court created" }); fetchCourts(); setShowCourtForm(false); setEditingCourt(null); } else { setMessage({ type: "error", text: "Error saving court" }); } } catch (error) { setMessage({ type: "error", text: "Connection error" }); } finally { setLoading(false); setTimeout(() => setMessage(null), 3000); } }; const handleDeleteCourt = async (courtId: string) => { if (!confirm("Are you sure you want to delete this court?")) return; try { const res = await fetch(`/api/courts/${courtId}`, { method: "DELETE" }); if (res.ok) { setMessage({ type: "success", text: "Court deleted" }); fetchCourts(); } else { setMessage({ type: "error", text: "Error deleting court" }); } } catch (error) { setMessage({ type: "error", text: "Connection error" }); } setTimeout(() => setMessage(null), 3000); }; return (
{/* Header */}

Settings

Manage system settings

{/* Message */} {message && (
{message.text}
)} {/* Tabs */} Organization Sites Courts Users {/* Organization Tab */} Organization Information
setOrgName(e.target.value)} placeholder="Name" />
setOrgEmail(e.target.value)} placeholder="email@example.com" />
setOrgPhone(e.target.value)} placeholder="+52 555 123 4567" />
Booking Settings
{/* Sites Tab */}

Sites

{loadingSites ? (
{[1, 2, 3].map((i) => (
))}
) : (
{sites.map((site) => (

{site.name}

{site.address}

{site.openTime} - {site.closeTime}

{site.phone && (

{site.phone}

)}
{site.isActive ? "Active" : "Inactive"}
))}
)} {/* Site Form Modal */} {showSiteForm && ( { setShowSiteForm(false); setEditingSite(null); }} loading={loading} /> )} {/* Courts Tab */}

Courts

{loadingCourts ? (
{[1, 2, 3].map((i) => (
))}
) : ( {courts.map((court) => ( ))}
Court Site Type Price/hour Status Actions
{court.name} {court.isOpenPlay && ( Open Play )} {court.site?.name || "-"} {court.type} ${court.hourlyRate} {["active", "AVAILABLE"].includes(court.status) ? "Active" : ["maintenance", "MAINTENANCE"].includes(court.status) ? "Maintenance" : "Inactive"}
)} {/* Court Form Modal */} {showCourtForm && ( { setShowCourtForm(false); setEditingCourt(null); }} loading={loading} /> )} {/* Users Tab */}

Users

{loadingUsers ? (
{[1, 2, 3].map((i) => (
))}
) : ( {users.map((user) => ( ))}
User Email Role Site Status Actions
{user.firstName} {user.lastName} {user.email} {user.role === "super_admin" ? "Super Admin" : user.role === "site_admin" ? "Site Admin" : user.role === "staff" ? "Staff" : user.role} {user.site?.name || "All"} {user.isActive ? "Active" : "Inactive"}
)}
); } // Site Form Modal Component function SiteFormModal({ site, onSave, onClose, loading, }: { site: Site | null; onSave: (site: Partial) => void; onClose: () => void; loading: boolean; }) { const [name, setName] = useState(site?.name || ""); const [address, setAddress] = useState(site?.address || ""); const [phone, setPhone] = useState(site?.phone || ""); const [openTime, setOpenTime] = useState(site?.openTime || "08:00"); const [closeTime, setCloseTime] = useState(site?.closeTime || "22:00"); const [isActive, setIsActive] = useState(site?.isActive ?? true); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onSave({ name, address, phone, openTime, closeTime, isActive }); }; return (

{site ? "Edit Site" : "New Site"}

setName(e.target.value)} required />
setAddress(e.target.value)} required />
setPhone(e.target.value)} />
setOpenTime(e.target.value)} />
setCloseTime(e.target.value)} />
setIsActive(e.target.checked)} className="rounded border-primary-300" />
); } // Court Form Modal Component function CourtFormModal({ court, sites, onSave, onClose, loading, }: { court: Court | null; sites: Site[]; onSave: (court: Partial) => void; onClose: () => void; loading: boolean; }) { const [name, setName] = useState(court?.name || ""); const [siteId, setSiteId] = useState(court?.siteId || sites[0]?.id || ""); const [type, setType] = useState(court?.type || "indoor"); const [hourlyRate, setHourlyRate] = useState(court?.hourlyRate?.toString() || "300"); const [peakHourlyRate, setPeakHourlyRate] = useState(court?.peakHourlyRate?.toString() || ""); const [status, setStatus] = useState(court?.status || "active"); const [isOpenPlay, setIsOpenPlay] = useState(court?.isOpenPlay ?? false); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onSave({ name, siteId, type, hourlyRate: parseFloat(hourlyRate), pricePerHour: parseFloat(hourlyRate), peakHourlyRate: peakHourlyRate ? parseFloat(peakHourlyRate) : null, status, isOpenPlay, } as Partial & { pricePerHour?: number }); }; return (

{court ? "Edit Court" : "New Court"}

setName(e.target.value)} placeholder="Court 1" required />
setHourlyRate(e.target.value)} min="0" required />
setPeakHourlyRate(e.target.value)} min="0" placeholder="Optional" />
setIsOpenPlay(e.target.checked)} className="rounded border-primary-300" />
); }