import React, { useState, useEffect, useCallback, useMemo } from 'react' import { useNavigate, useSearchParams } from 'react-router-dom' import { useAuthStore } from '../store/authStore' import { useSettingsStore } from '../store/settingsStore' import { SUPPORTED_LANGUAGES, useTranslation } from '../i18n' import Navbar from '../components/Layout/Navbar' import CustomSelect from '../components/shared/CustomSelect' import { useToast } from '../components/shared/Toast' import { Save, Map, Palette, User, Moon, Sun, Monitor, Shield, Camera, Trash2, Lock, KeyRound, AlertTriangle, Copy, Download, Printer, Terminal, Plus, Check, Info } from 'lucide-react' import { authApi, adminApi } from '../api/client' import apiClient from '../api/client' import { useAddonStore } from '../store/addonStore' import type { LucideIcon } from 'lucide-react' import type { UserWithOidc } from '../types' import { getApiErrorMessage } from '../types' import { MapView } from '../components/Map/MapView' import type { Place } from '../types' interface MapPreset { name: string url: string } const MFA_BACKUP_SESSION_KEY = 'trek_mfa_backup_codes_pending' interface McpToken { id: number name: string token_prefix: string created_at: string last_used_at: string | null } const MAP_PRESETS: MapPreset[] = [ { 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' }, ] interface SectionProps { title: string icon: LucideIcon children: React.ReactNode } function Section({ title, icon: Icon, children }: SectionProps): React.ReactElement { return (
{t('settings.notificationsDisabled')}
) } const channelLabel = notifChannel === 'email' ? (t('admin.notifications.email') || 'Email (SMTP)') : (t('admin.notifications.webhook') || 'Webhook') return ({t('settings.notificationsManagedByAdmin')}
${new Date().toLocaleString()}
${backupCodesText}`
const w = window.open('', '_blank', 'width=900,height=700')
if (!w) return
w.document.open()
w.document.write(html)
w.document.close()
w.focus()
w.print()
}
useEffect(() => {
setMapTileUrl(settings.map_tile_url || '')
setDefaultLat(settings.default_lat || 48.8566)
setDefaultLng(settings.default_lng || 2.3522)
setDefaultZoom(settings.default_zoom || 10)
setTempUnit(settings.temperature_unit || 'celsius')
}, [settings])
useEffect(() => {
setUsername(user?.username || '')
setEmail(user?.email || '')
}, [user])
const saveMapSettings = async (): Promise{t('settings.subtitle')}
{t('settings.mapDefaultHint')}
{mcpEndpoint}
{mcpJsonConfig}
{t('settings.mcp.clientConfigHint')}
{t('settings.mcp.noTokens')}
) : ({token.name}
{token.token_prefix}... {t('settings.mcp.tokenCreatedAt')} {new Date(token.created_at).toLocaleDateString(locale)} {token.last_used_at && ( · {t('settings.mcp.tokenUsedAt')} {new Date(token.last_used_at).toLocaleDateString(locale)} )}
{t('settings.mcp.modal.createdWarning')}
{mcpCreatedToken}
{t('settings.mcp.deleteTokenMessage')}
{t('settings.mfa.requiredByPolicy')}
{t('settings.mfa.description')}
{demoMode ? ({t('settings.mfa.demoBlocked')}
) : ( <>{user?.mfa_enabled ? t('settings.mfa.enabled') : t('settings.mfa.disabled')}
{!user?.mfa_enabled && !mfaQr && ( )} {!user?.mfa_enabled && mfaQr && ({t('settings.mfa.scanQr')}
{mfaSecret}
{t('settings.mfa.disableTitle')}
{t('settings.mfa.disableHint')}
setMfaDisablePwd(e.target.value)} placeholder={t('settings.currentPassword')} className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm" /> setMfaDisableCode(e.target.value.replace(/\D/g, '').slice(0, 8))} placeholder={t('settings.mfa.codePlaceholder')} className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm" />{t('settings.mfa.backupTitle')}
{t('settings.mfa.backupDescription')}
{backupCodesText}
{t('settings.mfa.backupWarning')}
{t('settings.oidcLinked')} {(user as UserWithOidc).oidc_issuer!.replace('https://', '').replace(/\/+$/, '')}
)}{t('settings.deleteBlockedMessage')}
{t('settings.deleteAccountWarning')}