ebanutsya

This commit is contained in:
2023-10-28 08:08:37 +03:00
parent 37d3fb5a78
commit 0bc1835405
19 changed files with 435 additions and 180 deletions

Binary file not shown.

View File

@@ -34,6 +34,7 @@
"react-native-keyevent-expo-config-plugin": "^1.0.49",
"react-native-modal": "^13.0.1",
"react-native-paper": "^5.10.6",
"react-native-progress": "^5.0.1",
"react-native-radio-buttons-group": "^3.0.5",
"react-native-reanimated": "3.3.0",
"react-native-responsive-dimensions": "^3.1.1",

12
src/api/printingApi.ts Normal file
View File

@@ -0,0 +1,12 @@
import apiClient from "./apiClient";
const router = '/printing';
const printingApi = {
getLabel: async (orderId: number): Promise<Uint8Array> => {
let response = await apiClient.get(`${router}/getLabel?orderId=${orderId}`, {responseType: 'arraybuffer'});
return new Uint8Array(response.data);
},
}
export default printingApi;

View File

@@ -10,15 +10,16 @@ type Props = {
containerStyle?: StyleProp<ViewStyle>;
isUnset?: boolean;
onPress?: (event: GestureResponderEvent) => void
disabled?: boolean
};
const BasicButton: FC<Props> = ({label, onPress, containerStyle, style, isUnset = false}) => {
const BasicButton: FC<Props> = ({label, onPress, containerStyle, style, isUnset = false, disabled = false}) => {
return (
<TouchableOpacity onPress={onPress}>
<TouchableOpacity style={{flex: 1}} disabled={disabled} onPress={onPress}>
<View style={[styles.container, style]}>
<DText style={styles.text}>{label}</DText>
</View>
<View style={[styles.container, style, disabled ? {backgroundColor: "#A0A0A0"} : {}]}>
<DText style={styles.text}>{label}</DText>
</View>
</TouchableOpacity>
);
@@ -33,11 +34,13 @@ const styles = StyleSheet.create({
backgroundColor: '#2478F8',
borderRadius: responsiveWidth(1),
padding: responsiveWidth(2),
flex: 1
},
text: {
color: "white",
fontSize: RFPercentage(2),
textAlignVertical: "center",
textAlign: "center"
}
});

View File

@@ -0,0 +1,55 @@
import {FC} from "react";
import {Props} from "react-native-paper";
import {StyleSheet, View} from "react-native";
import {BottomSheetModalProvider} from "@gorhom/bottom-sheet";
import {useSelector} from "react-redux";
import {RootState} from "../../../redux/store";
import Modal from "react-native-modal";
import {background, blue} from "../../../css/colors";
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
import * as Progress from 'react-native-progress';
import DTitle from "../../DTitle/DTitle";
import {RFPercentage} from "react-native-responsive-fontsize";
const LoadingModal: FC = () => {
const isVisible = useSelector((state: RootState) => state.loadingModal.isVisible);
const loadingText = useSelector((state: RootState) => state.loadingModal.loadingText);
return (
<Modal isVisible={isVisible}>
<View style={styles.container}>
<DTitle style={{textAlign: "center"}}>{loadingText}</DTitle>
<View style={styles.progressBarWrapper}>
<Progress.Circle size={RFPercentage(20)}
color={blue}
indeterminate={true}
style={styles.progressBar}
borderWidth={responsiveWidth(1)}
/>
</View>
</View>
</Modal>
)
}
const styles = StyleSheet.create({
container: {
alignSelf: "center",
backgroundColor: background,
width: responsiveWidth(80),
height: responsiveHeight(50),
borderRadius: responsiveWidth(2),
paddingHorizontal: responsiveWidth(20),
paddingVertical: responsiveHeight(10),
justifyContent: "center",
rowGap: responsiveHeight(5)
},
progressBarWrapper: {
alignItems: "center"
},
progressBar: {
justifyContent: "center"
}
})
export default LoadingModal;

View File

@@ -42,7 +42,7 @@ const SelectProductModal: FC<Props> = ({visible, products, onSelected}) => {
const styles = StyleSheet.create({
container: {
backgroundColor: background,
borderRadius: responsiveWidth(1),
borderRadius: responsiveWidth(2),
paddingHorizontal: responsiveWidth(5),
paddingVertical: responsiveHeight(5),
rowGap: responsiveHeight(3),

View File

@@ -5,42 +5,36 @@ import DText from "../DText/DText";
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
import DTitle from "../DTitle/DTitle";
import {Order} from "../../types/order";
import OrderProductsList from "./OrderProductsList";
type Props = {
onPress?: (event: GestureResponderEvent) => void
onSelect: (order: Order) => void
order: Order
}
const OrderCard: FC<Props> = React.memo(({onPress, order}) => {
const OrderCard: FC<Props> = React.memo(({onPress, onSelect, order}) => {
return (
<TouchableOpacity onPress={() => {
console.log("pressed11")
onSelect(order);
}}>
<View style={styles.container}>
<View style={styles.imageWrapper}>
<Image style={styles.image} source={{uri: order.imageUrl}}/>
</View>
<View style={styles.description}>
<View style={styles.descriptionContent}>
<View style={styles.title}>
<View style={styles.container}><View style={styles.description}>
<View style={styles.descriptionContent}>
<View style={styles.title}>
<DTitle>{order.orderNumber}</DTitle>
<Image source={require('assets/icons/marketplaces/ozon.png')} style={styles.titleImage}/>
</View>
<DText>Количество: 5</DText>
<DText>Поставщик: {order.supplierName}</DText>
<DText>Селлер: {order.sellerName}</DText>
<DText>Цвет: ГОЛУБОЙ</DText>
</View>
<View style={styles.descriptionStatus}>
<DText>
Ожидает сборки
</DText>
<DTitle>{order.orderNumber}</DTitle>
<Image source={require('assets/icons/marketplaces/ozon.png')} style={styles.titleImage}/>
</View>
<DText>Селлер: {order.sellerName}</DText>
<DText>Маркетплейс: {order.marketplaceName}</DText>
</View>
<View style={styles.descriptionStatus}>
<DText>
Ожидает сборки
</DText>
</View>
</View>
</View>
</TouchableOpacity>
@@ -52,7 +46,7 @@ const styles = StyleSheet.create({
backgroundColor: "white",
display: "flex",
borderRadius: RFPercentage(3),
height: responsiveHeight(20),
height: responsiveHeight(15),
flexDirection: "row",
padding: RFPercentage(2),
flex: 1

View File

@@ -0,0 +1,68 @@
import {FC} from "react";
import {FlatList, StyleSheet, View, Image, TouchableOpacity} from "react-native";
import {OrderProduct} from "../../types/order";
import DTitle from "../DTitle/DTitle";
import DText from "../DText/DText";
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
import {RFPercentage} from "react-native-responsive-fontsize";
import {background} from "../../css/colors";
type ListProps = {
products: OrderProduct[];
onSelected: (product: OrderProduct) => void;
}
type CardProps = {
product: OrderProduct;
onPress: (product: OrderProduct) => void;
id: number;
}
const OrderProductCard: FC<CardProps> = ({product, onPress, id}) => {
return (
<TouchableOpacity onPress={() => onPress(product)}>
<View style={cardStyles.container}>
<View style={cardStyles.content}>
<DText>{id + 1}) {product.productName}</DText>
</View>
</View>
</TouchableOpacity>
)
}
const cardStyles = StyleSheet.create({
container: {
flexDirection: "row",
backgroundColor: background,
borderRadius: RFPercentage(1),
padding: RFPercentage(1)
},
content:{
}
})
const OrderProductsList: FC<ListProps> = ({products, onSelected}) => {
return (
<View style={listStyles.container}>
<DTitle style={listStyles.title}>Товары</DTitle>
<FlatList data={products}
contentContainerStyle={{rowGap: responsiveHeight(1)}}
renderItem={(item) => <OrderProductCard id={item.index} product={item.item}
onPress={onSelected}/>}/>
</View>
)
}
const listStyles = StyleSheet.create({
container: {
backgroundColor: "white",
flex: 1
},
title: {
marginBottom: responsiveHeight(2),
textAlign: "center"
}
})
export default OrderProductsList;

View File

@@ -5,15 +5,14 @@ import {RFPercentage} from "react-native-responsive-fontsize";
import Modal from "react-native-modal";
import BasicButton from "../BasicButton/BasicButton";
import DText from "../DText/DText";
import {useDispatch} from "react-redux";
import {useDispatch, useSelector} from "react-redux";
import {RootState} from "../../redux/store";
import {closeScanModal, setScannedData} from "../../features/scanModal/scanModalSlice";
type Props = {
visible: boolean
onCancelButtonPress?: (event: GestureResponderEvent) => void,
onChanged: (text: string) => void
}
const ScanModal: FC<Props> = ({visible, onCancelButtonPress, onChanged}) => {
const ScanModal: FC = () => {
const inputRef = useRef<TextInput | null>(null);
const visible = useSelector((state: RootState) => state.scanModal.isVisible);
const dispatch = useDispatch();
useEffect(() => {
if (visible) inputRef.current?.focus();
}, [visible]);
@@ -22,10 +21,13 @@ const ScanModal: FC<Props> = ({visible, onCancelButtonPress, onChanged}) => {
<Modal isVisible={visible}>
<View style={styles.container}>
<DText style={styles.text}>Наведите сканер на штрихкод товара или заказа</DText>
<BasicButton onPress={onCancelButtonPress} style={styles.cancelButton} label={"Отмена"}/>
<BasicButton onPress={() => {
dispatch(closeScanModal());
}} style={styles.cancelButton} label={"Отмена"}/>
<TextInput
onEndEditing={(e) => {
onChanged(e.nativeEvent.text);
dispatch(setScannedData(e.nativeEvent.text));
dispatch(closeScanModal())
}}
style={styles.pseudoInput}
ref={inputRef}
@@ -39,7 +41,7 @@ const ScanModal: FC<Props> = ({visible, onCancelButtonPress, onChanged}) => {
const styles = StyleSheet.create({
container: {
borderRadius: responsiveWidth(1),
borderRadius: responsiveWidth(2),
backgroundColor: "white",
display: "flex",
flexDirection: "column",

View File

@@ -28,7 +28,7 @@ const SearchBar: FC<Props> = ({onSearch, onSupplierProductSelected}) => {
barcodeApi.searchProducts(scannedData).then(setProducts);
}, [scannedData]);
const selectProductModalVisible = products.length > 0;
const selectProductModalVisible = products.length > 0 && false;
return (
<View style={styles.container}>
@@ -74,8 +74,6 @@ const styles = StyleSheet.create({
borderRadius: 0,
borderTopRightRadius: responsiveWidth(1),
borderBottomRightRadius: responsiveWidth(1),
width: responsiveWidth(25),
flex: 1
},
scanImageWrapper: {
paddingHorizontal: responsiveWidth(1),
@@ -87,7 +85,7 @@ const styles = StyleSheet.create({
},
textInput: {
height: responsiveHeight(height),
flex: 1,
flex: 2,
borderWidth: 1,
borderColor: "#A5A5A5",
borderTopLeftRadius: responsiveWidth(1),

View File

@@ -0,0 +1,28 @@
import {createSlice} from "@reduxjs/toolkit";
import {Order} from "../../types/order";
export interface AssemblyState {
order?: Order;
}
const initialState: AssemblyState = {
order: undefined,
}
export const assembly = createSlice({
name: 'assembly',
initialState,
reducers: {
setOrder: (state, action) => {
state.order = action.payload;
},
setAssembled: (state, payload) => {
state.order = ({...state.order, orderNumber:"2282"})
},
setShipped: (state) => {
}
}
})
export const {setOrder} = assembly.actions;
export default assembly.reducer;

View File

@@ -0,0 +1,30 @@
import {createSlice} from "@reduxjs/toolkit";
export interface LoadingModalState {
isVisible: boolean;
loadingText: string
}
const initialState: LoadingModalState = {
isVisible: false,
loadingText: "Подождите..."
}
export const loadingModalSlice = createSlice({
name: 'loadingModal',
initialState,
reducers: {
openLoadingModal: (state) => {
state.isVisible = true
},
closeLoadingModal: (state) => {
state.isVisible = false
},
setLoadingText: (state, action) => {
state.loadingText = action.payload;
}
}
})
export const {openLoadingModal, closeLoadingModal, setLoadingText} = loadingModalSlice.actions;
export default loadingModalSlice.reducer;

View File

@@ -3,13 +3,17 @@ import {configureStore} from '@reduxjs/toolkit';
import authReducer from 'features/auth/authSlice';
import interfaceReducer from 'features/interface/interfaceSlice';
import scanModalReducer from 'features/scanModal/scanModalSlice';
import loadingModalReducer from 'features/loadingModal/loadingModalSlice';
import assemblyReducer from 'features/assembly/assemblySlice';
import {useDispatch} from "react-redux";
export const store = configureStore({
reducer: {
auth: authReducer,
interface: interfaceReducer,
scanModal: scanModalReducer
scanModal: scanModalReducer,
loadingModal: loadingModalReducer,
assembly: assemblyReducer
},
});

View File

@@ -12,11 +12,11 @@ import Toast from "react-native-toast-message";
import toastConfig from "../../components/Toast/Toast";
import ScanModal from "../../components/SearchBar/ScanModal";
import {closeScanModal, setScannedData} from "../../features/scanModal/scanModalSlice";
import LoadingModal from "../../components/Modals/LoadingModal/LoadingModal";
function CommonPage() {
const dim = useSelector((state: RootState) => state.interface.dim);
const isAuthorized = useSelector((state: RootState) => state.auth.isAuthorized);
const isScanModalVisible = useSelector((state: RootState) => state.scanModal.isVisible);
const dispatch = useDispatch();
@@ -35,15 +35,9 @@ function CommonPage() {
<View style={styles.main}>
{isAuthorized ? <MainScreen/> : <LoginScreen/>}
<View style={[styles.overlay, {display: dim ? 'flex' : 'none'}]}/>
<LoadingModal/>
<ScanModal/>
<Toast config={toastConfig}/>
<ScanModal visible={isScanModalVisible}
onCancelButtonPress={() => {
dispatch(closeScanModal());
}}
onChanged={text => {
dispatch(setScannedData(text));
dispatch(closeScanModal());
}}/>
</View>
)

View File

@@ -1,28 +1,32 @@
import {StyleSheet, Text, View, ImageBackground, Linking, Image} from 'react-native';
import {StyleSheet, Text, View, ImageBackground, Image} from 'react-native';
import {createBottomTabNavigator} from "@react-navigation/bottom-tabs";
import HomeScreen from "../HomeScreen/HomeScreen";
import BoxScreen from "../BoxScreen/BoxScreen";
import BarcodeScreen from "../BarcodeScreen/BarcodeScreen";
import MoneyScreen from "../MoneyScreen/MoneyScreen";
import ProfileScreen from "../ProfileScreen/ProfileScreen";
import {DefaultTheme, NavigationContainer} from "@react-navigation/native";
import moneyScreen from "../MoneyScreen/MoneyScreen";
import profileScreen from "../ProfileScreen/ProfileScreen";
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
import {RFPercentage} from "react-native-responsive-fontsize";
import LoginScreen from "../LoginScreen/LoginScreen";
import OrderScreen from "../OrderScreen/OrderScreen";
import OrdersScreen from "../OrdersScreen/OrdersScreen";
import {background} from "../../css/colors";
import * as fs from "fs";
export type TabNavigatorParamList = {
Home: undefined;
Box: undefined;
Barcode: undefined;
Money: undefined;
Profile: undefined;
};
interface CustomTabProps {
name: string;
component: React.ComponentType<any>;
icon: any;
hidden: boolean;
}
const CustomTab = ({name, component, icon}: CustomTabProps) => ({
const CustomTab = ({name, component, icon, hidden}: CustomTabProps) => ({
name,
component,
options: {
@@ -43,31 +47,36 @@ const CustomTab = ({name, component, icon}: CustomTabProps) => ({
function MainScreen() {
const Tab = createBottomTabNavigator();
const tabScreens = [
const tabScreens: CustomTabProps[] = [
{
name: "Home",
component: OrderScreen,
icon: require('assets/icons/home.png')
icon: require('assets/icons/home.png'),
hidden: false
},
{
name: "Box",
component: OrdersScreen,
icon: require('assets/icons/box.png')
icon: require('assets/icons/box.png'),
hidden: false
},
{
name: "Barcode",
component: BarcodeScreen,
icon: require('assets/icons/barcode.png')
icon: require('assets/icons/barcode.png'),
hidden: false
},
{
name: "Money",
component: moneyScreen,
icon: require('assets/icons/money.png')
icon: require('assets/icons/money.png'),
hidden: false
},
{
name: "Profile",
component: profileScreen,
icon: require('assets/icons/profile.png')
icon: require('assets/icons/profile.png'),
hidden: false
}
];
@@ -90,6 +99,7 @@ function MainScreen() {
name: tabScreen.name,
component: tabScreen.component,
icon: tabScreen.icon,
hidden: tabScreen.hidden
})}/>
)}
</Tab.Navigator>

View File

@@ -5,108 +5,151 @@ import {RFPercentage} from "react-native-responsive-fontsize";
import DTitle from "../../components/DTitle/DTitle";
import BasicButton from "../../components/BasicButton/BasicButton";
import Hyperlink from "../../components/Hyperlink/Hyperlink";
import React, {useState} from "react";
import React, {useEffect, useState} from "react";
import userApi from "../../api/userApi";
type ArticleTextProps = {
article: number
}
import {StatusBar} from "expo-status-bar";
import * as Progress from 'react-native-progress';
import {useDispatch, useSelector} from "react-redux";
import {RootState} from "../../redux/store";
import {closeLoadingModal, openLoadingModal, setLoadingText} from "../../features/loadingModal/loadingModalSlice";
import {useNavigation} from "@react-navigation/native";
import printingApi from "../../api/printingApi";
import PrintingService from "../../utils/PrintingService";
import OrderProductsList from "../../components/OrderCard/OrderProductsList";
import {setOrder} from "../../features/assembly/assemblySlice";
function OrderScreen() {
const [order, setOrder] = useState({
article: 183658,
imageUrl: "https://421421.selcdn.ru/denco/996956/thumbzoom/h0b41036e5dc84a88b3dd344a46ab33edt.jpg-640x640.jpg",
orderNumber: "93757290-0104-7",
productName: "Фигурки животных «Собачки» 258, 5-7 см., статичные / 12 шт.",
supplierName: "simaland",
marketplaceName: "Wildberries РЕНТА",
sellerName: "DENCO",
assembled: false
});
const order = useSelector((state: RootState) => state.assembly.order);
if (!order) return (
<View style={noOrderStyles.container}>
<DText style={noOrderStyles.title}>Заказ не выбран!</DText>
<View style={noOrderStyles.buttonWrapper}>
<BasicButton onPress={() => {
// @ts-ignore
navigator.navigate("Box");
}} label={"На главную"}/>
</View>
</View>
)
const dispatch = useDispatch();
const assembled = useSelector((state: RootState) => state.assembly.assembled);
const shipped = useSelector((state: RootState) => state.assembly.shipped);
const navigator = useNavigation();
const [selectedProduct, setSelectedProduct] = useState(order.products[0]);
return (
<View style={styles.container}>
<View style={styles.dataContainer}>
<View style={styles.productsContainer}>
<View style={styles.orderProductsListWrapper}>
<OrderProductsList products={order.products} onSelected={() => {
}}/>
</View>
<View style={styles.imageWrapper}>
<Image source={{uri: order.imageUrl}} style={styles.image}/>
</View>
<View style={styles.contentContainer}>
<View style={styles.contentWrapper}>
<DTitle style={styles.contentTitle}>{order.orderNumber}</DTitle>
<Hyperlink url={`https://denco.store/manager/?a=resource/update&id=${order.article}`}>
<DText style={styles.articleText}>Артикул: {order.article}</DText>
</Hyperlink>
<DText>Товар: {order.productName}</DText>
<DText>Поставщик: {order.supplierName}</DText>
<DText>Селлер: {order.sellerName}</DText>
<DText>Маркетплейс: {order.marketplaceName}</DText>
</View>
<Image style={styles.image} source={{uri: selectedProduct.imageUrl}}/>
</View>
</View>
<View style={styles.contentContainer}>
<View style={styles.dataContainer}>
<DTitle style={styles.contentTitle}>Заказ</DTitle>
<DText>Номер заказа: {order.orderNumber}</DText>
<DText>Маркетплейс: {order.marketplaceName}</DText>
<DText>Селлер: {order.sellerName}</DText>
<DText>{}</DText>
<DTitle style={styles.contentTitle}>Товар</DTitle>
<DText>Артикул DENCO: {selectedProduct.dencoArticle}</DText>
<DText>Поставщик: {selectedProduct.supplierName}</DText>
<DText>Номер товара: {0}</DText>
</View>
<View style={styles.buttonsContainer}>
<BasicButton label={"Отметить как собранный"}
disabled={!selectedProduct.assembled}
onPress={()=>{
setOrder(oldValue => ({ ...oldValue }));
}}
/>
<BasicButton label={"Печать этикетки"}
disabled={Boolean(order.products.find(product => product.assembled))}/>
</View>
</View>
<View style={styles.buttonsContainer}>
<View style={styles.buttonsWrapper}>
{!order.assembled &&
<BasicButton label={"Отметить как собранный"} onPress={() => {
userApi.test()
// setOrder({...order, assembled: true})
// console.log(order);
}}/>
}
{order.assembled &&
<BasicButton label={"Печать этикетки"}/>
}
{/*<BasicButton label={"Следующий товар"}/>*/}
</View>
</View>
</View>
)
}
const noOrderStyles = StyleSheet.create({
container: {
justifyContent: "center",
flex: 1,
rowGap: responsiveHeight(5)
},
title: {
textAlign: "center",
fontSize: responsiveWidth(5)
},
buttonWrapper: {
paddingHorizontal: responsiveWidth(20)
}
})
const styles = StyleSheet.create({
orderProductsListWrapper: {
flex: 0.5,
backgroundColor: "white",
borderRadius: RFPercentage(3),
padding: RFPercentage(2),
},
buttonWrapper: {
flex: 1,
backgroundColor: "red"
},
dataContainer: {
backgroundColor: "white",
padding: RFPercentage(2),
flex: 0.5,
borderRadius: RFPercentage(3),
},
buttonsContainer: {
backgroundColor: "white",
padding: RFPercentage(2),
flex: 0.5,
borderRadius: RFPercentage(3),
rowGap: responsiveHeight(2)
},
contentContainer: {
flex: 1,
borderRadius: RFPercentage(3),
flexDirection: "row",
columnGap: responsiveWidth(3),
},
container: {
width: "100%",
height: "100%",
display: "flex",
flex: 1,
paddingHorizontal: responsiveWidth(5)
paddingHorizontal: responsiveWidth(5),
paddingBottom: responsiveHeight(10),
rowGap: responsiveHeight(2)
},
dataContainer: {
// backgroundColor: "black",
productsContainer: {
display: "flex",
flexDirection: "row",
columnGap: responsiveWidth(3)
},
buttonsContainer: {
// backgroundColor: "blue",
flex: 1,
display: "flex",
justifyContent: "center",
paddingHorizontal: responsiveWidth(10)
columnGap: responsiveWidth(3),
height: responsiveHeight(30)
},
buttonsWrapper: {
// backgroundColor: "red",
rowGap: responsiveHeight(3)
},
imageWrapper: {
width: responsiveWidth(40),
height: responsiveHeight(40),
// height: responsiveHeight(40),
// backgroundColor: "red",
flex: 0.5,
backgroundColor: "white",
padding: RFPercentage(2),
borderRadius: RFPercentage(3)
},
image: {
flex: 1,
borderRadius: RFPercentage(3)
},
contentContainer: {
padding: RFPercentage(2),
backgroundColor: "white",
borderRadius: RFPercentage(3),
flex: 1
resizeMode: "contain"
},
contentWrapper: {
display: "flex",

View File

@@ -23,10 +23,15 @@ import sortingModal from "../../components/Modals/SortingModal/SortingModal";
import flashListSeparator from "../../components/FlashListSeparator/FlashListSeparator";
import {RootState} from "../../redux/store";
import ordersApi from "../../api/ordersApi";
import {setOrder} from "../../features/assembly/assemblySlice";
import {NavigationProp, useNavigation} from "@react-navigation/native";
import {TabNavigatorParamList} from "../MainScreen/MainScreen";
function OrdersScreen() {
const dispatch = useDispatch();
const navigator = useNavigation<NavigationProp<TabNavigatorParamList, 'Home'>>();
const [orders, setOrders] = useState<Order[]>([]);
const sortingModalRef = useRef<SortingModalHandles | null>(null);
const defaultSortingValue = 'createdOnAsc';
@@ -56,8 +61,9 @@ function OrdersScreen() {
data={orders}
keyExtractor={(item: Order) => item.orderNumber.toString()}
renderItem={({item}) =>
<OrderCard order={item} onPress={() => {
<OrderCard order={item} onSelect={(order) => {
dispatch(setOrder(order));
navigator.navigate("Home");
}}/>}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={true}
@@ -70,7 +76,6 @@ function OrdersScreen() {
/>
<SortingModal onChange={setSortingValue}
onClose={() => {
console.log("Closed")
}}
ref={sortingModalRef}
elements={sortingModalElements}

View File

@@ -1,45 +1,19 @@
export type Order = {
export type OrderProduct = {
databaseId: number;
article: number;
imageUrl: string;
orderNumber: string;
productName: string;
dencoArticle: number;
supplierName: string;
marketplaceName: string;
sellerName: string;
productName: string;
assembled: boolean;
shipped: boolean
imageUrl: string;
};
// Генератор случайных строк заданной длины
function generateRandomString(length: number): string {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
// Генератор случайных данных для заказа
function generateRandomOrder(): Order {
return {
databaseId: Math.floor(Math.random() * 1000), // Произвольное число для databaseId
article: Math.floor(Math.random() * 100000), // Произвольное число для article
imageUrl: 'https://example.com/image.png', // Произвольная ссылка на изображение
orderNumber: generateRandomString(12), // Случайная строка длиной 12 символов
productName: 'Random Product', // Произвольное название продукта
supplierName: 'Random Supplier', // Произвольное имя поставщика
marketplaceName: 'Random Marketplace', // Произвольное имя маркетплейса
sellerName: 'Random Seller', // Произвольное имя продавца
assembled: Math.random() < 0.5, // Произвольное булевое значение (true/false)
};
}
// Генератор массива случайных заказов
export function generateRandomOrders(count: number): Order[] {
const orders: Order[] = [];
for (let i = 0; i < count; i++) {
orders.push(generateRandomOrder());
}
return orders;
}
export type Order = {
databaseId: number;
orderNumber: string;
marketplaceName: string;
sellerName: string;
products: OrderProduct[];
};

View File

@@ -0,0 +1,34 @@
import axios from "axios";
class PrintingService {
private static instance: PrintingService | null = null;
private readonly apiUrl: string;
private readonly port: number;
public static getInstance(port?: number): PrintingService {
if (!this.instance) {
this.instance = new PrintingService(port);
}
return this.instance;
}
private constructor(port = 2282) {
this.apiUrl = "127.0.0.1";
this.port = port;
}
private async print(printer: string, type: string, bytes: Uint8Array): Promise<string> {
let response = await axios.post(`http://${this.apiUrl}:${this.port}/print/${printer}/${type}`, bytes.buffer);
return response.data;
}
public async printPdf(printer: string, pdfBytes: Uint8Array): Promise<string> {
return this.print(printer, "pdf", pdfBytes);
}
public async printImage(printer: string, imageBytes: Uint8Array): Promise<string> {
return this.print(printer, "image", imageBytes);
}
}
export default PrintingService;