Skip to content

Commit bfe947f

Browse files
ios fixes - F*** MMKV btw 🙄
1 parent bf95949 commit bfe947f

23 files changed

Lines changed: 459 additions & 226 deletions

File tree

frontends/react-native-ios/app.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"newArchEnabled": true,
1111
"splash": {
1212
"image": "./assets/splash-icon.png",
13-
"resizeMode": "contain",
13+
"resizeMode": "cover",
1414
"backgroundColor": "#0a0a0a"
1515
},
1616
"ios": {
@@ -29,7 +29,7 @@
2929
{
3030
"backgroundColor": "#0a0a0a",
3131
"image": "./assets/splash-icon.png",
32-
"imageWidth": 200
32+
"resizeMode": "cover"
3333
}
3434
]
3535
],

frontends/react-native-ios/app/(app)/(tabs)/home.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,19 @@
33
* home.tsx
44
*/
55

6+
import { useCurrentUser } from '@/api/hooks'
7+
import { DottedBackground } from '@/shared/components'
68
import type React from 'react'
79
import { SafeAreaView } from 'react-native-safe-area-context'
810
import { Stack, Text, YStack } from 'tamagui'
9-
import { useCurrentUser } from '@/api/hooks'
10-
import { colors } from '@/theme/tokens'
1111

1212
export default function HomeScreen(): React.ReactElement {
1313
const { data: user } = useCurrentUser()
1414

1515
return (
16-
<SafeAreaView
17-
style={{ flex: 1, backgroundColor: colors.bgDefault.val }}
18-
edges={['top']}
19-
>
20-
<YStack flex={1} padding="$6">
16+
<DottedBackground>
17+
<SafeAreaView style={{ flex: 1 }} edges={['top']}>
18+
<YStack flex={1} padding="$6">
2119
<Stack marginBottom="$6">
2220
<Text
2321
fontSize={26}
@@ -43,7 +41,8 @@ export default function HomeScreen(): React.ReactElement {
4341
This is a template home screen. Customize it for your app.
4442
</Text>
4543
</Stack>
46-
</YStack>
47-
</SafeAreaView>
44+
</YStack>
45+
</SafeAreaView>
46+
</DottedBackground>
4847
)
4948
}

frontends/react-native-ios/app/(app)/(tabs)/settings.tsx

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
* settings.tsx
44
*/
55

6-
import { ChevronRight, LogOut, Shield, User } from 'lucide-react-native'
7-
import type React from 'react'
8-
import { SafeAreaView } from 'react-native-safe-area-context'
9-
import { Stack, Switch, Text, YStack } from 'tamagui'
106
import { useCurrentUser, useLogout } from '@/api/hooks'
117
import { useBiometricsEnabled, useUIStore } from '@/core/lib'
8+
import { DottedBackground } from '@/shared/components'
129
import { getBiometricLabel, useBiometrics } from '@/shared/hooks'
1310
import { haptics } from '@/shared/utils'
1411
import { colors } from '@/theme/tokens'
12+
import { router } from 'expo-router'
13+
import { ChevronRight, LogOut, Shield, User } from 'lucide-react-native'
14+
import type React from 'react'
15+
import { SafeAreaView } from 'react-native-safe-area-context'
16+
import { Stack, Switch, Text, YStack } from 'tamagui'
1517

1618
function SettingsRow({
1719
icon,
@@ -67,11 +69,9 @@ export default function SettingsScreen(): React.ReactElement {
6769
const canUseBiometrics = isAvailable && isEnrolled
6870

6971
return (
70-
<SafeAreaView
71-
style={{ flex: 1, backgroundColor: colors.bgDefault.val }}
72-
edges={['top']}
73-
>
74-
<YStack flex={1} padding="$6">
72+
<DottedBackground>
73+
<SafeAreaView style={{ flex: 1 }} edges={['top']}>
74+
<YStack flex={1} padding="$6">
7575
<Stack marginBottom="$6">
7676
<Text
7777
fontSize={26}
@@ -97,23 +97,30 @@ export default function SettingsScreen(): React.ReactElement {
9797
<SettingsRow
9898
icon={<User size={18} color={colors.textLight.val} />}
9999
label="Profile"
100-
onPress={() => {}}
100+
onPress={() => router.push('/(app)/profile')}
101101
/>
102102

103103
{canUseBiometrics && (
104104
<SettingsRow
105105
icon={<Shield size={18} color={colors.textLight.val} />}
106-
label={getBiometricLabel(biometryType)}
106+
label={`${getBiometricLabel(biometryType)} Lock`}
107107
rightElement={
108108
<Switch
109-
size="$3"
109+
size="$4"
110110
checked={biometricsEnabled}
111111
onCheckedChange={handleBiometricsToggle}
112-
backgroundColor={
113-
biometricsEnabled ? '$accent' : '$bgSurface200'
114-
}
112+
backgroundColor={biometricsEnabled ? colors.accent.val : colors.bgSurface200.val}
113+
borderWidth={1}
114+
borderColor={biometricsEnabled ? colors.accent.val : colors.borderDefault.val}
115+
width={52}
116+
height={28}
115117
>
116-
<Switch.Thumb backgroundColor="$white" />
118+
<Switch.Thumb
119+
backgroundColor={colors.white.val}
120+
animation="quick"
121+
width={24}
122+
height={24}
123+
/>
117124
</Switch>
118125
}
119126
/>
@@ -133,7 +140,8 @@ export default function SettingsScreen(): React.ReactElement {
133140
onPress={handleLogout}
134141
/>
135142
</Stack>
136-
</YStack>
137-
</SafeAreaView>
143+
</YStack>
144+
</SafeAreaView>
145+
</DottedBackground>
138146
)
139147
}
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
/**
2+
* @AngelaMos | 2026
3+
* profile.tsx
4+
*/
5+
6+
import { useChangePassword, useCurrentUser } from '@/api/hooks'
7+
import { useUpdateProfile } from '@/api/hooks/useUsers'
8+
import { Button, DottedBackground, Input, PasswordInput } from '@/shared/components'
9+
import { haptics } from '@/shared/utils'
10+
import { router } from 'expo-router'
11+
import { ArrowLeft } from 'lucide-react-native'
12+
import type React from 'react'
13+
import { useEffect, useState } from 'react'
14+
import { Alert, KeyboardAvoidingView, Platform, ScrollView } from 'react-native'
15+
import { SafeAreaView } from 'react-native-safe-area-context'
16+
import { Stack, Text, YStack } from 'tamagui'
17+
import { colors } from '@/theme/tokens'
18+
19+
export default function ProfileScreen(): React.ReactElement {
20+
const { data: user } = useCurrentUser()
21+
const updateProfile = useUpdateProfile()
22+
const changePassword = useChangePassword()
23+
24+
const [fullName, setFullName] = useState('')
25+
const [currentPassword, setCurrentPassword] = useState('')
26+
const [newPassword, setNewPassword] = useState('')
27+
const [confirmPassword, setConfirmPassword] = useState('')
28+
29+
useEffect(() => {
30+
if (user) {
31+
setFullName(user.full_name ?? '')
32+
}
33+
}, [user])
34+
35+
const handleSaveProfile = (): void => {
36+
if (!fullName.trim()) {
37+
haptics.error()
38+
Alert.alert('Error', 'Please enter your name')
39+
return
40+
}
41+
42+
updateProfile.mutate(
43+
{ full_name: fullName.trim() },
44+
{
45+
onSuccess: () => {
46+
haptics.success()
47+
Alert.alert('Success', 'Profile updated')
48+
},
49+
onError: (err) => {
50+
haptics.error()
51+
Alert.alert('Error', err.message)
52+
},
53+
}
54+
)
55+
}
56+
57+
const handleChangePassword = (): void => {
58+
if (!currentPassword || !newPassword || !confirmPassword) {
59+
haptics.error()
60+
Alert.alert('Error', 'Please fill in all password fields')
61+
return
62+
}
63+
64+
if (newPassword !== confirmPassword) {
65+
haptics.error()
66+
Alert.alert('Error', 'New passwords do not match')
67+
return
68+
}
69+
70+
if (newPassword.length < 8) {
71+
haptics.error()
72+
Alert.alert('Error', 'Password must be at least 8 characters')
73+
return
74+
}
75+
76+
changePassword.mutate(
77+
{ current_password: currentPassword, new_password: newPassword },
78+
{
79+
onSuccess: () => {
80+
haptics.success()
81+
Alert.alert('Success', 'Password changed')
82+
setCurrentPassword('')
83+
setNewPassword('')
84+
setConfirmPassword('')
85+
},
86+
onError: (err) => {
87+
haptics.error()
88+
Alert.alert('Error', err.message)
89+
},
90+
}
91+
)
92+
}
93+
94+
return (
95+
<DottedBackground>
96+
<SafeAreaView style={{ flex: 1 }} edges={['top']}>
97+
<KeyboardAvoidingView
98+
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
99+
style={{ flex: 1 }}
100+
>
101+
<ScrollView
102+
contentContainerStyle={{ padding: 24 }}
103+
keyboardShouldPersistTaps="handled"
104+
>
105+
<Stack
106+
flexDirection="row"
107+
alignItems="center"
108+
gap="$2"
109+
marginBottom="$6"
110+
pressStyle={{ opacity: 0.7 }}
111+
onPress={() => router.back()}
112+
>
113+
<ArrowLeft size={18} color={colors.textLight.val} />
114+
<Text fontSize={14} color="$textLight">
115+
Back
116+
</Text>
117+
</Stack>
118+
119+
<Text
120+
fontSize={22}
121+
fontWeight="600"
122+
color="$textDefault"
123+
marginBottom="$6"
124+
>
125+
Profile
126+
</Text>
127+
128+
<YStack gap="$6">
129+
<Stack
130+
backgroundColor="$bgSurface100"
131+
borderWidth={1}
132+
borderColor="$borderDefault"
133+
borderRadius="$3"
134+
padding="$4"
135+
>
136+
<Text
137+
fontSize={14}
138+
fontWeight="500"
139+
color="$textDefault"
140+
marginBottom="$4"
141+
>
142+
Account Info
143+
</Text>
144+
145+
<YStack gap="$3">
146+
<Input
147+
label="Email"
148+
value={user?.email ?? ''}
149+
editable={false}
150+
autoCapitalize="none"
151+
keyboardType="email-address"
152+
/>
153+
154+
<Input
155+
label="Full Name"
156+
value={fullName}
157+
onChangeText={setFullName}
158+
placeholder="Enter your name"
159+
/>
160+
161+
<Stack marginTop="$2">
162+
<Button
163+
onPress={handleSaveProfile}
164+
loading={updateProfile.isPending}
165+
>
166+
{updateProfile.isPending ? 'Saving...' : 'Save Changes'}
167+
</Button>
168+
</Stack>
169+
</YStack>
170+
</Stack>
171+
172+
<Stack
173+
backgroundColor="$bgSurface100"
174+
borderWidth={1}
175+
borderColor="$borderDefault"
176+
borderRadius="$3"
177+
padding="$4"
178+
>
179+
<Text
180+
fontSize={14}
181+
fontWeight="500"
182+
color="$textDefault"
183+
marginBottom="$4"
184+
>
185+
Change Password
186+
</Text>
187+
188+
<YStack gap="$3">
189+
<PasswordInput
190+
label="Current Password"
191+
value={currentPassword}
192+
onChangeText={setCurrentPassword}
193+
/>
194+
195+
<PasswordInput
196+
label="New Password"
197+
value={newPassword}
198+
onChangeText={setNewPassword}
199+
/>
200+
201+
<PasswordInput
202+
label="Confirm New Password"
203+
value={confirmPassword}
204+
onChangeText={setConfirmPassword}
205+
/>
206+
207+
<Stack marginTop="$2">
208+
<Button
209+
variant="secondary"
210+
onPress={handleChangePassword}
211+
loading={changePassword.isPending}
212+
>
213+
{changePassword.isPending ? 'Updating...' : 'Update Password'}
214+
</Button>
215+
</Stack>
216+
</YStack>
217+
</Stack>
218+
</YStack>
219+
</ScrollView>
220+
</KeyboardAvoidingView>
221+
</SafeAreaView>
222+
</DottedBackground>
223+
)
224+
}

0 commit comments

Comments
 (0)