import React, { useEffect, useMemo, useState } from 'react' import { Settings2 } from 'lucide-react' import { adminApi } from '../../api/client' import { useTranslation } from '../../i18n' import { useToast } from '../shared/Toast' import Section from '../Settings/Section' import CustomSelect from '../shared/CustomSelect' import { MapView } from '../Map/MapView' import type { Place } from '../../types' const MAP_PRESETS = [ { name: 'OpenStreetMap', url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' }, { name: 'OpenStreetMap DE', url: 'https://tile.openstreetmap.de/{z}/{x}/{y}.png' }, { name: 'CartoDB Light', url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png' }, { name: 'CartoDB Dark', url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png' }, { name: 'Stadia Smooth', url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png' }, ] type Defaults = { temperature_unit?: string dark_mode?: string | boolean time_format?: string blur_booking_codes?: boolean map_tile_url?: string } function OptionRow({ label, hint, children, }: { label: React.ReactNode hint?: string children: React.ReactNode }) { return (
{hint &&

{hint}

}
{children}
) } function OptionButton({ active, onClick, children, }: { active: boolean onClick: () => void children: React.ReactNode }) { return ( ) } export default function DefaultUserSettingsTab(): React.ReactElement { const { t } = useTranslation() const toast = useToast() const [defaults, setDefaults] = useState({}) const [loaded, setLoaded] = useState(false) const [mapTileUrl, setMapTileUrl] = useState('') useEffect(() => { adminApi.getDefaultUserSettings().then((data: Defaults) => { setDefaults(data) setMapTileUrl(data.map_tile_url || '') setLoaded(true) }).catch(() => setLoaded(true)) }, []) const save = async (patch: Partial) => { try { const updated = await adminApi.updateDefaultUserSettings(patch as Record) setDefaults(updated) toast.success(t('admin.defaultSettings.saved')) } catch (err: unknown) { toast.error(err instanceof Error ? err.message : t('common.error')) } } const reset = async (key: keyof Defaults) => { try { const updated = await adminApi.updateDefaultUserSettings({ [key]: null }) setDefaults(updated) if (key === 'map_tile_url') setMapTileUrl('') toast.success(t('admin.defaultSettings.reset')) } catch (err: unknown) { toast.error(err instanceof Error ? err.message : t('common.error')) } } const isSet = (key: keyof Defaults) => defaults[key] !== undefined const ResetButton = ({ field }: { field: keyof Defaults }) => isSet(field) ? ( ) : null const mapPreviewPlaces = useMemo((): Place[] => [{ id: 1, trip_id: 1, name: 'Preview center', description: null, notes: null, lat: 48.8566, lng: 2.3522, address: null, category_id: null, price: null, currency: null, image_url: null, google_place_id: null, osm_id: null, route_geometry: null, place_time: null, end_time: null, duration_minutes: null, transport_mode: null, website: null, phone: null, created_at: Date(), }], []) if (!loaded) { return

Loading…

} const darkMode = defaults.dark_mode return (

{t('admin.defaultSettings.description')}

{/* Color Mode */} {t('settings.colorMode')} }> {([ { value: 'light', label: t('settings.light') }, { value: 'dark', label: t('settings.dark') }, { value: 'auto', label: t('settings.auto') }, ] as const).map(opt => ( save({ dark_mode: opt.value })} > {opt.label} ))} {/* Temperature */} {t('settings.temperature')} }> {([ { value: 'celsius', label: '°C Celsius' }, { value: 'fahrenheit', label: '°F Fahrenheit' }, ] as const).map(opt => ( save({ temperature_unit: opt.value })} > {opt.label} ))} {/* Time Format */} {t('settings.timeFormat')} }> {([ { value: '24h', label: '24h (14:30)' }, { value: '12h', label: '12h (2:30 PM)' }, ] as const).map(opt => ( save({ time_format: opt.value })} > {opt.label} ))} {/* Blur Booking Codes */} {t('settings.blurBookingCodes')} }> {([ { value: true, label: t('settings.on') || 'On' }, { value: false, label: t('settings.off') || 'Off' }, ] as const).map(opt => ( save({ blur_booking_codes: opt.value })} > {opt.label} ))} {/* Map Tile URL */}
{ if (value) { setMapTileUrl(value); save({ map_tile_url: value }) } }} placeholder={t('settings.mapTemplatePlaceholder.select')} options={MAP_PRESETS.map(p => ({ value: p.url, label: p.name }))} size="sm" style={{ marginBottom: 8 }} /> ) => setMapTileUrl(e.target.value)} onBlur={() => save({ map_tile_url: mapTileUrl })} placeholder="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm focus:ring-2 focus:ring-slate-400 focus:border-transparent" />

{t('settings.mapDefaultHint')}

{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} {React.createElement(MapView as any, { places: mapPreviewPlaces, dayPlaces: [], route: null, routeSegments: null, selectedPlaceId: null, onMarkerClick: null, onMapClick: null, onMapContextMenu: null, center: [48.8566, 2.3522], zoom: 10, tileUrl: mapTileUrl, fitKey: null, dayOrderMap: [], leftWidth: 0, rightWidth: 0, hasInspector: false, })}
) }