ebanutsya
This commit is contained in:
		@@ -14,6 +14,8 @@
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@expo/webpack-config": "^19.0.0",
 | 
			
		||||
    "@gorhom/bottom-sheet": "^4",
 | 
			
		||||
    "@react-native-community/datetimepicker": "7.2.0",
 | 
			
		||||
    "@react-native-picker/picker": "^2.5.1",
 | 
			
		||||
    "@react-navigation/bottom-tabs": "^6.5.8",
 | 
			
		||||
    "@react-navigation/native": "^6.1.7",
 | 
			
		||||
    "@reduxjs/toolkit": "^1.9.5",
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,6 @@ export default function App() {
 | 
			
		||||
    })
 | 
			
		||||
    if (!fontsLoading)
 | 
			
		||||
        return <View><Text>Loading...</Text></View>
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Provider store={store}>
 | 
			
		||||
            <GestureHandlerRootView style={{flex: 1}}>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,16 @@ import {Order} from "../types/order";
 | 
			
		||||
const router = '/orders';
 | 
			
		||||
 | 
			
		||||
const ordersApi = {
 | 
			
		||||
    getOrders: async (lastId: number) => {
 | 
			
		||||
 | 
			
		||||
    getOrders: async (page: number, orderBy: string, desc: boolean, shipmentDate: string, status: number): Promise<Order[]> => {
 | 
			
		||||
        const params = {
 | 
			
		||||
            page: page,
 | 
			
		||||
            orderBy: orderBy,
 | 
			
		||||
            desc: Number(desc), // Преобразование boolean в Number (0 или 1)
 | 
			
		||||
            status: status,
 | 
			
		||||
            shipmentDate: shipmentDate
 | 
			
		||||
        };
 | 
			
		||||
        let response = await apiClient.get(`${router}/getOrders`, {params})
 | 
			
		||||
        return response.data;
 | 
			
		||||
    },
 | 
			
		||||
    getOrdersBySupplierProduct: async (supplierProductId: number): Promise<Order[]> => {
 | 
			
		||||
        let response = await apiClient.get(`${router}/getBySupplierProductId?supplierProductId=${supplierProductId}`);
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ const ReprintModal: FC = () => {
 | 
			
		||||
            dispatch(closeReprintModal());
 | 
			
		||||
            dispatch(openLoadingModal());
 | 
			
		||||
            PrintingApi.getLabel(order.databaseId).then(pdfBytes => {
 | 
			
		||||
 | 
			
		||||
                PrintingService.getInstance().printPdf(printerName, pdfBytes).then(r => {
 | 
			
		||||
                    dispatch(closeLoadingModal());
 | 
			
		||||
                    if (r) dispatch(closeReprintModal());
 | 
			
		||||
 
 | 
			
		||||
@@ -3,11 +3,22 @@ import {BottomSheetModal} from "@gorhom/bottom-sheet";
 | 
			
		||||
import {disableDim, enableDim} from "../../../features/interface/interfaceSlice";
 | 
			
		||||
import {StyleSheet, View} from "react-native";
 | 
			
		||||
import BasicButton from "../../BasicButton/BasicButton";
 | 
			
		||||
import {useDispatch} from "react-redux";
 | 
			
		||||
import {useDispatch, useSelector} from "react-redux";
 | 
			
		||||
import {RFPercentage} from "react-native-responsive-fontsize";
 | 
			
		||||
import RadioGroup from 'react-native-radio-buttons-group';
 | 
			
		||||
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
 | 
			
		||||
import {blue} from "../../../css/colors";
 | 
			
		||||
import {Picker} from "@react-native-picker/picker";
 | 
			
		||||
import DateTimePicker from '@react-native-community/datetimepicker';
 | 
			
		||||
import {RootState} from "../../../redux/store";
 | 
			
		||||
import {
 | 
			
		||||
    closeOrdersFilterModal,
 | 
			
		||||
    OrderStatus,
 | 
			
		||||
    orderStatuses,
 | 
			
		||||
    setDesc,
 | 
			
		||||
    setOrderBy, setShipmentDate, setStatus
 | 
			
		||||
} from "../../../features/ordersFilter/ordersFilterSlice";
 | 
			
		||||
import {retry} from "@reduxjs/toolkit/query";
 | 
			
		||||
 | 
			
		||||
export type SortingModalHandles = {
 | 
			
		||||
    present: () => void;
 | 
			
		||||
@@ -19,12 +30,7 @@ export type SortingModalElement = {
 | 
			
		||||
    label: string;
 | 
			
		||||
    value: string;
 | 
			
		||||
}
 | 
			
		||||
type Props = {
 | 
			
		||||
    onChange: (sortingValue: string) => void;
 | 
			
		||||
    onClose: () => void;
 | 
			
		||||
    elements: SortingModalElement[];
 | 
			
		||||
    defaultElementId?: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const createRadioButton = (element: SortingModalElement) => {
 | 
			
		||||
    return {
 | 
			
		||||
@@ -41,55 +47,101 @@ const createRadioButton = (element: SortingModalElement) => {
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const SortingModal = forwardRef<SortingModalHandles, Props>((props: Props, ref) => {
 | 
			
		||||
    const {elements, onChange, onClose, defaultElementId = ""} = props;
 | 
			
		||||
    const snapPoints = useMemo(() => ['40%', '40%'], []);
 | 
			
		||||
const SortingModal = () => {
 | 
			
		||||
    const state = useSelector((state: RootState) => state.ordersFilter);
 | 
			
		||||
    const elements = [
 | 
			
		||||
        {id: 'createdOnAsc', value: 'createdOnAsc', label: 'Дата создания по возрастанию'},
 | 
			
		||||
        {id: 'createdOnDesc', value: 'createdOnDesc', label: 'Дата создания по убыванию'},
 | 
			
		||||
        {id: 'shipmentDateAsc', value: 'shipmentDateAsc', label: 'Дата отгрузки по возрастанию'},
 | 
			
		||||
        {id: 'shipmentDateDesc', value: 'shipmentDateDesc', label: 'Дата отгрузки по убыванию'},
 | 
			
		||||
    ];
 | 
			
		||||
    const [showShipmentPicker, setShowShipmentPicker] = useState(false);
 | 
			
		||||
    const snapPoints = useMemo(() => ['60%', '60%'], []);
 | 
			
		||||
    const dispatch = useDispatch();
 | 
			
		||||
    const modalRef = useRef<BottomSheetModal>(null);
 | 
			
		||||
    const dismiss = () => {
 | 
			
		||||
        if (!modalRef.current) return;
 | 
			
		||||
        dispatch(disableDim());
 | 
			
		||||
        modalRef.current.dismiss();
 | 
			
		||||
        onClose();
 | 
			
		||||
    }
 | 
			
		||||
    const present = () => {
 | 
			
		||||
        if (!modalRef.current) return;
 | 
			
		||||
        modalRef.current.present();
 | 
			
		||||
        dispatch(enableDim());
 | 
			
		||||
    }
 | 
			
		||||
    useImperativeHandle(ref, () => ({
 | 
			
		||||
        present: present,
 | 
			
		||||
        dismiss: dismiss
 | 
			
		||||
    }));
 | 
			
		||||
    const [selectedId, setSelectedId] = useState<string>(defaultElementId);
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        onChange(selectedId);
 | 
			
		||||
    }, [selectedId]);
 | 
			
		||||
        if (state.isVisible) present();
 | 
			
		||||
        else dismiss();
 | 
			
		||||
    }, [state.isVisible]);
 | 
			
		||||
    return (
 | 
			
		||||
        <BottomSheetModal
 | 
			
		||||
            ref={modalRef}
 | 
			
		||||
            snapPoints={snapPoints}
 | 
			
		||||
            onDismiss={() => {
 | 
			
		||||
                dispatch(disableDim());
 | 
			
		||||
                dispatch(closeOrdersFilterModal())
 | 
			
		||||
            }}>
 | 
			
		||||
            <View style={styles.container}>
 | 
			
		||||
                <View style={styles.content}>
 | 
			
		||||
                    <RadioGroup selectedId={selectedId}
 | 
			
		||||
                                onPress={setSelectedId}
 | 
			
		||||
                    <RadioGroup selectedId={state.orderBy + (state.desc ? "Desc" : "Asc")}
 | 
			
		||||
                                onPress={(event) => {
 | 
			
		||||
                                    const orderRegex = /(Asc|Desc)$/;
 | 
			
		||||
                                    const orderMatch = event.match(orderRegex);
 | 
			
		||||
                                    if (!orderMatch) return;
 | 
			
		||||
                                    const isDesc = orderMatch[0] === 'Desc';
 | 
			
		||||
                                    const orderByField = event.replace(orderRegex, '');
 | 
			
		||||
                                    if (!["createdOn", "shipmentDate"].includes(orderByField)) return
 | 
			
		||||
                                    dispatch(setDesc(isDesc));
 | 
			
		||||
                                    dispatch(setOrderBy(orderByField as "createdOn" | "shipmentDate"));
 | 
			
		||||
 | 
			
		||||
                                }}
 | 
			
		||||
                                containerStyle={styles.radioButtons}
 | 
			
		||||
                                radioButtons={elements.map(createRadioButton)}/>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    <View style={{
 | 
			
		||||
                        borderWidth: responsiveWidth(0.1),
 | 
			
		||||
                        borderRadius: responsiveWidth(1)
 | 
			
		||||
                    }}>
 | 
			
		||||
 | 
			
		||||
                        <Picker selectedValue={state.status}
 | 
			
		||||
                                onValueChange={(value, event) => dispatch(setStatus(value))}>
 | 
			
		||||
                            {orderStatuses.map((status) => {
 | 
			
		||||
 | 
			
		||||
                                return (
 | 
			
		||||
                                    <Picker.Item
 | 
			
		||||
                                        key={status.key}
 | 
			
		||||
                                        label={status.label}
 | 
			
		||||
                                        value={status.key}
 | 
			
		||||
                                        style={{fontSize: responsiveWidth(3)}}
 | 
			
		||||
                                    />
 | 
			
		||||
                                )
 | 
			
		||||
                            })}
 | 
			
		||||
                        </Picker>
 | 
			
		||||
                    </View>
 | 
			
		||||
                    <BasicButton onPress={() => setShowShipmentPicker(oldValue => !oldValue)}
 | 
			
		||||
                                 label={"Выбрать дату отгрузки"}/>
 | 
			
		||||
                    {showShipmentPicker &&
 | 
			
		||||
                        <DateTimePicker value={new Date(state.shipmentDate)}
 | 
			
		||||
                                        onChange={(event) => {
 | 
			
		||||
                                            if (!event.nativeEvent.timestamp) return;
 | 
			
		||||
                                            setShowShipmentPicker(false);
 | 
			
		||||
                                            if (event.type === 'set') {
 | 
			
		||||
                                                const selectedDate = new Date(event.nativeEvent.timestamp);
 | 
			
		||||
                                                dispatch(setShipmentDate(selectedDate.toISOString()));
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }}/>}
 | 
			
		||||
                </View>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                <BasicButton label={"Закрыть"} style={styles.button} onPress={() => {
 | 
			
		||||
                    dismiss();
 | 
			
		||||
                    dispatch(closeOrdersFilterModal());
 | 
			
		||||
                }}/>
 | 
			
		||||
 | 
			
		||||
            </View>
 | 
			
		||||
        </BottomSheetModal>
 | 
			
		||||
    );
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
    )
 | 
			
		||||
};
 | 
			
		||||
const styles = StyleSheet.create({
 | 
			
		||||
    container: {
 | 
			
		||||
        width: "100%",
 | 
			
		||||
@@ -97,13 +149,17 @@ const styles = StyleSheet.create({
 | 
			
		||||
        flex: 1,
 | 
			
		||||
        padding: RFPercentage(3),
 | 
			
		||||
        flexDirection: "column",
 | 
			
		||||
        justifyContent: "space-between"
 | 
			
		||||
        justifyContent: "space-between",
 | 
			
		||||
        rowGap: responsiveHeight(1)
 | 
			
		||||
    },
 | 
			
		||||
    radioButtons: {
 | 
			
		||||
        alignItems: "flex-start"
 | 
			
		||||
    },
 | 
			
		||||
    content: {},
 | 
			
		||||
    content: {
 | 
			
		||||
        rowGap: responsiveHeight(1)
 | 
			
		||||
    },
 | 
			
		||||
    button: {
 | 
			
		||||
 | 
			
		||||
        marginTop: "auto"
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,10 +4,11 @@ import {RFPercentage} from "react-native-responsive-fontsize";
 | 
			
		||||
import DText from "../DText/DText";
 | 
			
		||||
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
 | 
			
		||||
import DTitle from "../DTitle/DTitle";
 | 
			
		||||
import {Order} from "../../types/order";
 | 
			
		||||
import {BaseMarketplace, Order} from "../../types/order";
 | 
			
		||||
import OrderProductsList from "./OrderProductsList";
 | 
			
		||||
import {useDispatch} from "react-redux";
 | 
			
		||||
import {setOrder} from "../../features/assembly/assemblySlice";
 | 
			
		||||
import {OrderStatus, OrderStatusDictionary} from "../../features/ordersFilter/ordersFilterSlice";
 | 
			
		||||
 | 
			
		||||
type Props = {
 | 
			
		||||
    onPress?: (event: GestureResponderEvent) => void
 | 
			
		||||
@@ -15,9 +16,17 @@ type Props = {
 | 
			
		||||
    onSelect: (order: Order) => void
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const BaseMarketplaceIconDict = {
 | 
			
		||||
    [BaseMarketplace.Wildberries]: require('assets/icons/marketplaces/wildberries.png'),
 | 
			
		||||
    [BaseMarketplace.Ozon]: require('assets/icons/marketplaces/ozon.png'),
 | 
			
		||||
    [BaseMarketplace.YandexMarket]: require('assets/icons/marketplaces/yandex_market.png'),
 | 
			
		||||
};
 | 
			
		||||
const OrderCard: FC<Props> = ({onPress, onSelect, order}) => {
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <TouchableOpacity onPress={()=>{
 | 
			
		||||
        <TouchableOpacity onPress={() => {
 | 
			
		||||
            if (onSelect) onSelect(order);
 | 
			
		||||
 | 
			
		||||
        }}>
 | 
			
		||||
@@ -26,7 +35,7 @@ const OrderCard: FC<Props> = ({onPress, onSelect, order}) => {
 | 
			
		||||
                    <View style={styles.title}>
 | 
			
		||||
 | 
			
		||||
                        <DTitle>{order.orderNumber}</DTitle>
 | 
			
		||||
                        <Image source={require('assets/icons/marketplaces/ozon.png')} style={styles.titleImage}/>
 | 
			
		||||
                        <Image source={BaseMarketplaceIconDict[order.baseMarketplace]} style={styles.titleImage}/>
 | 
			
		||||
                    </View>
 | 
			
		||||
                    <DText>Селлер: {order.sellerName}</DText>
 | 
			
		||||
                    <DText>Маркетплейс: {order.marketplaceName}</DText>
 | 
			
		||||
@@ -34,7 +43,7 @@ const OrderCard: FC<Props> = ({onPress, onSelect, order}) => {
 | 
			
		||||
                </View>
 | 
			
		||||
                <View style={styles.descriptionStatus}>
 | 
			
		||||
                    <DText>
 | 
			
		||||
                        Ожидает сборки
 | 
			
		||||
                        {OrderStatusDictionary[order.status as OrderStatus]}
 | 
			
		||||
                    </DText>
 | 
			
		||||
                </View>
 | 
			
		||||
            </View>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,16 +9,16 @@ import {background} from "../../css/colors";
 | 
			
		||||
 | 
			
		||||
type ListProps = {
 | 
			
		||||
    products: OrderProduct[];
 | 
			
		||||
    onSelected: (product: OrderProduct) => void;
 | 
			
		||||
    onSelected: (product: number) => void;
 | 
			
		||||
}
 | 
			
		||||
type CardProps = {
 | 
			
		||||
    product: OrderProduct;
 | 
			
		||||
    onPress: (product: OrderProduct) => void;
 | 
			
		||||
    onPress: (product: number) => void;
 | 
			
		||||
    id: number;
 | 
			
		||||
}
 | 
			
		||||
const OrderProductCard: FC<CardProps> = ({product, onPress, id}) => {
 | 
			
		||||
    return (
 | 
			
		||||
        <TouchableOpacity onPress={() => onPress(product)}>
 | 
			
		||||
        <TouchableOpacity onPress={() => onPress(id)}>
 | 
			
		||||
            <View style={cardStyles.container}>
 | 
			
		||||
                <View style={cardStyles.content}>
 | 
			
		||||
                    <DText>{id + 1}) {product.productName}</DText>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,16 +7,15 @@ import SelectProductModal from "../Modals/SelectProductModal/SelectProductModal"
 | 
			
		||||
import {SupplierProduct} from "../../types/supplierProduct";
 | 
			
		||||
import barcodeApi from "../../api/barcodeApi";
 | 
			
		||||
import {useDispatch, useSelector} from "react-redux";
 | 
			
		||||
import {openScanModal} from "../../features/scanModal/scanModalSlice";
 | 
			
		||||
import {openScanModal, setScannedData} from "../../features/scanModal/scanModalSlice";
 | 
			
		||||
import {RootState} from "../../redux/store";
 | 
			
		||||
 | 
			
		||||
type Props = {
 | 
			
		||||
    onSearch: (text: string) => void;
 | 
			
		||||
    onSearch?: (text: string) => void;
 | 
			
		||||
    onSupplierProductSelected?: (supplierProduct: SupplierProduct) => void
 | 
			
		||||
}
 | 
			
		||||
const SearchBar: FC<Props> = ({onSearch, onSupplierProductSelected}) => {
 | 
			
		||||
    // const [isScanModalVisible, setIsScanModalVisible] = useState<boolean>(false);
 | 
			
		||||
    // const [, setSelectProductModalVisible] = useState(false);
 | 
			
		||||
 | 
			
		||||
    const dispatch = useDispatch();
 | 
			
		||||
    const [searchInput, setSearchInput] = useState<string>("");
 | 
			
		||||
    const textInputRef = useRef<TextInput>(null);
 | 
			
		||||
@@ -26,19 +25,19 @@ const SearchBar: FC<Props> = ({onSearch, onSupplierProductSelected}) => {
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (!scannedData) return;
 | 
			
		||||
        barcodeApi.searchProducts(scannedData).then((response) => {
 | 
			
		||||
            console.log("Response: " + response);
 | 
			
		||||
            setProducts(response)
 | 
			
		||||
        });
 | 
			
		||||
    }, [scannedData]);
 | 
			
		||||
    const selectProductModalVisible = products.length > 0;
 | 
			
		||||
    return (
 | 
			
		||||
        <View style={styles.container}>
 | 
			
		||||
 | 
			
		||||
            <SelectProductModal visible={selectProductModalVisible} products={products} onSelected={(product) => {
 | 
			
		||||
                if (onSupplierProductSelected) onSupplierProductSelected(product);
 | 
			
		||||
                setProducts([]);
 | 
			
		||||
                dispatch(setScannedData(undefined));
 | 
			
		||||
            }}/>
 | 
			
		||||
            <BasicButton onPress={() => {
 | 
			
		||||
                if (!onSearch) return;
 | 
			
		||||
                onSearch(searchInput);
 | 
			
		||||
                if (textInputRef.current) {
 | 
			
		||||
                    textInputRef.current.clear();
 | 
			
		||||
@@ -77,7 +76,7 @@ const styles = StyleSheet.create({
 | 
			
		||||
        borderTopRightRadius: responsiveWidth(1),
 | 
			
		||||
        borderBottomRightRadius: responsiveWidth(1),
 | 
			
		||||
        paddingHorizontal: responsiveWidth(5),
 | 
			
		||||
        height:'100%'
 | 
			
		||||
        height: '100%'
 | 
			
		||||
    },
 | 
			
		||||
    scanImageWrapper: {
 | 
			
		||||
        paddingHorizontal: responsiveWidth(1),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,16 @@
 | 
			
		||||
import {createSlice, PayloadAction} from "@reduxjs/toolkit";
 | 
			
		||||
import {Order} from "../../types/order";
 | 
			
		||||
import {Order, OrderProduct} from "../../types/order";
 | 
			
		||||
import {Assembly, ASSEMBLY_STATE} from "../../types/assembly";
 | 
			
		||||
import selectProductElement from "../../components/Modals/SelectProductModal/SelectProductElement";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export interface AssemblyState {
 | 
			
		||||
    order?: Order;
 | 
			
		||||
    initialOrder?: Order;
 | 
			
		||||
    assembly?: Assembly;
 | 
			
		||||
    localState?: ASSEMBLY_STATE
 | 
			
		||||
    selectedProductId?: number;
 | 
			
		||||
    localState?: ASSEMBLY_STATE;
 | 
			
		||||
    selectedProduct?: OrderProduct
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const initialState: AssemblyState = {
 | 
			
		||||
@@ -18,7 +22,9 @@ export const assembly = createSlice({
 | 
			
		||||
    initialState,
 | 
			
		||||
    reducers: {
 | 
			
		||||
        setOrder: (state, action) => {
 | 
			
		||||
            state.initialOrder = action.payload;
 | 
			
		||||
            state.order = action.payload;
 | 
			
		||||
            state.selectedProductId = 0;
 | 
			
		||||
        },
 | 
			
		||||
        setAssembly: (state, action: PayloadAction<Assembly>) => {
 | 
			
		||||
            state.assembly = action.payload;
 | 
			
		||||
@@ -56,6 +62,7 @@ export const assembly = createSlice({
 | 
			
		||||
                    product.assembled = true;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            state.selectedProduct = state.order.products.find(product => product.databaseId == action.payload.orderProductId);
 | 
			
		||||
            // If all products is assembled
 | 
			
		||||
            if (!state.order.products.find(product => !product.assembled)) {
 | 
			
		||||
                state.assembly.state = ASSEMBLY_STATE.ALL_PRODUCTS_ASSEMBLED;
 | 
			
		||||
@@ -72,9 +79,23 @@ export const assembly = createSlice({
 | 
			
		||||
                    product.shipped = true;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            state.selectedProduct = state.order.products.find(product => product.databaseId == action.payload.orderProductId);
 | 
			
		||||
 | 
			
		||||
        },
 | 
			
		||||
        selectProduct: (state, action: PayloadAction<number>) => {
 | 
			
		||||
            if (!state.order) return;
 | 
			
		||||
            state.selectedProduct = state.order.products[action.payload];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export const {setOrder, setAssembled, setAssembly, startAssembly, endAssembly, confirmAssembly} = assembly.actions;
 | 
			
		||||
export const {
 | 
			
		||||
    setOrder,
 | 
			
		||||
    setAssembled,
 | 
			
		||||
    selectProduct,
 | 
			
		||||
    setAssembly,
 | 
			
		||||
    startAssembly,
 | 
			
		||||
    endAssembly,
 | 
			
		||||
    confirmAssembly
 | 
			
		||||
} = assembly.actions;
 | 
			
		||||
export default assembly.reducer;
 | 
			
		||||
							
								
								
									
										100
									
								
								src/features/ordersFilter/ordersFilterSlice.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/features/ordersFilter/ordersFilterSlice.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
import {createSlice, PayloadAction} from "@reduxjs/toolkit";
 | 
			
		||||
 | 
			
		||||
export enum OrderStatus {
 | 
			
		||||
    ALL = -1,
 | 
			
		||||
    AWAITING_PACKAGING,
 | 
			
		||||
    AWAITING_DELIVER,
 | 
			
		||||
    DELIVERING,
 | 
			
		||||
    DELIVERED,
 | 
			
		||||
    CANCELLED,
 | 
			
		||||
    PARTIALLY_RETURNED,
 | 
			
		||||
    FULLY_RETURNED,
 | 
			
		||||
    DISPUTED
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const orderStatuses = [
 | 
			
		||||
    {key: OrderStatus.ALL, label: 'Все'},
 | 
			
		||||
    {key: OrderStatus.AWAITING_PACKAGING, label: 'Ожидает сборки'},
 | 
			
		||||
    {key: OrderStatus.AWAITING_DELIVER, label: 'Ожидает отгрузки'},
 | 
			
		||||
    {key: OrderStatus.DELIVERING, label: 'Доставляется'},
 | 
			
		||||
    {key: OrderStatus.DELIVERED, label: 'Доставлен'},
 | 
			
		||||
    {key: OrderStatus.CANCELLED, label: 'Отменен'},
 | 
			
		||||
    {key: OrderStatus.PARTIALLY_RETURNED, label: 'Частичный возврат'},
 | 
			
		||||
    {key: OrderStatus.FULLY_RETURNED, label: 'Полный возврат'},
 | 
			
		||||
    {key: OrderStatus.DISPUTED, label: 'Спорный'},
 | 
			
		||||
];
 | 
			
		||||
export const OrderStatusDictionary: { [key in OrderStatus]: string } = {
 | 
			
		||||
    [OrderStatus.ALL]: 'Все',
 | 
			
		||||
    [OrderStatus.AWAITING_PACKAGING]: 'Ожидает сборки',
 | 
			
		||||
    [OrderStatus.AWAITING_DELIVER]: 'Ожидает отгрузки',
 | 
			
		||||
    [OrderStatus.DELIVERING]: 'Доставляется',
 | 
			
		||||
    [OrderStatus.DELIVERED]: 'Доставлен',
 | 
			
		||||
    [OrderStatus.CANCELLED]: 'Отменен',
 | 
			
		||||
    [OrderStatus.PARTIALLY_RETURNED]: 'Частичный возврат',
 | 
			
		||||
    [OrderStatus.FULLY_RETURNED]: 'Полный возврат',
 | 
			
		||||
    [OrderStatus.DISPUTED]: 'Спорный',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export interface OrdersFilterState {
 | 
			
		||||
    isVisible: boolean;
 | 
			
		||||
    orderBy: "createdOn" | "shipmentDate";
 | 
			
		||||
    desc: boolean;
 | 
			
		||||
    status: OrderStatus;
 | 
			
		||||
    shipmentDate: string;
 | 
			
		||||
    page: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const initialState: OrdersFilterState = {
 | 
			
		||||
    isVisible: false,
 | 
			
		||||
    orderBy: "createdOn",
 | 
			
		||||
    desc: true,
 | 
			
		||||
    shipmentDate: (new Date()).toISOString(),
 | 
			
		||||
    status: OrderStatus.AWAITING_PACKAGING,
 | 
			
		||||
    page: 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const ordersFilterSlice = createSlice({
 | 
			
		||||
    name: 'ordersFilter',
 | 
			
		||||
    initialState,
 | 
			
		||||
    reducers: {
 | 
			
		||||
        openOrdersFilterModal: (state) => {
 | 
			
		||||
            state.isVisible = true
 | 
			
		||||
        },
 | 
			
		||||
        closeOrdersFilterModal: (state) => {
 | 
			
		||||
            state.isVisible = false
 | 
			
		||||
        },
 | 
			
		||||
        setOrderBy: (state, action: PayloadAction<"createdOn" | "shipmentDate">) => {
 | 
			
		||||
            state.orderBy = action.payload;
 | 
			
		||||
        },
 | 
			
		||||
        setDesc: (state, action: PayloadAction<boolean>) => {
 | 
			
		||||
            state.desc = action.payload;
 | 
			
		||||
        },
 | 
			
		||||
        setStatus: (state, action: PayloadAction<OrderStatus>) => {
 | 
			
		||||
            state.status = action.payload;
 | 
			
		||||
        },
 | 
			
		||||
        setShipmentDate: (state, action: PayloadAction<string>) => {
 | 
			
		||||
            state.shipmentDate = action.payload;
 | 
			
		||||
        },
 | 
			
		||||
        setPage: (state, action: PayloadAction<number>) => {
 | 
			
		||||
            state.page = action.payload;
 | 
			
		||||
        },
 | 
			
		||||
        nextPage: (state) => {
 | 
			
		||||
            state.page = state.page + 1
 | 
			
		||||
        },
 | 
			
		||||
        refreshPagination: (state) => {
 | 
			
		||||
            state.page = 0
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export const {
 | 
			
		||||
    openOrdersFilterModal,
 | 
			
		||||
    closeOrdersFilterModal,
 | 
			
		||||
    refreshPagination,
 | 
			
		||||
    nextPage,
 | 
			
		||||
    setOrderBy,
 | 
			
		||||
    setDesc,
 | 
			
		||||
    setStatus,
 | 
			
		||||
    setShipmentDate
 | 
			
		||||
} = ordersFilterSlice.actions;
 | 
			
		||||
export default ordersFilterSlice.reducer;
 | 
			
		||||
@@ -8,6 +8,7 @@ import imageZoomModalReducer from 'features/imageZoomModal/loadingModalSlice';
 | 
			
		||||
import assemblyReducer from 'features/assembly/assemblySlice';
 | 
			
		||||
import printingReducer from 'features/printing/printingSlice';
 | 
			
		||||
import reprintModalReducer from 'features/reprintModal/reprintModalSlice';
 | 
			
		||||
import ordersFilterReducer from 'features/ordersFilter/ordersFilterSlice';
 | 
			
		||||
import {useDispatch} from "react-redux";
 | 
			
		||||
 | 
			
		||||
export const store = configureStore({
 | 
			
		||||
@@ -19,7 +20,8 @@ export const store = configureStore({
 | 
			
		||||
        assembly: assemblyReducer,
 | 
			
		||||
        printing: printingReducer,
 | 
			
		||||
        reprintModal: reprintModalReducer,
 | 
			
		||||
        imageZoomModal: imageZoomModalReducer
 | 
			
		||||
        imageZoomModal: imageZoomModalReducer,
 | 
			
		||||
        ordersFilter: ordersFilterReducer
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,68 @@
 | 
			
		||||
import {Button, Text, View} from "react-native";
 | 
			
		||||
import {Button, StyleSheet, Text, View} from "react-native";
 | 
			
		||||
import {useAppDispatch} from "../../redux/store";
 | 
			
		||||
import * as process from "process";
 | 
			
		||||
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
 | 
			
		||||
import SearchBar from "../../components/SearchBar/SearchBar";
 | 
			
		||||
import {useDispatch} from "react-redux";
 | 
			
		||||
import {NavigationProp, useNavigation} from "@react-navigation/native";
 | 
			
		||||
import {TabNavigatorParamList} from "../MainScreen/MainScreen";
 | 
			
		||||
import {FlashList} from "@shopify/flash-list";
 | 
			
		||||
import {Order} from "../../types/order";
 | 
			
		||||
import OrderCard from "../../components/OrderCard/OrderCard";
 | 
			
		||||
import {setOrder} from "../../features/assembly/assemblySlice";
 | 
			
		||||
import flashListSeparator from "../../components/FlashListSeparator/FlashListSeparator";
 | 
			
		||||
import {useEffect, useState} from "react";
 | 
			
		||||
import {openScanModal} from "../../features/scanModal/scanModalSlice";
 | 
			
		||||
import ordersApi from "../../api/ordersApi";
 | 
			
		||||
 | 
			
		||||
function BarcodeScreen() {
 | 
			
		||||
    const dispatch = useDispatch();
 | 
			
		||||
    const navigator = useNavigation<NavigationProp<TabNavigatorParamList, 'Home'>>();
 | 
			
		||||
    const [orders, setOrders] = useState<Order[]>([]);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        dispatch(openScanModal());
 | 
			
		||||
    }, []);
 | 
			
		||||
    return (
 | 
			
		||||
        <View>
 | 
			
		||||
            <Text style={{fontSize: 36}}>Barcode</Text>
 | 
			
		||||
        <View style={styles.container}>
 | 
			
		||||
            <SearchBar onSupplierProductSelected={product => {
 | 
			
		||||
                ordersApi.getOrdersBySupplierProduct(product.supplierProductId).then(setOrders)
 | 
			
		||||
            }}/>
 | 
			
		||||
            <View style={styles.content}>
 | 
			
		||||
                <FlashList
 | 
			
		||||
 | 
			
		||||
                    keyboardShouldPersistTaps={"never"}
 | 
			
		||||
                    data={orders}
 | 
			
		||||
                    keyExtractor={(item: Order) => item.orderNumber.toString()}
 | 
			
		||||
                    renderItem={({item}) =>
 | 
			
		||||
                        <OrderCard onSelect={(order) => {
 | 
			
		||||
                            dispatch(setOrder(order));
 | 
			
		||||
                            navigator.navigate("Home");
 | 
			
		||||
                        }} order={item}/>}
 | 
			
		||||
                    showsHorizontalScrollIndicator={false}
 | 
			
		||||
                    showsVerticalScrollIndicator={true}
 | 
			
		||||
                    onEndReachedThreshold={0.1}
 | 
			
		||||
                    estimatedItemSize={720}
 | 
			
		||||
                    ItemSeparatorComponent={flashListSeparator}
 | 
			
		||||
 | 
			
		||||
                />
 | 
			
		||||
            </View>
 | 
			
		||||
        </View>
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const styles = StyleSheet.create({
 | 
			
		||||
    container: {
 | 
			
		||||
        width: "100%",
 | 
			
		||||
        height: "100%",
 | 
			
		||||
        display: "flex",
 | 
			
		||||
        paddingHorizontal: responsiveWidth(5),
 | 
			
		||||
        rowGap: responsiveHeight(2),
 | 
			
		||||
        fontWeight: '500'
 | 
			
		||||
    },
 | 
			
		||||
    content: {
 | 
			
		||||
        flex: 1,
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
export default BarcodeScreen;
 | 
			
		||||
@@ -18,6 +18,7 @@ import assemblyApi from "../../api/assemblyApi";
 | 
			
		||||
import {assembly, setAssembly, setOrder} from "../../features/assembly/assemblySlice";
 | 
			
		||||
import ordersApi from "../../api/ordersApi";
 | 
			
		||||
import ImageZoomModal from "../../components/Modals/ImageZoomModal/ImageZoomModal";
 | 
			
		||||
import SortingModal from "../../components/Modals/SortingModal/SortingModal";
 | 
			
		||||
 | 
			
		||||
function CommonPage() {
 | 
			
		||||
    const dim = useSelector((state: RootState) => state.interface.dim);
 | 
			
		||||
@@ -62,6 +63,7 @@ function CommonPage() {
 | 
			
		||||
            <ScanModal/>
 | 
			
		||||
            <ReprintModal/>
 | 
			
		||||
            <ImageZoomModal/>
 | 
			
		||||
            <SortingModal/>
 | 
			
		||||
            <Toast config={toastConfig}/>
 | 
			
		||||
        </View>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ import printingApi from "../../api/printingApi";
 | 
			
		||||
import PrintingService from "../../utils/PrintingService";
 | 
			
		||||
import OrderProductsList from "../../components/OrderCard/OrderProductsList";
 | 
			
		||||
import {
 | 
			
		||||
    confirmAssembly, endAssembly,
 | 
			
		||||
    confirmAssembly, endAssembly, selectProduct,
 | 
			
		||||
    setAssembled,
 | 
			
		||||
    setAssembly,
 | 
			
		||||
    setOrder,
 | 
			
		||||
@@ -82,9 +82,9 @@ const OrderScreen: FC<OrderScreenProps> = ({order}) => {
 | 
			
		||||
    const dispatch = useDispatch();
 | 
			
		||||
    const assembly = useSelector((state: RootState) => state.assembly.assembly);
 | 
			
		||||
    const assemblyState = useSelector((state: RootState) => state.assembly.localState);
 | 
			
		||||
    const initialOrder = useSelector((state: RootState) => state.assembly.initialOrder);
 | 
			
		||||
 | 
			
		||||
    const [selectedProduct, setSelectedProduct] = useState(order.products[0]);
 | 
			
		||||
 | 
			
		||||
    const selectedProduct = useSelector((state: RootState) => state.assembly.selectedProduct);
 | 
			
		||||
    const [acceptModalVisible, setAcceptModalVisible] = useState(false);
 | 
			
		||||
    const [skipConfirmButtonVisible, setSkipConfirmButtonVisible] = useState(false);
 | 
			
		||||
    const _confirmAssembly = async () => {
 | 
			
		||||
@@ -113,11 +113,13 @@ const OrderScreen: FC<OrderScreenProps> = ({order}) => {
 | 
			
		||||
                                     onPress={() => setAcceptModalVisible(true)}
 | 
			
		||||
                                     label={"Начать сборку"}/>)
 | 
			
		||||
            case ASSEMBLY_STATE.ASSEMBLING_PRODUCTS:
 | 
			
		||||
 | 
			
		||||
                return (<BasicButton
 | 
			
		||||
                    containerStyle={styles.buttonContainer}
 | 
			
		||||
                    label={"Отметить как собранный"}
 | 
			
		||||
                    disabled={selectedProduct.assembled}
 | 
			
		||||
                    disabled={selectedProduct?.assembled}
 | 
			
		||||
                    onPress={() => {
 | 
			
		||||
                        if (!selectedProduct) return;
 | 
			
		||||
                        dispatch(setAssembled({orderProductId: selectedProduct.databaseId}))
 | 
			
		||||
                    }}
 | 
			
		||||
                />)
 | 
			
		||||
@@ -183,10 +185,10 @@ const OrderScreen: FC<OrderScreenProps> = ({order}) => {
 | 
			
		||||
        dispatch(setLoadingText('Идет печать этикетки...'))
 | 
			
		||||
        dispatch(openLoadingModal())
 | 
			
		||||
        printingApi.getLabel(order.databaseId).then(pdfData => {
 | 
			
		||||
            printingService.getInstance().printPdf('ozon', pdfData).then((response) => {
 | 
			
		||||
            printingService.getInstance().printPdf('wildberries', pdfData).then((response) => {
 | 
			
		||||
                dispatch(closeLoadingModal());
 | 
			
		||||
                if (response) return;
 | 
			
		||||
                dispatch(setPrinterName({printerName: 'ozon'}));
 | 
			
		||||
                dispatch(setPrinterName({printerName: 'wildberries'}));
 | 
			
		||||
                dispatch(openReprintModal());
 | 
			
		||||
            });
 | 
			
		||||
        })
 | 
			
		||||
@@ -204,23 +206,27 @@ const OrderScreen: FC<OrderScreenProps> = ({order}) => {
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }, [assemblyState]);
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (!order) return;
 | 
			
		||||
        dispatch(selectProduct(0));
 | 
			
		||||
    }, [initialOrder]);
 | 
			
		||||
    return (
 | 
			
		||||
        <View style={styles.container}>
 | 
			
		||||
            <View style={styles.productsContainer}>
 | 
			
		||||
                <View style={styles.orderProductsListWrapper}>
 | 
			
		||||
                    <OrderProductsList products={order.products} onSelected={(product) => {
 | 
			
		||||
                    <OrderProductsList products={order.products} onSelected={(productId) => {
 | 
			
		||||
                        if (!order) return;
 | 
			
		||||
                        setSelectedProduct(product)
 | 
			
		||||
                        dispatch(selectProduct(productId))
 | 
			
		||||
                    }}/>
 | 
			
		||||
                </View>
 | 
			
		||||
 | 
			
		||||
                <TouchableOpacity style={styles.imageWrapper} onPress={()=>{
 | 
			
		||||
                <TouchableOpacity style={styles.imageWrapper} onPress={() => {
 | 
			
		||||
                    if (!selectedProduct) return;
 | 
			
		||||
                    dispatch(setImages([selectedProduct.imageUrl]));
 | 
			
		||||
                    dispatch(openImageZoomModal());
 | 
			
		||||
                }}>
 | 
			
		||||
                    <View style={{flex: 1}}>
 | 
			
		||||
                        <Image style={styles.image} source={{uri: selectedProduct.imageUrl}}/>
 | 
			
		||||
                        <Image style={styles.image} source={{uri: selectedProduct?.imageUrl}}/>
 | 
			
		||||
                    </View>
 | 
			
		||||
                </TouchableOpacity>
 | 
			
		||||
 | 
			
		||||
@@ -233,11 +239,11 @@ const OrderScreen: FC<OrderScreenProps> = ({order}) => {
 | 
			
		||||
                    <DText>Селлер: {order.sellerName}</DText>
 | 
			
		||||
                    <DText>{}</DText>
 | 
			
		||||
                    <DTitle style={styles.contentTitle}>Товар</DTitle>
 | 
			
		||||
                    <DText>Артикул DENCO: {selectedProduct.dencoArticle}</DText>
 | 
			
		||||
                    <DText>Поставщик: {selectedProduct.supplierName}</DText>
 | 
			
		||||
                    <DText>Артикул DENCO: {selectedProduct?.dencoArticle}</DText>
 | 
			
		||||
                    <DText>Поставщик: {selectedProduct?.supplierName}</DText>
 | 
			
		||||
                    <DText>Номер товара: {0}</DText>
 | 
			
		||||
                    <DText>{}</DText>
 | 
			
		||||
                    <DTitle style={styles.contentTitle}>Сборка</DTitle>
 | 
			
		||||
                    {/*<DText>{}</DText>*/}
 | 
			
		||||
                    {/*<DTitle style={styles.contentTitle}>Сборка</DTitle>*/}
 | 
			
		||||
 | 
			
		||||
                </View>
 | 
			
		||||
                <View style={styles.buttonsContainer}>
 | 
			
		||||
@@ -249,7 +255,6 @@ const OrderScreen: FC<OrderScreenProps> = ({order}) => {
 | 
			
		||||
                         onAccepted={() => {
 | 
			
		||||
                             setAcceptModalVisible(false);
 | 
			
		||||
                             assemblyApi.create(order.databaseId).then(creationResult => {
 | 
			
		||||
                                 console.log(creationResult.message)
 | 
			
		||||
                                 Toast.show({
 | 
			
		||||
                                     type: creationResult.ok ? 'success' : 'error',
 | 
			
		||||
                                     text1: 'Создание сборки',
 | 
			
		||||
@@ -273,7 +278,6 @@ const OrderScreen: FC<OrderScreenProps> = ({order}) => {
 | 
			
		||||
export const OrderScreenController: FC = () => {
 | 
			
		||||
    const order: Order | undefined = useSelector((state: RootState) => state.assembly.order);
 | 
			
		||||
    if (!order) return <NoOrderScreen/>
 | 
			
		||||
    console.log(order)
 | 
			
		||||
    return <OrderScreen order={order}/>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								src/screens/OrderScreen/useOrders.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/screens/OrderScreen/useOrders.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
import {useEffect, useState} from "react";
 | 
			
		||||
import {Order} from "../../types/order";
 | 
			
		||||
import ordersApi from "../../api/ordersApi";
 | 
			
		||||
import {setOrder} from "../../features/assembly/assemblySlice";
 | 
			
		||||
import {RootState} from "../../redux/store";
 | 
			
		||||
import {useDispatch, useSelector} from "react-redux";
 | 
			
		||||
import {refreshPagination} from "../../features/ordersFilter/ordersFilterSlice";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const useOrders = () => {
 | 
			
		||||
    const dispatch = useDispatch();
 | 
			
		||||
    const [orders, setOrders] = useState<Order[]>([]);
 | 
			
		||||
    const [isRefreshing, setIsRefreshing] = useState(false);
 | 
			
		||||
    const filterState = useSelector((state: RootState) => state.ordersFilter);
 | 
			
		||||
    const refresh = () => {
 | 
			
		||||
        if (filterState.page == 0) return;
 | 
			
		||||
        setIsRefreshing(true);
 | 
			
		||||
        setOrders([]);
 | 
			
		||||
        dispatch(refreshPagination());
 | 
			
		||||
    }
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (filterState.isVisible) return;
 | 
			
		||||
 | 
			
		||||
        ordersApi.getOrders(filterState.page, filterState.orderBy, filterState.desc, filterState.shipmentDate, filterState.status).then(response => {
 | 
			
		||||
            setOrders(oldOrders => [...oldOrders, ...response]);
 | 
			
		||||
            setIsRefreshing(false);
 | 
			
		||||
        });
 | 
			
		||||
    }, [filterState.page]);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (filterState.isVisible) return;
 | 
			
		||||
        setOrders([]);
 | 
			
		||||
        setIsRefreshing(true);
 | 
			
		||||
        dispatch(refreshPagination());
 | 
			
		||||
    }, [filterState.orderBy, filterState.desc, filterState.status, filterState.shipmentDate, filterState.isVisible]);
 | 
			
		||||
 | 
			
		||||
    return {refresh, isRefreshing, orders};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default useOrders;
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
import {StyleSheet, View} from "react-native";
 | 
			
		||||
import SearchBar from "../../components/SearchBar/SearchBar";
 | 
			
		||||
import OrderCard from "../../components/OrderCard/OrderCard";
 | 
			
		||||
import {RFPercentage} from "react-native-responsive-fontsize";
 | 
			
		||||
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
 | 
			
		||||
@@ -9,66 +8,50 @@ import {useEffect, useRef, useState} from "react";
 | 
			
		||||
import {Order} from "../../types/order";
 | 
			
		||||
import {FlashList} from "@shopify/flash-list";
 | 
			
		||||
import SortingModal, {
 | 
			
		||||
    SortingModalElement,
 | 
			
		||||
    SortingModalHandles
 | 
			
		||||
} from "../../components/Modals/SortingModal/SortingModal";
 | 
			
		||||
import flashListSeparator from "../../components/FlashListSeparator/FlashListSeparator";
 | 
			
		||||
import ordersApi from "../../api/ordersApi";
 | 
			
		||||
import {setOrder} from "../../features/assembly/assemblySlice";
 | 
			
		||||
import {NavigationProp, useNavigation} from "@react-navigation/native";
 | 
			
		||||
import {TabNavigatorParamList} from "../MainScreen/MainScreen";
 | 
			
		||||
import useOrders from "../OrderScreen/useOrders";
 | 
			
		||||
import {nextPage, openOrdersFilterModal} from "../../features/ordersFilter/ordersFilterSlice";
 | 
			
		||||
 | 
			
		||||
function OrdersScreen() {
 | 
			
		||||
 | 
			
		||||
    const dispatch = useDispatch();
 | 
			
		||||
    const navigator = useNavigation<NavigationProp<TabNavigatorParamList, 'Home'>>();
 | 
			
		||||
    const {refresh, isRefreshing, orders} = useOrders();
 | 
			
		||||
 | 
			
		||||
    const [orders, setOrders] = useState<Order[]>([]);
 | 
			
		||||
    const sortingModalRef = useRef<SortingModalHandles | null>(null);
 | 
			
		||||
    const defaultSortingValue = 'createdOnAsc';
 | 
			
		||||
    const sortingModalElements: SortingModalElement[] = [
 | 
			
		||||
        {id: 'createdOnAsc', value: 'createdOnAsc', label: 'Дата создания по убыванию'},
 | 
			
		||||
        {id: 'createdOnDesc', value: 'createdOnDesc', label: 'Дата создания по возрастанию'},
 | 
			
		||||
        {id: 'shipmentDateAsc', value: 'shipmentDateAsc', label: 'Дата отгрузки по убыванию'},
 | 
			
		||||
        {id: 'shipmentDateDesc', value: 'shipmentDateDesc', label: 'Дата отгрузки по возрастанию'},
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    const [sortingValue, setSortingValue] = useState(defaultSortingValue);
 | 
			
		||||
    return (
 | 
			
		||||
        <View style={styles.container}>
 | 
			
		||||
            <SearchBar onSearch={() => {
 | 
			
		||||
            }} onSupplierProductSelected={product => {
 | 
			
		||||
                ordersApi.getOrdersBySupplierProduct(product.supplierProductId).then(setOrders)
 | 
			
		||||
            }}/>
 | 
			
		||||
 | 
			
		||||
            <View style={styles.sortingButtonWrapper}>
 | 
			
		||||
                <SortingButton onPress={() => {
 | 
			
		||||
                    if (!sortingModalRef.current) return;
 | 
			
		||||
                    sortingModalRef.current.present();
 | 
			
		||||
                    dispatch(openOrdersFilterModal());
 | 
			
		||||
                }}/>
 | 
			
		||||
            </View>
 | 
			
		||||
            <View style={styles.content}>
 | 
			
		||||
                <FlashList
 | 
			
		||||
                    keyboardShouldPersistTaps={"never"}
 | 
			
		||||
                    data={orders}
 | 
			
		||||
                    keyExtractor={(item: Order) => item.orderNumber.toString()}
 | 
			
		||||
                    renderItem={({item}) =>
 | 
			
		||||
                        <OrderCard onSelect={(order) => dispatch(setOrder(order))} order={item}/>}
 | 
			
		||||
                    showsHorizontalScrollIndicator={false}
 | 
			
		||||
                    showsVerticalScrollIndicator={true}
 | 
			
		||||
                    onEndReachedThreshold={0.1}
 | 
			
		||||
                    estimatedItemSize={720}
 | 
			
		||||
                    onEndReached={() => {
 | 
			
		||||
                    }}
 | 
			
		||||
                    ItemSeparatorComponent={flashListSeparator}
 | 
			
		||||
                <FlashList onRefresh={refresh}
 | 
			
		||||
                           refreshing={isRefreshing}
 | 
			
		||||
                           keyboardShouldPersistTaps={"never"}
 | 
			
		||||
                           data={orders}
 | 
			
		||||
                           keyExtractor={(item: Order) => item.databaseId.toString()}
 | 
			
		||||
                           renderItem={({item}) =>
 | 
			
		||||
                               <OrderCard onSelect={(order) => {
 | 
			
		||||
                                   dispatch(setOrder(order));
 | 
			
		||||
                                   navigator.navigate("Home");
 | 
			
		||||
                               }} order={item}/>}
 | 
			
		||||
                           showsHorizontalScrollIndicator={false}
 | 
			
		||||
                           showsVerticalScrollIndicator={true}
 | 
			
		||||
                           onEndReachedThreshold={0.5}
 | 
			
		||||
                           estimatedItemSize={720}
 | 
			
		||||
                           onEndReached={() => {
 | 
			
		||||
                               if (!orders.length) return;
 | 
			
		||||
                               dispatch(nextPage());
 | 
			
		||||
                           }}
 | 
			
		||||
                           ItemSeparatorComponent={flashListSeparator}
 | 
			
		||||
 | 
			
		||||
                />
 | 
			
		||||
                <SortingModal onChange={setSortingValue}
 | 
			
		||||
                              onClose={() => {
 | 
			
		||||
                              }}
 | 
			
		||||
                              ref={sortingModalRef}
 | 
			
		||||
                              elements={sortingModalElements}
 | 
			
		||||
                              defaultElementId={defaultSortingValue}
 | 
			
		||||
                />
 | 
			
		||||
            </View>
 | 
			
		||||
 | 
			
		||||
        </View>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								src/screens/OrdersScreen/useOrdersFilter.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/screens/OrdersScreen/useOrdersFilter.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
const useOrdersFilter = () => {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -10,10 +10,19 @@ export type OrderProduct = {
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export enum BaseMarketplace {
 | 
			
		||||
    Wildberries,
 | 
			
		||||
    Ozon,
 | 
			
		||||
    YandexMarket
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type Order = {
 | 
			
		||||
    databaseId: number;
 | 
			
		||||
    orderNumber: string;
 | 
			
		||||
    marketplaceName: string;
 | 
			
		||||
    baseMarketplace: BaseMarketplace;
 | 
			
		||||
    sellerName: string;
 | 
			
		||||
    products: OrderProduct[];
 | 
			
		||||
    status: number;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user