fitst commit
This commit is contained in:
151
components/ui/AuthHeader.tsx
Normal file
151
components/ui/AuthHeader.tsx
Normal file
@@ -0,0 +1,151 @@
|
||||
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',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user