155 lines
4.5 KiB
TypeScript
155 lines
4.5 KiB
TypeScript
import { router } from 'expo-router';
|
|
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { Button } from '@/src/components/Button';
|
|
import { Screen } from '@/src/components/Screen';
|
|
import { useAuth } from '@/src/context/AuthContext';
|
|
import { useAppearance } from '@/src/context/AppearanceContext';
|
|
import { APPEARANCE_OPTIONS } from '@/src/theme/appearance';
|
|
import { setAppLanguage } from '@/src/i18n';
|
|
|
|
export default function SettingsScreen() {
|
|
const { t, i18n } = useTranslation();
|
|
const { user, logout } = useAuth();
|
|
const { colors, appearanceId, setAppearance } = useAppearance();
|
|
|
|
return (
|
|
<Screen title={t('settings.title')}>
|
|
<ScrollView contentContainerStyle={styles.scroll}>
|
|
<Text style={[styles.section, { color: colors.text }]}>{t('settings.account')}</Text>
|
|
<View style={[styles.card, { backgroundColor: colors.surface, borderColor: colors.border }]}>
|
|
<Text style={[styles.label, { color: colors.textMuted }]}>{t('auth.email')}</Text>
|
|
<Text style={[styles.value, { color: colors.text }]}>{user?.email ?? '—'}</Text>
|
|
{user?.userName ? (
|
|
<>
|
|
<Text style={[styles.label, { color: colors.textMuted, marginTop: 8 }]}>
|
|
{t('auth.displayName')}
|
|
</Text>
|
|
<Text style={[styles.value, { color: colors.text }]}>{user.userName}</Text>
|
|
</>
|
|
) : null}
|
|
</View>
|
|
|
|
<Text style={[styles.section, { color: colors.text }]}>{t('settings.preferences')}</Text>
|
|
<Text style={[styles.subsection, { color: colors.text }]}>{t('language.label')}</Text>
|
|
<View style={styles.row}>
|
|
{(['en', 'pl'] as const).map((code) => {
|
|
const selected = i18n.language.startsWith(code);
|
|
return (
|
|
<Pressable
|
|
key={code}
|
|
onPress={() => setAppLanguage(code)}
|
|
style={[
|
|
styles.chip,
|
|
{
|
|
backgroundColor: selected ? colors.brand : colors.surface,
|
|
borderColor: selected ? colors.brand : colors.border,
|
|
},
|
|
]}
|
|
>
|
|
<Text style={{ color: selected ? '#fff' : colors.text }}>
|
|
{t(`language.${code}`)}
|
|
</Text>
|
|
</Pressable>
|
|
);
|
|
})}
|
|
</View>
|
|
|
|
<Text style={[styles.subsection, { color: colors.text }]}>{t('appearance.label')}</Text>
|
|
{APPEARANCE_OPTIONS.map((option) => {
|
|
const selected = appearanceId === option.id;
|
|
return (
|
|
<Pressable
|
|
key={option.id}
|
|
onPress={() => setAppearance(option.id)}
|
|
style={[
|
|
styles.appearanceRow,
|
|
{
|
|
backgroundColor: colors.surface,
|
|
borderColor: selected ? colors.brand : colors.border,
|
|
},
|
|
]}
|
|
>
|
|
<View style={[styles.swatch, { backgroundColor: option.swatch }]} />
|
|
<View style={styles.appearanceText}>
|
|
<Text style={[styles.appearanceTitle, { color: colors.text }]}>
|
|
{t(option.labelKey)}
|
|
</Text>
|
|
<Text style={{ color: colors.textMuted }}>{t(option.descriptionKey)}</Text>
|
|
</View>
|
|
</Pressable>
|
|
);
|
|
})}
|
|
|
|
<Button
|
|
title={t('nav.logout')}
|
|
variant="danger"
|
|
onPress={async () => {
|
|
await logout();
|
|
router.replace('/(auth)/login');
|
|
}}
|
|
/>
|
|
</ScrollView>
|
|
</Screen>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
scroll: {
|
|
gap: 12,
|
|
paddingBottom: 32,
|
|
},
|
|
section: {
|
|
fontSize: 18,
|
|
fontWeight: '700',
|
|
marginTop: 4,
|
|
},
|
|
subsection: {
|
|
fontSize: 15,
|
|
fontWeight: '600',
|
|
},
|
|
card: {
|
|
borderWidth: 1,
|
|
borderRadius: 14,
|
|
padding: 14,
|
|
},
|
|
label: {
|
|
fontSize: 13,
|
|
},
|
|
value: {
|
|
fontSize: 16,
|
|
fontWeight: '500',
|
|
},
|
|
row: {
|
|
flexDirection: 'row',
|
|
gap: 10,
|
|
},
|
|
chip: {
|
|
borderWidth: 1,
|
|
borderRadius: 999,
|
|
paddingHorizontal: 16,
|
|
paddingVertical: 10,
|
|
},
|
|
appearanceRow: {
|
|
borderWidth: 1,
|
|
borderRadius: 14,
|
|
padding: 12,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: 12,
|
|
},
|
|
swatch: {
|
|
width: 28,
|
|
height: 28,
|
|
borderRadius: 14,
|
|
},
|
|
appearanceText: {
|
|
flex: 1,
|
|
gap: 2,
|
|
},
|
|
appearanceTitle: {
|
|
fontWeight: '600',
|
|
fontSize: 15,
|
|
},
|
|
});
|