/**
* Settings FormSheet
* Profile, preferences, premium, legal, reset progress.
*/
import { View, Text, StyleSheet, ScrollView, Pressable, Switch, Alert } from 'react-native'
import { useRouter } from 'expo-router'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { useTranslation } from 'react-i18next'
import { Icon, type IconName } from '@/src/shared/components/Icon'
import { useUserStore } from '@/src/shared/stores/userStore'
import { useProgressStore } from '@/src/shared/stores/progressStore'
import { TYPOGRAPHY } from '@/src/shared/constants/typography'
import { SPACING } from '@/src/shared/constants/spacing'
import { RADIUS } from '@/src/shared/constants/borderRadius'
import { TEXT, NAVY, GREEN, BORDER_COLORS } from '@/src/shared/constants/colors'
export default function SettingsScreen() {
const router = useRouter()
const insets = useSafeAreaInsets()
const { t } = useTranslation()
const profile = useUserStore(s => s.profile)
const settings = useUserStore(s => s.settings)
const updateSettings = useUserStore(s => s.updateSettings)
const resetProgress = useProgressStore(s => s.resetProgress)
const isPremium = profile.subscription !== 'free'
const handleResetProgress = () => {
Alert.alert(
t('screens:settings.resetTitle'),
t('screens:settings.resetMessage'),
[
{ text: t('common:cancel'), style: 'cancel' },
{
text: t('screens:settings.resetConfirm'),
style: 'destructive',
onPress: () => {
resetProgress()
},
},
],
)
}
return (
{t('screens:settings.title')}
{/* Profile */}
{!isPremium && (
router.push('/paywall')}
accent={GREEN[500]}
/>
)}
{/* Preferences */}
updateSettings({ haptics: v })}
/>
updateSettings({ soundEffects: v })}
/>
updateSettings({ voiceCoaching: v })}
/>
updateSettings({ musicEnabled: v })}
/>
{/* Legal */}
router.push('/terms')} />
router.push('/privacy')} />
{/* Danger */}
{t('screens:settings.resetProgress')}
{t('screens:settings.version')}
)
}
function Section({ title, children }: { title: string; children: React.ReactNode }) {
return (
{title}
{children}
)
}
function Row({ label, value, accent }: { label: string; value: string; accent?: string }) {
return (
{label}
{value}
)
}
function SwitchRow({
label,
value,
onChange,
}: {
label: string
value: boolean
onChange: (value: boolean) => void
}) {
return (
{label}
)
}
function LinkRow({
icon,
label,
onPress,
accent,
}: {
icon: IconName
label: string
onPress: () => void
accent?: string
}) {
return (
{label}
)
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: NAVY[900] },
header: { ...TYPOGRAPHY.LARGE_TITLE, color: TEXT.PRIMARY, marginBottom: SPACING[4] },
section: { marginBottom: SPACING[6] },
sectionTitle: {
...TYPOGRAPHY.CAPTION_1,
color: TEXT.TERTIARY,
textTransform: 'uppercase',
letterSpacing: 0.5,
marginBottom: SPACING[2],
paddingHorizontal: SPACING[2],
},
sectionBody: {
backgroundColor: NAVY[800],
borderRadius: RADIUS.MD,
borderWidth: 1,
borderColor: BORDER_COLORS.DIM,
overflow: 'hidden',
},
row: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: SPACING[4],
paddingVertical: SPACING[3],
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: BORDER_COLORS.DIM,
gap: SPACING[3],
},
rowLabel: { ...TYPOGRAPHY.BODY, color: TEXT.PRIMARY },
rowValue: { ...TYPOGRAPHY.BODY, color: TEXT.SECONDARY },
linkLeft: { flexDirection: 'row', alignItems: 'center', gap: SPACING[3] },
dangerRow: {
flexDirection: 'row',
alignItems: 'center',
gap: SPACING[3],
paddingHorizontal: SPACING[4],
paddingVertical: SPACING[3],
},
dangerText: { ...TYPOGRAPHY.BODY, color: '#FF453A' },
version: {
...TYPOGRAPHY.CAPTION_1,
color: TEXT.TERTIARY,
textAlign: 'center',
marginTop: SPACING[4],
},
})