Files
info-tager-mobile/components/ui/AuthHeader.tsx
Samandar Turgunboyev 124798419b fitst commit
2026-01-28 18:26:50 +05:00

152 lines
4.1 KiB
TypeScript

import { languages } from '@/constants/languages';
import { getLang, saveLang } from '@/hooks/storage.native';
import { useLanguage } from '@/i18n/useLanguage';
import { useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'expo-router';
import { ArrowLeft, Check, ChevronDown, Globe } from 'lucide-react-native';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export default function AuthHeader({ back = true }: { back?: boolean }) {
const router = useRouter();
const { language, changeLanguage, getLanguageName } = useLanguage();
const { i18n } = useTranslation();
const [open, setOpen] = useState(false);
const queryClient = useQueryClient();
useEffect(() => {
const loadLanguage = async () => {
const lang = await getLang();
if (lang === 'uz' || lang === 'ru' || lang === 'en') {
changeLanguage(lang);
}
};
loadLanguage();
}, [language]);
const selectLanguage = async (lang: string) => {
changeLanguage(lang as any);
queryClient.invalidateQueries();
await i18n.changeLanguage(lang);
await saveLang(lang);
setOpen(false);
};
return (
<View style={{ ...styles.header, justifyContent: back ? 'space-between' : 'flex-end' }}>
{/* Back */}
{back && (
<TouchableOpacity style={styles.back} onPress={() => router.back()} activeOpacity={0.7}>
<ArrowLeft size={22} color="#fff" />
</TouchableOpacity>
)}
{/* Language */}
<View>
<TouchableOpacity style={styles.langBtn} onPress={() => setOpen(!open)} activeOpacity={0.7}>
<Globe size={18} color="#94a3b8" />
<Text style={styles.langText}>{getLanguageName()}</Text>
<ChevronDown size={16} color="#94a3b8" />
</TouchableOpacity>
{open && (
<View style={styles.dropdown}>
{languages.map((l) => {
const active = language === l.code;
return (
<TouchableOpacity
key={l.code}
style={[styles.option, active && styles.optionActive]}
onPress={() => selectLanguage(l.code)}
>
<Text style={[styles.optionText, active && styles.optionTextActive]}>
{l.name}
</Text>
{active && (
<View style={styles.check}>
<Check size={14} color="#fff" />
</View>
)}
</TouchableOpacity>
);
})}
</View>
)}
</View>
</View>
);
}
const styles = StyleSheet.create({
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 24,
paddingVertical: 12,
zIndex: 50,
},
back: {
width: 44,
height: 44,
borderRadius: 12,
backgroundColor: 'rgba(255,255,255,0.1)',
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderColor: 'rgba(255,255,255,0.15)',
},
langBtn: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
backgroundColor: 'rgba(255,255,255,0.1)',
paddingHorizontal: 14,
paddingVertical: 10,
borderRadius: 12,
borderWidth: 1,
borderColor: 'rgba(255,255,255,0.15)',
},
langText: {
color: '#94a3b8',
fontWeight: '600',
fontSize: 14,
},
dropdown: {
position: 'absolute',
top: 52,
right: 0,
backgroundColor: '#fff',
borderRadius: 16,
padding: 8,
minWidth: 180,
elevation: 20,
},
option: {
flexDirection: 'row',
justifyContent: 'space-between',
padding: 12,
borderRadius: 12,
},
optionActive: {
backgroundColor: '#eff6ff',
},
optionText: {
color: '#475569',
fontWeight: '600',
},
optionTextActive: {
color: '#3b82f6',
},
check: {
width: 20,
height: 20,
borderRadius: 10,
backgroundColor: '#3b82f6',
alignItems: 'center',
justifyContent: 'center',
},
});