feat: implement filter state management and enhance order fetching in BarcodeScreen
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/webpack-config": "^19.0.1",
|
||||
"@gorhom/bottom-sheet": "^4.6.4",
|
||||
"@gorhom/bottom-sheet": "^5.1.6",
|
||||
"@react-native-community/datetimepicker": "8.3.0",
|
||||
"@react-native-picker/picker": "2.11.0",
|
||||
"@react-navigation/bottom-tabs": "^6.6.1",
|
||||
@@ -43,6 +43,7 @@
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react-hook-form": "^7.57.0",
|
||||
"react-native": "0.79.2",
|
||||
"react-native-animatable": "^1.4.0",
|
||||
"react-native-gesture-handler": "~2.24.0",
|
||||
@@ -50,6 +51,7 @@
|
||||
"react-native-image-zoom-viewer": "^3.0.1",
|
||||
"react-native-modal": "^13.0.1",
|
||||
"react-native-paper": "^5.12.5",
|
||||
"react-native-picker-select": "^9.3.1",
|
||||
"react-native-progress": "^5.0.1",
|
||||
"react-native-radio-buttons-group": "^3.1.0",
|
||||
"react-native-reanimated": "~3.17.4",
|
||||
|
||||
@@ -15,7 +15,6 @@ export default function App() {
|
||||
<CommonPage/>
|
||||
</BottomSheetModalProvider>
|
||||
</GestureHandlerRootView>
|
||||
|
||||
</Provider>
|
||||
|
||||
);
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import apiClient from "./apiClient";
|
||||
import {Order} from "../types/order";
|
||||
import * as inspector from "inspector";
|
||||
import {OrderStatus} from "../features/ordersFilter/ordersFilterSlice";
|
||||
import {ShippingWarehouse} from "../types/shippingWarehouse";
|
||||
import {City} from "../types/city";
|
||||
|
||||
const router = '/orders';
|
||||
|
||||
const ordersApi = {
|
||||
getOrders: async (page: number, orderBy: string, desc: boolean, shipmentDate: string, status: number, shipmentWarehouseId: number): Promise<Order[]> => {
|
||||
getOrders: async ({page, orderBy, desc, status, shipmentDate, shipmentWarehouseId}: {
|
||||
page: number,
|
||||
orderBy: string,
|
||||
desc: boolean,
|
||||
shipmentDate: string,
|
||||
status: number,
|
||||
shipmentWarehouseId: number
|
||||
}): Promise<Order[]> => {
|
||||
const params = {
|
||||
page: page,
|
||||
orderBy: orderBy,
|
||||
@@ -22,18 +25,14 @@ const ordersApi = {
|
||||
},
|
||||
getOrdersByProduct: async (params: {
|
||||
productId: number,
|
||||
orderBy: "createdOn" | "shipmentDate",
|
||||
orderBy: string,
|
||||
desc: boolean,
|
||||
status: OrderStatus,
|
||||
shipmentDate: string,
|
||||
shippingWarehouse: ShippingWarehouse,
|
||||
city: City
|
||||
shippingWarehouseId: number,
|
||||
}): Promise<Order[]> => {
|
||||
let response = await apiClient.get(`${router}/getByProductId`, {
|
||||
params: {
|
||||
...params,
|
||||
shippingWarehouse: params.shippingWarehouse.id,
|
||||
city: params.city.id
|
||||
shippingWarehouse: params.shippingWarehouseId,
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
|
||||
@@ -12,7 +12,6 @@ const Hyperlink: React.FC<HyperlinkProps> = ({url, children}) => {
|
||||
if (supported) {
|
||||
Linking.openURL(url);
|
||||
} else {
|
||||
console.log("Don't know how to open URI: " + url);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -31,7 +31,6 @@ const ImageZoomModal: FC = () => {
|
||||
</View>
|
||||
<ImageViewer
|
||||
imageUrls={imageUrls.map(imageUrl => {
|
||||
console.log(imageUrl)
|
||||
return {
|
||||
url: imageUrl
|
||||
}
|
||||
|
||||
19
src/components/Modals/SortingModal/SortingButton.tsx
Normal file
19
src/components/Modals/SortingModal/SortingButton.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import {View} from "react-native";
|
||||
import {RadioButton} from "react-native-paper";
|
||||
import DText from "../../DText/DText";
|
||||
import {FC} from "react";
|
||||
|
||||
type Props = {
|
||||
value: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
const SortingButton: FC<Props> = ({value, label}) => {
|
||||
return (<View style={{display: "flex", flexDirection: "row", alignItems: "center"}}>
|
||||
<RadioButton value={value}/>
|
||||
<DText>{label}</DText>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export default SortingButton;
|
||||
24
src/components/Modals/SortingModal/SortingButtons.tsx
Normal file
24
src/components/Modals/SortingModal/SortingButtons.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import {ControllerRenderProps} from 'react-hook-form';
|
||||
import {FilterState} from "../../../features/filterSlice/filterSlice";
|
||||
import {FC} from "react";
|
||||
import {RadioButton} from "react-native-paper";
|
||||
import SortingButton from "./SortingButton";
|
||||
import {View} from 'react-native';
|
||||
|
||||
type Props = ControllerRenderProps<FilterState, "sorting">;
|
||||
|
||||
|
||||
const SortingButtons: FC<Props> = ({value, onChange, disabled}) => {
|
||||
return (
|
||||
<RadioButton.Group value={value} onValueChange={onChange}>
|
||||
<View style={{display: "flex", flexDirection: "column"}}>
|
||||
<SortingButton value={"shipment_date_desc"} label={"Дата отгрузки по возрастанию"}/>
|
||||
<SortingButton value={"shipment_date_asc"} label={"Дата отгрузки по убыванию"}/>
|
||||
<SortingButton value={"created_date_desc"} label={"Дата создание по возрастанию"}/>
|
||||
<SortingButton value={"created_date_asc"} label={"Дата создания по убыванию"}/>
|
||||
</View>
|
||||
|
||||
</RadioButton.Group>
|
||||
)
|
||||
}
|
||||
export default SortingButtons;
|
||||
@@ -1,185 +1,37 @@
|
||||
import {FC, forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState} from "react";
|
||||
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, 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,
|
||||
orderStatuses, setCity,
|
||||
setDesc,
|
||||
setOrderBy, setShipmentDate, setShippingWarehouse, setStatus
|
||||
} from "../../../features/ordersFilter/ordersFilterSlice";
|
||||
import ShippingWarehouseSelect from "../../ShippingWarehouseSelect/ShippingWarehouseSelect";
|
||||
import CitySelect from "../../CitySelect/CitySelect";
|
||||
import {useEffect, useRef} from "react";
|
||||
import {BottomSheetModal, BottomSheetView} from "@gorhom/bottom-sheet";
|
||||
import {useSelector} from "react-redux";
|
||||
import {RootState, useAppDispatch} from "../../../redux/store";
|
||||
import {closeFilter} from "../../../features/filterSlice/filterSlice";
|
||||
import SortingModalBody from "./SortingModalBody";
|
||||
import {View} from "react-native";
|
||||
|
||||
export type SortingModalHandles = {
|
||||
present: () => void;
|
||||
dismiss: () => void;
|
||||
}
|
||||
|
||||
export type SortingModalElement = {
|
||||
id: string;
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
|
||||
const createRadioButton = (element: SortingModalElement) => {
|
||||
return {
|
||||
id: element.id,
|
||||
label: element.label,
|
||||
value: element.value,
|
||||
size: RFPercentage(5),
|
||||
color: blue,
|
||||
labelStyle: {
|
||||
fontSize: responsiveWidth(3),
|
||||
fontWeight: "500" as const
|
||||
},
|
||||
borderSize: RFPercentage(0.5)
|
||||
};
|
||||
}
|
||||
|
||||
const SortingModal = () => {
|
||||
const state = useSelector((state: RootState) => state.ordersFilter);
|
||||
const shipmentWarehouseSelectorState = useSelector((state: RootState) => state.shippingWarehouseSelect);
|
||||
const citySelectorState = useSelector((state: RootState) => state.citySelect);
|
||||
|
||||
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();
|
||||
export const SortingModal = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const modalRef = useRef<BottomSheetModal>(null);
|
||||
const dismiss = () => {
|
||||
const visible = useSelector((state: RootState) => state.filter.visible);
|
||||
|
||||
useEffect(() => {
|
||||
if (!modalRef.current) return;
|
||||
dispatch(disableDim());
|
||||
if (visible) {
|
||||
modalRef.current.present();
|
||||
} else {
|
||||
modalRef.current.dismiss();
|
||||
}
|
||||
const present = () => {
|
||||
if (!modalRef.current) return;
|
||||
modalRef.current.present();
|
||||
dispatch(enableDim());
|
||||
}
|
||||
useEffect(() => {
|
||||
if (state.isVisible) present();
|
||||
else dismiss();
|
||||
}, [state.isVisible]);
|
||||
useEffect(() => {
|
||||
dispatch(setShippingWarehouse(shipmentWarehouseSelectorState.selectedShippingWarehouse));
|
||||
}, [shipmentWarehouseSelectorState.selectedShippingWarehouse]);
|
||||
useEffect(() => {
|
||||
dispatch(setCity(citySelectorState.selectedCity));
|
||||
}, [citySelectorState.selectedCity]);
|
||||
}, [visible]);
|
||||
return (
|
||||
<BottomSheetModal
|
||||
onDismiss={() => dispatch(closeFilter())}
|
||||
ref={modalRef}
|
||||
snapPoints={snapPoints}
|
||||
onDismiss={() => {
|
||||
dispatch(disableDim());
|
||||
dispatch(closeOrdersFilterModal())
|
||||
}}>
|
||||
<View style={styles.container}>
|
||||
<View style={styles.content}>
|
||||
<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"));
|
||||
>
|
||||
<BottomSheetView>
|
||||
<View>
|
||||
|
||||
}}
|
||||
containerStyle={styles.radioButtons}
|
||||
radioButtons={elements.map(createRadioButton)}/>
|
||||
|
||||
|
||||
<View style={styles.selectors}>
|
||||
{/*<View style={styles.selector}>*/}
|
||||
{/* <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>*/}
|
||||
|
||||
<ShippingWarehouseSelect/>
|
||||
{/*<CitySelect/>*/}
|
||||
<SortingModalBody/>
|
||||
</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={() => {
|
||||
dispatch(closeOrdersFilterModal());
|
||||
}}/>
|
||||
|
||||
</View>
|
||||
</BottomSheetView>
|
||||
</BottomSheetModal>
|
||||
)
|
||||
};
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
flex: 1,
|
||||
padding: RFPercentage(3),
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-between",
|
||||
rowGap: responsiveHeight(1)
|
||||
},
|
||||
radioButtons: {
|
||||
alignItems: "flex-start"
|
||||
},
|
||||
content: {
|
||||
rowGap: responsiveHeight(1)
|
||||
},
|
||||
button: {
|
||||
|
||||
marginTop: "auto"
|
||||
},
|
||||
selectors: {
|
||||
rowGap: responsiveHeight(1)
|
||||
},
|
||||
selector: {
|
||||
borderWidth: responsiveWidth(0.1),
|
||||
borderRadius: responsiveWidth(1)
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export default SortingModal;
|
||||
|
||||
43
src/components/Modals/SortingModal/SortingModalBody.tsx
Normal file
43
src/components/Modals/SortingModal/SortingModalBody.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import {closeFilter, FilterState, setFilterState} from "../../../features/filterSlice/filterSlice";
|
||||
import {Controller, useForm} from "react-hook-form";
|
||||
import {Button, View} from "react-native";
|
||||
import ShippingWarehouseSelect from "../../ShippingWarehouseSelect/ShippingWarehouseSelect";
|
||||
import {RFPercentage} from "react-native-responsive-fontsize";
|
||||
import SortingButtons from "./SortingButtons";
|
||||
import {useSelector} from "react-redux";
|
||||
import {RootState, useAppDispatch} from "../../../redux/store";
|
||||
|
||||
const SortingModalBody = () => {
|
||||
const currentState = useSelector((state: RootState) => state.filter.state);
|
||||
const dispatch = useAppDispatch();
|
||||
const {control, handleSubmit} = useForm<FilterState>({
|
||||
defaultValues: currentState,
|
||||
})
|
||||
const onSubmit = (data: FilterState) => {
|
||||
dispatch(setFilterState(data));
|
||||
dispatch(closeFilter())
|
||||
}
|
||||
return (
|
||||
<View style={{
|
||||
padding: RFPercentage(1),
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: RFPercentage(1),
|
||||
}}>
|
||||
|
||||
<Controller
|
||||
name={"sorting"}
|
||||
control={control}
|
||||
render={({field}) => (<SortingButtons {...field}/>)}
|
||||
/>
|
||||
<Controller control={control} name={"shippingWarehouseId"}
|
||||
render={({field}) => (
|
||||
<ShippingWarehouseSelect
|
||||
controllerProps={field}/>)}/>
|
||||
<Button title={"Применить"} onPress={handleSubmit(onSubmit)}/>
|
||||
</View>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
export default SortingModalBody;
|
||||
@@ -1,43 +1,40 @@
|
||||
import {FC, useEffect} from "react";
|
||||
import {useDispatch, useSelector} from "react-redux";
|
||||
import {RootState} from "../../redux/store";
|
||||
import {Picker} from "@react-native-picker/picker";
|
||||
import {FC, useEffect, useState} from "react";
|
||||
import RNPickerSelect, {PickerSelectProps} from 'react-native-picker-select';
|
||||
import {ControllerRenderProps} from "react-hook-form";
|
||||
import {FilterState} from "../../features/filterSlice/filterSlice";
|
||||
import {ShippingWarehouse} from "../../types/shippingWarehouse";
|
||||
import generalApi from "../../api/generalApi";
|
||||
import {
|
||||
initializeShippingWarehouseSelect,
|
||||
selectShippingWarehouse
|
||||
} from "../../features/shippingWarehouseSelect/shippingWarehouseSelectSlice";
|
||||
import {responsiveWidth} from "react-native-responsive-dimensions";
|
||||
import {View} from "react-native";
|
||||
|
||||
const ShippingWarehouseSelect: FC = () => {
|
||||
const state = useSelector((state: RootState) => state.shippingWarehouseSelect);
|
||||
const dispatch = useDispatch();
|
||||
type Props = {
|
||||
selectProps?: Omit<PickerSelectProps, "items" | "onValueChange">;
|
||||
controllerProps?: ControllerRenderProps<FilterState, "shippingWarehouseId">
|
||||
}
|
||||
const ShippingWarehouseSelect: FC<Props> = (props) => {
|
||||
const [items, setItems] = useState<ShippingWarehouse[]>([]);
|
||||
useEffect(() => {
|
||||
if (state.initialized) return;
|
||||
generalApi.getShippingWarehouses().then(shippingWarehouses =>
|
||||
dispatch(initializeShippingWarehouseSelect(shippingWarehouses)))
|
||||
generalApi.getShippingWarehouses().then(response => {
|
||||
setItems(response);
|
||||
})
|
||||
}, []);
|
||||
return (
|
||||
<View style={{
|
||||
borderWidth: responsiveWidth(0.1),
|
||||
borderRadius: responsiveWidth(1)
|
||||
}}>
|
||||
<Picker
|
||||
selectedValue={state.selectedShippingWarehouse?.id}
|
||||
onValueChange={(value, event) => dispatch(selectShippingWarehouse({shippingWarehouseId: value}))}
|
||||
>
|
||||
{state.shippingWarehouses.map(shippingWarehouse => (
|
||||
<Picker.Item
|
||||
key={shippingWarehouse.id}
|
||||
label={shippingWarehouse.name}
|
||||
value={shippingWarehouse.id}
|
||||
style={{fontSize: responsiveWidth(3)}}
|
||||
/>
|
||||
))}
|
||||
</Picker>
|
||||
</View>
|
||||
|
||||
<RNPickerSelect
|
||||
useNativeAndroidPickerStyle={true}
|
||||
style={{
|
||||
viewContainer: {
|
||||
borderWidth: 1,
|
||||
borderColor: "#9EA0A4",
|
||||
borderRadius: "1%"
|
||||
}
|
||||
}}
|
||||
placeholder={{label: "Все склады", value: -1, color: "#9EA0A4"}}
|
||||
{...props.selectProps}
|
||||
onValueChange={(value, _) => {
|
||||
if (typeof value !== 'number') return;
|
||||
props.controllerProps?.onChange(value);
|
||||
}}
|
||||
value={props.controllerProps?.value}
|
||||
itemKey={"value"}
|
||||
items={items.map(sw => ({label: sw.name, value: sw.id, color:"black"}))}/>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import {FC} from "react";
|
||||
import {StyleSheet, View, Image, TouchableOpacity, GestureResponderEvent} from "react-native";
|
||||
import {GestureResponderEvent, Image, StyleSheet, TouchableOpacity, View} from "react-native";
|
||||
import DText from "../DText/DText";
|
||||
import {RFPercentage} from "react-native-responsive-fontsize";
|
||||
import {responsiveWidth} from "react-native-responsive-dimensions";
|
||||
import {useAppDispatch} from "../../redux/store";
|
||||
import {openFilter} from "../../features/filterSlice/filterSlice";
|
||||
|
||||
type Props = {
|
||||
onPress?: (event: GestureResponderEvent) => void
|
||||
|
||||
};
|
||||
const SortingButton: FC<Props> = ({onPress}) => {
|
||||
const SortingButton: FC = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const onPress = (event: GestureResponderEvent) => {
|
||||
dispatch(openFilter())
|
||||
}
|
||||
return (
|
||||
<TouchableOpacity onPress={onPress}>
|
||||
<View style={styles.container}>
|
||||
|
||||
38
src/features/filterSlice/filterSlice.ts
Normal file
38
src/features/filterSlice/filterSlice.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import {createSlice} from "@reduxjs/toolkit";
|
||||
|
||||
export type FilterState = {
|
||||
sorting: string;
|
||||
shippingWarehouseId: number;
|
||||
}
|
||||
|
||||
export interface FilterSliceState {
|
||||
visible: boolean;
|
||||
state: FilterState
|
||||
}
|
||||
|
||||
const initialState: FilterSliceState = {
|
||||
visible: true,
|
||||
state: {
|
||||
sorting: 'shipment_date_desc',
|
||||
shippingWarehouseId: -1,
|
||||
}
|
||||
}
|
||||
|
||||
export const filterSlice = createSlice({
|
||||
name: 'filter',
|
||||
initialState,
|
||||
reducers: {
|
||||
openFilter: (state) => {
|
||||
state.visible = true;
|
||||
},
|
||||
closeFilter: (state) => {
|
||||
state.visible = false;
|
||||
},
|
||||
setFilterState: (state, action) => {
|
||||
state.state = action.payload;
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const {openFilter, closeFilter, setFilterState} = filterSlice.actions;
|
||||
export default filterSlice.reducer;
|
||||
@@ -89,7 +89,6 @@ export const ordersFilterSlice = createSlice({
|
||||
state.city = action.payload;
|
||||
},
|
||||
setPage: (state, action: PayloadAction<number>) => {
|
||||
console.log(action)
|
||||
state.page = action.payload;
|
||||
},
|
||||
nextPage: (state) => {
|
||||
|
||||
@@ -14,6 +14,7 @@ import citySelectReducer from 'features/citySelect/citySelectSlice';
|
||||
import cancelAssemblyModal from 'features/cancelAssemblyModal/cancelAssemblyModalSlice';
|
||||
import balanceReducer from 'features/balance/balanceSlice';
|
||||
import animationsReducer from 'features/animations/animationsSlice';
|
||||
import filterReducer from 'features/filterSlice/filterSlice';
|
||||
import {useDispatch} from "react-redux";
|
||||
|
||||
export const store = configureStore({
|
||||
@@ -31,7 +32,8 @@ export const store = configureStore({
|
||||
citySelect: citySelectReducer,
|
||||
cancelAssemblyModal: cancelAssemblyModal,
|
||||
balance: balanceReducer,
|
||||
animations: animationsReducer
|
||||
animations: animationsReducer,
|
||||
filter:filterReducer
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@ import {openScanModal} from "../../features/scanModal/scanModalSlice";
|
||||
import DTitle from "../../components/DTitle/DTitle";
|
||||
import SortingButton from "../../components/SortingButton/SortingButton";
|
||||
import useBarcodeOrders from "./useBarcodeOrders";
|
||||
import {openOrdersFilterModal} from "../../features/ordersFilter/ordersFilterSlice";
|
||||
|
||||
function BarcodeScreen() {
|
||||
const dispatch = useDispatch();
|
||||
const filterState = useSelector((state: RootState) => state.filter.state);
|
||||
const [productId, setProductId] = useState(-1);
|
||||
const {orders, isUpdating,refresh} = useBarcodeOrders({productId});
|
||||
const {orders, isUpdating, refresh} = useBarcodeOrders({productId, filterState});
|
||||
|
||||
const isScanModalVisible = useSelector((state: RootState) => state.scanModal.isVisible);
|
||||
const navigator = useNavigation<NavigationProp<TabNavigatorParamList, 'Home'>>();
|
||||
@@ -29,7 +29,6 @@ function BarcodeScreen() {
|
||||
useEffect(() => {
|
||||
if (!navigationState.history) return;
|
||||
if (productId < 0) return;
|
||||
console.log('refreshing orders for productId:', productId);
|
||||
refresh();
|
||||
// @ts-ignore
|
||||
let currentTabKey: string = navigationState.history[navigationState.history.length - 1].key;
|
||||
@@ -40,9 +39,7 @@ function BarcodeScreen() {
|
||||
<SearchBar onProductSelected={product => {
|
||||
setProductId(product.productId);
|
||||
}}/>
|
||||
<SortingButton onPress={() => {
|
||||
dispatch(openOrdersFilterModal());
|
||||
}}
|
||||
<SortingButton
|
||||
/>
|
||||
<View style={styles.content}>
|
||||
{orders.length > 0 || isUpdating ? <FlashList
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
import {useSelector} from "react-redux";
|
||||
import {RootState} from "../../redux/store";
|
||||
import {useEffect, useState} from "react";
|
||||
import {Order} from "../../types/order";
|
||||
import ordersApi from "../../api/ordersApi";
|
||||
import {FilterState} from "../../features/filterSlice/filterSlice";
|
||||
|
||||
export type Props = {
|
||||
productId: number;
|
||||
filterState: FilterState;
|
||||
}
|
||||
const useBarcodeOrders = (props: Props) => {
|
||||
export const parseOrderBy = (orderBy: string): { orderBy: string, desc: boolean } => {
|
||||
const ascDesc = orderBy.split('_').at(-1);
|
||||
const field = orderBy.split('_').slice(0, -1).join('_');
|
||||
if (ascDesc === 'asc') return {orderBy: field, desc: false};
|
||||
if (ascDesc === 'desc') return {orderBy: field, desc: true};
|
||||
return {orderBy: field, desc: false};
|
||||
}
|
||||
const useBarcodeOrders = ({filterState, productId}: Props) => {
|
||||
const [orders, setOrders] = useState<Order[]>([]);
|
||||
const [isUpdating, setIsUpdating] = useState(false);
|
||||
const {productId} = props;
|
||||
const {
|
||||
orderBy,
|
||||
isVisible,
|
||||
desc,
|
||||
shipmentDate,
|
||||
status,
|
||||
shippingWarehouse,
|
||||
city
|
||||
} = useSelector((state: RootState) => state.ordersFilter);
|
||||
|
||||
const fetchOrders = async (): Promise<Order[]> => {
|
||||
return ordersApi.getOrdersByProduct({productId, orderBy, shipmentDate, status, shippingWarehouse, city, desc});
|
||||
return ordersApi.getOrdersByProduct({
|
||||
...parseOrderBy(filterState.sorting),
|
||||
productId: productId,
|
||||
shippingWarehouseId: filterState.shippingWarehouseId,
|
||||
});
|
||||
}
|
||||
const refresh = () => {
|
||||
setOrders([]);
|
||||
@@ -32,16 +34,11 @@ const useBarcodeOrders = (props: Props) => {
|
||||
});
|
||||
}
|
||||
useEffect(() => {
|
||||
if (isVisible || productId < 0) return;
|
||||
if (productId < 0) return;
|
||||
refresh()
|
||||
}, [
|
||||
productId,
|
||||
isVisible,
|
||||
desc,
|
||||
orderBy,
|
||||
shipmentDate,
|
||||
status,
|
||||
shippingWarehouse,
|
||||
filterState
|
||||
]);
|
||||
|
||||
return {
|
||||
|
||||
@@ -16,7 +16,7 @@ import assemblyApi from "../../api/assemblyApi";
|
||||
import {setAssembly, setLocalState, setOrder} from "../../features/assembly/assemblySlice";
|
||||
import ordersApi from "../../api/ordersApi";
|
||||
import ImageZoomModal from "../../components/Modals/ImageZoomModal/ImageZoomModal";
|
||||
import SortingModal from "../../components/Modals/SortingModal/SortingModal";
|
||||
import {SortingModal} from "../../components/Modals/SortingModal/SortingModal";
|
||||
import {ASSEMBLY_STATE} from "../../types/assembly";
|
||||
import * as FileSystem from 'expo-file-system';
|
||||
import applicationApi from "../../api/applicationApi";
|
||||
|
||||
@@ -11,7 +11,6 @@ function HomeScreen() {
|
||||
return (
|
||||
<View style={{backgroundColor: "white"}}>
|
||||
<SearchBar onSearch={(text) => {
|
||||
console.log(`From scanner: ${text}`)
|
||||
}}/>
|
||||
<DText>Хуй</DText>
|
||||
</View>
|
||||
|
||||
@@ -50,7 +50,6 @@ function MoneyScreen() {
|
||||
const onPress = () => {
|
||||
printingApi.getLabel(391845).then(async result => {
|
||||
PrintingService.getInstance().printPdf("", result).then(() => {
|
||||
console.log("Printed successfully");
|
||||
}
|
||||
).catch(error => {
|
||||
console.error("Error printing:", error);
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
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,
|
||||
setOrderBy,
|
||||
setPage,
|
||||
setShippingWarehouse
|
||||
} from "../../features/ordersFilter/ordersFilterSlice";
|
||||
import {setPage} from "../../features/ordersFilter/ordersFilterSlice";
|
||||
import {parseOrderBy} from "../BarcodeScreen/useBarcodeOrders";
|
||||
|
||||
|
||||
const useOrders = () => {
|
||||
@@ -18,15 +13,16 @@ const useOrders = () => {
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
const filterState = useSelector((state: RootState) => state.ordersFilter);
|
||||
const filter2state = useSelector((state: RootState) => state.filter.state);
|
||||
const fetchOrders = async (): Promise<Order[]> => {
|
||||
return ordersApi.getOrders(
|
||||
filterState.page,
|
||||
filterState.orderBy,
|
||||
filterState.desc,
|
||||
filterState.shipmentDate,
|
||||
filterState.status,
|
||||
filterState.shippingWarehouse.id
|
||||
);
|
||||
return ordersApi.getOrders({
|
||||
...parseOrderBy(filter2state.sorting),
|
||||
page: filterState.page,
|
||||
shipmentDate: "",
|
||||
shipmentWarehouseId: filter2state.shippingWarehouseId,
|
||||
status: -1
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
const appendOrders = (newOrders: Order[]) => {
|
||||
@@ -51,11 +47,12 @@ const useOrders = () => {
|
||||
filterState.status,
|
||||
filterState.shipmentDate,
|
||||
filterState.isVisible,
|
||||
filterState.shippingWarehouse
|
||||
filterState.shippingWarehouse,
|
||||
filter2state
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchOrders().then(newOrders=>{
|
||||
fetchOrders().then(newOrders => {
|
||||
setOrders(newOrders);
|
||||
setIsInitialized(true);
|
||||
|
||||
|
||||
@@ -4,18 +4,14 @@ import {RFPercentage} from "react-native-responsive-fontsize";
|
||||
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
||||
import SortingButton from "../../components/SortingButton/SortingButton";
|
||||
import {useDispatch} from "react-redux";
|
||||
import {useEffect, useRef, useState} from "react";
|
||||
import {Order} from "../../types/order";
|
||||
import {FlashList} from "@shopify/flash-list";
|
||||
import SortingModal, {
|
||||
SortingModalHandles
|
||||
} from "../../components/Modals/SortingModal/SortingModal";
|
||||
import flashListSeparator from "../../components/FlashListSeparator/FlashListSeparator";
|
||||
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";
|
||||
import {nextPage} from "../../features/ordersFilter/ordersFilterSlice";
|
||||
import DTitle from "../../components/DTitle/DTitle";
|
||||
|
||||
function OrdersScreen() {
|
||||
@@ -27,9 +23,7 @@ function OrdersScreen() {
|
||||
<View style={styles.container}>
|
||||
|
||||
<View style={styles.sortingButtonWrapper}>
|
||||
<SortingButton onPress={() => {
|
||||
dispatch(openOrdersFilterModal());
|
||||
}}/>
|
||||
<SortingButton/>
|
||||
</View>
|
||||
<View style={styles.content}>
|
||||
<FlashList onRefresh={refresh}
|
||||
|
||||
@@ -57,7 +57,6 @@ function ProfileScreen() {
|
||||
useEffect(() => {
|
||||
if (printerIpDebounce.length > 0) {
|
||||
SecureStore.setItemAsync("printerIp", printerIpDebounce).then(() => {
|
||||
console.log("Printer IP saved to secure store");
|
||||
}).catch((error) => {
|
||||
console.error("Error saving printer IP to secure store:", error);
|
||||
});
|
||||
|
||||
@@ -44,7 +44,6 @@ class PrintingService {
|
||||
await this.printLabelAsync(bytes);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user