Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions apps/frontend/app/(auth)/(signup)/info.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { images } from '@/assets';
import { InputField, PrimaryButton } from '@/components';
import { InputField, PhoneInputField, PrimaryButton } from '@/components';
import { AlertStrings, Strings } from '@/constants';
import { useAuth, useMarket } from '@/hooks';
import { formatPhoneNumber, validateConfirmPassword, validateName, validatePassword, validatePhone } from '@/utils';
import { useAuth, useCountry, useMarket } from '@/hooks';
import {
formatPhoneNumber,
trimPhoneNumber,
validateConfirmPassword,
validateName,
validatePassword,
validatePhone,
} from '@/utils';
import { router, useLocalSearchParams } from 'expo-router';
import { useState } from 'react';
import { Alert, Dimensions, Image, KeyboardAvoidingView, Platform, ScrollView, Text, View } from 'react-native';
Expand All @@ -11,12 +18,14 @@ import { SafeAreaView } from 'react-native-safe-area-context';
const SignUpInfo = () => {
const { fetchAllTickers } = useMarket();
const { signup, isLoading } = useAuth();
const { currentCountry } = useCountry();
const { email } = useLocalSearchParams<{ email: string }>();

const [formData, setFormData] = useState({ name: '', email: email, password: '', confirmPassword: '', phone: '' });

const submitForm = async () => {
const { name, email, password, confirmPassword, phone } = formData;
const { name, email, password, confirmPassword } = formData;
const phone = trimPhoneNumber(formData.phone);

const nameValidationResult = validateName(name);
const phoneValidationResult = validatePhone(phone);
Expand Down Expand Up @@ -64,13 +73,14 @@ const SignUpInfo = () => {
value={formData.email}
disabled={true}
/>
<InputField

<PhoneInputField
label={Strings.signupInfo.PHONE_LABEL}
keyboardType='phone-pad'
value={formatPhoneNumber(formData.phone)}
disabled={isLoading}
onChangeText={(value) => setFormData((prev) => ({ ...prev, phone: value }))}
number={formatPhoneNumber(formData.phone)}
countryId={currentCountry?.id}
onChange={(value) => setFormData((prev) => ({ ...prev, phone: value }))}
/>

<InputField
label={Strings.signupInfo.PASSWORD_LABEL}
secureTextEntry
Expand Down
13 changes: 8 additions & 5 deletions apps/frontend/app/(tabs)/(profile)/edit.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { InitialsAvatar, InputField, PrimaryButton } from '@/components';
import { InitialsAvatar, InputField, PhoneInputField, PrimaryButton } from '@/components';
import { AlertStrings, Strings } from '@/constants';
import { useProfile } from '@/hooks';
import { useCountry, useProfile } from '@/hooks';
import { useAuthStore } from '@/store';
import { formatPhoneNumber, validateName } from '@/utils';
import { validateName } from '@/utils';
import { useState } from 'react';
import { Alert, KeyboardAvoidingView, Platform, ScrollView, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

const Edit = () => {
const { user } = useAuthStore();
const { currentCountry } = useCountry();
const { isLoading, profile, updateProfile } = useProfile();

const [formData, setFormData] = useState<Partial<Profile>>(profile ?? {});

const updateInfo = (key: string, value: string) => {
Expand Down Expand Up @@ -53,9 +55,10 @@ const Edit = () => {

<InputField label={Strings.editProfile.EMAIL_LABEL} value={user?.user_metadata.email} disabled={true} />

<InputField
<PhoneInputField
label={Strings.editProfile.PHONE_LABEL}
value={formatPhoneNumber(user?.user_metadata.phone)}
countryId={currentCountry?.id}
number={user?.user_metadata.phone}
disabled={true}
/>

Expand Down
16 changes: 8 additions & 8 deletions apps/frontend/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@
@apply gap-y-4;
}

.input-wrapper {
/* .input-wrapper {
@apply w-full;
}
} */

.input-label {
@apply pl-1 font-clashDisplay;
Expand Down Expand Up @@ -497,15 +497,15 @@
}

.deposit-form-value-wrapper {
@apply flex-1 rounded-l-lg bg-card px-4 py-3 dark:bg-card-dark;
@apply flex-1 rounded-l-lg bg-base-white px-4 py-3 dark:bg-base-dark;
}

.deposit-form-value {
@apply font-satoshi text-sm text-body dark:text-body-dark;
}

.deposit-form-icon-wrapper {
@apply w-14 items-center justify-center rounded-r-lg bg-base-white dark:bg-base-dark;
@apply w-14 items-center justify-center rounded-r-lg bg-card dark:bg-card-dark;
}

.deposit-form-footer {
Expand Down Expand Up @@ -545,15 +545,15 @@
}

.dropdown-wrapper {
@apply flex-row rounded-lg border border-stroke dark:border-stroke-dark;
@apply w-full flex-row rounded-lg border border-stroke dark:border-stroke-dark;
}

.dropdown-label {
@apply font-clashDisplay text-sm text-label dark:text-label-dark;
}

.dropdown-value-wrapper {
@apply flex-1 rounded-l-lg bg-card px-4 py-3 dark:bg-card-dark;
@apply flex-1 rounded-l-lg bg-base-white px-4 py-3 dark:bg-base-dark;
}

.dropdown-value {
Expand All @@ -565,15 +565,15 @@
}

.dropdown-icon-wrapper {
@apply w-14 items-center justify-center rounded-r-lg bg-base-white dark:bg-base-dark;
@apply w-14 items-center justify-center rounded-r-lg bg-card dark:bg-card-dark;
}

.dropdown-error {
@apply font-satoshi-medium text-xs text-red-500;
}

.dropdown-options-wrapper {
@apply rounded-lg border-[0.5px] border-stroke bg-card shadow-lg dark:border-stroke-dark dark:bg-card-dark;
@apply rounded-lg border-[0.5px] border-stroke bg-card shadow-lg dark:border-stroke-dark dark:bg-card-info-dark;
}

.dropdown-option {
Expand Down
70 changes: 51 additions & 19 deletions apps/frontend/components/filters/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ const Dropdown = (props: DropdownProps) => {

const animationProgress = useSharedValue(0);

const showIcon = props.showIcon ?? 'true';
const value = props.items.find((item) => item.id === props.value?.id);
const displayValue = value?.label || props.placeholder || 'Select an option';
const disabled = props.disabled ?? props.items.length === 1;

const handleSelect = (item: FilterItem) => {
handleCloseDropdown();
Expand All @@ -23,7 +25,7 @@ const Dropdown = (props: DropdownProps) => {
};

const handleOpenDropdown = () => {
if (props.disabled) return;
if (disabled) return;
setIsOpen(true);
requestAnimationFrame(() => {
requestAnimationFrame(() => {
Expand Down Expand Up @@ -57,32 +59,52 @@ const Dropdown = (props: DropdownProps) => {
{props.title && <Text className='dropdown-label'>{props.title}</Text>}

<Pressable
className={cn(
'dropdown-wrapper',
props.disabled ? 'opacity-50' : '',
props.error ? 'border-red-500' : '',
props.buttonStyle,
)}
className={cn('dropdown-wrapper', props.error ? 'border-red-500' : '', props.buttonStyle)}
onPress={handleOpenDropdown}
disabled={props.disabled}
disabled={disabled}
>
<View className='dropdown-value-wrapper'>
<View
className={cn(
'dropdown-value-wrapper flex-row items-center',
!showIcon && 'rounded-r-lg',
value?.secondaryLabel && 'justify-between',
disabled && 'bg-card dark:bg-card-info-dark',
)}
>
<Text
className={cn(value == undefined ? 'dropdown-placeholder' : 'dropdown-value')}
className={cn(
value == undefined ? 'dropdown-placeholder' : 'dropdown-value',
disabled && 'text-body/45 dark:text-body-dark/45',
)}
numberOfLines={1}
ellipsizeMode='tail'
>
{displayValue}
</Text>
</View>

<View className='dropdown-icon-wrapper'>
<Image
source={isDark ? icons.dark.arrowDown : icons.light.arrowDown}
className='size-8'
resizeMode='contain'
/>
{value?.secondaryLabel && (
<Text
className={cn(
value == undefined ? 'dropdown-placeholder' : 'dropdown-value',
disabled && 'text-body/45 dark:text-body-dark/45',
)}
numberOfLines={1}
ellipsizeMode='tail'
>
{value?.secondaryLabel}
</Text>
)}
</View>

{showIcon && (
<View className='dropdown-icon-wrapper'>
<Image
source={isDark ? icons.dark.arrowDown : icons.light.arrowDown}
className='size-8'
resizeMode='contain'
/>
</View>
)}
</Pressable>
{props.error && <Text className='dropdown-error'>{props.error}</Text>}
{isOpen && (
Expand All @@ -96,7 +118,7 @@ const Dropdown = (props: DropdownProps) => {
renderItem={({ item, index }) => (
<Pressable
className={cn(
'dropdown-option',
'dropdown-option flex-row items-center justify-between',
index === 0 && 'rounded-t-md',
index !== props.items.length - 1
? 'border-b-[0.5px] border-stroke dark:border-stroke-dark'
Expand All @@ -108,11 +130,21 @@ const Dropdown = (props: DropdownProps) => {
<Text
className={cn(
'dropdown-option-txt',
item.id === props.value?.id ? 'text-title dark:text-title-dark' : 'text-label dark:text-label',
item.id === props.value?.id ? 'text-title' : 'text-label dark:text-label',
)}
>
{item.label}
</Text>
{value?.secondaryLabel && (
<Text
className={cn(
'dropdown-option-txt',
item.id === props.value?.id ? 'text-title' : 'text-label dark:text-label',
)}
>
{value?.secondaryLabel}
</Text>
)}
</Pressable>
)}
showsVerticalScrollIndicator={false}
Expand Down
37 changes: 37 additions & 0 deletions apps/frontend/components/form/PhoneInputField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useCountry } from '@/hooks';
import { formatPhoneNumber } from '@/utils';
import { Text, View } from 'react-native';
import { Dropdown } from '../filters';
import SecondaryInputField from './SecondaryInputField';

const PhoneInputField = (props: PhoneInputFieldProps) => {
const { countryPhoneCodeFilterItems, getCountryFilterItemById } = useCountry();
const countryFilter = getCountryFilterItemById(countryPhoneCodeFilterItems, props.countryId ?? '');
const disabled = props.disabled ?? false;

return (
<View className='gap-y-2'>
{props.label && <Text className='font-clashDisplay text-sm text-label dark:text-label-dark'>{props.label}</Text>}
<View className='flex-row items-end gap-x-2'>
<Dropdown
value={countryFilter}
items={countryPhoneCodeFilterItems}
showIcon={false}
containerStyle='w-28'
disabled={disabled || countryPhoneCodeFilterItems.length === 1}
/>

<View className='flex-1 justify-start'>
<SecondaryInputField
label=''
value={formatPhoneNumber(props.number ?? '')}
disabled={disabled}
onChangeText={props.onChange}
/>
</View>
</View>
</View>
);
};

export default PhoneInputField;
11 changes: 6 additions & 5 deletions apps/frontend/components/form/SecondaryInputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const SecondaryInputField = (props: SecondaryInputFieldProps) => {

return (
<View className='gap-y-2'>
<Text className='font-clashDisplay text-sm text-label dark:text-label-dark'>{props.label}</Text>
{props.label && <Text className='font-clashDisplay text-sm text-label dark:text-label-dark'>{props.label}</Text>}
<View
className={cn(
'flex-row items-stretch rounded-lg border',
Expand All @@ -20,15 +20,16 @@ const SecondaryInputField = (props: SecondaryInputFieldProps) => {
>
<View
className={cn(
'relative flex-1 bg-card px-4 font-satoshi text-sm dark:bg-card-dark',
'flex-1 px-4 font-satoshi text-sm',
props.secondarylabel ? 'rounded-l-lg' : 'rounded-lg',
props.disabled ? 'bg-card dark:bg-card-info-dark' : 'bg-base-white dark:bg-base-dark',
)}
>
<TextInput
className={cn(
'px-0 font-satoshi text-sm',
isIOS ? 'py-2 pb-3' : 'py-3',
props.disabled ? 'text-body/75 dark:text-body-dark/75' : 'text-body dark:text-body-dark',
props.disabled ? 'text-body/45 dark:text-body-dark/45' : 'text-body dark:text-body-dark',
)}
value={value}
autoCapitalize='none'
Expand All @@ -48,8 +49,8 @@ const SecondaryInputField = (props: SecondaryInputFieldProps) => {
{props.secondarylabel && (
<View
className={cn(
'justify-center rounded-r-lg px-4 py-3',
isFocused ? 'bg-primary' : 'bg-base-white dark:bg-base-dark',
'it w-14 items-center justify-center rounded-r-lg py-3',
isFocused ? 'bg-primary' : 'bg-card dark:bg-card-dark',
props.disabled && 'opacity-45',
)}
>
Expand Down
1 change: 1 addition & 0 deletions apps/frontend/components/form/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as FileUplaod } from './FileUpload';
export { default as InputField } from './InputField';
export { default as PhoneInputField } from './PhoneInputField';
export { default as SecondaryInputField } from './SecondaryInputField';
export { default as StepperInput } from './StepperInput';
6 changes: 4 additions & 2 deletions apps/frontend/components/sections/VerifyIdentity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import FileUpload from '../form/FileUpload';

const VerifyIdentity = () => {
const { kyc, updateKyc } = useKyc();
const { countryNameFilterItems, getCountryNameFilterItemById } = useCountry();
const { countryNameFilterItems, getCountryFilterItemById } = useCountry();

const country = getCountryNameFilterItemById(kyc?.countryId ?? '');
const country = getCountryFilterItemById(countryNameFilterItems, kyc?.countryId ?? '');

return (
<>
Expand All @@ -23,8 +23,10 @@ const VerifyIdentity = () => {

<Dropdown
value={country}
disabled={false}
title={Strings.info.COUNTRY_LABEL}
items={countryNameFilterItems}
placeholder={Strings.info.COUNTRY_HINT}
onSelect={(item) => updateKyc('countryId', item.id)}
/>

Expand Down
Loading