update
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
export const BASE_URL = 'https://api.cpcargo.uz/api/v1';
|
||||
export const BASE_URL = 'http://141.105.64.233:7723/api/v1';
|
||||
|
||||
export const REGISTER = '/mobile/auth/register';
|
||||
export const LOGIN = '/mobile/auth/login';
|
||||
|
||||
@@ -3,7 +3,7 @@ import axios, { AxiosError } from 'axios';
|
||||
import { navigate } from 'components/NavigationRef';
|
||||
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: 'https://api.cpcargo.uz/api/v1',
|
||||
baseURL: 'http://141.105.64.233:7723/api/v1',
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
49
src/components/Layout.tsx
Normal file
49
src/components/Layout.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
// src/components/Layout.tsx
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import Navbar from './Navbar';
|
||||
import Navigation from './Navigation';
|
||||
|
||||
interface LayoutProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Layout: React.FC<LayoutProps> = ({ children }) => {
|
||||
return (
|
||||
<SafeAreaView style={styles.safeArea}>
|
||||
<View style={styles.container}>
|
||||
<Navbar />
|
||||
<View style={styles.content}>{children}</View>
|
||||
<Navigation />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
export default Layout;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
safeArea: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
header: {
|
||||
height: 60,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
},
|
||||
footer: {
|
||||
height: 50,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#eee',
|
||||
},
|
||||
});
|
||||
50
src/components/LayoutTwo.tsx
Normal file
50
src/components/LayoutTwo.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
// src/components/Layout.tsx
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import NavbarBack from './NavbarBack';
|
||||
import Navigation from './Navigation';
|
||||
|
||||
interface LayoutProps {
|
||||
title: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const LayoutTwo: React.FC<LayoutProps> = ({ title, children }) => {
|
||||
return (
|
||||
<SafeAreaView style={styles.safeArea}>
|
||||
<View style={styles.container}>
|
||||
<NavbarBack title={title} />
|
||||
<View style={styles.content}>{children}</View>
|
||||
<Navigation />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
export default LayoutTwo;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
safeArea: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
header: {
|
||||
height: 60,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
},
|
||||
footer: {
|
||||
height: 50,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#eee',
|
||||
},
|
||||
});
|
||||
@@ -2,6 +2,7 @@ import { useNavigation } from '@react-navigation/native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { branchApi } from 'api/branch';
|
||||
import LayoutTwo from 'components/LayoutTwo';
|
||||
import NavbarBack from 'components/NavbarBack';
|
||||
import NoResult from 'components/NoResult';
|
||||
import * as React from 'react';
|
||||
@@ -38,8 +39,7 @@ const Branches = (props: BranchesProps) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<NavbarBack title={t('Filiallar ro’yxati')} />
|
||||
<LayoutTwo title={t('Filiallar ro’yxati')}>
|
||||
<View style={styles.scrollWrapper}>
|
||||
<ScrollView contentContainerStyle={styles.scrollContainer}>
|
||||
{data &&
|
||||
@@ -60,7 +60,7 @@ const Branches = (props: BranchesProps) => {
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</LayoutTwo>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -76,20 +76,28 @@ const styles = StyleSheet.create({
|
||||
card: {
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderRadius: 8,
|
||||
padding: 16,
|
||||
padding: 4,
|
||||
marginBottom: 12,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
|
||||
elevation: 1,
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
paddingHorizontal: 5,
|
||||
fontWeight: '600',
|
||||
color: '#000',
|
||||
marginBottom: 6,
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 16,
|
||||
paddingHorizontal: 5,
|
||||
fontWeight: '500',
|
||||
color: '#000000B2',
|
||||
},
|
||||
|
||||
@@ -3,13 +3,11 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Branch, branchApi } from 'api/branch';
|
||||
import BottomModal from 'components/BottomModal';
|
||||
import LayoutTwo from 'components/LayoutTwo';
|
||||
import LoadingScreen from 'components/LoadingScreen';
|
||||
import NavbarBack from 'components/NavbarBack';
|
||||
import Navigation from 'components/Navigation';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import WebView from 'react-native-webview';
|
||||
import Minus from 'svg/Minus';
|
||||
import Plus from 'svg/Plus';
|
||||
@@ -123,8 +121,7 @@ const ListBranches = () => {
|
||||
if (!data) return <LoadingScreen />;
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<NavbarBack title={t('Filiallar ro’yxati')} />
|
||||
<LayoutTwo title={t('Filiallar ro’yxati')}>
|
||||
{!webViewReady && (
|
||||
<View style={{ width: '100%', height: '100%', margin: 'auto' }}>
|
||||
<LoadingScreen />
|
||||
@@ -195,8 +192,7 @@ const ListBranches = () => {
|
||||
branch={selectedBranch}
|
||||
/>
|
||||
</View>
|
||||
<Navigation />
|
||||
</SafeAreaView>
|
||||
</LayoutTwo>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import NavbarBack from 'components/NavbarBack';
|
||||
import Navigation from 'components/Navigation';
|
||||
import LayoutTwo from 'components/LayoutTwo';
|
||||
import * as React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -11,7 +10,6 @@ import {
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import Tabs from '../../home/ui/Tabs';
|
||||
|
||||
interface CargoPricesProps {}
|
||||
@@ -21,13 +19,12 @@ const CargoPrices = (props: CargoPricesProps) => {
|
||||
const [activeTab, setActiveTab] = React.useState<'avia' | 'auto'>('avia');
|
||||
const navigation = useNavigation<NativeStackNavigationProp<any>>();
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<NavbarBack title={t('Kargo narxlari')} />
|
||||
<LayoutTwo title={t('Kargo narxlari')}>
|
||||
<ScrollView style={{ flex: 1 }}>
|
||||
<View style={styles.container}>
|
||||
<Tabs activeTab={activeTab} setActiveTab={setActiveTab} />
|
||||
{activeTab === 'avia' && (
|
||||
<View style={{ marginTop: 20, gap: 10, marginBottom: 20 }}>
|
||||
<View style={{ marginTop: 10, gap: 10, marginBottom: 20 }}>
|
||||
<View style={styles.cardWhite}>
|
||||
<View style={styles.priceCard}>
|
||||
<Text style={styles.titleBlack}>
|
||||
@@ -231,8 +228,7 @@ const CargoPrices = (props: CargoPricesProps) => {
|
||||
)}
|
||||
</View>
|
||||
</ScrollView>
|
||||
<Navigation />
|
||||
</SafeAreaView>
|
||||
</LayoutTwo>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -240,7 +236,7 @@ export default CargoPrices;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
marginTop: 20,
|
||||
marginTop: 10,
|
||||
},
|
||||
card: {
|
||||
width: '95%',
|
||||
@@ -254,6 +250,14 @@ const styles = StyleSheet.create({
|
||||
margin: 'auto',
|
||||
padding: 10,
|
||||
borderRadius: 8,
|
||||
paddingVertical: 15,
|
||||
paddingHorizontal: 12,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
|
||||
elevation: 1,
|
||||
},
|
||||
titleBlack: {
|
||||
fontSize: 16,
|
||||
|
||||
@@ -1,20 +1,12 @@
|
||||
'use client';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import calendarAPi from 'api/calendar';
|
||||
import Layout from 'components/Layout';
|
||||
import LoadingScreen from 'components/LoadingScreen';
|
||||
import Navbar from 'components/Navbar';
|
||||
import Navigation from 'components/Navigation';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import {
|
||||
RefreshControl,
|
||||
ScrollView,
|
||||
useWindowDimensions,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { RefreshControl, ScrollView, useWindowDimensions } from 'react-native';
|
||||
import Pages from './Pages';
|
||||
import PartyCarousel from './PartyCarousel';
|
||||
import { HomeStyle } from './styled';
|
||||
import Tabs from './Tabs';
|
||||
import TabsAuto from './TabsAuto';
|
||||
import TabsAvia from './TabsAvia';
|
||||
@@ -24,7 +16,6 @@ const Home = () => {
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
const scale = screenWidth < 360 ? 0.85 : 1;
|
||||
const styles = useMemo(() => HomeStyle(scale), [scale]);
|
||||
|
||||
const {
|
||||
data: autoData,
|
||||
@@ -71,20 +62,14 @@ const Home = () => {
|
||||
|
||||
if (autoLoad || aviaLoad || fetchAuto || fetchAvia) {
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<View style={styles.container}>
|
||||
<Navbar />
|
||||
<Layout>
|
||||
<LoadingScreen />
|
||||
<Navigation />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<View style={styles.container}>
|
||||
<Navbar />
|
||||
<Layout>
|
||||
<ScrollView
|
||||
refreshControl={refreshControl}
|
||||
removeClippedSubviews={true}
|
||||
@@ -95,9 +80,7 @@ const Home = () => {
|
||||
{activeTabContent}
|
||||
<Pages />
|
||||
</ScrollView>
|
||||
<Navigation />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,24 +2,16 @@ import { useNavigation } from '@react-navigation/native';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
useWindowDimensions,
|
||||
} from 'react-native';
|
||||
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import ArrowRightUnderline from 'svg/ArrowRightUnderline';
|
||||
import Usd from 'svg/Dollar';
|
||||
import InfoIcon from 'svg/Info';
|
||||
import Store from 'svg/Store';
|
||||
|
||||
const Pages = () => {
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
const navigation = useNavigation<NativeStackNavigationProp<any>>();
|
||||
const scale = screenWidth < 360 ? 0.85 : 1;
|
||||
const { t } = useTranslation();
|
||||
const styles = makeStyles(scale);
|
||||
const styles = makeStyles();
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
@@ -28,19 +20,10 @@ const Pages = () => {
|
||||
style={styles.card}
|
||||
>
|
||||
<View style={styles.text}>
|
||||
<Usd
|
||||
color="#28A7E8"
|
||||
width={28 * scale}
|
||||
height={28 * scale}
|
||||
colorCircle="#28A7E8"
|
||||
/>
|
||||
<Usd color="#28A7E8" width={28} height={28} colorCircle="#28A7E8" />
|
||||
<Text style={styles.title}>{t('Kargo narxlari')}</Text>
|
||||
</View>
|
||||
<ArrowRightUnderline
|
||||
color="#000000"
|
||||
width={24 * scale}
|
||||
height={24 * scale}
|
||||
/>
|
||||
<ArrowRightUnderline color="#000000" width={24} height={24} />
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
@@ -48,14 +31,10 @@ const Pages = () => {
|
||||
style={styles.card}
|
||||
>
|
||||
<View style={styles.text}>
|
||||
<InfoIcon color="#28A7E8" width={28 * scale} height={28 * scale} />
|
||||
<InfoIcon color="#28A7E8" width={28} height={28} />
|
||||
<Text style={styles.title}>{t('Taqiqlangan buyumlar')}</Text>
|
||||
</View>
|
||||
<ArrowRightUnderline
|
||||
color="#000000"
|
||||
width={24 * scale}
|
||||
height={24 * scale}
|
||||
/>
|
||||
<ArrowRightUnderline color="#000000" width={24} height={24} />
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* <View style={styles.card}>
|
||||
@@ -80,14 +59,10 @@ const Pages = () => {
|
||||
onPress={() => navigation.navigate('ListBranches')}
|
||||
>
|
||||
<View style={styles.text}>
|
||||
<Store color="#28A7E8" width={28 * scale} height={28 * scale} />
|
||||
<Store color="#28A7E8" width={28} height={28} />
|
||||
<Text style={styles.title}>{t('Filiallar ro’yxati')}</Text>
|
||||
</View>
|
||||
<ArrowRightUnderline
|
||||
color="#000000"
|
||||
width={24 * scale}
|
||||
height={24 * scale}
|
||||
/>
|
||||
<ArrowRightUnderline color="#000000" width={24} height={24} />
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* <TouchableOpacity
|
||||
@@ -108,33 +83,39 @@ const Pages = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const makeStyles = (scale: number) =>
|
||||
const makeStyles = () =>
|
||||
StyleSheet.create({
|
||||
container: {
|
||||
width: '100%',
|
||||
width: '95%',
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
marginTop: 10 * scale,
|
||||
borderRadius: 12 * scale,
|
||||
padding: 12 * scale,
|
||||
gap: 10 * scale,
|
||||
borderRadius: 12,
|
||||
marginBottom: 10,
|
||||
gap: 10,
|
||||
},
|
||||
card: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: '#FFFFFF',
|
||||
shadowColor: '#F2FAFF',
|
||||
padding: 15 * scale,
|
||||
borderRadius: 8 * scale,
|
||||
alignItems: 'center',
|
||||
|
||||
backgroundColor: '#FFFFFF',
|
||||
paddingVertical: 15,
|
||||
paddingHorizontal: 12,
|
||||
borderRadius: 10,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
|
||||
elevation: 1,
|
||||
},
|
||||
text: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 10 * scale,
|
||||
gap: 10,
|
||||
},
|
||||
title: {
|
||||
fontSize: 16 * scale,
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -24,9 +24,8 @@ const PartyCarousel = ({
|
||||
aviaData: any;
|
||||
}) => {
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
const scale = screenWidth < 360 ? 0.85 : 1;
|
||||
const cardWidth = screenWidth * 0.95;
|
||||
const styles = useMemo(() => HomeStyle(scale), [scale]);
|
||||
const styles = useMemo(() => HomeStyle(), []);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const statusConfig: any = {
|
||||
@@ -57,11 +56,9 @@ const PartyCarousel = ({
|
||||
},
|
||||
};
|
||||
|
||||
// calendarList tayyorlash
|
||||
const calendarList = useMemo(() => {
|
||||
const data: any[] = [];
|
||||
|
||||
const prepareList = (calendar: any, type: 'auto' | 'avia') => {
|
||||
if (!calendar) return;
|
||||
const weekdays = [
|
||||
{ key: 'sunday', label: 'Ya' },
|
||||
{ key: 'monday', label: 'Du' },
|
||||
@@ -72,6 +69,8 @@ const PartyCarousel = ({
|
||||
{ key: 'saturday', label: 'Sha' },
|
||||
];
|
||||
|
||||
const prepareList = (calendar: any, type: 'auto' | 'avia') => {
|
||||
if (!calendar) return;
|
||||
data.push({
|
||||
cargo: type,
|
||||
party: calendar.cargoType,
|
||||
@@ -79,7 +78,6 @@ const PartyCarousel = ({
|
||||
start: weekdays.map((day, index) => {
|
||||
const start = new Date(calendar.weekStartDate);
|
||||
start.setDate(start.getDate() + index);
|
||||
|
||||
const status =
|
||||
calendar[day.key as keyof typeof calendar] || 'DEFAULT';
|
||||
return {
|
||||
@@ -93,7 +91,6 @@ const PartyCarousel = ({
|
||||
|
||||
prepareList(autoData, 'auto');
|
||||
prepareList(aviaData, 'avia');
|
||||
|
||||
return data;
|
||||
}, [autoData, aviaData]);
|
||||
|
||||
@@ -103,14 +100,10 @@ const PartyCarousel = ({
|
||||
d.setHours(0, 0, 0, 0);
|
||||
return d;
|
||||
}, []);
|
||||
|
||||
// --- MODAL STATE ---
|
||||
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 (
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
@@ -119,19 +112,22 @@ const PartyCarousel = ({
|
||||
}}
|
||||
style={[
|
||||
styles.autoContainer,
|
||||
{ width: cardWidth, marginRight: isLast ? 0 : 10 },
|
||||
{
|
||||
width: cardWidth,
|
||||
marginRight: isLast ? 0 : 10,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{item.isAni && (
|
||||
<>
|
||||
<View style={styles.cardBody}>
|
||||
{Array.isArray(item.start) &&
|
||||
item.start.map((day: any, idx: number) => {
|
||||
<FlatList
|
||||
data={item.start}
|
||||
numColumns={7}
|
||||
keyExtractor={(_, idx) => idx.toString()}
|
||||
renderItem={({ item: day }) => {
|
||||
const dateObj = new Date(day.date);
|
||||
const isToday =
|
||||
dateObj.toDateString() === today.toDateString();
|
||||
const config =
|
||||
statusConfig[day.status] || statusConfig.DEFAULT;
|
||||
const isToday = dateObj.toDateString() === today.toDateString();
|
||||
const config = statusConfig[day.status] || statusConfig.DEFAULT;
|
||||
|
||||
let backgroundColor = config.backgroundColor;
|
||||
let textColor = config.textColor;
|
||||
@@ -148,14 +144,11 @@ const PartyCarousel = ({
|
||||
|
||||
return (
|
||||
<View
|
||||
key={idx}
|
||||
style={[
|
||||
styles.date,
|
||||
{
|
||||
backgroundColor,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: 70,
|
||||
marginRight: 5,
|
||||
},
|
||||
]}
|
||||
>
|
||||
@@ -167,21 +160,18 @@ const PartyCarousel = ({
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
}}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
/>
|
||||
|
||||
<View style={styles.divider} />
|
||||
<View style={styles.autoCard}>
|
||||
<View style={styles.row}>
|
||||
|
||||
<View style={styles.rowFull}>
|
||||
<Text style={styles.reysTitle}>
|
||||
{item.cargo.toUpperCase()}
|
||||
</Text>
|
||||
<Text style={styles.reysTitle}>{item.cargo.toUpperCase()}</Text>
|
||||
<View style={styles.animatedIconWrapper}>
|
||||
<AnimatedIcon type={item.cargo} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
</Pressable>
|
||||
@@ -200,9 +190,9 @@ const PartyCarousel = ({
|
||||
decelerationRate="fast"
|
||||
contentContainerStyle={{
|
||||
paddingHorizontal: (screenWidth - cardWidth) / 2,
|
||||
padding: 10,
|
||||
}}
|
||||
pagingEnabled
|
||||
style={{ marginBottom: 20 }}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
getItemLayout={(_, index) => ({
|
||||
length: cardWidth,
|
||||
@@ -210,8 +200,6 @@ const PartyCarousel = ({
|
||||
index,
|
||||
})}
|
||||
/>
|
||||
|
||||
{/* MODAL */}
|
||||
<Modal
|
||||
transparent
|
||||
visible={modalVisible}
|
||||
@@ -223,15 +211,12 @@ const PartyCarousel = ({
|
||||
<Text style={modalStyles.modalTitle}>
|
||||
{t('Yetkazish tafsilotlari')}
|
||||
</Text>
|
||||
{selectedItem && (
|
||||
<>
|
||||
{selectedItem.start.map((day: any, idx: number) => (
|
||||
{selectedItem &&
|
||||
selectedItem.start.map((day: any, idx: number) => (
|
||||
<Text key={idx} style={{ textAlign: 'left', width: '100%' }}>
|
||||
{day.date} - {t(day.weekday)} - {t(day.status)}
|
||||
</Text>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
<Pressable
|
||||
onPress={() => setModalVisible(false)}
|
||||
style={modalStyles.closeButton}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Dispatch, SetStateAction, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
FlatList,
|
||||
Image,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
useWindowDimensions,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import AviaLogo from 'screens/../../assets/bootsplash/Avia.png';
|
||||
@@ -18,22 +18,14 @@ interface Props {
|
||||
}
|
||||
|
||||
const Tabs = ({ activeTab, setActiveTab }: Props) => {
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
const { t } = useTranslation();
|
||||
const scale = useMemo(() => (screenWidth < 360 ? 0.85 : 1), [screenWidth]);
|
||||
|
||||
const styles = useMemo(() => HomeStyle(scale), [scale]);
|
||||
|
||||
const handleTabPress = useCallback(
|
||||
(type: 'avia' | 'auto') => {
|
||||
setActiveTab(type);
|
||||
},
|
||||
[setActiveTab],
|
||||
);
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
const cardWidth = screenWidth * 0.95;
|
||||
const styles = useMemo(() => HomeStyle(), []);
|
||||
|
||||
const gradientStyle = useMemo(
|
||||
() => ({
|
||||
width: '100%' as const,
|
||||
flex: 1,
|
||||
borderRadius: 8,
|
||||
flexDirection: 'row' as const,
|
||||
alignItems: 'center' as const,
|
||||
@@ -44,48 +36,75 @@ const Tabs = ({ activeTab, setActiveTab }: Props) => {
|
||||
[],
|
||||
);
|
||||
|
||||
const renderTabButton = useCallback(
|
||||
(type: 'avia' | 'auto', label: string, logo: any) => {
|
||||
const isActive = activeTab === type;
|
||||
// Tabs data
|
||||
const tabsData = useMemo(
|
||||
() => [
|
||||
{
|
||||
type: 'avia' as const,
|
||||
label: t('Avia orqali yetkazish'),
|
||||
logo: AviaLogo,
|
||||
},
|
||||
{
|
||||
type: 'auto' as const,
|
||||
label: t('Avto orqali yetkazish'),
|
||||
logo: AutoLogo,
|
||||
},
|
||||
],
|
||||
[t],
|
||||
);
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ item }: { item: (typeof tabsData)[number] }) => {
|
||||
const isActive = activeTab === item.type;
|
||||
const gradientColors = isActive
|
||||
? ['#28A7E8', '#28A7E8']
|
||||
: ['#28a8e82d', '#28A7E8'];
|
||||
const textStyle = [
|
||||
styles.tabsText,
|
||||
{ color: isActive ? '#fff' : '#000' },
|
||||
];
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => handleTabPress(type)}
|
||||
style={styles.tabs}
|
||||
key={type}
|
||||
onPress={() => setActiveTab(item.type)}
|
||||
style={{ flex: 1 }}
|
||||
>
|
||||
<LinearGradient
|
||||
colors={gradientColors}
|
||||
start={{ x: 0.5, y: 1 }}
|
||||
end={{ x: 1.5, y: 1 }}
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 1, y: 0 }}
|
||||
style={gradientStyle}
|
||||
>
|
||||
<Image source={logo} style={styles.tabsLogo} />
|
||||
<Text style={textStyle}>{label}</Text>
|
||||
<Image source={item.logo} style={styles.tabsLogo} />
|
||||
<Text
|
||||
style={[styles.tabsText, { color: isActive ? '#fff' : '#000' }]}
|
||||
>
|
||||
{item.label}
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
[activeTab, styles, handleTabPress, gradientStyle],
|
||||
[activeTab, styles, gradientStyle, setActiveTab],
|
||||
);
|
||||
|
||||
const tabButtons = useMemo(
|
||||
() => [
|
||||
renderTabButton('avia', t('Avia orqali yetkazish'), AviaLogo),
|
||||
renderTabButton('auto', t('Avto orqali yetkazish'), AutoLogo),
|
||||
],
|
||||
[renderTabButton],
|
||||
return (
|
||||
<FlatList
|
||||
data={tabsData}
|
||||
numColumns={2}
|
||||
keyExtractor={(_, idx) => idx.toString()}
|
||||
renderItem={renderItem}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
scrollEnabled={false}
|
||||
columnWrapperStyle={{
|
||||
gap: 8,
|
||||
}}
|
||||
contentContainerStyle={{
|
||||
paddingHorizontal: (screenWidth - cardWidth) / 2,
|
||||
}}
|
||||
getItemLayout={(_, index) => ({
|
||||
length: cardWidth,
|
||||
offset: cardWidth * index,
|
||||
index,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
|
||||
return <View style={styles.tabsContainer}>{tabButtons}</View>;
|
||||
};
|
||||
|
||||
export default Tabs;
|
||||
|
||||
@@ -84,7 +84,7 @@ const TabsAuto = () => {
|
||||
decelerationRate="fast"
|
||||
contentContainerStyle={{
|
||||
paddingHorizontal: (screenWidth - cardWidth) / 2,
|
||||
marginTop: 10,
|
||||
padding: 10,
|
||||
}}
|
||||
renderItem={({ item, index }) => {
|
||||
const isLast = index === addressList.length - 1;
|
||||
|
||||
@@ -85,7 +85,7 @@ const TabsAvia = () => {
|
||||
decelerationRate="fast"
|
||||
contentContainerStyle={{
|
||||
paddingHorizontal: (screenWidth - cardWidth) / 2,
|
||||
marginTop: 20,
|
||||
padding: 10,
|
||||
}}
|
||||
renderItem={({ item, index }) => {
|
||||
const isLast = index === addressList.length - 1;
|
||||
@@ -125,7 +125,7 @@ const makeStyles = (scale: number, cardWidth: number, screenWidth: number) =>
|
||||
width: '95%',
|
||||
backgroundColor: '#28a8e82c',
|
||||
margin: 'auto',
|
||||
marginTop: 20,
|
||||
// marginTop: 20,
|
||||
borderRadius: 12,
|
||||
padding: 12,
|
||||
gap: 10,
|
||||
|
||||
@@ -1,46 +1,42 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
|
||||
export const HomeStyle = (scale: number) =>
|
||||
export const HomeStyle = () =>
|
||||
StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
header: {
|
||||
backgroundColor: '#28A7E8',
|
||||
height: 80 * scale,
|
||||
paddingHorizontal: 10 * scale,
|
||||
paddingVertical: 10 * scale,
|
||||
height: 80,
|
||||
paddingHorizontal: 10,
|
||||
paddingVertical: 10,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
title: {
|
||||
color: '#fff',
|
||||
fontSize: 20 * scale,
|
||||
fontSize: 20,
|
||||
},
|
||||
logo: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 5 * scale,
|
||||
gap: 5,
|
||||
},
|
||||
links: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 15 * scale,
|
||||
gap: 15,
|
||||
},
|
||||
autoContainer: {
|
||||
width: '90%',
|
||||
height: 140 * scale,
|
||||
borderRadius: 8 * scale,
|
||||
padding: 10 * scale,
|
||||
borderRadius: 8,
|
||||
padding: 8,
|
||||
backgroundColor: '#FFFFFF',
|
||||
marginTop: 10,
|
||||
gap: 8 * scale,
|
||||
gap: 8,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 * scale },
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2 * scale,
|
||||
margin: 'auto',
|
||||
shadowRadius: 2,
|
||||
elevation: 2,
|
||||
},
|
||||
autoCard: {
|
||||
@@ -48,33 +44,34 @@ export const HomeStyle = (scale: number) =>
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
reysTitle: {
|
||||
fontSize: 20 * scale,
|
||||
fontSize: 20,
|
||||
color: '#28A7E8',
|
||||
fontWeight: '600',
|
||||
},
|
||||
text: {
|
||||
fontWeight: '500',
|
||||
color: 'red',
|
||||
fontSize: 14 * scale,
|
||||
fontSize: 14,
|
||||
},
|
||||
box: {
|
||||
backgroundColor: '#28A7E81A',
|
||||
padding: 10 * scale,
|
||||
padding: 10,
|
||||
width: 'auto',
|
||||
alignSelf: 'flex-start',
|
||||
borderRadius: 8 * scale,
|
||||
borderRadius: 8,
|
||||
},
|
||||
date: {
|
||||
backgroundColor: '#28A7E8',
|
||||
padding: 6 * scale,
|
||||
width: '13%',
|
||||
height: 50,
|
||||
textAlign: 'center',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: 8 * scale,
|
||||
borderRadius: 8,
|
||||
padding: 0,
|
||||
},
|
||||
dateLabel: {
|
||||
fontSize: 14 * scale,
|
||||
fontSize: 14,
|
||||
fontWeight: '500',
|
||||
color: '#FFFFFF',
|
||||
},
|
||||
@@ -84,23 +81,23 @@ export const HomeStyle = (scale: number) =>
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
logoIcon: {
|
||||
width: 50 * scale,
|
||||
height: 50 * scale,
|
||||
width: 50,
|
||||
height: 50,
|
||||
resizeMode: 'contain',
|
||||
},
|
||||
bellWrapper: {
|
||||
position: 'relative',
|
||||
},
|
||||
bellDot: {
|
||||
width: 10 * scale,
|
||||
height: 10 * scale,
|
||||
width: 10,
|
||||
height: 10,
|
||||
position: 'absolute',
|
||||
backgroundColor: 'red',
|
||||
right: 2 * scale,
|
||||
right: 2,
|
||||
borderRadius: 100,
|
||||
},
|
||||
divider: {
|
||||
height: 2 * scale,
|
||||
height: 2,
|
||||
width: '100%',
|
||||
backgroundColor: '#28A7E81F',
|
||||
},
|
||||
@@ -111,23 +108,23 @@ export const HomeStyle = (scale: number) =>
|
||||
infoBlock: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
gap: 6 * scale,
|
||||
gap: 6,
|
||||
},
|
||||
iconBox: {
|
||||
backgroundColor: '#28A7E81A',
|
||||
padding: 8 * scale,
|
||||
borderRadius: 8 * scale,
|
||||
padding: 8,
|
||||
borderRadius: 8,
|
||||
},
|
||||
infoTextBlock: {
|
||||
flexDirection: 'column',
|
||||
},
|
||||
infoTitle: {
|
||||
fontWeight: '500',
|
||||
fontSize: 18 * scale,
|
||||
fontSize: 18,
|
||||
},
|
||||
infoSubtext: {
|
||||
fontWeight: '500',
|
||||
fontSize: 14 * scale,
|
||||
fontSize: 14,
|
||||
color: '#00000066',
|
||||
},
|
||||
subtextRight: {
|
||||
@@ -136,38 +133,35 @@ export const HomeStyle = (scale: number) =>
|
||||
highlightBox: {
|
||||
backgroundColor: '#69ec6d9c',
|
||||
alignSelf: 'flex-start',
|
||||
padding: 4 * scale,
|
||||
borderRadius: 8 * scale,
|
||||
padding: 4,
|
||||
borderRadius: 8,
|
||||
},
|
||||
highlightText: {
|
||||
fontSize: 16 * scale,
|
||||
fontSize: 16,
|
||||
},
|
||||
animatedIconWrapper: {
|
||||
width: '80%',
|
||||
height: 40,
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
gap: 10 * scale,
|
||||
width: '100%',
|
||||
// flexDirection: 'row',
|
||||
// gap: 10,
|
||||
// width: '100%',
|
||||
},
|
||||
rowFull: {
|
||||
flexDirection: 'row',
|
||||
gap: 2 * scale,
|
||||
width: '100%',
|
||||
gap: 2,
|
||||
},
|
||||
tabs: {
|
||||
width: '50%',
|
||||
borderRadius: 8 * scale,
|
||||
justifyContent: 'space-between',
|
||||
gap: 10 * scale,
|
||||
},
|
||||
tabsContainer: {
|
||||
marginLeft: 'auto',
|
||||
paddingLeft: 8 * scale,
|
||||
paddingRight: 18 * scale,
|
||||
flexDirection: 'row',
|
||||
gap: 8 * scale,
|
||||
borderRadius: 8,
|
||||
},
|
||||
// tabsContainer: {
|
||||
// marginLeft: 'auto',
|
||||
// paddingLeft: 8,
|
||||
// paddingRight: 18,
|
||||
// flexDirection: 'row',
|
||||
// gap: 8,
|
||||
// },
|
||||
tabsLogo: {
|
||||
width: '40%',
|
||||
height: '50%',
|
||||
@@ -176,7 +170,7 @@ export const HomeStyle = (scale: number) =>
|
||||
tabsText: {
|
||||
width: '60%',
|
||||
color: '#FFFFFF',
|
||||
fontSize: 16 * scale,
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import NavbarBack from 'components/NavbarBack';
|
||||
import Navigation from 'components/Navigation';
|
||||
import LayoutTwo from 'components/LayoutTwo';
|
||||
import * as React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import Battery from 'svg/Battery';
|
||||
import Blade from 'svg/Blade';
|
||||
import Book from 'svg/Book';
|
||||
@@ -22,13 +20,12 @@ const RestrictedProduct = (props: RestrictedProductProps) => {
|
||||
const [activeTab, setActiveTab] = React.useState<'avia' | 'auto'>('avia');
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<NavbarBack title={t('Taqiqlangan buyumlar')} />
|
||||
<LayoutTwo title={t('Taqiqlangan buyumlar')}>
|
||||
<ScrollView style={{ flex: 1 }}>
|
||||
<View style={styles.container}>
|
||||
<Tabs activeTab={activeTab} setActiveTab={setActiveTab} />
|
||||
{activeTab === 'avia' && (
|
||||
<View style={{ marginTop: 20, gap: 10, marginBottom: 20 }}>
|
||||
<View style={{ marginTop: 10, gap: 10, marginBottom: 20 }}>
|
||||
<Text
|
||||
style={{
|
||||
width: '95%',
|
||||
@@ -179,7 +176,7 @@ const RestrictedProduct = (props: RestrictedProductProps) => {
|
||||
</View>
|
||||
)}
|
||||
{activeTab === 'auto' && (
|
||||
<View style={{ marginTop: 20, gap: 10, marginBottom: 20 }}>
|
||||
<View style={{ marginTop: 10, gap: 10, marginBottom: 20 }}>
|
||||
<View style={styles.cardWhite}>
|
||||
<View style={styles.priceCard}>
|
||||
<Text style={styles.titleBlack}>
|
||||
@@ -273,8 +270,7 @@ const RestrictedProduct = (props: RestrictedProductProps) => {
|
||||
)}
|
||||
</View>
|
||||
</ScrollView>
|
||||
<Navigation />
|
||||
</SafeAreaView>
|
||||
</LayoutTwo>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -282,7 +278,7 @@ export default RestrictedProduct;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
marginTop: 20,
|
||||
marginTop: 10,
|
||||
},
|
||||
card: {
|
||||
width: '95%',
|
||||
@@ -294,8 +290,15 @@ const styles = StyleSheet.create({
|
||||
width: '95%',
|
||||
gap: 5,
|
||||
margin: 'auto',
|
||||
padding: 10,
|
||||
borderRadius: 8,
|
||||
paddingVertical: 15,
|
||||
paddingHorizontal: 12,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
|
||||
elevation: 1,
|
||||
},
|
||||
titleBlack: {
|
||||
fontSize: 16,
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
useWindowDimensions,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import PassportIcon from 'svg/Passport';
|
||||
@@ -26,8 +25,6 @@ import MyPassport from './MyPassport';
|
||||
const Passport = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation<NativeStackNavigationProp<any>>();
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
const scale = screenWidth < 360 ? 0.85 : 1;
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
const {
|
||||
@@ -105,11 +102,7 @@ const Passport = () => {
|
||||
{myPassport && myPassport.length === 0 ? (
|
||||
<View style={styles.content}>
|
||||
<View style={styles.emptyState}>
|
||||
<PassportIcon
|
||||
color="#ccc"
|
||||
width={80 * scale}
|
||||
height={80 * scale}
|
||||
/>
|
||||
<PassportIcon color="#ccc" width={80} height={80} />
|
||||
<Text style={styles.emptyText}>
|
||||
{t("Hali pasport qo'shilmagan")}
|
||||
</Text>
|
||||
@@ -127,7 +120,7 @@ const Passport = () => {
|
||||
onPress={handleNavigateToCreatePassword}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<Plus color="#fff" width={24 * scale} height={24 * scale} />
|
||||
<Plus color="#fff" width={24} height={24} />
|
||||
<Text style={styles.addButtonText}>
|
||||
{t("Yangi pasport qo'shish")}
|
||||
</Text>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { PacketsData } from 'api/packets';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
FlatList,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
@@ -11,11 +12,7 @@ import {
|
||||
import CloseIcon from 'svg/Close';
|
||||
import FilterIcon from 'svg/Filter';
|
||||
|
||||
const transportTypes = [
|
||||
// 'all',
|
||||
'AUTO',
|
||||
'AVIA',
|
||||
] as const;
|
||||
const transportTypes = ['AUTO', 'AVIA'] as const;
|
||||
type TransportType = (typeof transportTypes)[number];
|
||||
|
||||
interface Props {
|
||||
@@ -38,9 +35,8 @@ const Filter = ({
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
const { t } = useTranslation();
|
||||
const scale = screenWidth < 360 ? 0.85 : 1;
|
||||
|
||||
const styles = makeStyles(scale);
|
||||
const styles = makeStyles();
|
||||
const newOrders = React.useMemo(
|
||||
() => data.data.filter(item => item.paymentStatus === 'NEW'),
|
||||
[data],
|
||||
@@ -48,32 +44,35 @@ const Filter = ({
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{/* Tugma */}
|
||||
<TouchableOpacity
|
||||
style={styles.card}
|
||||
onPress={() => setOpen(prev => !prev)}
|
||||
>
|
||||
<FilterIcon color="#000000" width={18 * scale} height={18 * scale} />
|
||||
<FilterIcon color="#000000" width={18} height={18} />
|
||||
<Text style={styles.text}>{t('Filter')}</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
{open && (
|
||||
<View style={styles.dropdown}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
{/* Header */}
|
||||
<View style={styles.dropdownHeader}>
|
||||
<Text style={styles.sectionTitle}>{t('Transport')}</Text>
|
||||
<TouchableOpacity onPress={() => setOpen(false)}>
|
||||
<CloseIcon />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.typeList}>
|
||||
{transportTypes.map(type => (
|
||||
|
||||
{/* Transport Types -> FlatList */}
|
||||
<FlatList
|
||||
data={transportTypes}
|
||||
keyExtractor={item => item}
|
||||
numColumns={2}
|
||||
scrollEnabled={false}
|
||||
columnWrapperStyle={{ gap: 8 }}
|
||||
contentContainerStyle={{ gap: 8, marginBottom: 12 }}
|
||||
renderItem={({ item: type }) => (
|
||||
<TouchableOpacity
|
||||
key={type}
|
||||
style={[
|
||||
styles.typeButton,
|
||||
selectedType === type && styles.activeType,
|
||||
@@ -89,48 +88,28 @@ const Filter = ({
|
||||
selectedType === type && styles.activeTypeText,
|
||||
]}
|
||||
>
|
||||
{
|
||||
// type === 'all'
|
||||
// ? t('Barchasi')
|
||||
// :
|
||||
type === 'AUTO' ? t('Avto') : t('Avia')
|
||||
}
|
||||
{type === 'AUTO' ? t('Avto') : t('Avia')}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Text style={styles.sectionTitle}>{t('Reys raqami')}</Text>
|
||||
<View style={styles.flightList}>
|
||||
<FlatList
|
||||
data={[{ id: 'all', packetName: 'all' }, ...newOrders]}
|
||||
keyExtractor={item => item.id?.toString() || 'all'}
|
||||
numColumns={1}
|
||||
scrollEnabled={false}
|
||||
contentContainerStyle={{ gap: 8 }} // faqat shu kifoya
|
||||
renderItem={({ item }) => (
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.flightButton,
|
||||
selectedFlight === 'all' && styles.activeFlight,
|
||||
]}
|
||||
onPress={() => {
|
||||
setReys('all');
|
||||
setSelectedData(null);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.flightText,
|
||||
selectedFlight === 'all' && styles.activeFlightText,
|
||||
]}
|
||||
>
|
||||
{t('Barchasi')}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
{newOrders.map(item => (
|
||||
<TouchableOpacity
|
||||
key={item.id}
|
||||
style={[
|
||||
styles.flightButton,
|
||||
selectedFlight === item.packetName && styles.activeFlight,
|
||||
]}
|
||||
onPress={() => {
|
||||
setReys(item.packetName);
|
||||
setSelectedData(item);
|
||||
setSelectedData(item.id === 'all' ? null : item);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
@@ -141,75 +120,73 @@ const Filter = ({
|
||||
styles.activeFlightText,
|
||||
]}
|
||||
>
|
||||
{item.packetName}
|
||||
{item.packetName === 'all' ? t('Barchasi') : item.packetName}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
const makeStyles = (scale: number) =>
|
||||
|
||||
const makeStyles = () =>
|
||||
StyleSheet.create({
|
||||
container: {
|
||||
height: 'auto',
|
||||
borderRadius: 8 * scale,
|
||||
borderRadius: 8,
|
||||
alignItems: 'flex-end',
|
||||
justifyContent: 'flex-start',
|
||||
position: 'relative',
|
||||
zIndex: 10,
|
||||
},
|
||||
card: {
|
||||
paddingHorizontal: 12 * scale,
|
||||
height: 40 * scale,
|
||||
paddingHorizontal: 12,
|
||||
height: 40,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#D8DADC',
|
||||
borderRadius: 8 * scale,
|
||||
borderRadius: 8,
|
||||
flexDirection: 'row',
|
||||
gap: 4 * scale,
|
||||
gap: 4,
|
||||
},
|
||||
text: {
|
||||
color: '#000000',
|
||||
fontWeight: '500',
|
||||
fontSize: 14 * scale,
|
||||
fontSize: 14,
|
||||
},
|
||||
dropdown: {
|
||||
position: 'absolute',
|
||||
top: 50 * scale,
|
||||
top: 50,
|
||||
right: 0,
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 8 * scale,
|
||||
paddingVertical: 8 * scale,
|
||||
paddingHorizontal: 10 * scale,
|
||||
borderRadius: 8,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 10,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.2,
|
||||
shadowRadius: 4,
|
||||
elevation: 5,
|
||||
zIndex: 10,
|
||||
minWidth: 200 * scale,
|
||||
minWidth: 200,
|
||||
},
|
||||
dropdownHeader: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 10,
|
||||
},
|
||||
|
||||
sectionTitle: {
|
||||
fontWeight: '600',
|
||||
marginBottom: 6 * scale,
|
||||
marginBottom: 6,
|
||||
color: '#333',
|
||||
fontSize: 16 * scale,
|
||||
},
|
||||
typeList: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: 8 * scale,
|
||||
marginBottom: 12 * scale,
|
||||
fontSize: 16,
|
||||
},
|
||||
typeButton: {
|
||||
flex: 1,
|
||||
backgroundColor: '#F3FAFF',
|
||||
paddingHorizontal: 5 * scale,
|
||||
paddingVertical: 6 * scale,
|
||||
borderRadius: 6 * scale,
|
||||
paddingHorizontal: 5,
|
||||
paddingVertical: 6,
|
||||
borderRadius: 6,
|
||||
},
|
||||
activeType: {
|
||||
backgroundColor: '#28A7E8',
|
||||
@@ -217,22 +194,18 @@ const makeStyles = (scale: number) =>
|
||||
typeText: {
|
||||
color: '#28A7E8',
|
||||
fontWeight: '500',
|
||||
fontSize: 14 * scale,
|
||||
fontSize: 14,
|
||||
textAlign: 'center',
|
||||
},
|
||||
activeTypeText: {
|
||||
color: '#fff',
|
||||
},
|
||||
flightList: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: 8 * scale,
|
||||
marginBottom: 12 * scale,
|
||||
},
|
||||
flightButton: {
|
||||
flex: 1,
|
||||
backgroundColor: '#F3FAFF',
|
||||
paddingHorizontal: 10 * scale,
|
||||
paddingVertical: 6 * scale,
|
||||
borderRadius: 6 * scale,
|
||||
paddingHorizontal: 10,
|
||||
paddingVertical: 6,
|
||||
borderRadius: 6,
|
||||
},
|
||||
activeFlight: {
|
||||
backgroundColor: '#28A7E8',
|
||||
@@ -240,7 +213,8 @@ const makeStyles = (scale: number) =>
|
||||
flightText: {
|
||||
color: '#28A7E8',
|
||||
fontWeight: '500',
|
||||
fontSize: 14 * scale,
|
||||
fontSize: 14,
|
||||
textAlign: 'center',
|
||||
},
|
||||
activeFlightText: {
|
||||
color: '#fff',
|
||||
|
||||
@@ -2,11 +2,11 @@ import { PacketsData } from 'api/packets';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
FlatList,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
useWindowDimensions,
|
||||
} from 'react-native';
|
||||
import Auto from 'svg/Auto';
|
||||
import Avia from 'svg/Avia';
|
||||
@@ -53,44 +53,39 @@ interface Props {
|
||||
}
|
||||
|
||||
const Order = ({ data, openModal, selectedData }: Props) => {
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
const scale = useMemo(() => (screenWidth < 360 ? 0.85 : 1), [screenWidth]);
|
||||
const { t } = useTranslation();
|
||||
const styles = useMemo(
|
||||
() => makeStyles(scale, screenWidth),
|
||||
[scale, screenWidth],
|
||||
);
|
||||
const styles = useMemo(() => makeStyles(), []);
|
||||
|
||||
const createIcons = useCallback(
|
||||
(scale: number, cargo: string) => [
|
||||
(cargo: string) => [
|
||||
{
|
||||
status: 'COLLECTING',
|
||||
icon: <BoxIcon width={20 * scale} height={20 * scale} color="" />,
|
||||
icon: <BoxIcon width={24} height={24} color="" />,
|
||||
},
|
||||
{
|
||||
status: 'ON_THE_WAY',
|
||||
icon:
|
||||
cargo === 'avia' ? (
|
||||
<Avia width={20 * scale} height={20 * scale} color="" />
|
||||
<Avia width={24} height={24} color="" />
|
||||
) : (
|
||||
<Auto width={20 * scale} height={20 * scale} color="" view="-4" />
|
||||
<Auto width={24} height={24} color="" view="-4" />
|
||||
),
|
||||
},
|
||||
{
|
||||
status: 'IN_CUSTOMS',
|
||||
icon: <BagIcon width={20 * scale} height={20 * scale} color="" />,
|
||||
icon: <BagIcon width={24} height={24} color="" />,
|
||||
},
|
||||
{
|
||||
status: 'IN_WAREHOUSE',
|
||||
icon: <Store width={20 * scale} height={20 * scale} color="" />,
|
||||
icon: <Store width={24} height={24} color="" />,
|
||||
},
|
||||
{
|
||||
status: 'DELIVERED',
|
||||
icon: <TrunkIcon width={20 * scale} height={20 * scale} color="" />,
|
||||
icon: <TrunkIcon width={24} height={24} color="" />,
|
||||
},
|
||||
{
|
||||
status: 'PAID',
|
||||
icon: <SuccessIcon width={20 * scale} height={20 * scale} color="" />,
|
||||
icon: <SuccessIcon width={24} height={24} color="" />,
|
||||
},
|
||||
],
|
||||
[],
|
||||
@@ -104,31 +99,31 @@ const Order = ({ data, openModal, selectedData }: Props) => {
|
||||
);
|
||||
|
||||
const renderOrderItem = useCallback(
|
||||
(ItemLayout: DataInfo, index: number) => {
|
||||
({ item, index }: { item: DataInfo; index: number }) => {
|
||||
const currentStatusIndex = statuses.indexOf(
|
||||
ItemLayout.deliveryStatus as FilterType,
|
||||
item.deliveryStatus as FilterType,
|
||||
);
|
||||
|
||||
const icons = createIcons(scale, ItemLayout.deliveryStatus);
|
||||
const icons = createIcons(item.deliveryStatus);
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
key={index}
|
||||
onPress={() => handleItemPress(ItemLayout)}
|
||||
>
|
||||
<TouchableOpacity key={index} onPress={() => handleItemPress(item)}>
|
||||
<View style={styles.card}>
|
||||
<View style={styles.statusCard}>
|
||||
{icons.map((item, i) => {
|
||||
<FlatList
|
||||
data={icons}
|
||||
keyExtractor={(iconItem, i) => iconItem.status + i}
|
||||
numColumns={6}
|
||||
contentContainerStyle={styles.statusCard}
|
||||
renderItem={({ item: iconItem, index: i }) => {
|
||||
const iconColor = i <= currentStatusIndex ? '#28A7E8' : '#000';
|
||||
const viewColor =
|
||||
i <= currentStatusIndex ? '#28A7E81A' : '#0000001A';
|
||||
|
||||
return (
|
||||
<React.Fragment key={item.status}>
|
||||
<View style={styles.iconWrapper}>
|
||||
<View
|
||||
style={[styles.circle, { backgroundColor: viewColor }]}
|
||||
>
|
||||
{React.cloneElement(item.icon, { color: iconColor })}
|
||||
{React.cloneElement(iconItem.icon, { color: iconColor })}
|
||||
</View>
|
||||
{i !== icons.length - 1 && (
|
||||
<View
|
||||
@@ -138,186 +133,159 @@ const Order = ({ data, openModal, selectedData }: Props) => {
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Status Label */}
|
||||
<View
|
||||
style={[
|
||||
styles.statusLabelWrapper,
|
||||
{
|
||||
backgroundColor: `${
|
||||
statusColorMap[ItemLayout.deliveryStatus]
|
||||
}1A`,
|
||||
backgroundColor: `${statusColorMap[item.deliveryStatus]}1A`,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.statusText,
|
||||
{ color: statusColorMap[ItemLayout.deliveryStatus] },
|
||||
{ color: statusColorMap[item.deliveryStatus] },
|
||||
]}
|
||||
>
|
||||
{t(
|
||||
tabList.find(item => item.value === ItemLayout.deliveryStatus)
|
||||
tabList.find(tab => tab.value === item.deliveryStatus)
|
||||
?.label || '',
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* Info */}
|
||||
<View style={styles.infoCard}>
|
||||
<Text style={styles.infoTitle}>{t('Reys raqami')}</Text>
|
||||
<Text
|
||||
style={[styles.infoText, { width: '50%', textAlign: 'right' }]}
|
||||
>
|
||||
{ItemLayout.packetName}
|
||||
{item.packetName}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.infoCard}>
|
||||
<Text style={styles.infoTitle}>{t('Mahsulotlar og’irligi')}</Text>
|
||||
<Text style={styles.infoText}>{ItemLayout.weight}</Text>
|
||||
<Text style={styles.infoText}>{item.weight}</Text>
|
||||
</View>
|
||||
<View style={styles.infoCard}>
|
||||
<Text style={styles.infoTitle}>{t('Umumiy narxi')}</Text>
|
||||
<Text style={styles.infoText}>{ItemLayout.totalPrice}</Text>
|
||||
<Text style={styles.infoText}>{item.totalPrice}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
[scale, createIcons, handleItemPress],
|
||||
[createIcons, handleItemPress],
|
||||
);
|
||||
|
||||
const orderItems = useMemo(() => {
|
||||
if (selectedData) {
|
||||
return [renderOrderItem(selectedData, 0)];
|
||||
}
|
||||
return data.data.map(renderOrderItem);
|
||||
}, [data, renderOrderItem, selectedData]);
|
||||
|
||||
const countSection = useMemo(
|
||||
() => (
|
||||
<View style={styles.count}>
|
||||
<Text style={styles.title}>{t('Buyurtmalar soni')}</Text>
|
||||
{selectedData ? (
|
||||
<Text style={styles.title}>1</Text>
|
||||
) : (
|
||||
<Text style={styles.title}>{data.data.length}</Text>
|
||||
)}
|
||||
</View>
|
||||
),
|
||||
[styles.count, styles.title, data.data.length, selectedData],
|
||||
const ordersData = useMemo(
|
||||
() => (selectedData ? [selectedData] : data.data),
|
||||
[data, selectedData],
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{countSection}
|
||||
{orderItems}
|
||||
<View style={styles.count}>
|
||||
<Text style={styles.title}>{t('Buyurtmalar soni')}</Text>
|
||||
<Text style={styles.title}>
|
||||
{selectedData ? '1' : data.data.length}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<FlatList
|
||||
data={ordersData}
|
||||
scrollEnabled={false}
|
||||
renderItem={renderOrderItem}
|
||||
keyExtractor={(item, index) => item.id?.toString() || index.toString()}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const makeStyles = (scale: number, screenWidth: number) =>
|
||||
const makeStyles = () =>
|
||||
StyleSheet.create({
|
||||
container: {
|
||||
width: screenWidth * 0.95,
|
||||
marginTop: 10,
|
||||
alignSelf: 'center',
|
||||
borderRadius: 8 * scale,
|
||||
padding: 8 * scale,
|
||||
backgroundColor: '#F5F5F5',
|
||||
width: '95%',
|
||||
margin: 'auto',
|
||||
borderRadius: 10,
|
||||
},
|
||||
count: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginTop: 10,
|
||||
},
|
||||
title: {
|
||||
fontSize: 16 * scale,
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
color: '#333',
|
||||
},
|
||||
card: {
|
||||
backgroundColor: '#FFFFFF',
|
||||
marginTop: 12 * scale,
|
||||
padding: 15 * scale,
|
||||
borderRadius: 10 * scale,
|
||||
gap: 5 * scale,
|
||||
flexDirection: 'column',
|
||||
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: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 10 * scale,
|
||||
marginBottom: 10,
|
||||
},
|
||||
circle: {
|
||||
padding: 8 * scale,
|
||||
padding: 8,
|
||||
borderRadius: 50,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
divider: {
|
||||
width: 20 * scale,
|
||||
borderBottomWidth: 2 * scale,
|
||||
width: 20,
|
||||
borderBottomWidth: 2,
|
||||
borderStyle: 'dashed',
|
||||
},
|
||||
statusLabelWrapper: {
|
||||
borderRadius: 8 * scale,
|
||||
borderRadius: 8,
|
||||
alignSelf: 'flex-start',
|
||||
paddingVertical: 6 * scale,
|
||||
paddingHorizontal: 10 * scale,
|
||||
marginBottom: 12 * scale,
|
||||
paddingVertical: 6,
|
||||
paddingHorizontal: 10,
|
||||
marginBottom: 12,
|
||||
},
|
||||
statusText: {
|
||||
fontWeight: '600',
|
||||
fontSize: 16 * scale,
|
||||
fontSize: 16,
|
||||
},
|
||||
infoCard: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 6 * scale,
|
||||
marginBottom: 6,
|
||||
},
|
||||
iconWrapper: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
marginBottom: 10,
|
||||
},
|
||||
infoTitle: {
|
||||
fontSize: 16 * scale,
|
||||
fontSize: 16,
|
||||
color: '#979797',
|
||||
fontWeight: '500',
|
||||
},
|
||||
infoText: {
|
||||
fontSize: 14 * scale,
|
||||
fontSize: 14,
|
||||
color: '#28A7E8',
|
||||
fontWeight: '500',
|
||||
},
|
||||
modalOverlay: {
|
||||
flex: 1,
|
||||
backgroundColor: 'rgba(0,0,0,0.4)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
zIndex: 20,
|
||||
},
|
||||
modalContent: {
|
||||
width: '90%',
|
||||
maxHeight: '80%',
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 10,
|
||||
padding: 20,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.3,
|
||||
shadowRadius: 4,
|
||||
elevation: 5,
|
||||
},
|
||||
modalTitle: {
|
||||
fontSize: 20 * scale,
|
||||
fontWeight: '600',
|
||||
marginBottom: 10,
|
||||
},
|
||||
closeButton: {
|
||||
marginTop: 20,
|
||||
backgroundColor: '#28A7E8',
|
||||
paddingVertical: 10,
|
||||
borderRadius: 8,
|
||||
alignItems: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default Order;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import packetsApi from 'api/packets';
|
||||
import Layout from 'components/Layout';
|
||||
import LoadingScreen from 'components/LoadingScreen';
|
||||
import Navbar from 'components/Navbar';
|
||||
import Navigation from 'components/Navigation';
|
||||
import NoResult from 'components/NoResult';
|
||||
import Pagination from 'components/Pagination';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
@@ -15,7 +14,6 @@ import {
|
||||
View,
|
||||
useWindowDimensions,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import Serach from 'svg/Serach';
|
||||
import { DataInfo } from '../lib/data';
|
||||
import Filter from './Filter';
|
||||
@@ -140,31 +138,17 @@ const Status = () => {
|
||||
|
||||
if (isLoading || isFetching) {
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<View style={styles.container}>
|
||||
<Navbar />
|
||||
<Layout>
|
||||
<LoadingScreen message={loadingMessage} progress={progress} />
|
||||
<Navigation />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
if (statusData?.data.length === 0) {
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<View style={styles.container}>
|
||||
<Navbar />
|
||||
<Layout>
|
||||
<Tabs filter={filter} setFilter={setFilter} />
|
||||
<View style={styles.controls}>
|
||||
{/* <View style={styles.searchContainer}>
|
||||
<TextInput
|
||||
placeholder={t('ID orqali izlash')}
|
||||
placeholderTextColor="#D8DADC"
|
||||
style={styles.search}
|
||||
/>
|
||||
<View style={styles.searchIcon}>{searchIcon}</View>
|
||||
</View> */}
|
||||
<View style={{ position: 'relative' }}>
|
||||
<Filter
|
||||
transportTypes={transportTypes}
|
||||
@@ -177,16 +161,12 @@ const Status = () => {
|
||||
</View>
|
||||
</View>
|
||||
<NoResult message={t("Hech qanday ma'lumot topilmadi")} />
|
||||
<Navigation />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<View style={styles.container}>
|
||||
<Navbar />
|
||||
<Layout>
|
||||
<ScrollView
|
||||
keyboardShouldPersistTaps="handled"
|
||||
refreshControl={refreshControl}
|
||||
@@ -240,9 +220,7 @@ const Status = () => {
|
||||
setPage={setPage}
|
||||
/>
|
||||
</View>
|
||||
<Navigation />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { Dispatch, SetStateAction, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
FlatList,
|
||||
NativeScrollEvent,
|
||||
NativeSyntheticEvent,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
@@ -32,31 +32,29 @@ const tabList: { label: string; value: FilterType }[] = [
|
||||
{ label: 'Bojxonada', value: 'IN_CUSTOMS' },
|
||||
{ label: 'Toshkent omboriga yetib keldi', value: 'IN_WAREHOUSE' },
|
||||
{ label: 'Topshirish punktiga yuborildi', value: 'DELIVERED' },
|
||||
// { label: 'Qabul qilingan', value: 'DELIVERED' },
|
||||
];
|
||||
|
||||
const Tabs = ({ filter, setFilter }: Props) => {
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
const scale = screenWidth < 360 ? 0.85 : 1;
|
||||
const styles = makeStyles(scale);
|
||||
const scrollRef = useRef<ScrollView>(null);
|
||||
const cardWidth = screenWidth * 0.95;
|
||||
const styles = makeStyles();
|
||||
const flatListRef = useRef<FlatList>(null);
|
||||
const [scrollX, setScrollX] = useState(0);
|
||||
const { t } = useTranslation();
|
||||
const scrollStep = 120;
|
||||
|
||||
const handleScrollLeft = () => {
|
||||
if (scrollRef.current) {
|
||||
scrollRef.current.scrollTo({
|
||||
x: Math.max(0, scrollX - scrollStep),
|
||||
flatListRef.current?.scrollToOffset({
|
||||
offset: Math.max(0, scrollX - scrollStep),
|
||||
animated: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleScrollRight = () => {
|
||||
if (scrollRef.current) {
|
||||
scrollRef.current.scrollTo({ x: scrollX + scrollStep, animated: true });
|
||||
}
|
||||
flatListRef.current?.scrollToOffset({
|
||||
offset: scrollX + scrollStep,
|
||||
animated: true,
|
||||
});
|
||||
};
|
||||
|
||||
const onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
||||
@@ -69,27 +67,27 @@ const Tabs = ({ filter, setFilter }: Props) => {
|
||||
<ArrowLeft color="#28A7E8" width={20} height={20} />
|
||||
</TouchableOpacity>
|
||||
|
||||
<ScrollView
|
||||
<FlatList
|
||||
ref={flatListRef}
|
||||
horizontal
|
||||
onScroll={onScroll}
|
||||
ref={scrollRef}
|
||||
data={tabList}
|
||||
keyExtractor={item => item.value}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
>
|
||||
{tabList.map(tab => (
|
||||
onScroll={onScroll}
|
||||
renderItem={({ item }) => (
|
||||
<TouchableOpacity
|
||||
key={tab.value}
|
||||
style={[styles.card, filter === tab.value && styles.activeCard]}
|
||||
onPress={() => setFilter(tab.value)}
|
||||
style={[styles.card, filter === item.value && styles.activeCard]}
|
||||
onPress={() => setFilter(item.value)}
|
||||
>
|
||||
<Text
|
||||
style={[styles.text, filter === tab.value && styles.activeText]}
|
||||
style={[styles.text, filter === item.value && styles.activeText]}
|
||||
>
|
||||
{t(tab.label)}
|
||||
{t(item.label)}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</ScrollView>
|
||||
)}
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
/>
|
||||
|
||||
<TouchableOpacity style={styles.navButton} onPress={handleScrollRight}>
|
||||
<ArrowRightUnderline color="#28A7E8" width={20} height={20} />
|
||||
@@ -98,32 +96,38 @@ const Tabs = ({ filter, setFilter }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
const makeStyles = (scale: number) =>
|
||||
const makeStyles = () =>
|
||||
StyleSheet.create({
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
width: '95%',
|
||||
height: 50 * scale,
|
||||
height: 50,
|
||||
backgroundColor: '#FFFFFF',
|
||||
marginTop: 20 * scale,
|
||||
marginTop: 10,
|
||||
alignSelf: 'center',
|
||||
borderRadius: 8 * scale,
|
||||
paddingHorizontal: 4 * scale,
|
||||
borderRadius: 8,
|
||||
paddingHorizontal: 4,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
|
||||
elevation: 1,
|
||||
},
|
||||
scrollContent: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 4 * scale,
|
||||
paddingHorizontal: 4,
|
||||
},
|
||||
card: {
|
||||
paddingHorizontal: 12 * scale,
|
||||
paddingVertical: 8 * scale,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 8,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#F3FAFF',
|
||||
marginRight: 8 * scale,
|
||||
borderRadius: 8 * scale,
|
||||
marginRight: 8,
|
||||
borderRadius: 8,
|
||||
},
|
||||
activeCard: {
|
||||
backgroundColor: '#28A7E8',
|
||||
@@ -131,13 +135,13 @@ const makeStyles = (scale: number) =>
|
||||
text: {
|
||||
color: '#28A7E8',
|
||||
fontWeight: '500',
|
||||
fontSize: 14 * scale,
|
||||
fontSize: 14,
|
||||
},
|
||||
activeText: {
|
||||
color: '#fff',
|
||||
},
|
||||
navButton: {
|
||||
padding: 6 * scale,
|
||||
padding: 6,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user