167 lines
5.0 KiB
TypeScript
167 lines
5.0 KiB
TypeScript
import GB from '@/assets/images/GB.png';
|
|
import RU from '@/assets/images/RU.png';
|
|
import UZ from '@/assets/images/UZ.png';
|
|
import { useTheme } from '@/components/ThemeContext';
|
|
import { saveLang } from '@/hooks/storage.native';
|
|
import { useLanguage } from '@/i18n/useLanguage';
|
|
import { useQueryClient } from '@tanstack/react-query';
|
|
import { Image } from 'expo-image';
|
|
import { useRouter } from 'expo-router';
|
|
import { ChevronLeft, Moon, Sun } from 'lucide-react-native';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { Pressable, ScrollView, StyleSheet, Switch, Text, View } from 'react-native';
|
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
|
|
export default function SettingsScreen() {
|
|
const router = useRouter();
|
|
const { language, changeLanguage } = useLanguage();
|
|
const { t, i18n } = useTranslation();
|
|
const queryClient = useQueryClient();
|
|
|
|
const selectLanguage = async (lang: string) => {
|
|
changeLanguage(lang as 'uz' | 'ru' | 'en');
|
|
await i18n.changeLanguage(lang);
|
|
queryClient.invalidateQueries();
|
|
await saveLang(lang);
|
|
};
|
|
const { isDark, toggleTheme } = useTheme();
|
|
|
|
const languages = [
|
|
{ code: 'uz', label: "O'zbek", icon: UZ },
|
|
{ code: 'ru', label: 'Русский', icon: RU },
|
|
{ code: 'en', label: 'English', icon: GB },
|
|
];
|
|
|
|
return (
|
|
<SafeAreaView style={[styles.container, isDark ? styles.darkBg : styles.lightBg]}>
|
|
<ScrollView contentContainerStyle={{ paddingBottom: 32 }}>
|
|
{/* Header */}
|
|
<View style={styles.header}>
|
|
<Pressable onPress={() => router.back()}>
|
|
<ChevronLeft size={26} color={isDark ? '#f8fafc' : '#0f172a'} />
|
|
</Pressable>
|
|
|
|
<Text style={[styles.headerTitle, isDark ? styles.darkText : styles.lightText]}>
|
|
{t('Sozlamalar')}
|
|
</Text>
|
|
|
|
<View style={{ width: 26 }} />
|
|
</View>
|
|
|
|
{/* Language Cards */}
|
|
<Text style={[styles.sectionTitle, isDark ? styles.darkText : styles.lightText]}>
|
|
{t('Tilni tanlang')}
|
|
</Text>
|
|
{languages.map((lang) => {
|
|
const active = language === lang.code;
|
|
return (
|
|
<Pressable
|
|
key={lang.code}
|
|
onPress={() => selectLanguage(lang.code)}
|
|
style={[
|
|
styles.langCard,
|
|
isDark ? styles.darkCard : styles.lightCard,
|
|
active && styles.langActiveCard,
|
|
]}
|
|
>
|
|
<View style={styles.row}>
|
|
<Image source={lang.icon} style={{ width: 32, height: 24 }} />
|
|
<Text
|
|
style={[
|
|
styles.label,
|
|
isDark ? styles.darkText : styles.lightText,
|
|
active && { color: '#fff' },
|
|
]}
|
|
>
|
|
{lang.label}
|
|
</Text>
|
|
</View>
|
|
</Pressable>
|
|
);
|
|
})}
|
|
|
|
{/* Theme */}
|
|
<View style={{ marginTop: 10 }}>
|
|
<Text style={[styles.sectionTitle, isDark ? styles.darkText : styles.lightText]}>
|
|
{t('Rejimni tanlang')}
|
|
</Text>
|
|
<View style={[styles.card, isDark ? styles.darkCard : styles.lightCard]}>
|
|
<View style={styles.row}>
|
|
{isDark ? <Moon size={22} color="#818cf8" /> : <Sun size={22} color="#f59e0b" />}
|
|
<Text style={[styles.label, isDark ? styles.darkText : styles.lightText]}>
|
|
{isDark ? t('Tungi rejim') : t("Yorug' rejim")}
|
|
</Text>
|
|
</View>
|
|
|
|
<Switch
|
|
value={isDark}
|
|
onValueChange={toggleTheme}
|
|
trackColor={{ false: '#d1d5db', true: '#6366f1' }}
|
|
thumbColor={isDark ? '#e5e7eb' : '#ffffff'}
|
|
/>
|
|
</View>
|
|
</View>
|
|
</ScrollView>
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
},
|
|
|
|
/* Backgrounds */
|
|
lightBg: { backgroundColor: '#f9fafb' },
|
|
darkBg: { backgroundColor: '#0f172a' },
|
|
|
|
header: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
padding: 16,
|
|
},
|
|
|
|
headerTitle: {
|
|
fontSize: 18,
|
|
fontWeight: '600',
|
|
},
|
|
|
|
sectionTitle: {
|
|
fontSize: 16,
|
|
fontWeight: '600',
|
|
paddingHorizontal: 16,
|
|
marginBottom: 8,
|
|
},
|
|
|
|
card: {
|
|
borderRadius: 14,
|
|
padding: 16,
|
|
marginHorizontal: 16,
|
|
marginVertical: 8,
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
},
|
|
|
|
lightCard: { backgroundColor: '#ffffff' },
|
|
darkCard: { backgroundColor: '#1e293b', borderWidth: 1, borderColor: '#334155' },
|
|
|
|
row: { flexDirection: 'row', alignItems: 'center', gap: 10 },
|
|
|
|
label: { fontSize: 15, fontWeight: '500' },
|
|
darkText: { color: '#f8fafc' },
|
|
lightText: { color: '#0f172a' },
|
|
|
|
/* Language Cards */
|
|
langCard: {
|
|
borderRadius: 14,
|
|
padding: 16,
|
|
marginHorizontal: 16,
|
|
marginVertical: 6,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
},
|
|
langActiveCard: { backgroundColor: '#3b82f6' },
|
|
});
|