From 2d5d04987b8efe2cfa2377bb7b33b350257d38dd Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 12 Jun 2025 22:32:10 +0300 Subject: [PATCH] feat: implement filter state management and enhance order fetching in BarcodeScreen --- package.json | 4 +- src/App.tsx | 3 +- src/api/ordersApi.ts | 23 +- src/components/Hyperlink/Hyperlink.tsx | 1 - .../Modals/ImageZoomModal/ImageZoomModal.tsx | 1 - .../Modals/SortingModal/SortingButton.tsx | 19 ++ .../Modals/SortingModal/SortingButtons.tsx | 24 +++ .../Modals/SortingModal/SortingModal.tsx | 196 +++--------------- .../Modals/SortingModal/SortingModalBody.tsx | 43 ++++ .../ShippingWarehouseSelect.tsx | 67 +++--- .../SortingButton/SortingButton.tsx | 14 +- src/features/filterSlice/filterSlice.ts | 38 ++++ .../ordersFilter/ordersFilterSlice.ts | 1 - src/redux/store.ts | 4 +- src/screens/BarcodeScreen/BarcodeScreen.tsx | 11 +- .../BarcodeScreen/useBarcodeOrders.tsx | 39 ++-- src/screens/CommonPage/CommonPage.tsx | 2 +- src/screens/HomeScreen/HomeScreen.tsx | 1 - src/screens/MoneyScreen/MoneyScreen.tsx | 1 - src/screens/OrderScreen/useOrders.tsx | 31 ++- src/screens/OrdersScreen/OrdersScreen.tsx | 10 +- src/screens/ProfileScreen/ProfileScreen.tsx | 1 - src/utils/PrintingService.ts | 1 - 23 files changed, 245 insertions(+), 290 deletions(-) create mode 100644 src/components/Modals/SortingModal/SortingButton.tsx create mode 100644 src/components/Modals/SortingModal/SortingButtons.tsx create mode 100644 src/components/Modals/SortingModal/SortingModalBody.tsx create mode 100644 src/features/filterSlice/filterSlice.ts diff --git a/package.json b/package.json index 179b8c7..5f2a7ec 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/App.tsx b/src/App.tsx index 4a7287e..35666fc 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,10 +12,9 @@ export default function App() { - + - ); diff --git a/src/api/ordersApi.ts b/src/api/ordersApi.ts index 2953062..ee8a341 100644 --- a/src/api/ordersApi.ts +++ b/src/api/ordersApi.ts @@ -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 => { + getOrders: async ({page, orderBy, desc, status, shipmentDate, shipmentWarehouseId}: { + page: number, + orderBy: string, + desc: boolean, + shipmentDate: string, + status: number, + shipmentWarehouseId: number + }): Promise => { 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 => { let response = await apiClient.get(`${router}/getByProductId`, { params: { ...params, - shippingWarehouse: params.shippingWarehouse.id, - city: params.city.id + shippingWarehouse: params.shippingWarehouseId, } }); return response.data; diff --git a/src/components/Hyperlink/Hyperlink.tsx b/src/components/Hyperlink/Hyperlink.tsx index 02823b4..a2ce4df 100644 --- a/src/components/Hyperlink/Hyperlink.tsx +++ b/src/components/Hyperlink/Hyperlink.tsx @@ -12,7 +12,6 @@ const Hyperlink: React.FC = ({url, children}) => { if (supported) { Linking.openURL(url); } else { - console.log("Don't know how to open URI: " + url); } }); }; diff --git a/src/components/Modals/ImageZoomModal/ImageZoomModal.tsx b/src/components/Modals/ImageZoomModal/ImageZoomModal.tsx index 09f982d..2d01bcb 100644 --- a/src/components/Modals/ImageZoomModal/ImageZoomModal.tsx +++ b/src/components/Modals/ImageZoomModal/ImageZoomModal.tsx @@ -31,7 +31,6 @@ const ImageZoomModal: FC = () => { { - console.log(imageUrl) return { url: imageUrl } diff --git a/src/components/Modals/SortingModal/SortingButton.tsx b/src/components/Modals/SortingModal/SortingButton.tsx new file mode 100644 index 0000000..e8b0587 --- /dev/null +++ b/src/components/Modals/SortingModal/SortingButton.tsx @@ -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 = ({value, label}) => { + return ( + + {label} + + ) +} + +export default SortingButton; \ No newline at end of file diff --git a/src/components/Modals/SortingModal/SortingButtons.tsx b/src/components/Modals/SortingModal/SortingButtons.tsx new file mode 100644 index 0000000..dfc7796 --- /dev/null +++ b/src/components/Modals/SortingModal/SortingButtons.tsx @@ -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; + + +const SortingButtons: FC = ({value, onChange, disabled}) => { + return ( + + + + + + + + + + ) +} +export default SortingButtons; \ No newline at end of file diff --git a/src/components/Modals/SortingModal/SortingModal.tsx b/src/components/Modals/SortingModal/SortingModal.tsx index 0eb533e..6fad001 100644 --- a/src/components/Modals/SortingModal/SortingModal.tsx +++ b/src/components/Modals/SortingModal/SortingModal.tsx @@ -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(null); - const dismiss = () => { + const visible = useSelector((state: RootState) => state.filter.visible); + + useEffect(() => { if (!modalRef.current) return; - dispatch(disableDim()); - 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]); + if (visible) { + modalRef.current.present(); + } else { + modalRef.current.dismiss(); + } + }, [visible]); return ( dispatch(closeFilter())} ref={modalRef} - snapPoints={snapPoints} - onDismiss={() => { - dispatch(disableDim()); - dispatch(closeOrdersFilterModal()) - }}> - - - { - 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)}/> - - - - {/**/} - {/* dispatch(setStatus(value))}>*/} - {/* {orderStatuses.map((status) => {*/} - {/* return (*/} - {/* */} - {/* )*/} - {/* })}*/} - {/* */} - {/**/} - - - {/**/} - - - {/* setShowShipmentPicker(oldValue => !oldValue)}*/} - {/* label={"Выбрать дату отгрузки"}/>*/} - {/*{showShipmentPicker &&*/} - {/* {*/} - {/* if (!event.nativeEvent.timestamp) return;*/} - {/* setShowShipmentPicker(false);*/} - {/* if (event.type === 'set') {*/} - {/* const selectedDate = new Date(event.nativeEvent.timestamp);*/} - {/* dispatch(setShipmentDate(selectedDate.toISOString()));*/} - {/* }*/} - {/* }}/>}*/} + - - { - dispatch(closeOrdersFilterModal()); - }}/> - - + ) }; -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; diff --git a/src/components/Modals/SortingModal/SortingModalBody.tsx b/src/components/Modals/SortingModal/SortingModalBody.tsx new file mode 100644 index 0000000..ddd9956 --- /dev/null +++ b/src/components/Modals/SortingModal/SortingModalBody.tsx @@ -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({ + defaultValues: currentState, + }) + const onSubmit = (data: FilterState) => { + dispatch(setFilterState(data)); + dispatch(closeFilter()) + } + return ( + + + ()} + /> + ( + )}/> +