This commit is contained in:
Samandar Turgunboyev
2025-10-02 17:05:40 +05:00
parent 38badbe3dd
commit 9aac17072f
27 changed files with 1636 additions and 1380 deletions

View File

@@ -1,8 +1,6 @@
'use client';
import { zodResolver } from '@hookform/resolvers/zod';
// import { getApp } from '@react-native-firebase/app';
// import { getMessaging, getToken } from '@react-native-firebase/messaging';
import {
type RouteProp,
useNavigation,
@@ -15,15 +13,15 @@ import { registerPayload } from 'api/auth/type';
import { Branch, branchApi } from 'api/branch';
import AppText from 'components/AppText';
import formatPhone from 'helpers/formatPhone';
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import {
ActivityIndicator,
Animated,
ImageBackground,
Keyboard,
KeyboardAvoidingView,
Platform,
ScrollView,
TextInput,
TouchableOpacity,
@@ -66,37 +64,6 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
queryFn: branchApi.branchList,
});
// const [firebaseToken, setFirebseToken] = useState<{
// fcmToken: string;
// deviceId: string;
// deviceName: string;
// deviceType: string;
// } | null>();
// const app = getApp();
// const messaging = getMessaging(app);
// const getDeviceData = async () => {
// try {
// const fcmToken = await getToken(messaging);
// return {
// fcmToken,
// deviceId: await DeviceInfo.getUniqueId(),
// deviceName: await DeviceInfo.getDeviceName(),
// deviceType: await DeviceInfo.getDeviceType(),
// };
// } catch (e) {
// console.log('Xato:', e);
// return null;
// }
// };
// useEffect(() => {
// getDeviceData().then(data => {
// setFirebseToken(data);
// });
// }, []);
const { mutate, isPending } = useMutation({
mutationFn: (payload: registerPayload) => authApi.register(payload),
onSuccess: res => {
@@ -114,12 +81,12 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
const navigation = useNavigation<LoginScreenNavigationProp>();
const [rawPhone, setRawPhone] = useState('+998');
const route = useRoute<RouteProp<RootStackParamList, 'Register'>>();
const {
control,
handleSubmit,
setValue,
formState: { errors },
getValues,
} = useForm<FirstStepFormType>({
resolver: zodResolver(FirstStepSchema),
defaultValues: {
@@ -130,6 +97,12 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
},
});
// 🔑 Input ref'lar
const firstNameRef = useRef<TextInput>(null);
const lastNameRef = useRef<TextInput>(null);
const phoneRef = useRef<TextInput>(null);
const addressRef = useRef<TextInput>(null);
const onSubmit = (data: FirstStepFormType) => {
setUser({
firstName: data.firstName,
@@ -195,7 +168,7 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
imageStyle={{
opacity: 0.1,
height: '100%',
width: '100%',
width: '90%',
transform: [{ scale: 1 }],
}}
>
@@ -207,12 +180,13 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
<LanguageSelector />
</View>
<KeyboardAvoidingView
style={RegisterStyle.container}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{ flex: 1 }}
behavior="padding"
keyboardVerticalOffset={50}
>
<ScrollView
showsVerticalScrollIndicator={false}
style={RegisterStyle.content}
contentContainerStyle={{ flexGrow: 1 }}
keyboardShouldPersistTaps="handled"
>
<View style={RegisterStyle.scrollContainer}>
<View style={RegisterStyle.loginContainer}>
@@ -220,18 +194,22 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
{t("Ro'yxatdan o'tish")}
</AppText>
{/* Ism */}
<Controller
control={control}
name="firstName"
render={({ field: { onChange, value } }) => (
<View>
<AppText style={RegisterStyle.label}>{t('Ism')} </AppText>
<AppText style={RegisterStyle.label}>{t('Ism')}</AppText>
<TextInput
ref={firstNameRef}
style={RegisterStyle.input}
placeholder={t('Ismingiz')}
onChangeText={onChange}
value={value}
placeholderTextColor={'#D8DADC'}
returnKeyType="next"
onSubmitEditing={() => lastNameRef.current?.focus()}
/>
{errors.firstName && (
<AppText style={RegisterStyle.errorText}>
@@ -241,20 +219,25 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
</View>
)}
/>
{/* Familiya */}
<Controller
control={control}
name="lastName"
render={({ field: { onChange, value } }) => (
<View>
<AppText style={RegisterStyle.label}>
{t('Familiya')}{' '}
{t('Familiya')}
</AppText>
<TextInput
ref={lastNameRef}
style={RegisterStyle.input}
placeholder={t('Familiyangiz')}
placeholderTextColor={'#D8DADC'}
onChangeText={onChange}
value={value}
returnKeyType="next"
onSubmitEditing={() => phoneRef.current?.focus()}
/>
{errors.lastName && (
<AppText style={RegisterStyle.errorText}>
@@ -264,6 +247,8 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
</View>
)}
/>
{/* Telefon raqami */}
<Controller
control={control}
name="phoneNumber"
@@ -275,6 +260,7 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
{t('Telefon raqami')}
</AppText>
<TextInput
ref={phoneRef}
keyboardType="numeric"
placeholder="+998 __ ___-__-__"
value={formatted}
@@ -289,6 +275,10 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
style={RegisterStyle.input}
placeholderTextColor="#D8DADC"
maxLength={17}
returnKeyType="next"
onSubmitEditing={
() => setFilialDropdownVisible(true) // ❗ Branch select ochiladi
}
/>
{errors.phoneNumber && (
<AppText style={RegisterStyle.errorText}>
@@ -299,20 +289,23 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
);
}}
/>
{/* Filial (dropdown) */}
<Controller
control={control}
name="branchId"
render={({ field: { value } }) => (
<View style={{ position: 'relative' }}>
<AppText style={RegisterStyle.label}>
{t('Filial')}{' '}
{t('Filial')}
</AppText>
<View style={RegisterStyle.input}>
<TouchableOpacity
style={RegisterStyle.selector}
onPress={() =>
setFilialDropdownVisible(prev => !prev)
}
onPress={() => {
setFilialDropdownVisible(prev => !prev);
Keyboard.dismiss();
}}
>
<AppText
style={
@@ -344,6 +337,11 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
onPress={() => {
setValue('branchId', item.id);
setFilialDropdownVisible(false);
// keyingi inputga focus
setTimeout(
() => addressRef.current?.focus(),
200,
);
}}
>
<AppText
@@ -364,6 +362,8 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
</View>
)}
/>
{/* Manzil */}
<Controller
control={control}
name="address"
@@ -373,6 +373,7 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
{t('Manzilingizni kiriting')}
</AppText>
<TextInput
ref={addressRef}
style={RegisterStyle.input}
placeholder={t(
"Toshkent Shahri, Mirzo Ulug'bek tumani...",
@@ -380,15 +381,21 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
placeholderTextColor={'#D8DADC'}
onChangeText={onChange}
value={value}
returnKeyType="done"
onSubmitEditing={
() => setRecommendedDropdownVisible(true) // ❗ recommend select ochiladi
}
/>
{errors.lastName && (
{errors.address && (
<AppText style={RegisterStyle.errorText}>
{t(errors.lastName.message || '')}
{t(errors.address.message || '')}
</AppText>
)}
</View>
)}
/>
{/* Recommend (dropdown) */}
<Controller
control={control}
name="recommend"
@@ -458,6 +465,8 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
</View>
)}
/>
{/* Terms */}
<View style={RegisterStyle.termsContainer}>
<TouchableOpacity
style={RegisterStyle.checkboxContainer}
@@ -503,7 +512,6 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => {
</View>
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={handleSubmit(onSubmit)}
style={[