Skip to content

Commit 3025dba

Browse files
Merge pull request #63 from binarapps/feat/profile-image-section
Feat/profile image section
2 parents 1306d44 + a5cf84d commit 3025dba

23 files changed

Lines changed: 245 additions & 149 deletions

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
"expo-device": "~5.9.4",
122122
"expo-font": "~11.10.3",
123123
"expo-haptics": "~12.8.1",
124+
"expo-image-picker": "~14.7.1",
124125
"expo-linear-gradient": "~12.7.2",
125126
"expo-linking": "~6.2.2",
126127
"expo-local-authentication": "~13.8.0",

src/components/FeaturedIcon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Box, Icon } from '@baca/design-system'
2-
import { IconNames } from '@baca/types/icon'
2+
import { IconNames } from '@baca/types'
33

44
type FeatureIconSize = 'sm' | 'md' | 'lg' | 'xl'
55

src/components/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,10 @@ export * from './LanguagePicker'
1212
export * from './Modal'
1313
export * from './StatusBar'
1414
export * from './Version'
15+
16+
export * from './screens/profile/ProfileControlledInput'
17+
export * from './screens/profile/ProfileDeleteAccountButton'
18+
export * from './screens/profile/ProfileDetailsForm'
19+
export * from './screens/profile/ProfileEditImage'
20+
export * from './screens/profile/ProfileHeader'
21+
export * from './screens/profile/ProfilePasswordForm'
Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
import { ControlledField } from '@baca/components'
22
import { isWeb } from '@baca/constants'
3-
import { Text, Box } from '@baca/design-system'
3+
import { Box, Text } from '@baca/design-system'
44
import { useWeb } from '@baca/hooks'
5-
import { ProfileControlledInputProps } from '@baca/types/ProfileInputProps'
5+
import { ProfileControlledInputProps } from '@baca/types'
6+
import { StyleSheet } from 'react-native'
67

78
export const ProfileControlledInput = ({
89
label,
910
name,
10-
placeholder,
11-
control,
12-
errors,
1311
isDisabled = false,
14-
onFocus,
15-
onSubmitEditing,
12+
...rest
1613
}: ProfileControlledInputProps) => {
1714
const { shouldApplyMobileStyles } = useWeb()
1815

@@ -23,22 +20,23 @@ export const ProfileControlledInput = ({
2320
mb={isWeb ? 10 : 0}
2421
maxW={800}
2522
>
26-
<Text.SmBold flex={1}>{label}</Text.SmBold>
23+
<Text.SmBold flex={1} color="text.primary" style={styles.labelMargin}>
24+
{label}
25+
</Text.SmBold>
2726
<Box flex={isWeb ? 2 : 0}>
2827
<ControlledField.Input
29-
control={control}
30-
errors={errors}
3128
autoCapitalize="none"
3229
inputMode={name === 'email' ? 'email' : 'text'}
3330
name={name}
34-
placeholder={placeholder}
3531
testID={`${name}Input`}
3632
isDisabled={isDisabled}
37-
onFocus={onFocus}
38-
onSubmitEditing={onSubmitEditing}
39-
{...(!isWeb && { label })}
33+
{...rest}
4034
/>
4135
</Box>
4236
</Box>
4337
)
4438
}
39+
40+
const styles = StyleSheet.create({
41+
labelMargin: { marginBottom: 10 },
42+
})

src/components/screens/profile/ProfileDeleteAccountButton.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,16 @@ export const ProfileDeleteAccountButton = () => {
5757
)
5858

5959
return (
60-
<Box>
61-
<Box borderColor="border.secondary" borderTopWidth={1} py={6} alignItems="flex-start">
62-
<Button
63-
leftIconName="delete-bin-line"
64-
variant="SecondaryDestructive"
65-
borderRadius={8}
66-
onPress={presentBottomSheet}
67-
>
68-
{t('profile_screen.remove_account')}
69-
</Button>
70-
{bottomSheet}
71-
</Box>
60+
<Box borderColor="border.secondary" borderTopWidth={1} py={6} alignItems="flex-start">
61+
<Button
62+
leftIconName="delete-bin-line"
63+
variant="SecondaryDestructive"
64+
borderRadius={8}
65+
onPress={presentBottomSheet}
66+
>
67+
{t('profile_screen.remove_account')}
68+
</Button>
69+
{bottomSheet}
7270
</Box>
7371
)
7472
}

src/components/screens/profile/ProfileDetailsForm.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,20 @@ export const ProfileDetailsForm = () => {
2020
label={t('form.labels.first_name')}
2121
name="firstName"
2222
placeholder={t('form.placeholders.first_name')}
23-
control={control}
24-
errors={errors}
23+
{...{ control, errors }}
2524
onFocus={focusLastNameInput}
2625
/>
2726
<ProfileControlledInput
2827
label={t('form.labels.last_name')}
2928
name="lastName"
3029
placeholder={t('form.placeholders.last_name')}
31-
control={control}
32-
errors={errors}
30+
{...{ control, errors }}
3331
/>
3432
<ProfileControlledInput
3533
label={t('form.labels.email')}
3634
name="email"
3735
placeholder={t('form.placeholders.email')}
38-
control={control}
39-
errors={errors}
36+
{...{ control, errors }}
4037
isDisabled
4138
onSubmitEditing={submit}
4239
/>
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { isWeb } from '@baca/constants'
2+
import { Box, Text, Button, Row, themeColors } from '@baca/design-system'
3+
import * as ImagePicker from 'expo-image-picker'
4+
import { t } from 'i18next'
5+
import { useState, useCallback } from 'react'
6+
import { Image, StyleSheet } from 'react-native'
7+
8+
export const ProfileEditImage: React.FC = () => {
9+
const [image, setImage] = useState<string | null>(null)
10+
11+
const pickImage = useCallback(async () => {
12+
const result = await ImagePicker.launchImageLibraryAsync({
13+
mediaTypes: ImagePicker.MediaTypeOptions.Images,
14+
allowsEditing: true,
15+
aspect: [4, 3],
16+
quality: 1,
17+
})
18+
19+
if (!result.canceled && result.assets && result.assets.length > 0) {
20+
setImage(result.assets[0].uri)
21+
}
22+
}, [])
23+
24+
return (
25+
<Box borderColor="border.secondary" borderTopWidth={1} py={6}>
26+
<Box style={styles.marginBottom}>
27+
<Text.SmBold color="text.primary">{t('profile_screen.your_photo')}</Text.SmBold>
28+
<Text.SmRegular color="text.secondary">
29+
{t('profile_screen.your_photo_description')}
30+
</Text.SmRegular>
31+
</Box>
32+
<Box style={styles.imageContainer}>
33+
{image ? (
34+
<Image source={{ uri: image }} style={styles.image} />
35+
) : (
36+
<Box style={styles.placeholder}>
37+
<Text color="Gray modern.600">{t('profile_screen.photo_innerText')}</Text>
38+
</Box>
39+
)}
40+
</Box>
41+
<Row maxW={800} justifyContent="flex-end">
42+
<Button onPress={pickImage}>{t('common.upload')}</Button>
43+
</Row>
44+
</Box>
45+
)
46+
}
47+
48+
const styles = StyleSheet.create({
49+
image: {
50+
height: '100%',
51+
width: '100%',
52+
},
53+
imageContainer: {
54+
alignSelf: 'center',
55+
borderRadius: 50,
56+
height: 100,
57+
marginBottom: 10,
58+
overflow: 'hidden',
59+
right: isWeb ? 150 : 0,
60+
width: 100,
61+
},
62+
marginBottom: {
63+
marginBottom: 10,
64+
},
65+
placeholder: {
66+
alignItems: 'center',
67+
backgroundColor: themeColors.primitives['Gray neutral']['50'],
68+
height: '100%',
69+
justifyContent: 'center',
70+
width: '100%',
71+
},
72+
})
Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Box, Button, Row } from '@baca/design-system'
22
import { useUpdatePasswordForm } from '@baca/hooks/forms/useUpdatePasswordForm'
3-
import React from 'react'
43
import { useTranslation } from 'react-i18next'
54

65
import { ProfileControlledInput } from './ProfileControlledInput'
@@ -10,33 +9,31 @@ export const ProfilePasswordForm = () => {
109
const { control, errors, submit, isSubmitting } = useUpdatePasswordForm()
1110

1211
return (
13-
<Box>
14-
<Box borderColor="border.secondary" borderTopWidth={1} py={6}>
15-
<ProfileControlledInput
16-
label={t('form.labels.old_password')}
17-
name="oldPassword"
18-
placeholder={t('form.placeholders.old_password')}
19-
control={control}
20-
errors={errors}
21-
/>
22-
<ProfileControlledInput
23-
label={t('form.labels.new_password')}
24-
name="password"
25-
placeholder={t('form.placeholders.new_password')}
26-
control={control}
27-
errors={errors}
28-
/>
29-
<Row maxW={800} justifyContent="flex-end">
30-
<Button
31-
disabled={isSubmitting}
32-
loading={isSubmitting}
33-
onPress={submit}
34-
testID="changePasswordButton"
35-
>
36-
{t('common.change')}
37-
</Button>
38-
</Row>
39-
</Box>
12+
<Box borderColor="border.secondary" borderTopWidth={1} py={6}>
13+
<ProfileControlledInput
14+
label={t('form.labels.old_password')}
15+
name="oldPassword"
16+
placeholder={t('form.placeholders.old_password')}
17+
control={control}
18+
errors={errors}
19+
/>
20+
<ProfileControlledInput
21+
label={t('form.labels.new_password')}
22+
name="password"
23+
placeholder={t('form.placeholders.new_password')}
24+
control={control}
25+
errors={errors}
26+
/>
27+
<Row maxW={800} justifyContent="flex-end">
28+
<Button
29+
disabled={isSubmitting}
30+
loading={isSubmitting}
31+
onPress={submit}
32+
testID="changePasswordButton"
33+
>
34+
{t('common.change')}
35+
</Button>
36+
</Row>
4037
</Box>
4138
)
4239
}

src/design-system/bottomSheets/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IconNames } from '@baca/types/icon'
1+
import { IconNames } from '@baca/types'
22
import { BottomSheetModal } from '@gorhom/bottom-sheet'
33
import { RefObject } from 'react'
44

src/design-system/components/Button/Button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useTheme } from '@baca/hooks'
2-
import { IconNames } from '@baca/types/icon'
2+
import { IconNames } from '@baca/types'
33
import { getColorValue } from '@baca/utils'
44
import {
55
useMemo,

0 commit comments

Comments
 (0)