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

@@ -5,7 +5,6 @@ export const loginSchema = z.object({
phone: z.string().min(12, 'Xato raqam kiritildi'),
passportSeriya: z.string().length(2, '2 ta harf kerak'),
passportNumber: z.string().length(7, '7 ta raqam kerak'),
branchId: z.number().min(1, 'Filialni tanlang'),
});
export type LoginFormType = z.infer<typeof loginSchema>;

View File

@@ -1,10 +1,9 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { authApi } from 'api/auth';
import { loginPayload } from 'api/auth/type';
import { Branch, branchApi } from 'api/branch';
import AppText from 'components/AppText';
import formatPhone from 'helpers/formatPhone';
import React, { useCallback, useMemo, useRef, useState } from 'react';
@@ -24,9 +23,7 @@ import { SafeAreaView } from 'react-native-safe-area-context';
import Logo from 'screens/../../assets/bootsplash/logo_512.png';
import { LoginFormType, loginSchema } from 'screens/auth/login/lib/form';
import LanguageSelector from 'screens/auth/select-language/SelectLang';
import ArrowDown from 'svg/ArrowDown';
import ArrowLeft from 'svg/ArrowLeft';
import ArrowUp from 'svg/ArrowUp';
import { useUserStore } from '../lib/userstore';
import { Loginstyle } from './styled';
@@ -46,10 +43,10 @@ const Login = () => {
const { setUser, setExpireTime } = useUserStore(state => state);
const [error, setError] = useState<string>();
const [rawPhone, setRawPhone] = useState('+998');
const { data: branchList } = useQuery({
queryKey: ['branchList'],
queryFn: branchApi.branchList,
});
// const { data: branchList } = useQuery({
// queryKey: ['branchList'],
// queryFn: branchApi.branchList,
// });
// const [firebaseToken, setFirebseToken] = useState<{
// fcmToken: string;
// deviceId: string;
@@ -109,7 +106,6 @@ const Login = () => {
const onSubmit = (data: LoginFormType) => {
mutate({
branchId: data.branchId,
phoneNumber: data.phone,
passportSerial: `${data.passportSeriya.toUpperCase()}${
data.passportNumber
@@ -164,7 +160,7 @@ const Login = () => {
style={Loginstyle.container}
behavior={keyboardBehavior}
>
<ScrollView style={{ flex: 1 }}>
<ScrollView style={{ flex: 1 }} keyboardShouldPersistTaps="handled">
<View style={Loginstyle.scrollContainer}>
<View style={Loginstyle.loginContainer}>
<AppText style={Loginstyle.title}>
@@ -251,7 +247,7 @@ const Login = () => {
)}
</View>
<Controller
{/* <Controller
control={control}
name="branchId"
render={({ field: { value } }) => (
@@ -314,7 +310,7 @@ const Login = () => {
)}
</View>
)}
/>
/> */}
<TouchableOpacity
onPress={handleSubmit(onSubmit)}

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={[

View File

@@ -21,8 +21,8 @@ import {
Dimensions,
Image,
ImageBackground,
Keyboard,
KeyboardAvoidingView,
Platform,
ScrollView,
TextInput,
TouchableOpacity,
@@ -55,8 +55,11 @@ const SecondStep = () => {
const passportNumberRef = useRef<TextInput>(null);
const [checkboxAnimation] = useState(new Animated.Value(1));
const [inputValue, setInputValue] = useState('');
const [error, setError] = useState<string>('');
const { firstName, lastName } = useUserStore(state => state);
const passportSeriyaRef = useRef<TextInput>(null);
const jshshirRef = useRef<TextInput>(null);
const birthDateRef = useRef<TextInput>(null);
const navigation =
useNavigation<NativeStackNavigationProp<RootStackParamList, 'Login'>>();
const route = useRoute<RouteProp<RootStackParamList, 'Register'>>();
@@ -76,8 +79,8 @@ const SecondStep = () => {
onSuccess: res => {
navigation.navigate('Home');
},
onError: err => {
console.dir(err);
onError: (err: any) => {
setError(err.response.data);
},
});
@@ -145,10 +148,14 @@ const SecondStep = () => {
</View>
<KeyboardAvoidingView
style={RegisterStyle.container}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{ flex: 1 }}
behavior="padding"
keyboardVerticalOffset={50}
>
<ScrollView style={RegisterStyle.content}>
<ScrollView
contentContainerStyle={{ flexGrow: 1 }}
keyboardShouldPersistTaps="handled"
>
<View style={RegisterStyle.scrollContainer}>
<View style={RegisterStyle.loginContainer}>
<AppText style={RegisterStyle.title}>
@@ -170,6 +177,7 @@ const SecondStep = () => {
name="passportSeriya"
render={({ field: { onChange, value } }) => (
<TextInput
ref={passportSeriyaRef}
style={[
RegisterStyle.input,
RegisterStyle.seriyaInput,
@@ -178,12 +186,16 @@ const SecondStep = () => {
maxLength={2}
autoCapitalize="characters"
value={value}
returnKeyType="next"
onChangeText={text => {
onChange(text);
if (text.length === 2)
passportNumberRef.current?.focus();
}}
placeholderTextColor="#D8DADC"
onSubmitEditing={() =>
passportNumberRef.current?.focus()
}
/>
)}
/>
@@ -201,10 +213,12 @@ const SecondStep = () => {
maxLength={7}
keyboardType="numeric"
value={value}
returnKeyType="next"
onChangeText={text => {
const onlyNumbers = text.replace(/[^0-9]/g, '');
onChange(onlyNumbers);
}}
onSubmitEditing={() => jshshirRef.current?.focus()}
placeholderTextColor="#D8DADC"
/>
)}
@@ -228,14 +242,17 @@ const SecondStep = () => {
</AppText>
<TextInput
style={RegisterStyle.input}
ref={jshshirRef}
placeholder="12345678901234"
placeholderTextColor="#D8DADC"
keyboardType="numeric"
maxLength={14}
returnKeyType="next"
value={value}
onChangeText={text =>
onChange(text.replace(/[^0-9]/g, ''))
}
onSubmitEditing={() => birthDateRef.current?.focus()}
/>
{errors.jshshir && (
<AppText style={RegisterStyle.errorText}>
@@ -267,10 +284,12 @@ const SecondStep = () => {
RegisterStyle.input,
{ flex: 1, borderWidth: 0 },
]}
ref={birthDateRef}
placeholder="dd/mm/yyyy"
placeholderTextColor="#D8DADC"
keyboardType="numeric"
value={value}
returnKeyType="done"
onChangeText={text => {
let cleaned = text
.replace(/[^\d]/g, '')
@@ -326,6 +345,7 @@ const SecondStep = () => {
setValue('birthDate', formatted);
}}
onSubmitEditing={handleSubmit(onSubmit)}
/>
<TouchableOpacity
onPress={() => setDatePickerVisibility(true)}
@@ -377,7 +397,10 @@ const SecondStep = () => {
>
<SingleFileDrop
title={t('Old tomon')}
onFileSelected={setFrontImage}
onFileSelected={file => {
setFrontImage(file);
Keyboard.dismiss();
}}
/>
</View>
<View
@@ -388,11 +411,18 @@ const SecondStep = () => {
>
<SingleFileDrop
title={t('Orqa tomon')}
onFileSelected={setBackImage}
onFileSelected={file => {
setBackImage(file);
Keyboard.dismiss();
}}
/>
</View>
</View>
{error && (
<AppText style={[RegisterStyle.errorText, { fontSize: 14 }]}>
{error}
</AppText>
)}
{/* BUTTON */}
<TouchableOpacity
onPress={handleSubmit(onSubmit)}

View File

@@ -3,7 +3,14 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import AppText from 'components/AppText';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native';
import {
Linking,
ScrollView,
StyleSheet,
TouchableOpacity,
View,
} from 'react-native';
import AppLink from 'react-native-app-link';
import { SafeAreaView } from 'react-native-safe-area-context';
import ArrowLeft from 'svg/ArrowLeft';
import { RootStackParamList } from 'types/types';
@@ -16,11 +23,21 @@ type TermsScreenNavigationProp = NativeStackNavigationProp<
const TermsAndConditions = () => {
const navigation = useNavigation<TermsScreenNavigationProp>();
const { t } = useTranslation();
const handleAgree = () => {
navigation.goBack();
};
const openTelegram = React.useCallback(async () => {
try {
await AppLink.maybeOpenURL('tg://resolve?domain=cpost_admin', {
appName: 'Telegram',
appStoreId: 686449807,
appStoreLocale: 'us',
playStoreId: 'org.telegram.messenger',
});
} catch (err) {
Linking.openURL('https://t.me/cpost_admin');
}
}, []);
return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
@@ -35,16 +52,24 @@ const TermsAndConditions = () => {
<ScrollView style={styles.content} showsVerticalScrollIndicator={false}>
<AppText style={styles.title}>
{t('foydalanish_shartlari_va_qoidalari')}
{t('Foydalanish shartlari va qoidalari')}
</AppText>
<AppText style={styles.sectionTitle}>{t('umumiy_qoidalar')}</AppText>
<AppText style={styles.text}>{t('umumiy_qoidalar_text')}</AppText>
<AppText style={styles.text}>
{t(
"Biz sizdan Xitoy xalq Respublikasi Davlatidan sotib olingan tovarlarni olib kelishda quyidagi tovarlarni jonatmaslikka rozilik so'raymiz.",
)}
</AppText>
<AppText style={styles.sectionTitle}>1. {t('Umumiy qoidalar')}</AppText>
<AppText style={styles.text}>{t('Taqiqlangan tovarlar matni')}</AppText>
<AppText style={styles.text}>{t('Tovarlar')}</AppText>
<AppText style={styles.sectionTitle}>
{t('foydalanuvchi_majburiyatlari')}
</AppText>
<AppText style={styles.text}>
<AppText style={[styles.text, { textAlign: 'left' }]}>
{t('foydalanuvchi_majburiyatlari_text')}
</AppText>
@@ -63,17 +88,30 @@ const TermsAndConditions = () => {
<AppText style={styles.sectionTitle}>{t('aloqa')}</AppText>
<AppText style={styles.text}>{t('aloqa_text')}</AppText>
<TouchableOpacity
onPress={() => Linking.openURL('mailto:info@cpost.uz')}
>
<AppText style={styles.text}>{t('Email')}: info@cpost.uz</AppText>
</TouchableOpacity>
<TouchableOpacity onPress={() => Linking.openURL('tel:+998951264477')}>
<AppText style={styles.text}>
{t('Telefon')}: +998 (95) 126 44 77
</AppText>
</TouchableOpacity>
<TouchableOpacity onPress={openTelegram}>
<AppText style={styles.text}>{t('Telegram')}: @cpost_admin</AppText>
</TouchableOpacity>
<View style={styles.footer}>
<AppText style={styles.footerText}>
{t('oxirgi_yangilanish')} {new Date().toLocaleDateString('uz-UZ')}
{t('oxirgi_yangilanish')} 01/09/2025
</AppText>
</View>
</ScrollView>
<View style={styles.bottomContainer}>
<TouchableOpacity style={styles.agreeButton} onPress={handleAgree}>
<AppText style={styles.agreeButtonText}>{t('roziman')}</AppText>
<AppText style={styles.agreeButtonText}>{t('Roziman')}</AppText>
</TouchableOpacity>
</View>
</SafeAreaView>

View File

@@ -41,10 +41,16 @@ const SelectAuth = () => {
styles.logoImage,
{
width: 180,
height: 180,
height: 150,
marginLeft: 35,
},
]}
/>
<AppText
style={[styles.logoText, { fontSize: 52, fontWeight: '900' }]}
>
CPOST
</AppText>
{/* <AppText style={[styles.logoText, { fontSize: 32 }]}>CPOST</AppText> */}
</View>

View File

@@ -6,7 +6,14 @@ import AppText from 'components/AppText';
import LayoutTwo from 'components/LayoutTwo';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native';
import {
Linking,
ScrollView,
StyleSheet,
TouchableOpacity,
View,
} from 'react-native';
import AppLink from 'react-native-app-link';
import Tabs from '../../home/ui/Tabs';
interface CargoPricesProps {}
@@ -25,6 +32,19 @@ const CargoPrices = (props: CargoPricesProps) => {
refetch();
}, [activeTab]);
const openTelegram = React.useCallback(async () => {
try {
await AppLink.maybeOpenURL('tg://resolve?domain=cpost_admin', {
appName: 'Telegram',
appStoreId: 686449807,
appStoreLocale: 'us',
playStoreId: 'org.telegram.messenger',
});
} catch (err) {
Linking.openURL('https://t.me/cpost_admin');
}
}, []);
return (
<LayoutTwo title={t('Kargo narxlari')}>
<ScrollView style={{ flex: 1 }}>
@@ -105,7 +125,10 @@ const CargoPrices = (props: CargoPricesProps) => {
</AppText>
</View>
<AppText style={[styles.desc, { color: '#000000' }]}>
{t('Batafsil')}: @CPcargo_admin
{t('Batafsil')}:{' '}
<AppText style={{ color: '#28A7E8' }} onPress={openTelegram}>
@cpost_admin
</AppText>
</AppText>
</View>
<View style={[styles.card]}>
@@ -193,7 +216,10 @@ const CargoPrices = (props: CargoPricesProps) => {
</AppText>
</View>
<AppText style={[styles.desc, { color: '#000000' }]}>
{t('Batafsil')}: @CPcargo_admin
{t('Batafsil')}:{' '}
<AppText style={{ color: '#28A7E8' }} onPress={openTelegram}>
@cpost_admin
</AppText>
</AppText>
</View>
<View style={[styles.card]}>

View File

@@ -75,7 +75,11 @@ const Home = () => {
removeClippedSubviews={true}
keyboardShouldPersistTaps="handled"
>
<PartyCarousel autoData={autoData} aviaData={aviaData} />
<PartyCarousel
autoData={autoData}
aviaData={aviaData}
activeTab={activeTab}
/>
<Tabs setActiveTab={setActiveTab} activeTab={activeTab} />
{activeTabContent}
<Pages />

View File

@@ -1,6 +1,6 @@
import AnimatedIcon from 'components/AnimatedIcon';
import AppText from 'components/AppText';
import React, { useMemo, useRef, useState } from 'react';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
FlatList,
@@ -10,6 +10,11 @@ import {
useWindowDimensions,
View,
} from 'react-native';
import Animated, {
useAnimatedStyle,
useSharedValue,
withTiming,
} from 'react-native-reanimated';
import Auto from 'svg/Auto';
import Avia from 'svg/Avia';
import BoxCreate from 'svg/BoxCreate';
@@ -18,16 +23,35 @@ import { HomeStyle } from './styled';
const PartyCarousel = ({
aviaData,
activeTab,
autoData,
}: {
autoData: any;
aviaData: any;
activeTab: 'AUTO' | 'AVIA';
}) => {
const { width: screenWidth } = useWindowDimensions();
const cardWidth = screenWidth * 0.95;
const styles = useMemo(() => HomeStyle(), []);
const { t } = useTranslation();
// animatsiya
const opacity = useSharedValue(0);
const translateY = useSharedValue(20);
useEffect(() => {
opacity.value = 1;
translateY.value = 0;
opacity.value = withTiming(1, { duration: 500 });
translateY.value = withTiming(0, { duration: 500 });
}, [activeTab]);
const animatedStyle = useAnimatedStyle(() => ({
opacity: opacity.value,
transform: [{ translateY: translateY.value }],
}));
// status config
const statusConfig: any = {
COLLECTING: {
backgroundColor: '#28A7E8',
@@ -56,7 +80,7 @@ const PartyCarousel = ({
},
};
// calendarList tayyorlash
// calendarList faqat activeTab uchun
const calendarList = useMemo(() => {
const data: any[] = [];
const weekdays = [
@@ -89,10 +113,14 @@ const PartyCarousel = ({
});
};
prepareList(autoData, 'auto');
prepareList(aviaData, 'avia');
if (activeTab === 'AUTO') {
prepareList(autoData, 'auto');
} else if (activeTab === 'AVIA') {
prepareList(aviaData, 'avia');
}
return data;
}, [autoData, aviaData]);
}, [autoData, aviaData, activeTab]);
const flatListRef = useRef<FlatList>(null);
const today = useMemo(() => {
@@ -102,6 +130,7 @@ const PartyCarousel = ({
}, []);
const [selectedItem, setSelectedItem] = useState<any>(null);
const [modalVisible, setModalVisible] = useState(false);
const renderItem = ({ item, index }: { item: any; index: number }) => {
const isLast = index === calendarList.length - 1;
return (
@@ -171,7 +200,7 @@ const PartyCarousel = ({
{item.cargo.toUpperCase()}
</AppText>
<View style={styles.animatedIconWrapper}>
<AnimatedIcon type={item.cargo} />
<AnimatedIcon type={activeTab} />
</View>
</View>
</>
@@ -181,9 +210,8 @@ const PartyCarousel = ({
};
return (
<>
<Animated.View style={animatedStyle}>
<FlatList
ref={flatListRef}
data={calendarList}
keyExtractor={(_, index) => index.toString()}
renderItem={renderItem}
@@ -233,7 +261,7 @@ const PartyCarousel = ({
</View>
</View>
</Modal>
</>
</Animated.View>
);
};

View File

@@ -12,7 +12,6 @@ import {
ActivityIndicator,
Dimensions,
KeyboardAvoidingView,
Platform,
ScrollView,
TextInput,
TouchableOpacity,
@@ -42,6 +41,17 @@ const CreatePassword = () => {
const [error, setError] = useState(false);
const [frontImage, setFrontImage] = useState<FileData | null>(null);
const [backImage, setBackImage] = useState<FileData | null>(null);
// firstName: '',
// lastName: '',
// birthDate: '',
// passportSeriya: '',
// passportNumber: '',
// jshshir: '',
const firstNameRef = useRef<TextInput>(null);
const lastNameRef = useRef<TextInput>(null);
const birthDateRef = useRef<TextInput>(null);
const passportSeriyaRef = useRef<TextInput>(null);
const jshshirRef = useRef<TextInput>(null);
const { mutate, isPending } = useMutation({
mutationFn: (payload: AddPassportPayload) => {
@@ -105,12 +115,14 @@ const CreatePassword = () => {
});
};
return (
<LayoutTwo title="Yangi pasport qo'shish">
<LayoutTwo title={t("Yangi pasport qo'shish")}>
<KeyboardAvoidingView
style={PassportStyle.container}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
behavior={'padding'}
keyboardVerticalOffset={30}
>
<ScrollView
keyboardShouldPersistTaps="handled"
showsVerticalScrollIndicator={false}
style={PassportStyle.content}
>
@@ -123,6 +135,9 @@ const CreatePassword = () => {
<View>
<AppText style={PassportStyle.label}>{t('Ism')}</AppText>
<TextInput
ref={firstNameRef}
returnKeyType="next"
onSubmitEditing={() => lastNameRef.current?.focus()}
style={PassportStyle.input}
placeholder={t('Ismingiz')}
onChangeText={onChange}
@@ -146,6 +161,9 @@ const CreatePassword = () => {
{t('Familiya')}
</AppText>
<TextInput
ref={lastNameRef}
returnKeyType="next"
onSubmitEditing={() => passportSeriyaRef.current?.focus()}
style={PassportStyle.input}
placeholder={t('Familiyangiz')}
placeholderTextColor={'#D8DADC'}
@@ -170,6 +188,11 @@ const CreatePassword = () => {
name="passportSeriya"
render={({ field: { onChange, value } }) => (
<TextInput
ref={passportSeriyaRef}
returnKeyType="next"
onSubmitEditing={() =>
passportNumberRef.current?.focus()
}
style={[PassportStyle.input, PassportStyle.seriyaInput]}
placeholder="AA"
maxLength={2}
@@ -191,6 +214,8 @@ const CreatePassword = () => {
render={({ field: { onChange, value } }) => (
<TextInput
ref={passportNumberRef}
returnKeyType="next"
onSubmitEditing={() => jshshirRef.current?.focus()}
style={[PassportStyle.input, PassportStyle.raqamInput]}
placeholder="1234567"
maxLength={7}
@@ -220,6 +245,9 @@ const CreatePassword = () => {
render={({ field: { onChange, value } }) => (
<TextInput
style={PassportStyle.input}
ref={jshshirRef}
returnKeyType="next"
onSubmitEditing={() => birthDateRef.current?.focus()}
placeholder="12345678901234"
placeholderTextColor={'#D8DADC'}
keyboardType="numeric"
@@ -250,6 +278,8 @@ const CreatePassword = () => {
<View style={[PassportStyle.inputContainer]}>
<TextInput
ref={birthDateRef}
returnKeyType="done"
style={[
PassportStyle.input,
{ flex: 1, borderWidth: 0, padding: 0 },

View File

@@ -51,15 +51,14 @@ const ProfilePages = (props: componentNameProps) => {
const openTelegram = React.useCallback(async () => {
try {
await AppLink.maybeOpenURL('tg://resolve?domain=cpostuz', {
await AppLink.maybeOpenURL('tg://resolve?domain=cpost_admin', {
appName: 'Telegram',
appStoreId: 686449807,
appStoreLocale: 'us',
playStoreId: 'org.telegram.messenger',
});
} catch (err) {
// Agar ilovani ham, storeni ham ochib bolmasa, fallback URL
Linking.openURL('https://t.me/cpostuz');
Linking.openURL('https://t.me/cpost_admin');
}
}, []);

View File

@@ -75,7 +75,7 @@ const TabsAutoWarehouses = () => {
};
const { data } = useQuery({
queryKey: ['warhouses'],
queryKey: ['warhouses_auto'],
queryFn: () => warhouses_api.getWarhouses({ cargoType: 'AUTO' }),
});

View File

@@ -75,7 +75,7 @@ const TabsAviaWarehouses = () => {
};
const { data } = useQuery({
queryKey: ['warhouses'],
queryKey: ['warhouses_avia'],
queryFn: () => warhouses_api.getWarhouses({ cargoType: 'AVIA' }),
});
@@ -108,7 +108,7 @@ const TabsAviaWarehouses = () => {
<View style={[styles.card, { marginRight: isLast ? 0 : 10 }]}>
<View style={styles.titleCard}>
<Kitay width={24 * scale} height={24 * scale} />
<AppText style={styles.title}>China (Auto)</AppText>
<AppText style={styles.title}>China (AVIA)</AppText>
</View>
<View style={styles.infoId}>
<View style={{ gap: 4 * scale, width: '90%' }}>

View File

@@ -100,15 +100,14 @@ Cargo Idsi: ${getMe?.aviaCargoId}
);
const openTelegram = React.useCallback(async () => {
try {
await AppLink.maybeOpenURL('tg://resolve?domain=cpostuz', {
await AppLink.maybeOpenURL('tg://resolve?domain=cpost_admin', {
appName: 'Telegram',
appStoreId: 686449807,
appStoreLocale: 'us',
playStoreId: 'org.telegram.messenger',
});
} catch (err) {
// Agar ilovani ham, storeni ham ochib bolmasa, fallback URL
Linking.openURL('https://t.me/cpostuz');
Linking.openURL('https://t.me/cpost_admin');
}
}, []);
return (

View File

@@ -40,11 +40,14 @@ const SelectLangPage = ({
styles.logoImage,
{
width: 180,
height: 180,
height: 150,
marginLeft: 35,
},
]}
/>
<AppText style={[styles.logoText, { fontSize: 24 }]}>
<AppText
style={[styles.logoText, { fontSize: 42, fontWeight: '700' }]}
>
CPOST
</AppText>
</View>
@@ -59,10 +62,19 @@ const SelectLangPage = ({
<View style={styles.btnContainer}>
<TouchableOpacity
onPress={() => onSelectLang('uz')}
style={styles.button}
style={[
styles.button,
{
backgroundColor: 'none',
borderWidth: 1,
borderColor: '#28A7E8',
},
]}
>
<Image source={UZ} style={styles.flag} />
<AppText style={styles.btnText}>O'zbek tili</AppText>
<AppText style={[styles.btnText, { color: '#28A7E8' }]}>
O'zbek tili
</AppText>
</TouchableOpacity>
<TouchableOpacity
@@ -134,7 +146,7 @@ const styles = StyleSheet.create({
},
flag: {
width: 30,
height: 30,
height: 20,
resizeMode: 'cover',
},
});