'use client'; import { useState, useEffect } from 'react'; import { Loader2, AlertCircle, CheckCircle, Info, Pencil } from 'lucide-react'; import { getClubProfile, updateClubProfile } from '@/src/lib/api/courts'; import type { ClubProfile, ClubProfileUpdateRequest} from '@/src/types/courts'; import { COMMON_TIMEZONES, isValidEmail, isValidUrl } from '@/src/types/courts'; /** * Editable Field Component - Click to edit with pencil icon */ interface EditableFieldProps { fieldName: string; value: string; onChange: (value: string) => void; isEditing: boolean; onToggleEdit: () => void; placeholder?: string; maxLength?: number; type?: 'text' | 'email' | 'tel' | 'url'; error?: string; disabled?: boolean; } function EditableField({ fieldName, value, onChange, isEditing, onToggleEdit, placeholder, maxLength, type = 'text', error, disabled = false, }: EditableFieldProps) { const hasValue = value.trim().length > 0; if (isEditing || !hasValue) { return ( onChange(e.target.value)} onBlur={() => hasValue && onToggleEdit()} autoFocus placeholder={placeholder} maxLength={maxLength} className={`w-full px-4 py-3 border-2 rounded-lg font-medium transition-colors ${ error ? 'border-red-300 focus:border-red-500' : 'border-slate-200 focus:border-slate-900' } focus:outline-none`} disabled={disabled} /> ); } return (
{value}
); } interface ClubProfileTabProps { clubId: number; onUpdate?: () => void; } export default function ClubProfileTab({ clubId, onUpdate }: ClubProfileTabProps) { const [profile, setProfile] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); const [errors, setErrors] = useState>({}); // Form state const [name, setName] = useState(''); const [timezone, setTimezone] = useState(''); const [addressLine1, setAddressLine1] = useState(''); const [addressLine2, setAddressLine2] = useState(''); const [city, setCity] = useState(''); const [postalCode, setPostalCode] = useState(''); const [country, setCountry] = useState(''); const [phone, setPhone] = useState(''); const [email, setEmail] = useState(''); const [website, setWebsite] = useState(''); // Edit mode tracking for each field const [editingFields, setEditingFields] = useState>(new Set()); useEffect(() => { loadProfile(); }, [clubId]); async function loadProfile() { setLoading(true); const result = await getClubProfile(clubId); if (result.success) { const prof = result.data; setProfile(prof); // Populate form - read from settings structure setName(prof.name); setTimezone(prof.timezone); setAddressLine1(prof.settings?.address?.line_1 || ''); setAddressLine2(prof.settings?.address?.line_2 || ''); setCity(prof.settings?.address?.city || ''); setPostalCode(prof.settings?.address?.postal_code || ''); setCountry(prof.settings?.address?.country || ''); setPhone(prof.settings?.contact?.phone || ''); setEmail(prof.settings?.contact?.email || ''); setWebsite(prof.settings?.contact?.website || ''); setError(null); } else { setError(result.error.detail); } setLoading(false); } function validateForm(): boolean { const newErrors: Record = {}; if (!name || name.trim().length === 0) { newErrors.name = 'Name is required'; } if (!timezone) { newErrors.timezone = 'Timezone is required'; } if (email && !isValidEmail(email)) { newErrors.email = 'Invalid email format'; } if (website && !isValidUrl(website)) { newErrors.website = 'Invalid URL format (must include http:// or https://)'; } setErrors(newErrors); return Object.keys(newErrors).length === 0; } async function handleSubmit(e: React.FormEvent) { e.preventDefault(); if (!validateForm()) { return; } setSaving(true); setError(null); setSuccess(false); // Build settings structure, preserving existing settings const updatedSettings = { ...profile?.settings, address: { ...profile?.settings?.address, line_1: addressLine1.trim() || undefined, line_2: addressLine2.trim() || undefined, city: city.trim() || undefined, postal_code: postalCode.trim() || undefined, country: country.trim() || undefined, }, contact: { ...profile?.settings?.contact, phone: phone.trim() || undefined, email: email.trim() || undefined, website: website.trim() || undefined, }, }; const request: ClubProfileUpdateRequest = { name: name.trim(), timezone, settings: updatedSettings, }; const result = await updateClubProfile(clubId, request); if (result.success) { setProfile(result.data); setSuccess(true); setError(null); // Call parent update callback if (onUpdate) { onUpdate(); } // Hide success message after 3 seconds setTimeout(() => setSuccess(false), 3000); } else { // Handle validation errors if (result.error.code === 'validation_error' && result.error.errors) { const fieldErrors: Record = {}; result.error.errors.forEach(err => { fieldErrors[err.field] = err.message; }); setErrors(fieldErrors); } else { setError(result.error.detail); } } setSaving(false); } function handleCancel() { if (!profile) return; // Reset form to original values - read from settings structure setName(profile.name); setTimezone(profile.timezone); setAddressLine1(profile.settings?.address?.line_1 || ''); setAddressLine2(profile.settings?.address?.line_2 || ''); setCity(profile.settings?.address?.city || ''); setPostalCode(profile.settings?.address?.postal_code || ''); setCountry(profile.settings?.address?.country || ''); setPhone(profile.settings?.contact?.phone || ''); setEmail(profile.settings?.contact?.email || ''); setWebsite(profile.settings?.contact?.website || ''); setErrors({}); setError(null); setEditingFields(new Set()); } function toggleEditField(fieldName: string) { setEditingFields(prev => { const next = new Set(prev); if (next.has(fieldName)) { next.delete(fieldName); } else { next.add(fieldName); } return next; }); } function isFieldEditing(fieldName: string): boolean { return editingFields.has(fieldName); } function hasFieldValue(value: string): boolean { return value.trim().length > 0; } // Loading state if (loading) { return (
); } // Error state if (error && !profile) { return (

{error}

); } if (!profile) return null; return (
{/* Success message */} {success && (

Profile updated successfully

)} {/* Error message */} {error && (

{error}

)}
{/* Basic Information */}

Basic Information

{/* Name */}
{isFieldEditing('name') || !hasFieldValue(name) ? ( setName(e.target.value)} onBlur={() => hasFieldValue(name) && toggleEditField('name')} autoFocus className={`w-full px-4 py-3 border-2 rounded-lg font-medium transition-colors ${ errors.name ? 'border-red-300 focus:border-red-500' : 'border-slate-200 focus:border-slate-900' } focus:outline-none`} disabled={saving} /> ) : (
toggleEditField('name')} className="flex items-center justify-between px-4 py-3 border-2 border-slate-200 rounded-lg cursor-pointer hover:border-slate-300 hover:bg-slate-50 transition-colors group" > {name}
)} {errors.name && (

{errors.name}

)}
{/* Timezone */}
{isFieldEditing('timezone') ? ( ) : (
toggleEditField('timezone')} className="flex items-center justify-between px-4 py-3 border-2 border-slate-200 rounded-lg cursor-pointer hover:border-slate-300 hover:bg-slate-50 transition-colors group" > {COMMON_TIMEZONES.find(tz => tz.value === timezone)?.label || timezone}
)} {errors.timezone && (

{errors.timezone}

)}
{/* Location */}

Location

Stored in settings until native fields ship
{/* Address Line 1 */}
toggleEditField('addressLine1')} placeholder="123 High Street" maxLength={200} disabled={saving} />
{/* Address Line 2 */}
toggleEditField('addressLine2')} placeholder="Building A" maxLength={200} disabled={saving} />
{/* City & Postal Code */}
toggleEditField('city')} placeholder="London" maxLength={100} disabled={saving} />
toggleEditField('postalCode')} placeholder="SW1A 1AA" maxLength={20} disabled={saving} />
{/* Country */}
toggleEditField('country')} placeholder="United Kingdom" maxLength={100} disabled={saving} />
{/* Contact */}

Contact

Stored in settings until native fields ship
{/* Phone */}
toggleEditField('phone')} placeholder="+44 20 1234 5678" maxLength={50} type="tel" disabled={saving} />
{/* Email */}
toggleEditField('email')} placeholder="info@centralpadel.com" maxLength={100} type="email" error={errors.email} disabled={saving} /> {errors.email && (

{errors.email}

)}
{/* Website */}
toggleEditField('website')} placeholder="https://www.centralpadel.com" maxLength={200} type="url" error={errors.website} disabled={saving} /> {errors.website && (

{errors.website}

)}
{/* Actions */}
); }