* Extended functionalities

* Added different UIs
This commit is contained in:
2026-06-24 21:43:40 +02:00
parent 282f4864c4
commit f15bb7a916
348 changed files with 59057 additions and 498 deletions

View File

@@ -0,0 +1,154 @@
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,
},
});