import { Dropdown } from '@/aesthetics/Dropdown'; import { Text } from '@/aesthetics/Text'; import { TextInput } from '@/aesthetics/TextInput'; import { font, radius, shadows, spacing, useColors, weight } from '@/aesthetics/styles'; import { ChevronRight, LogOut, Mail, User, type LucideIcon } from 'lucide-react-native'; import { ReactNode, useRef, useState } from 'react'; import { Pressable, ScrollView, StyleSheet, Switch, View } from 'react-native'; import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'; import { getBiologicalSexOptions, useProfileSettings } from './useProfile'; type SectionProps = { title: string; children: ReactNode; c: ReturnType; }; const Section = ({ title, children, c }: SectionProps) => ( {title} {children} ); type ActionRowProps = { icon?: LucideIcon; label: string; onPress?: () => void; iconBg?: string; iconColor?: string; labelColor?: string; rightContent?: ReactNode; showChevron?: boolean; border?: boolean; c: ReturnType; }; const ActionRow = ({ icon: Icon, label, onPress, iconBg, iconColor, labelColor, rightContent, showChevron = true, border = true, c, }: ActionRowProps) => ( [ styles.actionRow, pressed && styles.pressed, !border && { borderBottomWidth: 0 }, border && { borderBottomWidth: 1, borderBottomColor: c.borderSubtle }, ]} onPress={onPress} > {Icon && ( )} {label} {rightContent} {showChevron && } ); const getLanguageOptions = (strings: ReturnType['strings']) => [ { label: strings.profile.languages.system, value: 'system' }, { label: strings.profile.languages.english, value: 'en' }, { label: strings.profile.languages.korean, value: 'ko' }, ]; export function ProfileContent() { const c = useColors(); const insets = useSafeAreaInsets(); const languageRowRef = useRef(null); const [languageDropdownOpen, setLanguageDropdownOpen] = useState(false); const { isDarkMode, hapticFeedback, user, profile, isDemo, languagePreference, strings, editingField, tempValue, setTheme, setHapticFeedback, setTempValue, handleSignOut, startEditing, saveField, updateSex, setLanguage, handleOpenPrivacy, handleOpenTerms, handleContactSupport, handleNavigateToBoard, handleNavigateToCastle, handleNavigateToSignIn, } = useProfileSettings(); const renderRow = ( label: string, value: string | null, field?: string, keyboardType: 'default' | 'numeric' = 'default', suffix?: string ) => { const isEditing = editingField === field; return ( {label} {field && isEditing ? ( saveField(field)} onSubmitEditing={() => saveField(field)} /> ) : ( startEditing(field, value) : undefined}> {value ? `${value}${suffix || ''}` : strings.common.notSet} )} ); }; return ( {strings.profile.title} {strings.profile.subtitle}
{isDemo ? ( ) : ( <> {user?.email} )}
{!isDemo && (
{renderRow( strings.profile.birthYear, profile?.birth_year?.toString() || null, 'birth_year', 'numeric' )} {strings.profile.biologicalSex} {getBiologicalSexOptions(strings).map(option => ( updateSex(option.value)} > {option.label} ))} {renderRow( strings.profile.height, profile?.body_height_cm?.toString() || null, 'body_height_cm', 'numeric', ` ${strings.profile.cm}` )} {renderRow( strings.profile.weight, profile?.body_weight_kg?.toString() || null, 'body_weight_kg', 'numeric', ` ${strings.profile.kg}` )}
)}
{strings.profile.darkMode} setTheme(v ? 'dark' : 'light')} trackColor={{ false: c.progressBg, true: c.accent }} thumbColor="#FFFFFF" /> {strings.profile.hapticFeedback} setLanguageDropdownOpen(true)} border={false} rightContent={ {languagePreference === 'system' ? strings.profile.languages.systemDisplay : languagePreference === 'en' ? strings.profile.languages.englishDisplay : strings.profile.languages.koreanDisplay} } c={c} /> setLanguageDropdownOpen(false)} options={getLanguageOptions(strings)} selected={languagePreference} onSelect={v => setLanguage(v as 'system' | 'en' | 'ko')} />
{!isDemo && ( )}
{strings.common.appName} {strings.common.tagline}
); } const styles = StyleSheet.create({ container: { flex: 1, }, scroll: { flex: 1, }, content: { paddingHorizontal: spacing.xl, paddingTop: spacing.lg, }, header: { marginBottom: spacing.xxl, }, title: { fontSize: font.xxl, letterSpacing: 0.5, }, subtitle: { fontSize: font.sm, marginTop: spacing.xs, }, sections: { gap: spacing.xl, }, section: { gap: spacing.sm, }, sectionTitle: { fontSize: font.xs, fontWeight: weight.medium, textTransform: 'uppercase', letterSpacing: 1, marginLeft: spacing.xs, }, card: { borderRadius: radius.lg, borderWidth: 1, overflow: 'hidden', }, row: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: spacing.md, paddingHorizontal: spacing.lg, borderBottomWidth: 1, }, rowRight: { flexDirection: 'row', alignItems: 'center', gap: 0, }, rowLabel: { fontSize: font.md, fontWeight: weight.medium, }, rowValue: { fontSize: font.md, }, actionRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: spacing.md, paddingHorizontal: spacing.lg, }, actionRowLeft: { flexDirection: 'row', alignItems: 'center', gap: spacing.md, }, actionLabel: { fontSize: font.md, fontWeight: weight.medium, }, iconCircle: { width: 32, height: 32, borderRadius: radius.sm, alignItems: 'center', justifyContent: 'center', }, input: { fontSize: font.md, borderRadius: radius.sm, paddingHorizontal: spacing.md, paddingVertical: spacing.sm, minWidth: 80, textAlign: 'right', }, segmentedControl: { flexDirection: 'row', padding: 3, borderRadius: radius.sm, }, segment: { paddingHorizontal: spacing.md, paddingVertical: spacing.sm, borderRadius: radius.sm - 2, }, segmentText: { fontSize: font.sm, fontWeight: weight.medium, }, pressed: { opacity: 0.7, }, footer: { marginTop: spacing.xxxl, alignItems: 'center', paddingBottom: spacing.xl, }, footerBrand: { fontSize: font.lg, letterSpacing: 1, }, footerTagline: { fontSize: font.xs, letterSpacing: 2, textTransform: 'uppercase', marginTop: spacing.xs, }, });