/** * BUS-Tickets - Settings Screen * Copyright (c) 2024-2026 IT Enterprise */ import { useState } from 'react'; import { View, Text, ScrollView, TouchableOpacity, Switch, TextInput, StyleSheet, Alert, Linking, } from 'react-native'; import { useRouter } from 'expo-router'; import { Ionicons } from '@expo/vector-icons'; import { useTheme } from '@/contexts/ThemeContext'; import { useConfig } from '@/contexts/ConfigContext'; import { useNetwork } from '@/contexts/NetworkContext'; import { useLocale } from '@/contexts/LocaleContext'; import { SyncIndicator } from '@/components/SyncIndicator'; export default function SettingsScreen() { const router = useRouter(); const { colors, isDark, toggleTheme, setTheme, themeMode } = useTheme(); const { config, loadConfigFromUrl, resetToDefault } = useConfig(); const { isOnline, syncState, forceSync } = useNetwork(); const { locale, setLocale, t, availableLanguages, getLanguageName, getLanguageFlag } = useLocale(); const [showBackendInput, setShowBackendInput] = useState(false); const [backendUrl, setBackendUrl] = useState(config.backend.apiUrl); const [isConnecting, setIsConnecting] = useState(false); const handleConnectBackend = async () => { if (!backendUrl) { Alert.alert('Error', 'Please enter a backend URL'); return; } setIsConnecting(true); try { await loadConfigFromUrl(backendUrl); Alert.alert('Success', 'Connected to backend successfully'); setShowBackendInput(false); } catch (error) { Alert.alert('Error', 'Could not connect to backend. Please check the URL.'); } finally { setIsConnecting(false); } }; const handleResetConfig = () => { Alert.alert( 'Reset Configuration', 'This will reset all settings to default. Continue?', [ { text: 'Cancel', style: 'cancel' }, { text: 'Reset', style: 'destructive', onPress: async () => { await resetToDefault(); setBackendUrl(config.backend.apiUrl); }, }, ] ); }; const styles = createStyles(colors); return ( {/* Theme Settings */} {t.settings.appearance} {t.settings.darkMode} {(['light', 'dark', 'system'] as const).map((mode) => ( setTheme(mode)} > {t.settings[mode]} ))} {/* Notifications & Sync */} {t.settings.notifications} router.push('/settings/notifications')} > {t.settings.notifications} {t.settings.notificationsDesc} {t.settings.syncStatus} {!isOnline ? t.settings.offline : syncState.pendingActions > 0 ? `${syncState.pendingActions} ${t.settings.pending}` : t.settings.synced} {isOnline && ( <> {t.settings.forceSync} )} {/* Backend Settings */} {t.settings.backend} {t.settings.currentBackend} {config.backend.apiUrl} setShowBackendInput(!showBackendInput)} > {t.settings.changeBackend} {showBackendInput && ( {isConnecting ? t.settings.connecting : t.settings.connect} )} router.push('/settings/providers' as any)} > Bus Operators Manage multiple bus company connections {/* Language Settings */} {t.settings.language} {availableLanguages.map((lang, index) => ( {index > 0 && } setLocale(lang)} > {getLanguageFlag(lang)} {getLanguageName(lang)} {locale === lang && ( )} ))} {/* Legal */} {t.settings.legal} Linking.openURL(config.legal.privacyPolicyUrl)} > {t.settings.privacyPolicy} Linking.openURL(config.legal.termsUrl || config.legal.termsOfServiceUrl)} > {t.settings.termsOfService} {/* About */} {t.settings.about} {t.settings.appName} {config.instanceName} {t.settings.version} 1.0.0 {t.settings.developer} IT Enterprise {/* Reset */} {t.settings.resetSettings} © 2024-2026 IT Enterprise{'\n'} support@it-enterprise.cz ); } const createStyles = (colors: any) => StyleSheet.create({ container: { flex: 1, backgroundColor: colors.background, }, content: { padding: 16, }, section: { marginBottom: 24, }, sectionTitle: { fontSize: 14, fontWeight: '600', color: colors.textSecondary, textTransform: 'uppercase', marginBottom: 8, }, settingCard: { backgroundColor: colors.card, borderRadius: 12, padding: 16, }, settingRow: { flexDirection: 'row', alignItems: 'center', }, settingInfo: { flex: 1, marginLeft: 12, }, settingText: { flex: 1, fontSize: 16, color: colors.text, marginLeft: 12, }, settingValue: { fontSize: 12, color: colors.textSecondary, marginTop: 2, }, divider: { height: 1, backgroundColor: colors.border, marginVertical: 12, }, themeOptions: { flexDirection: 'row', gap: 8, }, themeOption: { flex: 1, paddingVertical: 8, alignItems: 'center', borderRadius: 8, backgroundColor: colors.background, }, themeOptionActive: { backgroundColor: colors.primary, }, themeOptionText: { fontSize: 14, color: colors.textSecondary, }, themeOptionTextActive: { color: '#fff', fontWeight: '600', }, actionButton: { flexDirection: 'row', alignItems: 'center', gap: 8, }, actionButtonText: { fontSize: 16, color: colors.primary, }, inputContainer: { marginTop: 12, }, input: { backgroundColor: colors.background, borderRadius: 8, padding: 12, fontSize: 16, color: colors.text, marginBottom: 8, }, connectButton: { backgroundColor: colors.primary, borderRadius: 8, padding: 12, alignItems: 'center', }, connectButtonDisabled: { opacity: 0.6, }, connectButtonText: { color: '#fff', fontSize: 16, fontWeight: '600', }, languageOption: { flexDirection: 'row', alignItems: 'center', paddingVertical: 12, gap: 12, }, languageFlag: { fontSize: 24, }, languageText: { flex: 1, fontSize: 16, color: colors.text, }, languageTextActive: { fontWeight: '600', color: colors.primary, }, legalItem: { flexDirection: 'row', alignItems: 'center', gap: 12, }, legalText: { flex: 1, fontSize: 16, color: colors.text, }, aboutItem: { flexDirection: 'row', justifyContent: 'space-between', }, aboutLabel: { fontSize: 16, color: colors.textSecondary, }, aboutValue: { fontSize: 16, color: colors.text, }, resetButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 8, backgroundColor: colors.card, borderRadius: 12, padding: 16, marginBottom: 24, }, resetButtonText: { fontSize: 16, color: colors.error, }, footer: { alignItems: 'center', paddingVertical: 24, }, footerText: { fontSize: 12, color: colors.textSecondary, textAlign: 'center', }, });