screen bug fix
This commit is contained in:
41
App.tsx
41
App.tsx
@@ -7,14 +7,7 @@ import { navigationRef } from 'components/NavigationRef';
|
||||
import i18n from 'i18n/i18n';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import {
|
||||
Animated,
|
||||
Dimensions,
|
||||
LogBox,
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { Animated, Dimensions, LogBox, StatusBar, View } from 'react-native';
|
||||
import Toast from 'react-native-toast-message';
|
||||
import SplashScreen from './src/components/SplashScreen';
|
||||
|
||||
@@ -68,6 +61,7 @@ export default function App() {
|
||||
const [isSplashVisible, setIsSplashVisible] = useState(true);
|
||||
const isMounted = useRef(false);
|
||||
const currentAnimation = useRef<Animated.CompositeAnimation | null>(null);
|
||||
const token = getToken();
|
||||
|
||||
useEffect(() => {
|
||||
loadInitialAuthData();
|
||||
@@ -165,8 +159,19 @@ export default function App() {
|
||||
[],
|
||||
);
|
||||
|
||||
if (initialRoute === null) {
|
||||
return <View style={{ flex: 1, backgroundColor: '#000' }} />;
|
||||
if (!initialRoute || isSplashVisible || !currentAnimation) {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#ffff',
|
||||
}}
|
||||
>
|
||||
<SplashScreen onFinish={handleSplashFinish} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -178,10 +183,9 @@ export default function App() {
|
||||
<Stack.Navigator
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
animation: 'none',
|
||||
animation: 'slide_from_right',
|
||||
gestureEnabled: false,
|
||||
}}
|
||||
// initialRouteName set once (we ensure it's available before first render)
|
||||
initialRouteName={initialRoute}
|
||||
>
|
||||
<Stack.Screen name="Onboarding">
|
||||
@@ -225,19 +229,6 @@ export default function App() {
|
||||
</Stack.Navigator>
|
||||
</NavigationContainer>
|
||||
|
||||
{/* Splash transition */}
|
||||
{isSplashVisible && (
|
||||
<Animated.View
|
||||
style={{
|
||||
...StyleSheet.absoluteFillObject,
|
||||
transform: [{ translateX: slideAnim }],
|
||||
zIndex: 10,
|
||||
}}
|
||||
>
|
||||
<SplashScreen onFinish={handleSplashFinish} />
|
||||
</Animated.View>
|
||||
)}
|
||||
|
||||
<Toast config={toastConfig} />
|
||||
</View>
|
||||
</I18nextProvider>
|
||||
|
||||
@@ -89,7 +89,7 @@ android {
|
||||
versionName "0.7"
|
||||
multiDexEnabled true
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
|
||||
// Performance optimizations
|
||||
// ndk {
|
||||
// abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -15,7 +15,7 @@ class MainActivity : ReactActivity() {
|
||||
override fun getMainComponentName(): String = "first"
|
||||
|
||||
override fun onCreate(savedInstanceState: android.os.Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
super.onCreate(null)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.facebook.react.ReactNativeHost
|
||||
import com.facebook.react.ReactPackage
|
||||
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
||||
import com.facebook.react.defaults.DefaultReactNativeHost
|
||||
import com.swmansion.rnscreens.RNScreensPackage
|
||||
|
||||
class MainApplication : Application(), ReactApplication {
|
||||
|
||||
|
||||
6
index.js
6
index.js
@@ -4,9 +4,15 @@
|
||||
// import notifee, { AndroidImportance } from '@notifee/react-native';
|
||||
// import messaging from '@react-native-firebase/messaging';
|
||||
import { AppRegistry } from 'react-native';
|
||||
import { enableScreens } from 'react-native-screens';
|
||||
import App from './App';
|
||||
import { name as appName } from './app.json';
|
||||
|
||||
|
||||
enableScreens({
|
||||
freezeOnBlur: true, // background screen componenti freeze bo'ladi
|
||||
});
|
||||
|
||||
// messaging().setBackgroundMessageHandler(async remoteMessage => {
|
||||
// console.log('Background message:', remoteMessage);
|
||||
|
||||
|
||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -27,7 +27,7 @@
|
||||
"react-native-app-link": "^1.0.1",
|
||||
"react-native-asset": "^2.1.1",
|
||||
"react-native-biometrics": "^3.0.1",
|
||||
"react-native-config": "^1.5.6",
|
||||
"react-native-config": "^1.5.0",
|
||||
"react-native-confirmation-code-field": "^8.0.1",
|
||||
"react-native-device-info": "^14.0.4",
|
||||
"react-native-dotenv": "^3.4.11",
|
||||
@@ -13011,9 +13011,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-config": {
|
||||
"version": "1.5.6",
|
||||
"resolved": "https://registry.npmjs.org/react-native-config/-/react-native-config-1.5.6.tgz",
|
||||
"integrity": "sha512-UB3LEco0FGGbbGvS+DfH2VmGKiP/y5C2MkmfBmfsIaxHSbM1KOTMKYG7YRf6xFhZbJ/01BedHG7SIny5i7N9BQ==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-config/-/react-native-config-1.5.0.tgz",
|
||||
"integrity": "sha512-slecooA/0tCwhb+RuWEbwLqtKirGh9vWPRpgDfH7uPAraCciqHNH2XjS9ylW+Spn4FUrHg5KWTqUGs9BdBADHg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react-native-windows": ">=0.61"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"react-native-app-link": "^1.0.1",
|
||||
"react-native-asset": "^2.1.1",
|
||||
"react-native-biometrics": "^3.0.1",
|
||||
"react-native-config": "^1.5.6",
|
||||
"react-native-config": "^1.5.0",
|
||||
"react-native-confirmation-code-field": "^8.0.1",
|
||||
"react-native-device-info": "^14.0.4",
|
||||
"react-native-dotenv": "^3.4.11",
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
// helpers/event.ts
|
||||
import { EventEmitter } from 'events';
|
||||
import { createMMKV } from 'react-native-mmkv';
|
||||
|
||||
export const authEvents = new EventEmitter();
|
||||
|
||||
export const enum AUTH {
|
||||
USER = 'user',
|
||||
AUTH = 'auth',
|
||||
}
|
||||
|
||||
// MMKV instance
|
||||
export const storage = createMMKV();
|
||||
|
||||
// Memory cachez
|
||||
// Memory cache
|
||||
let tokenCache: string | null = null;
|
||||
let languageCache: string | null = null;
|
||||
|
||||
// Load on app start
|
||||
// Load on app start (synchronous)
|
||||
export function loadInitialAuthData() {
|
||||
tokenCache = storage.getString('token') || null;
|
||||
languageCache = storage.getString('language') || null;
|
||||
}
|
||||
|
||||
export function getToken() {
|
||||
return tokenCache;
|
||||
return storage.getString('token');
|
||||
}
|
||||
|
||||
export function setToken(token: string | null) {
|
||||
@@ -29,6 +35,18 @@ export function setToken(token: string | null) {
|
||||
}
|
||||
}
|
||||
|
||||
export function saveAuth() {
|
||||
storage.set('user', AUTH.USER);
|
||||
}
|
||||
|
||||
export function removeAuth() {
|
||||
storage.set('user', AUTH.AUTH);
|
||||
}
|
||||
|
||||
export function getAuth() {
|
||||
storage.getString('user');
|
||||
}
|
||||
|
||||
export function getLanguage() {
|
||||
return languageCache;
|
||||
}
|
||||
|
||||
8
src/helpers/formatPrice.ts
Normal file
8
src/helpers/formatPrice.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export const formatPrice = (amount: number | string) => {
|
||||
const numericAmount = Number(amount) || 0;
|
||||
const formatted = numericAmount
|
||||
.toString()
|
||||
.replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
|
||||
|
||||
return formatted;
|
||||
};
|
||||
@@ -246,7 +246,10 @@
|
||||
"Email": "Электронная почта",
|
||||
"Telegram": "Телеграм",
|
||||
"Roziman": "Согласен",
|
||||
"To'lov kutilmoqda": "Ожидание оплаты",
|
||||
"Reys": "Рейс",
|
||||
"To'lov holati": "Статус оплаты",
|
||||
"Bekor qilingan": "Отменено",
|
||||
"Mahsulot nomi": "Название товара",
|
||||
"Ma'lumotlarni to'liq kiriting": "Введите полные данные"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
"Familiya": "Familiya",
|
||||
"Familiyangiz": "Familiyangiz",
|
||||
"Bizni qaerdan topdingiz?": "Bizni qaerdan topdingiz?",
|
||||
"Reys": "Reys",
|
||||
"narxi": "narxi",
|
||||
"Bizni kim tavsiya qildi...": "Bizni kim tavsiya qildi...",
|
||||
"Foydalanish shartlari": "Foydalanish shartlari",
|
||||
"bilan tanishib chiqdim!": "bilan tanishib chiqdim!",
|
||||
@@ -156,6 +158,7 @@
|
||||
"Mahsulotlar og’irligi": "Mahsulotlar og’irligi",
|
||||
"Faol": "Faol",
|
||||
"Kutilmoqda": "Kutilmoqda",
|
||||
"To'lov kutilmoqda": "To'lov kutilmoqda",
|
||||
"Faol emas": "Faol emas",
|
||||
"Xatolik yuz berdi!": "Xatolik yuz berdi!",
|
||||
"Akkaunt faol emas!": "Akkaunt faol emas!",
|
||||
@@ -177,6 +180,7 @@
|
||||
"so‘m": "so'm",
|
||||
"Umumiy narx": "Umumiy narx",
|
||||
"Yopish": "Yopish",
|
||||
"Mahsulot nomi": "Mahsulot nomi",
|
||||
"Passportlarim": "Passportlarim",
|
||||
"Hali pasport qo'shilmagan": "Hali pasport qo'shilmagan",
|
||||
"Yangi pasport qo'shish uchun tugmani bosing": "Yangi passport qo'shish uchun tugmani bosing",
|
||||
|
||||
@@ -5,7 +5,7 @@ import { authApi } from 'api/auth';
|
||||
import { otpPayload, resendPayload } from 'api/auth/type';
|
||||
import AppText from 'components/AppText';
|
||||
import ErrorNotification from 'components/ErrorNotification';
|
||||
import { setToken } from 'helpers/event';
|
||||
import { saveAuth, setToken } from 'helpers/event';
|
||||
import formatPhone from 'helpers/formatPhone';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -78,7 +78,11 @@ const Confirm = () => {
|
||||
mutationFn: (payload: otpPayload) => authApi.verifyOtp(payload),
|
||||
onSuccess: async res => {
|
||||
setToken(res.data.accessToken);
|
||||
navigation.navigate('Home');
|
||||
saveAuth();
|
||||
navigation.reset({
|
||||
index: 0,
|
||||
routes: [{ name: 'Home' }], // login sahifasiga qaytarish
|
||||
});
|
||||
setVisible(false);
|
||||
},
|
||||
onError: (err: any) => {
|
||||
|
||||
@@ -84,7 +84,10 @@ const Confirm = ({
|
||||
mutationFn: (payload: otpPayload) => authApi.verifyOtp(payload),
|
||||
onSuccess: async res => {
|
||||
setToken(res.data.accessToken);
|
||||
navigation.navigate('Confirm');
|
||||
navigation.reset({
|
||||
index: 0,
|
||||
routes: [{ name: 'Home' }], // login sahifasiga qaytarish
|
||||
});
|
||||
setErrorConfirm(null);
|
||||
},
|
||||
onError: (err: any) => {
|
||||
|
||||
@@ -13,6 +13,7 @@ import AppText from 'components/AppText';
|
||||
import DatePickerInput from 'components/DatePicker';
|
||||
import ErrorNotification from 'components/ErrorNotification';
|
||||
import SingleFileDrop from 'components/FileDrop';
|
||||
import { saveAuth } from 'helpers/event';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -79,11 +80,10 @@ const SecondStep = () => {
|
||||
mutationFn: (payload: sendPassportPayload) =>
|
||||
passportApi.sendPassport(payload),
|
||||
onSuccess: res => {
|
||||
navigation.navigate('Home');
|
||||
navigation.replace('Home');
|
||||
saveAuth();
|
||||
},
|
||||
onError: (err: any) => {
|
||||
console.dir(err);
|
||||
|
||||
setError(err?.response?.data || 'Xatolik yuz berdi');
|
||||
setVisible(true);
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import AppText from 'components/AppText';
|
||||
import { setToken } from 'helpers/event';
|
||||
import { removeAuth, setToken } from 'helpers/event';
|
||||
import * as React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -36,7 +36,8 @@ const ProfilePages = (props: componentNameProps) => {
|
||||
style: 'destructive',
|
||||
onPress: async () => {
|
||||
try {
|
||||
setToken(null);
|
||||
setToken('');
|
||||
removeAuth();
|
||||
navigation.reset({
|
||||
index: 0,
|
||||
routes: [{ name: 'Login' }], // login sahifasiga qaytarish
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { PacketsData } from 'api/packets';
|
||||
import AppText from 'components/AppText';
|
||||
import { formatPrice } from 'helpers/formatPrice';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FlatList, StyleSheet, TouchableOpacity, View } from 'react-native';
|
||||
import Auto from 'svg/Auto';
|
||||
import Avia from 'svg/Avia';
|
||||
import BagIcon from 'svg/BagIcon';
|
||||
import BoxIcon from 'svg/Box';
|
||||
import Store from 'svg/Store';
|
||||
import SuccessIcon from 'svg/SuccessIcon';
|
||||
import TrunkIcon from 'svg/TrunkIcon';
|
||||
import Wallet from 'svg/Wallet';
|
||||
import { DataInfo } from '../lib/data';
|
||||
|
||||
const statusColorMap: Record<string, string> = {
|
||||
@@ -30,13 +30,14 @@ const statuses = [
|
||||
'DELIVERED',
|
||||
'PAID',
|
||||
] as const;
|
||||
|
||||
type FilterType = (typeof statuses)[number];
|
||||
|
||||
const tabList: { label: string; value: FilterType }[] = [
|
||||
{ label: "Yig'ilmoqda", value: 'COLLECTING' },
|
||||
{ label: "Yo'lda", value: 'ON_THE_WAY' },
|
||||
{ label: 'Bojxonada', value: 'IN_CUSTOMS' },
|
||||
{ label: 'Toshkent omboriga yetib keldi', value: 'IN_WAREHOUSE' },
|
||||
{ label: 'Omborga yetib keldi', value: 'IN_WAREHOUSE' },
|
||||
{ label: 'Topshirish punktida', value: 'DELIVERED' },
|
||||
{ label: 'Qabul qilingan', value: 'PAID' },
|
||||
];
|
||||
@@ -51,20 +52,18 @@ const Order = ({ data, openModal, selectedData }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const styles = useMemo(() => makeStyles(), []);
|
||||
|
||||
const createIcons = useCallback(
|
||||
(cargo: string) => [
|
||||
/** 🔥 SUCCESS ICON faqat paymentStatus ga qarab o‘zgaradi */
|
||||
const createIcons = useCallback((cargo: string, paymentStatus?: string) => {
|
||||
const isPaid = paymentStatus === 'PAYED';
|
||||
|
||||
return [
|
||||
{
|
||||
status: 'COLLECTING',
|
||||
icon: <BoxIcon width={24} height={24} color="" />,
|
||||
},
|
||||
{
|
||||
status: 'ON_THE_WAY',
|
||||
icon:
|
||||
cargo === 'avia' ? (
|
||||
<Avia width={24} height={24} color="" />
|
||||
) : (
|
||||
<Auto width={24} height={24} color="" view="-4" />
|
||||
),
|
||||
icon: <Avia width={24} height={24} color="" />,
|
||||
},
|
||||
{
|
||||
status: 'IN_CUSTOMS',
|
||||
@@ -79,29 +78,33 @@ const Order = ({ data, openModal, selectedData }: Props) => {
|
||||
icon: <TrunkIcon width={24} height={24} color="" />,
|
||||
},
|
||||
{
|
||||
status: 'PAID',
|
||||
icon: <SuccessIcon width={24} height={24} color="" />,
|
||||
status: 'PENDING',
|
||||
icon: (
|
||||
<Wallet
|
||||
width={24}
|
||||
height={24}
|
||||
color={isPaid ? '#28A7E8' : '#C0C0C0'}
|
||||
/>
|
||||
),
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
];
|
||||
}, []);
|
||||
|
||||
const handleItemPress = useCallback(
|
||||
(item: DataInfo) => {
|
||||
openModal(item);
|
||||
},
|
||||
(item: DataInfo) => openModal(item),
|
||||
[openModal],
|
||||
);
|
||||
|
||||
const renderOrderItem = useCallback(
|
||||
({ item, index }: { item: DataInfo; index: number }) => {
|
||||
({ item }: { item: DataInfo }) => {
|
||||
const currentStatusIndex = statuses.indexOf(
|
||||
item.deliveryStatus as FilterType,
|
||||
);
|
||||
const icons = createIcons(item.deliveryStatus);
|
||||
|
||||
const icons = createIcons(item.deliveryStatus, item.paymentStatus);
|
||||
|
||||
return (
|
||||
<TouchableOpacity key={index} onPress={() => handleItemPress(item)}>
|
||||
<TouchableOpacity onPress={() => handleItemPress(item)}>
|
||||
<View style={styles.card}>
|
||||
<FlatList
|
||||
data={icons}
|
||||
@@ -109,14 +112,42 @@ const Order = ({ data, openModal, selectedData }: Props) => {
|
||||
numColumns={6}
|
||||
contentContainerStyle={styles.statusCard}
|
||||
renderItem={({ item: iconItem, index: i }) => {
|
||||
const iconColor = i <= currentStatusIndex ? '#28A7E8' : '#000';
|
||||
const viewColor =
|
||||
i <= currentStatusIndex ? '#28A7E81A' : '#0000001A';
|
||||
let iconColor = '#000';
|
||||
let bgColor = '#0000001A';
|
||||
|
||||
if (
|
||||
iconItem.status === 'DELIVERED' &&
|
||||
item.deliveryStatus === 'DELIVERED'
|
||||
) {
|
||||
iconColor = '#28A7E8';
|
||||
bgColor = '#28A7E81A';
|
||||
} else if (iconItem.status === 'PENDING') {
|
||||
if (item.paymentStatus === 'PAYED') {
|
||||
iconColor = '#28A7E8'; // blue
|
||||
bgColor = '#28A7E81A';
|
||||
} else if (item.paymentStatus === 'PENDING') {
|
||||
iconColor = '#FFA500'; // orange
|
||||
bgColor = '#FFA5001A';
|
||||
} else {
|
||||
iconColor = '#C0C0C0'; // gray
|
||||
bgColor = '#C0C0C01A';
|
||||
}
|
||||
} else if (i <= currentStatusIndex) {
|
||||
iconColor = '#28A7E8'; // blue
|
||||
bgColor = '#28A7E81A';
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.iconWrapper}>
|
||||
<View
|
||||
style={[styles.circle, { backgroundColor: viewColor }]}
|
||||
style={[
|
||||
styles.circle,
|
||||
{
|
||||
backgroundColor: bgColor,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
]}
|
||||
>
|
||||
{React.cloneElement(iconItem.icon, { color: iconColor })}
|
||||
</View>
|
||||
@@ -133,29 +164,62 @@ const Order = ({ data, openModal, selectedData }: Props) => {
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Status Label */}
|
||||
<View
|
||||
style={[
|
||||
styles.statusLabelWrapper,
|
||||
{
|
||||
backgroundColor: `${statusColorMap[item.deliveryStatus]}1A`,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
width: '100%',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<AppText
|
||||
style={[
|
||||
styles.statusText,
|
||||
{ color: statusColorMap[item.deliveryStatus] },
|
||||
styles.statusLabelWrapper,
|
||||
{
|
||||
color: statusColorMap[item.deliveryStatus],
|
||||
backgroundColor: `${statusColorMap[item.deliveryStatus]}1A`,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{t(
|
||||
tabList.find(tab => tab.value === item.deliveryStatus)
|
||||
?.label || '',
|
||||
tabList.find(el => el.value === item.deliveryStatus)?.label ||
|
||||
'',
|
||||
)}
|
||||
</AppText>
|
||||
<AppText
|
||||
style={[
|
||||
styles.statusText,
|
||||
styles.statusLabelWrapper,
|
||||
{
|
||||
color:
|
||||
item.paymentStatus === 'NEW'
|
||||
? '#D32F2F'
|
||||
: item.paymentStatus === 'PENDING'
|
||||
? '#FFA500'
|
||||
: item.paymentStatus === 'PAYED'
|
||||
? '#32CD32'
|
||||
: '#D32F2F',
|
||||
backgroundColor:
|
||||
item.paymentStatus === 'NEW'
|
||||
? '#D32F2F1A'
|
||||
: item.paymentStatus === 'PENDING'
|
||||
? '#FFA5001A'
|
||||
: item.paymentStatus === 'PAYED'
|
||||
? '#32CD321A'
|
||||
: '#D32F2F',
|
||||
},
|
||||
]}
|
||||
>
|
||||
{item.paymentStatus === 'NEW'
|
||||
? t("To'lanmagan")
|
||||
: item.paymentStatus === 'PENDING'
|
||||
? t("To'lov kutilmoqda")
|
||||
: item.paymentStatus === 'PAYED' && t("To'langan")}
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
{/* Info */}
|
||||
<View style={styles.infoCard}>
|
||||
<AppText style={styles.infoTitle}>{t('Reys raqami')}</AppText>
|
||||
<AppText
|
||||
@@ -164,16 +228,70 @@ const Order = ({ data, openModal, selectedData }: Props) => {
|
||||
{item.packetName}
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
{item.items.map(e => (
|
||||
<View
|
||||
key={e.trekId}
|
||||
style={{
|
||||
...styles.infoCard,
|
||||
flexDirection: 'column',
|
||||
gap: 4,
|
||||
marginTop: 4,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<AppText style={styles.infoTitle}>
|
||||
{t('Mahsulot nomi')}
|
||||
</AppText>
|
||||
<AppText style={styles.infoText}>{e.name}</AppText>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<AppText style={styles.infoTitle}>{t('Trek ID')}</AppText>
|
||||
<AppText style={styles.infoText}>{e.trekId}</AppText>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<AppText style={styles.infoTitle}>{t('Og’irligi')}</AppText>
|
||||
<AppText style={styles.infoText}>{e.weight} kg</AppText>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
|
||||
<View style={styles.infoCard}>
|
||||
<AppText style={styles.infoTitle}>
|
||||
{t('Mahsulotlar og’irligi')}
|
||||
</AppText>
|
||||
<AppText style={styles.infoText}>{item.weight}</AppText>
|
||||
</View>
|
||||
<View style={styles.infoCard}>
|
||||
<AppText style={styles.infoTitle}>{t('Umumiy narxi')}</AppText>
|
||||
<AppText style={styles.infoText}>{item.totalPrice}</AppText>
|
||||
<AppText style={styles.infoText}>{item.weight} kg</AppText>
|
||||
</View>
|
||||
{(item.deliveryStatus === 'DELIVERED' ||
|
||||
item.paymentStatus === 'PAID') && (
|
||||
<View style={styles.infoCard}>
|
||||
<AppText style={styles.infoTitle}>{t('Umumiy narxi')}</AppText>
|
||||
<AppText style={styles.infoText}>
|
||||
{formatPrice(item.totalPrice)} {t('so‘m')}
|
||||
</AppText>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
@@ -207,49 +325,37 @@ const Order = ({ data, openModal, selectedData }: Props) => {
|
||||
|
||||
const makeStyles = () =>
|
||||
StyleSheet.create({
|
||||
container: {
|
||||
width: '95%',
|
||||
margin: 'auto',
|
||||
borderRadius: 10,
|
||||
},
|
||||
container: { width: '95%', margin: 'auto', borderRadius: 10 },
|
||||
count: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginTop: 10,
|
||||
},
|
||||
title: {
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
color: '#333',
|
||||
},
|
||||
title: { fontSize: 16, fontWeight: '500', color: '#333' },
|
||||
card: {
|
||||
backgroundColor: '#fff',
|
||||
margin: 1,
|
||||
marginTop: 8,
|
||||
padding: 15,
|
||||
borderRadius: 10,
|
||||
// iOS
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.2,
|
||||
shadowRadius: 2,
|
||||
// Android
|
||||
elevation: 2,
|
||||
},
|
||||
statusCard: {
|
||||
marginBottom: 10,
|
||||
},
|
||||
statusCard: { marginBottom: 10 },
|
||||
circle: {
|
||||
padding: 8,
|
||||
borderRadius: 50,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
divider: {
|
||||
width: 20,
|
||||
borderBottomWidth: 2,
|
||||
borderStyle: 'dashed',
|
||||
divider: { width: 20, borderBottomWidth: 2, borderStyle: 'dashed' },
|
||||
iconWrapper: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
marginBottom: 10,
|
||||
},
|
||||
statusLabelWrapper: {
|
||||
borderRadius: 8,
|
||||
@@ -258,31 +364,14 @@ const makeStyles = () =>
|
||||
paddingHorizontal: 10,
|
||||
marginBottom: 12,
|
||||
},
|
||||
statusText: {
|
||||
fontFamily: 'GolosText-Bold',
|
||||
fontSize: 16,
|
||||
},
|
||||
statusText: { fontFamily: 'GolosText-Bold', fontSize: 16 },
|
||||
infoCard: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 6,
|
||||
},
|
||||
iconWrapper: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
marginBottom: 10,
|
||||
},
|
||||
infoTitle: {
|
||||
fontSize: 16,
|
||||
color: '#979797',
|
||||
fontWeight: '500',
|
||||
},
|
||||
infoText: {
|
||||
fontSize: 14,
|
||||
color: '#28A7E8',
|
||||
fontWeight: '500',
|
||||
},
|
||||
infoTitle: { fontSize: 16, color: '#979797', fontWeight: '500' },
|
||||
infoText: { fontSize: 14, color: '#28A7E8', fontWeight: '500' },
|
||||
});
|
||||
|
||||
export default Order;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import AppText from 'components/AppText';
|
||||
import { formatPrice } from 'helpers/formatPrice';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -22,14 +23,6 @@ const OrderDetailModal = ({ visible, setVisible, selectedOrder }: Props) => {
|
||||
const translateY = useRef(new Animated.Value(50)).current;
|
||||
const { t } = useTranslation();
|
||||
|
||||
const parsePrice = (priceStr: string) => {
|
||||
return Number(priceStr.replace(/[^\d]/g, ''));
|
||||
};
|
||||
|
||||
const parseWeight = (weightStr: string) => {
|
||||
return Number(weightStr.replace(/[^\d.]/g, ''));
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
Animated.timing(opacity, {
|
||||
toValue: 0,
|
||||
@@ -82,10 +75,6 @@ const OrderDetailModal = ({ visible, setVisible, selectedOrder }: Props) => {
|
||||
style={{ maxHeight: 250 }}
|
||||
>
|
||||
{selectedOrder.items.map((product, index) => {
|
||||
const totalPrice = product.totalPrice;
|
||||
const weight = product.weight;
|
||||
const pricePerKg = Math.ceil(weight ? totalPrice / weight : 0);
|
||||
|
||||
return (
|
||||
<View key={product.trekId + index} style={styles.productItem}>
|
||||
<View style={styles.row}>
|
||||
@@ -100,13 +89,12 @@ const OrderDetailModal = ({ visible, setVisible, selectedOrder }: Props) => {
|
||||
{t('Og’irligi')}: {product.weight}
|
||||
</AppText>
|
||||
<AppText style={styles.detail}>
|
||||
{t('Narxi')}: 1kg * {pricePerKg.toLocaleString('uz-UZ')}{' '}
|
||||
{t("so'm")}
|
||||
{t('Narxi')}: {product.price}$
|
||||
</AppText>
|
||||
</View>
|
||||
<View style={styles.rowRight}>
|
||||
<AppText style={styles.total}>
|
||||
{t('Umumiy narxi')}: {product.totalPrice} {t('so‘m')}
|
||||
{t('Umumiy narxi')}: {product.totalPrice}$
|
||||
</AppText>
|
||||
</View>
|
||||
</View>
|
||||
@@ -117,7 +105,7 @@ const OrderDetailModal = ({ visible, setVisible, selectedOrder }: Props) => {
|
||||
<View style={styles.totalRow}>
|
||||
<AppText style={styles.totalLabel}>{t('Umumiy narx')}:</AppText>
|
||||
<AppText style={styles.totalValue}>
|
||||
{selectedOrder.totalPrice}
|
||||
{formatPrice(selectedOrder.totalPrice)} {t('so‘m')}
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ import { DataInfo } from '../lib/data';
|
||||
import Filter from './Filter';
|
||||
import Order from './Order';
|
||||
import OrderDetailModal from './OrderDetailModal';
|
||||
import PaymentFilter from './PaymentFilter';
|
||||
import Tabs from './Tabs';
|
||||
|
||||
const Status = () => {
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
@@ -47,14 +45,13 @@ const Status = () => {
|
||||
isLoading,
|
||||
isFetching,
|
||||
} = useQuery({
|
||||
queryKey: ['status', filter, transportTypes, page, paymentStatus],
|
||||
queryKey: ['status', transportTypes, page, paymentStatus],
|
||||
queryFn: () =>
|
||||
packetsApi.getPacketsStatus(filter, {
|
||||
packetsApi.getPackets({
|
||||
page,
|
||||
size: 10,
|
||||
cargoType: transportTypes,
|
||||
sort: 'id',
|
||||
paymentStatus: paymentStatus,
|
||||
direction: 'DESC',
|
||||
}),
|
||||
});
|
||||
@@ -146,7 +143,7 @@ const Status = () => {
|
||||
if (statusData?.data.length === 0 || statusData === undefined) {
|
||||
return (
|
||||
<Layout>
|
||||
<Tabs filter={filter} setFilter={setFilter} />
|
||||
{/* <Tabs filter={filter} setFilter={setFilter} /> */}
|
||||
<View style={styles.controls}>
|
||||
<View
|
||||
style={{
|
||||
@@ -163,10 +160,10 @@ const Status = () => {
|
||||
data={statusData}
|
||||
setSelectedData={setSelectedData}
|
||||
/>
|
||||
<PaymentFilter
|
||||
{/* <PaymentFilter
|
||||
paymentStatus={paymentStatus}
|
||||
setPaymentStatus={setPaymentStatus}
|
||||
/>
|
||||
/> */}
|
||||
</View>
|
||||
</View>
|
||||
<NoResult message={t("Hech qanday ma'lumot topilmadi")} />
|
||||
@@ -181,7 +178,7 @@ const Status = () => {
|
||||
refreshControl={refreshControl}
|
||||
removeClippedSubviews={true}
|
||||
>
|
||||
<Tabs filter={filter} setFilter={setFilter} />
|
||||
{/* <Tabs filter={filter} setFilter={setFilter} /> */}
|
||||
<View style={styles.controls}>
|
||||
{/* <View style={styles.searchContainer}>
|
||||
<TextInput
|
||||
@@ -206,10 +203,10 @@ const Status = () => {
|
||||
data={statusData!}
|
||||
setSelectedData={setSelectedData}
|
||||
/>
|
||||
<PaymentFilter
|
||||
{/* <PaymentFilter
|
||||
paymentStatus={paymentStatus}
|
||||
setPaymentStatus={setPaymentStatus}
|
||||
/>
|
||||
/> */}
|
||||
</View>
|
||||
</View>
|
||||
<Order
|
||||
|
||||
@@ -4,7 +4,7 @@ import { PacketsData } from 'api/packets';
|
||||
import AppText from 'components/AppText';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { TouchableOpacity, View } from 'react-native';
|
||||
import { StyleSheet, TouchableOpacity, View } from 'react-native';
|
||||
import { PaymentStyle } from './style';
|
||||
|
||||
type WalletStackParamList = {
|
||||
@@ -22,6 +22,7 @@ interface Props {
|
||||
const Payment = ({ packets }: Props) => {
|
||||
const navigation = useNavigation<LoginScreenNavigationProp>();
|
||||
const { t } = useTranslation();
|
||||
const styles = useMemo(() => makeStyles(), []);
|
||||
|
||||
const handlePaymentPress = useCallback(
|
||||
(item: any) => {
|
||||
@@ -52,10 +53,17 @@ const Payment = ({ packets }: Props) => {
|
||||
const renderPaymentCard = useCallback(
|
||||
(item: any) => {
|
||||
const isPaid =
|
||||
item.paymentStatus === 'PAYED' || item.paymentStatus === 'PENDING';
|
||||
item.paymentStatus === 'PAYED' || item.paymentStatus === 'PAID';
|
||||
const cardStyle = [
|
||||
PaymentStyle.card,
|
||||
{ borderColor: isPaid ? '#4CAF50' : '#D32F2F', borderWidth: 1.5 },
|
||||
{
|
||||
borderColor: isPaid
|
||||
? '#4CAF50'
|
||||
: item.paymentStatus === 'PENDING'
|
||||
? '#FFA500'
|
||||
: '#D32F2F',
|
||||
borderWidth: 1.5,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -70,6 +78,20 @@ const Payment = ({ packets }: Props) => {
|
||||
<AppText style={PaymentStyle.title}>{item.packetName}</AppText>
|
||||
{isPaid ? (
|
||||
<AppText style={PaymentStyle.badge}>{t("To'langan")}</AppText>
|
||||
) : item.paymentStatus === 'PENDING' ? (
|
||||
<AppText
|
||||
style={{
|
||||
backgroundColor: '#FFA500',
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
paddingHorizontal: 8,
|
||||
paddingVertical: 2,
|
||||
borderRadius: 5,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
{t('Kutilmoqda')}
|
||||
</AppText>
|
||||
) : (
|
||||
<AppText style={badgeStyle}>{t("To'lanmagan")}</AppText>
|
||||
)}
|
||||
@@ -87,7 +109,53 @@ const Payment = ({ packets }: Props) => {
|
||||
{item.packetName}
|
||||
</AppText>
|
||||
</View>
|
||||
<View style={PaymentStyle.row}>
|
||||
{item.items.map((e: any) => (
|
||||
<View
|
||||
key={e.trekId}
|
||||
style={{
|
||||
...styles.infoCard,
|
||||
flexDirection: 'column',
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<AppText style={styles.infoTitle}>
|
||||
{t('Mahsulot nomi')}
|
||||
</AppText>
|
||||
<AppText style={styles.infoText}>{e.name}</AppText>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<AppText style={styles.infoTitle}>{t('Trek ID')}</AppText>
|
||||
<AppText style={styles.infoText}>{e.trekId}</AppText>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<AppText style={styles.infoTitle}>{t('Og’irligi')}</AppText>
|
||||
<AppText style={styles.infoText}>{e.weight} kg</AppText>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
{/* <View style={PaymentStyle.row}>
|
||||
<AppText style={PaymentStyle.infoTitle}>
|
||||
{t("Mahsulotlar og'irligi")}
|
||||
</AppText>
|
||||
@@ -104,7 +172,7 @@ const Payment = ({ packets }: Props) => {
|
||||
{t('Umumiy narxi')}
|
||||
</AppText>
|
||||
<AppText style={PaymentStyle.text}>{item.totalPrice}</AppText>
|
||||
</View>
|
||||
</View> */}
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
@@ -120,4 +188,59 @@ const Payment = ({ packets }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
const makeStyles = () =>
|
||||
StyleSheet.create({
|
||||
container: { width: '95%', margin: 'auto', borderRadius: 10 },
|
||||
count: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginTop: 10,
|
||||
},
|
||||
title: { fontSize: 16, fontWeight: '500', color: '#333' },
|
||||
|
||||
card: {
|
||||
backgroundColor: '#fff',
|
||||
marginTop: 8,
|
||||
padding: 15,
|
||||
borderRadius: 10,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.2,
|
||||
shadowRadius: 2,
|
||||
elevation: 2,
|
||||
},
|
||||
|
||||
statusCard: { marginBottom: 10 },
|
||||
circle: {
|
||||
padding: 8,
|
||||
borderRadius: 50,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
divider: { width: 20, borderBottomWidth: 2, borderStyle: 'dashed' },
|
||||
iconWrapper: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
marginBottom: 10,
|
||||
},
|
||||
|
||||
statusLabelWrapper: {
|
||||
borderRadius: 8,
|
||||
alignSelf: 'flex-start',
|
||||
paddingVertical: 6,
|
||||
paddingHorizontal: 10,
|
||||
marginBottom: 12,
|
||||
},
|
||||
statusText: { fontFamily: 'GolosText-Bold', fontSize: 16 },
|
||||
|
||||
infoCard: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 6,
|
||||
},
|
||||
infoTitle: { fontSize: 16, color: '#979797', fontWeight: '500' },
|
||||
infoText: { fontSize: 14, color: '#28A7E8', fontWeight: '500' },
|
||||
});
|
||||
|
||||
export default Payment;
|
||||
|
||||
@@ -58,8 +58,6 @@ const ModalPay = ({
|
||||
queryFn: authApi.getMe,
|
||||
});
|
||||
|
||||
console.log(getMe, 'getMe');
|
||||
|
||||
const { mutate, isPending } = useMutation({
|
||||
mutationFn: ({ id, payType }: { id: number; payType: string }) =>
|
||||
packetsApi.payPackets(id, { payType }),
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import exchanges_api from 'api/exchanges';
|
||||
import AppText from 'components/AppText';
|
||||
import { formatPrice } from 'helpers/formatPrice';
|
||||
import * as React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Dimensions, ScrollView, View } from 'react-native';
|
||||
import { Dimensions, ScrollView, StyleSheet, View } from 'react-native';
|
||||
import Svg, { Circle, Path } from 'react-native-svg';
|
||||
import Plane from 'svg/Plane';
|
||||
import { PaymentStyle } from '../../payment/ui/style';
|
||||
@@ -17,6 +18,7 @@ const PaymentProduct = ({ packet }: PaymentProductProps) => {
|
||||
const screenWidth = Dimensions.get('window').width;
|
||||
const isSmallScreen = screenWidth < 380;
|
||||
const svgWidth = screenWidth * 0.8;
|
||||
const svgWidthProduct = screenWidth * 1;
|
||||
|
||||
const { data } = useQuery({
|
||||
queryKey: ['exchanges'],
|
||||
@@ -80,21 +82,23 @@ const PaymentProduct = ({ packet }: PaymentProductProps) => {
|
||||
: { flexBasis: '48%', alignItems: 'flex-end' },
|
||||
]}
|
||||
>
|
||||
<AppText style={PaymentStyle.titleMethod}>Cargo</AppText>
|
||||
<AppText style={PaymentStyle.textMethod}>12.267 UZS/ kg</AppText>
|
||||
<AppText style={PaymentStyle.titleMethod}>{t('Reys')}</AppText>
|
||||
<AppText style={[PaymentStyle.textMethod, { textAlign: 'left' }]}>
|
||||
{packet.packetName}
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
{/* <View
|
||||
style={[
|
||||
PaymentStyle.info,
|
||||
isSmallScreen
|
||||
? { flexBasis: '48%', alignItems: 'flex-start' }
|
||||
: { flexBasis: '48%', alignItems: 'flex-start' },
|
||||
? { flexBasis: '48%', alignItems: 'flex-end' }
|
||||
: { flexBasis: '48%', alignItems: 'flex-end' },
|
||||
]}
|
||||
>
|
||||
<AppText style={PaymentStyle.titleMethod}>{t('Yetkazish vaqti')}</AppText>
|
||||
<AppText style={PaymentStyle.textMethod}>08.25.2025</AppText>
|
||||
</View> */}
|
||||
<AppText style={PaymentStyle.titleMethod}>Cargo</AppText>
|
||||
<AppText style={PaymentStyle.textMethod}>12.267 UZS/ kg</AppText>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={[
|
||||
@@ -104,11 +108,11 @@ const PaymentProduct = ({ packet }: PaymentProductProps) => {
|
||||
: { flexBasis: '48%', alignItems: 'flex-start' },
|
||||
]}
|
||||
>
|
||||
<AppText style={PaymentStyle.titleMethod}>Reys</AppText>
|
||||
<AppText style={[PaymentStyle.textMethod, { textAlign: 'left' }]}>
|
||||
{packet.packetName}
|
||||
<AppText style={PaymentStyle.titleMethod}>
|
||||
{t('Yetkazish vaqti')}
|
||||
</AppText>
|
||||
</View>
|
||||
<AppText style={PaymentStyle.textMethod}>08.25.2025</AppText>
|
||||
</View> */}
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
@@ -149,36 +153,40 @@ const PaymentProduct = ({ packet }: PaymentProductProps) => {
|
||||
/>
|
||||
</View>
|
||||
{packet.items.map((item: any, index: number) => {
|
||||
const price = Number(item.price);
|
||||
const weight = Number(item.weight);
|
||||
const total = price * weight;
|
||||
|
||||
// formatlash: 0 decimal, so‘m bilan
|
||||
const formattedPrice = price.toFixed(0);
|
||||
const formattedTotal = total.toFixed(0);
|
||||
return (
|
||||
<View key={index} style={{ marginBottom: 15 }}>
|
||||
<View style={PaymentStyle.receiptCard}>
|
||||
<View style={PaymentStyle.rowBetween}>
|
||||
<AppText style={PaymentStyle.itemName}>{item.name}</AppText>
|
||||
<AppText style={PaymentStyle.track}>
|
||||
{t('Trek ID')}: {item.trackId}
|
||||
</AppText>
|
||||
<View style={{ width: '100%' }}>
|
||||
<AppText style={PaymentStyle.itemName}>{item.name}</AppText>
|
||||
<AppText style={PaymentStyle.track}>
|
||||
{t('Trek ID')}: {item.trekId}
|
||||
</AppText>
|
||||
</View>
|
||||
</View>
|
||||
<View style={PaymentStyle.rowBetween}>
|
||||
<AppText style={PaymentStyle.weight}>
|
||||
{t('Og’irligi')}: {weight} kg
|
||||
{t('Og’irligi')}: {item.weight} kg
|
||||
</AppText>
|
||||
<AppText style={PaymentStyle.price}>
|
||||
1kg * {formattedPrice} {t('so‘m')}
|
||||
{t('Narxi')}: {item.price}$
|
||||
</AppText>
|
||||
</View>
|
||||
<View style={PaymentStyle.rowRight}>
|
||||
<AppText style={PaymentStyle.total}>
|
||||
{t('Umumiy narxi')}: {formattedTotal} {t('so‘m')}
|
||||
{t('Umumiy narxi')}: {item.totalPrice} $
|
||||
</AppText>
|
||||
</View>
|
||||
</View>
|
||||
<Svg height="1" width={svgWidthProduct}>
|
||||
<Path
|
||||
d={`M 0 0 Q ${svgWidthProduct} 0 ${svgWidthProduct} 0`}
|
||||
stroke="#8C8A93"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
strokeDasharray="9"
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
@@ -205,7 +213,7 @@ const PaymentProduct = ({ packet }: PaymentProductProps) => {
|
||||
]}
|
||||
>
|
||||
<AppText style={PaymentStyle.titleMethod}>
|
||||
{packet.totalPrice}
|
||||
{formatPrice(packet.totalPrice)} {t('so‘m')}
|
||||
</AppText>
|
||||
</View>
|
||||
</View>
|
||||
@@ -214,4 +222,15 @@ const PaymentProduct = ({ packet }: PaymentProductProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
cornerStyle: {
|
||||
position: 'absolute' as const,
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderTopWidth: 6,
|
||||
borderLeftWidth: 6,
|
||||
borderColor: '#007AFF',
|
||||
},
|
||||
});
|
||||
|
||||
export default PaymentProduct;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { RouteProp, useRoute } from '@react-navigation/native';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { authApi } from 'api/auth';
|
||||
import exchanges_api from 'api/exchanges';
|
||||
import AppText from 'components/AppText';
|
||||
import LayoutTwo from 'components/LayoutTwo';
|
||||
import { formatPrice } from 'helpers/formatPrice';
|
||||
import * as React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -42,6 +44,10 @@ const PaymentQrCode = () => {
|
||||
const [cardModal, setCardModal] = React.useState(false);
|
||||
const [payModal, setPayModal] = React.useState(false);
|
||||
const [success, setSuccess] = React.useState(false);
|
||||
const { data: getMe } = useQuery({
|
||||
queryKey: ['getMe'],
|
||||
queryFn: authApi.getMe,
|
||||
});
|
||||
|
||||
const screenWidth = Dimensions.get('window').width;
|
||||
const isSmallScreen = screenWidth < 380;
|
||||
@@ -102,7 +108,7 @@ const PaymentQrCode = () => {
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View
|
||||
{/* <View
|
||||
style={[
|
||||
PaymentStyle.info,
|
||||
isSmallScreen
|
||||
@@ -112,7 +118,7 @@ const PaymentQrCode = () => {
|
||||
>
|
||||
<AppText style={PaymentStyle.titleMethod}>Cargo</AppText>
|
||||
<AppText style={PaymentStyle.textMethod}>12.267 UZS/ kg</AppText>
|
||||
</View>
|
||||
</View> */}
|
||||
|
||||
{/* <View
|
||||
style={[
|
||||
@@ -132,11 +138,11 @@ const PaymentQrCode = () => {
|
||||
style={[
|
||||
PaymentStyle.info,
|
||||
isSmallScreen
|
||||
? { flexBasis: '48%', alignItems: 'flex-start' }
|
||||
: { flexBasis: '48%', alignItems: 'flex-start' },
|
||||
? { flexBasis: '48%', alignItems: 'flex-end' }
|
||||
: { flexBasis: '48%', alignItems: 'flex-end' },
|
||||
]}
|
||||
>
|
||||
<AppText style={PaymentStyle.titleMethod}>Reys</AppText>
|
||||
<AppText style={PaymentStyle.titleMethod}>{t('Reys')}</AppText>
|
||||
<AppText style={[PaymentStyle.textMethod, { textAlign: 'left' }]}>
|
||||
{packets.packetName}
|
||||
</AppText>
|
||||
@@ -180,42 +186,46 @@ const PaymentQrCode = () => {
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
{packets.items.map((item: any, index: number) => (
|
||||
<View key={index} style={{ marginBottom: 15 }}>
|
||||
<View style={PaymentStyle.receiptCard}>
|
||||
<View style={PaymentStyle.rowBetween}>
|
||||
<View style={{ width: '100%' }}>
|
||||
<AppText style={PaymentStyle.itemName}>{item.name}</AppText>
|
||||
<AppText style={PaymentStyle.track}>
|
||||
{t('Trek ID')}: {item.trekId}
|
||||
{packets.items.map((item: any, index: number) => {
|
||||
return (
|
||||
<View key={index} style={{ marginBottom: 15 }}>
|
||||
<View style={PaymentStyle.receiptCard}>
|
||||
<View style={PaymentStyle.rowBetween}>
|
||||
<View style={{ width: '100%' }}>
|
||||
<AppText style={PaymentStyle.itemName}>
|
||||
{item.name}
|
||||
</AppText>
|
||||
<AppText style={PaymentStyle.track}>
|
||||
{t('Trek ID')}: {item.trekId}
|
||||
</AppText>
|
||||
</View>
|
||||
</View>
|
||||
<View style={PaymentStyle.rowBetween}>
|
||||
<AppText style={PaymentStyle.weight}>
|
||||
{t('Og’irligi')}: {item.weight} kg
|
||||
</AppText>
|
||||
<AppText style={PaymentStyle.price}>
|
||||
{t('Narxi')}: {item.price}$
|
||||
</AppText>
|
||||
</View>
|
||||
<View style={PaymentStyle.rowRight}>
|
||||
<AppText style={PaymentStyle.total}>
|
||||
{t('Umumiy narxi')}: {item.totalPrice} $
|
||||
</AppText>
|
||||
</View>
|
||||
</View>
|
||||
<View style={PaymentStyle.rowBetween}>
|
||||
<AppText style={PaymentStyle.weight}>
|
||||
{t('Og’irligi')}: {item.weight}
|
||||
</AppText>
|
||||
<AppText style={PaymentStyle.price}>
|
||||
1kg * {item.price}
|
||||
</AppText>
|
||||
</View>
|
||||
<View style={PaymentStyle.rowRight}>
|
||||
<AppText style={PaymentStyle.total}>
|
||||
{t('Umumiy narxi')}: {item.totalPrice} {t('so‘m')}
|
||||
</AppText>
|
||||
</View>
|
||||
<Svg height="1" width={svgWidthProduct}>
|
||||
<Path
|
||||
d={`M 0 0 Q ${svgWidthProduct} 0 ${svgWidthProduct} 0`}
|
||||
stroke="#8C8A93"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
strokeDasharray="9"
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
<Svg height="1" width={svgWidthProduct}>
|
||||
<Path
|
||||
d={`M 0 0 Q ${svgWidthProduct} 0 ${svgWidthProduct} 0`}
|
||||
stroke="#8C8A93"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
strokeDasharray="9"
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
<View style={PaymentStyle.infoCard}>
|
||||
<View
|
||||
style={[
|
||||
@@ -239,7 +249,7 @@ const PaymentQrCode = () => {
|
||||
]}
|
||||
>
|
||||
<AppText style={PaymentStyle.titleMethod}>
|
||||
{packets.totalPrice}
|
||||
{formatPrice(packets.totalPrice)} {t('so‘m')}
|
||||
</AppText>
|
||||
</View>
|
||||
<View
|
||||
@@ -339,13 +349,17 @@ const PaymentQrCode = () => {
|
||||
setPayModal={setPayModal}
|
||||
/>
|
||||
)}
|
||||
{packets.paymentStatus !== 'PAYED' && (
|
||||
<TouchableOpacity
|
||||
style={[PaymentStyle.button, { bottom: bottom + 80 }]}
|
||||
onPress={toggleModal}
|
||||
>
|
||||
<AppText style={PaymentStyle.btnText}>{t("To'lash")}</AppText>
|
||||
</TouchableOpacity>
|
||||
{getMe && !getMe.aviaCargoId.includes('CP') && (
|
||||
<>
|
||||
{packets.paymentStatus !== 'PAYED' && (
|
||||
<TouchableOpacity
|
||||
style={[PaymentStyle.button, { bottom: bottom + 80 }]}
|
||||
onPress={toggleModal}
|
||||
>
|
||||
<AppText style={PaymentStyle.btnText}>{t("To'lash")}</AppText>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</LayoutTwo>
|
||||
);
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
import * as React from "react"
|
||||
import Svg, { Path } from "react-native-svg"
|
||||
import * as React from 'react';
|
||||
import Svg, { Path } from 'react-native-svg';
|
||||
|
||||
interface Props {
|
||||
color: string,
|
||||
width?: number,
|
||||
height?: number,
|
||||
view?: string
|
||||
color: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
view?: string;
|
||||
}
|
||||
|
||||
const Auto = ({ color, height = 24, width = 24, view = "0" }: Props) => (
|
||||
<Svg
|
||||
width={width}
|
||||
height={height}
|
||||
fill="none"
|
||||
viewBox={`0 ${view} 24 24`}
|
||||
>
|
||||
<Path
|
||||
fill={color}
|
||||
d="M7.965 13a3.5 3.5 0 0 1-6.93 0H0V1a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2h3l3 4.056V13h-2.035a3.501 3.501 0 0 1-6.93 0h-5.07ZM14 2H2v8.05a3.5 3.5 0 0 1 5.663.95h5.674c.168-.353.393-.674.663-.95V2Zm2 6h4v-.285L17.992 5H16v3Zm.5 6a1.5 1.5 0 1 0 0-3.001 1.5 1.5 0 0 0 0 3.001ZM6 12.5a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0Z"
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
export default Auto
|
||||
const Auto = ({ color, height = 24, width = 24, view = '0' }: Props) => (
|
||||
<Svg width={width} height={height} fill="none" viewBox={`0 ${view} 24 24`}>
|
||||
<Path
|
||||
fill={color}
|
||||
d="M7.965 13a3.5 3.5 0 0 1-6.93 0H0V1a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2h3l3 4.056V13h-2.035a3.501 3.501 0 0 1-6.93 0h-5.07ZM14 2H2v8.05a3.5 3.5 0 0 1 5.663.95h5.674c.168-.353.393-.674.663-.95V2Zm2 6h4v-.285L17.992 5H16v3Zm.5 6a1.5 1.5 0 1 0 0-3.001 1.5 1.5 0 0 0 0 3.001ZM6 12.5a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0Z"
|
||||
/>
|
||||
</Svg>
|
||||
);
|
||||
export default Auto;
|
||||
|
||||
Reference in New Issue
Block a user