fitst commit

This commit is contained in:
Samandar Turgunboyev
2026-01-28 18:26:50 +05:00
parent 166a55b1e9
commit 124798419b
196 changed files with 26627 additions and 421 deletions

View 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',
},
});