'use client'; import { useState, useEffect } from 'react'; import Link from 'next/link'; import { useLanguage } from '@/context/LanguageContext'; import { siteSettingsApi, eventsApi, legalSettingsApi, SiteSettings, TimezoneOption, Event, LegalSettingsData } from '@/lib/api'; import { parseDate } from '@/lib/utils'; import Card from '@/components/ui/Card'; import Button from '@/components/ui/Button'; import Input from '@/components/ui/Input'; import { Cog6ToothIcon, GlobeAltIcon, ClockIcon, EnvelopeIcon, WrenchScrewdriverIcon, CheckCircleIcon, StarIcon, ScaleIcon, } from '@heroicons/react/24/outline'; import toast from 'react-hot-toast'; type SettingsTab = 'general' | 'legal'; export default function AdminSettingsPage() { const { t, locale } = useLanguage(); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [savingLegal, setSavingLegal] = useState(false); const [activeTab, setActiveTab] = useState('general'); const [timezones, setTimezones] = useState([]); const [featuredEvent, setFeaturedEvent] = useState(null); const [clearingFeatured, setClearingFeatured] = useState(false); const [settings, setSettings] = useState({ timezone: 'America/Asuncion', siteName: 'Spanglish', siteDescription: null, siteDescriptionEs: null, contactEmail: null, contactPhone: null, facebookUrl: null, instagramUrl: null, twitterUrl: null, linkedinUrl: null, featuredEventId: null, maintenanceMode: false, maintenanceMessage: null, maintenanceMessageEs: null, }); const [legalSettings, setLegalSettings] = useState({ companyName: null, legalEntityName: null, rucNumber: null, companyAddress: null, companyCity: null, companyCountry: null, supportEmail: null, legalEmail: null, governingLaw: null, jurisdictionCity: null, }); const [legalErrors, setLegalErrors] = useState>({}); useEffect(() => { loadData(); }, []); const loadData = async () => { try { const [settingsRes, timezonesRes, legalRes] = await Promise.all([ siteSettingsApi.get(), siteSettingsApi.getTimezones(), legalSettingsApi.get().catch(() => ({ settings: {} as LegalSettingsData })), ]); setSettings(settingsRes.settings); setTimezones(timezonesRes.timezones); setLegalSettings(legalRes.settings); // Load featured event details if one is set if (settingsRes.settings.featuredEventId) { try { const { event } = await eventsApi.getById(settingsRes.settings.featuredEventId); setFeaturedEvent(event); } catch { // Featured event may no longer exist setFeaturedEvent(null); } } } catch (error) { toast.error('Failed to load settings'); } finally { setLoading(false); } }; const handleClearFeatured = async () => { setClearingFeatured(true); try { await siteSettingsApi.setFeaturedEvent(null); setSettings(prev => ({ ...prev, featuredEventId: null })); setFeaturedEvent(null); toast.success(locale === 'es' ? 'Evento destacado eliminado' : 'Featured event removed'); } catch (error: any) { toast.error(error.message || 'Failed to clear featured event'); } finally { setClearingFeatured(false); } }; const handleSave = async () => { setSaving(true); try { const response = await siteSettingsApi.update(settings); setSettings(response.settings); toast.success(locale === 'es' ? 'Configuración guardada' : 'Settings saved'); } catch (error: any) { toast.error(error.message || 'Failed to save settings'); } finally { setSaving(false); } }; const validateLegalSettings = (): boolean => { const errors: Record = {}; // Validate email formats if provided const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (legalSettings.supportEmail && !emailRegex.test(legalSettings.supportEmail)) { errors.supportEmail = locale === 'es' ? 'Email no válido' : 'Invalid email address'; } if (legalSettings.legalEmail && !emailRegex.test(legalSettings.legalEmail)) { errors.legalEmail = locale === 'es' ? 'Email no válido' : 'Invalid email address'; } setLegalErrors(errors); return Object.keys(errors).length === 0; }; const handleSaveLegal = async () => { if (!validateLegalSettings()) return; setSavingLegal(true); try { const response = await legalSettingsApi.update(legalSettings); setLegalSettings(response.settings); toast.success(locale === 'es' ? 'Configuración legal guardada' : 'Legal settings saved'); } catch (error: any) { toast.error(error.message || 'Failed to save legal settings'); } finally { setSavingLegal(false); } }; const updateSetting = (key: K, value: SiteSettings[K]) => { setSettings((prev) => ({ ...prev, [key]: value })); }; const updateLegalSetting = (key: K, value: LegalSettingsData[K]) => { setLegalSettings((prev) => ({ ...prev, [key]: value })); // Clear error for this field when user types if (legalErrors[key]) { setLegalErrors((prev) => { const next = { ...prev }; delete next[key]; return next; }); } }; if (loading) { return (
); } const tabs: { id: SettingsTab; label: string; labelEs: string; icon: React.ReactNode }[] = [ { id: 'general', label: 'General Settings', labelEs: 'Configuración General', icon: , }, { id: 'legal', label: 'Legal Settings', labelEs: 'Configuración Legal', icon: , }, ]; return (

{locale === 'es' ? 'Configuración del Sitio' : 'Site Settings'}

{locale === 'es' ? 'Configura las opciones generales del sitio web' : 'Configure general website settings'}

{activeTab === 'general' && ( )} {activeTab === 'legal' && ( )}
{/* Tabs */}
{/* General Settings Tab */} {activeTab === 'general' && (
{/* Timezone Settings */}

{locale === 'es' ? 'Zona Horaria' : 'Timezone'}

{locale === 'es' ? 'Zona horaria para mostrar las fechas de eventos' : 'Timezone used for displaying event dates'}

{locale === 'es' ? 'Esta zona horaria se usará como referencia para las fechas de eventos.' : 'This timezone will be used as reference for event dates.'}

{/* Featured Event */}

{locale === 'es' ? 'Evento Destacado' : 'Featured Event'}

{locale === 'es' ? 'El evento destacado aparece en la página de inicio y linktree' : 'The featured event is displayed on the homepage and linktree'}

{featuredEvent ? (
{featuredEvent.bannerUrl && ( {featuredEvent.title} )}

{featuredEvent.title}

{parseDate(featuredEvent.startDatetime).toLocaleDateString(locale === 'es' ? 'es-ES' : 'en-US', { month: 'long', day: 'numeric', year: 'numeric', timeZone: 'America/Asuncion', })}

{locale === 'es' ? 'Estado:' : 'Status:'} {featuredEvent.status}

{locale === 'es' ? 'Cambiar' : 'Change'}
) : (

{locale === 'es' ? 'No hay evento destacado. El próximo evento publicado se mostrará automáticamente.' : 'No featured event set. The next upcoming published event will be shown automatically.'}

{locale === 'es' ? 'Ir a Eventos para destacar uno' : 'Go to Events to feature one'}
)}

{locale === 'es' ? 'Cuando el evento destacado termine o se despublique, el sistema mostrará automáticamente el próximo evento.' : 'When the featured event ends or is unpublished, the system will automatically show the next upcoming event.'}

{/* Site Information */}

{locale === 'es' ? 'Información del Sitio' : 'Site Information'}

{locale === 'es' ? 'Información básica del sitio web' : 'Basic website information'}

updateSetting('siteName', e.target.value)} placeholder="Spanglish" />