diff --git a/package.json b/package.json index 9689d9b..6084c26 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,8 @@ "react-feather": "^2.0.10", "react-i18next": "^13.3.1", "react-icons": "^4.11.0", + "react-input-range": "^1.3.0", + "react-number-format": "^5.3.4", "react-query": "^3.39.3", "react-redux": "^8.1.3", "react-router-dom": "^6.18.0", diff --git a/src/Components/ValidationField/Ui/SearchBar.tsx b/src/Components/ValidationField/Ui/SearchBar.tsx index 76c855c..f70b289 100644 --- a/src/Components/ValidationField/Ui/SearchBar.tsx +++ b/src/Components/ValidationField/Ui/SearchBar.tsx @@ -13,7 +13,7 @@ const SearchBar = () => { }; const updateUrlParams = (value:any) => { - navigate(`?search=${value}`, { replace: true }); + navigate(`?search=${value}`); }; diff --git a/src/Components/ValidationField/View/SearchField.tsx b/src/Components/ValidationField/View/SearchField.tsx index b03d775..4b34de5 100644 --- a/src/Components/ValidationField/View/SearchField.tsx +++ b/src/Components/ValidationField/View/SearchField.tsx @@ -23,11 +23,11 @@ const SearchField = ({ name, label, placeholder, isDisabled, searchBy, option, i }; const SearchHandleChange = (value:any) => { if (value || value !== "") { - navigate(`${window?.location?.pathname}?${searchBy}=${value}`, { replace: true }); + navigate(`${window?.location?.pathname}?${searchBy}=${value}`); } else { const params = new URLSearchParams(location.search); params.delete(searchBy ?? "search"); - navigate(`${window?.location.pathname}?${params.toString()}`, { replace: true }); + navigate(`${window?.location.pathname}?${params.toString()}`); } }; diff --git a/src/Hooks/usePagination.tsx b/src/Hooks/usePagination.tsx index 3654bb3..5008afe 100644 --- a/src/Hooks/usePagination.tsx +++ b/src/Hooks/usePagination.tsx @@ -11,11 +11,11 @@ export const PaginationBody = ({ data }: any) => { const [searchParams] = useSearchParams() const onChange = (page: number, pageSize?: number) => { - navigate(`?page=${page}&per_page=${pageSize || data?.per_page}`, { replace: true }); + navigate(`?page=${page}&per_page=${pageSize || data?.per_page}`); }; const onShowSizeChange = (current: number, pageSize: number) => { - navigate(`?page=${current}&per_page=${pageSize}`, { replace: true }); + navigate(`?page=${current}&per_page=${pageSize}`); }; const [t] = useTranslation() diff --git a/src/Layout/Dashboard/SearchField.tsx b/src/Layout/Dashboard/SearchField.tsx index 8137d71..02b03d2 100644 --- a/src/Layout/Dashboard/SearchField.tsx +++ b/src/Layout/Dashboard/SearchField.tsx @@ -16,11 +16,11 @@ const SearchField = ({ searchBy }: any) => { const onSearch: SearchProps['onSearch'] = (value, _e, info) => { if (value || value !== "") { - navigate(`${location?.pathname}?${searchBy ?? "search"}=${value}`, { replace: true }); + navigate(`${location?.pathname}?${searchBy ?? "search"}=${value}`); } else { const params = new URLSearchParams(location.search); params.delete(searchBy ?? "search"); - navigate(`${location.pathname}?${params.toString()}`, { replace: true }); + navigate(`${location.pathname}?${params.toString()}`); } } @@ -30,7 +30,7 @@ const SearchField = ({ searchBy }: any) => { if (value === "") { const params = new URLSearchParams(location.search); params.delete(searchBy ?? "search"); - navigate(`${location.pathname}?${params.toString()}`, { replace: true }); + navigate(`${location.pathname}?${params.toString()}`); } } diff --git a/src/Layout/Dashboard/SelectField.tsx b/src/Layout/Dashboard/SelectField.tsx index 0136367..a770134 100644 --- a/src/Layout/Dashboard/SelectField.tsx +++ b/src/Layout/Dashboard/SelectField.tsx @@ -18,7 +18,7 @@ const SelectField = ({ selectBy, lebel, option }: any) => { const handleSelectChange = (value: any) => { if (value) { console.log(`${location.pathname}?${selectBy}=${value}`); - navigate(`${location.pathname}?${selectBy}=${value}`, { replace: true }); + navigate(`${location.pathname}?${selectBy}=${value}`); } } diff --git a/src/Layout/Dashboard/SelectWSearchField.tsx b/src/Layout/Dashboard/SelectWSearchField.tsx index 702870d..bd28411 100644 --- a/src/Layout/Dashboard/SelectWSearchField.tsx +++ b/src/Layout/Dashboard/SelectWSearchField.tsx @@ -16,11 +16,11 @@ const SelectWSearchField = ({ selectBy, submiteBy, lebel, option }: any) => { const handleSearchChange = (value: any) => { if (value || value !== "") { - navigate(`${location.pathname}?${selectBy}=${value}`, { replace: true }); + navigate(`${location.pathname}?${selectBy}=${value}`); } else { const params = new URLSearchParams(location.search); params.delete(selectBy ?? "search"); - navigate(`${location.pathname}?${params.toString()}`, { replace: true }); + navigate(`${location.pathname}?${params.toString()}`); } }; @@ -28,7 +28,7 @@ const SelectWSearchField = ({ selectBy, submiteBy, lebel, option }: any) => { if (value) { console.log(`${location.pathname}?${submiteBy}=${value}`); - navigate(`${location.pathname}?${submiteBy}=${value}`, { replace: true }); + navigate(`${location.pathname}?${submiteBy}=${value}`); } } diff --git a/src/Layout/app/Header.tsx b/src/Layout/app/Header.tsx index 89afcba..aad55cb 100644 --- a/src/Layout/app/Header.tsx +++ b/src/Layout/app/Header.tsx @@ -29,7 +29,7 @@ const Header = () => { const { logout , user} = useAuthState() const handelClick = () => { logout() - navigate('/auth', { replace: true }) + navigate('/auth') } diff --git a/src/Layout/app/Layout.tsx b/src/Layout/app/Layout.tsx index 1a8a9ab..ca21133 100644 --- a/src/Layout/app/Layout.tsx +++ b/src/Layout/app/Layout.tsx @@ -12,7 +12,7 @@ const Layout = ({ children }: { children: React.ReactNode }) => { useEffect(() => { if (!isAuthenticated) { - navigate('/auth', { replace: true }) + navigate('/auth') } }, [navigate]) return ( diff --git a/src/Pages/Products/View/AddPage.tsx b/src/Pages/Products/View/AddPage.tsx index 60fd7da..57141d8 100644 --- a/src/Pages/Products/View/AddPage.tsx +++ b/src/Pages/Products/View/AddPage.tsx @@ -40,7 +40,7 @@ const AddProductPage = () => { ar: values?.name_ar, de: values?.name_de }, - category_id: 1 + category_id: values?.category_id } mutate(new_category) } diff --git a/src/Pages/Products/View/BasicInfo.tsx b/src/Pages/Products/View/BasicInfo.tsx index 57ef532..fc60f60 100644 --- a/src/Pages/Products/View/BasicInfo.tsx +++ b/src/Pages/Products/View/BasicInfo.tsx @@ -6,6 +6,7 @@ import { useFormikContext } from 'formik'; import { toast } from 'react-toastify'; import { useGetCategories } from '../../../api/Categories'; import useFormatToSelect from '../../../Hooks/useFormatToSelect'; +import { useParams } from 'react-router-dom'; const BasicInfo = ({ setIsValed, IsValed }: any) => { const [t] = useTranslation(); @@ -13,6 +14,7 @@ const BasicInfo = ({ setIsValed, IsValed }: any) => { const { values, isValid } = formikContext; const { data } = useGetCategories() const language = localStorage.getItem("language") ?? "en" + const {id}=useParams() const SelectData = data?.categories?.map((item:any)=>( { @@ -41,7 +43,10 @@ const BasicInfo = ({ setIsValed, IsValed }: any) => { {/* */} - + {!id && + + + } diff --git a/src/Pages/order/OrderPage.tsx b/src/Pages/order/OrderPage.tsx index f4b149e..3d8957d 100644 --- a/src/Pages/order/OrderPage.tsx +++ b/src/Pages/order/OrderPage.tsx @@ -5,12 +5,17 @@ import DashHeader from "../../Layout/Dashboard/DashHeader"; import { QueryStatusEnum } from "../../config/QueryStatus"; import LyTable from "../../Layout/Dashboard/LyTable"; import { useGetOrder } from "../../api/order"; -import SearchField from "../../Layout/Dashboard/SearchField"; -import SelectField from "../../Layout/Dashboard/SelectField"; +import SelectField from "./ui/CustomSelectField"; import { useGetCoupon } from "../../api/Coupon"; -import SelectWSearchField from "../../Layout/Dashboard/SelectWSearchField"; +import SelectWSearchField from "./ui/CustomSelectWSearchField"; // import SearchField from "../../Components/ValidationField/View/SearchField"; import CustomDateRange from "./ui/CustomDateRange"; +import { FaCheck, FaTimes, FaClock, FaBan } from 'react-icons/fa'; +import { Button } from "antd"; +import { useLocation, useNavigate } from "react-router-dom"; +import { useOrderFillterState } from "../../zustand/OrderFillter"; +import CustomSearchField from "./ui/CustomSearchField"; +import CustomNumber from "./ui/CustomNumber"; const OrderPage = () => { @@ -21,8 +26,12 @@ const OrderPage = () => { const columns = useTableColumns(); /// Coupon status Created from -> to Price from => to - const statusData = [{label:"active",value:"active"},{label:"inActive",value:"inActive"}] - + const stateSelect = [ + { label:
Pending Approve
, value: "pending_approve" }, + { label:
Approved
, value: "approved" }, + { label:
Rejected
, value: "rejected" }, + { label:
Pending Cancellation
, value: "pending_cancellation" } + ]; const { data:Coupon } = useGetCoupon() @@ -32,17 +41,66 @@ const OrderPage = () => { value : item?.id } )) + const location = useLocation(); + const navigate = useNavigate(); + const { username, coupon, state, fromDate, toDate, totalFrom, totalTo,reset } = useOrderFillterState(); + + const handleSubmit = () => { + let queryParams = []; + + if (username !== null) { + queryParams.push(`username=${username}`); + } + if (coupon !== null) { + queryParams.push(`coupon=${coupon}`); + } + if (state !== null) { + queryParams.push(`state=${state}`); + } + if (fromDate !== null) { + queryParams.push(`fromDate=${fromDate}`); + } + if (toDate !== null) { + queryParams.push(`toDate=${toDate}`); + } + if (totalFrom !== null) { + queryParams.push(`totalFrom=${totalFrom}`); + } + if (totalTo !== null) { + queryParams.push(`totalTo=${totalTo}`); + } + + const queryString = queryParams.join('&'); + const newPathname = `${location.pathname}${queryString ? '?' : ''}${queryString}`; + + navigate(newPathname); + }; + + + const handelReset=()=>{ + + navigate(`${location.pathname}`); + reset() + + + } + + return ( + <>
- + - + + + +
diff --git a/src/Pages/order/ui/CustomDateRange.tsx b/src/Pages/order/ui/CustomDateRange.tsx index 5cf0acb..4974989 100644 --- a/src/Pages/order/ui/CustomDateRange.tsx +++ b/src/Pages/order/ui/CustomDateRange.tsx @@ -1,16 +1,19 @@ import React from 'react' import { DatePicker } from 'antd' +import { useLocation, useNavigate } from 'react-router-dom'; +import { useOrderFillterState } from '../../../zustand/OrderFillter'; const { RangePicker } = DatePicker; const CustomDateRange = () => { const dateFormat = 'YYYY-MM-DD'; + const { toDate,fromDate,setFromDate,setToDate } = useOrderFillterState(); // Moved hook call inside the functional component const onCalendarChange = (value: any) => { const FromData = value[0]?.format(dateFormat) const ToData = value[1]?.format(dateFormat) - console.log(FromData,"FromData"); - console.log(ToData,"ToData"); + setFromDate(FromData) + setToDate(ToData) }; return ( diff --git a/src/Pages/order/ui/CustomNumber.tsx b/src/Pages/order/ui/CustomNumber.tsx new file mode 100644 index 0000000..f2d9846 --- /dev/null +++ b/src/Pages/order/ui/CustomNumber.tsx @@ -0,0 +1,30 @@ +import { InputNumber } from 'antd'; +import { useState, useEffect } from 'react'; +import { useOrderFillterState } from '../../../zustand/OrderFillter'; + +const CustomNumber = () => { + const [valueFrom, setValueFrom] = useState(null); + const [valueTo, setValueTo] = useState(null); + const { totalFrom, setTotalFrom, totalTo, setTotalTo } = useOrderFillterState(); + + // Set initial state based on totalFrom and totalTo + + const onChangeFrom = (value: number | null) => { + setValueFrom(value); + setTotalFrom(value); + }; + + const onChangeTo = (value: number | null) => { + setValueTo(value); + setTotalTo(value); + }; + + return ( +
+ + +
+ ); +}; + +export default CustomNumber; diff --git a/src/Pages/order/ui/CustomSearchField.tsx b/src/Pages/order/ui/CustomSearchField.tsx new file mode 100644 index 0000000..be9c27b --- /dev/null +++ b/src/Pages/order/ui/CustomSearchField.tsx @@ -0,0 +1,50 @@ +import { Input } from 'antd'; +import { SearchProps } from 'antd/es/input' +import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSearchParams } from 'react-router-dom'; +import { useOrderFillterState } from '../../../zustand/OrderFillter'; +const { Search } = Input; + +const CustomSearchField = ({ searchBy }: any) => { + const { t } = useTranslation(); + const {setUsername,username} = useOrderFillterState((state) => state) + + + const [searchParams,] = useSearchParams(); + const [searchValue, setSearchValue] = useState(searchParams.get(searchBy ) || ""); + + const onSearch: SearchProps['onSearch'] = (value, _e, info) => { + if (value || value !== "") { + setUsername(value) + } else { + setUsername(value) + } + } + + const onChange = (e: any) => { + const value = e.target.value + setSearchValue(value); + setUsername(value) + } + + + return ( +
+ + +
+ ) +} + +export default CustomSearchField \ No newline at end of file diff --git a/src/Pages/order/ui/CustomSelectField.tsx b/src/Pages/order/ui/CustomSelectField.tsx new file mode 100644 index 0000000..313933e --- /dev/null +++ b/src/Pages/order/ui/CustomSelectField.tsx @@ -0,0 +1,43 @@ +import { Select } from 'antd'; +import React, { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useLocation, useNavigate } from 'react-router-dom'; +import { useOrderFillterState } from '../../../zustand/OrderFillter'; + +const SelectField = ({ selectBy, lebel, option }: any) => { + const [searchQuery, setSearchQuery] = useState(''); + const location = useLocation(); + const navigate = useNavigate(); + const [t] = useTranslation(); + const {setstate,state} = useOrderFillterState((state) => state) + + + useEffect(() => { + const searchParams = new URLSearchParams(location.search); + setSearchQuery(searchParams.get( selectBy) || ''); + }, []); + + + const handleSelectChange = (value: any) => { + if (value) { + console.log(`${location.pathname}?${selectBy}=${value}`); + // navigate(`${location.pathname}?${selectBy}=${value}`); + setstate(value) + } + } + + return ( +
+ +
+ ); +}; + +export default React.memo(SelectWSearchField); diff --git a/src/Pages/order/useTableColumns.tsx b/src/Pages/order/useTableColumns.tsx index 8ad5d36..99680ed 100644 --- a/src/Pages/order/useTableColumns.tsx +++ b/src/Pages/order/useTableColumns.tsx @@ -36,7 +36,7 @@ const useTableColumns = () => { { name: t("status"), center: true, - width:"250", + width:"300", cell: (row: any) => { let status = row?.state; let icon; diff --git a/src/Styles/Layout/Layout.scss b/src/Styles/Layout/Layout.scss index 2393d7c..c7f30d2 100644 --- a/src/Styles/Layout/Layout.scss +++ b/src/Styles/Layout/Layout.scss @@ -588,7 +588,7 @@ padding: 10px 40px; gap: 5px; padding-inline: 10px; text-wrap: nowrap; - width: 250px; + width: 300px; align-items: center; justify-content: center; svg{ @@ -611,4 +611,24 @@ padding: 10px 40px; } .OrderDetails{ padding: 20px 4vw ; +} +.CustomNumber{ + display: flex; + gap: 20px; +} +.SliderDataRange{ + display: flex; + // flex-direction: column; + // justify-content: center; + // align-items: center; + // background: var(--bg); + // gap: 20px; + // width: 300px; + padding-inline: 20px; + h1{ + font-size: 18px; + text-wrap: nowrap; + white-space: nowrap; + } + } \ No newline at end of file diff --git a/src/zustand/OrderFillter.ts b/src/zustand/OrderFillter.ts new file mode 100644 index 0000000..6c6e6bf --- /dev/null +++ b/src/zustand/OrderFillter.ts @@ -0,0 +1,50 @@ +import { create } from 'zustand'; + +interface ModalState { + username: string | null; + coupon: string | null; + state: string | null; + fromDate: Date | null; + toDate: Date | null; + totalFrom: number | null; + totalTo: number | null; + setUsername: (value: string | null) => void; + setCoupon: (value: string | null) => void; + setstate: (value: string | null) => void; + setFromDate: (value: Date | null) => void; + setToDate: (value: Date | null) => void; + setTotalFrom: (value: number | null) => void; + setTotalTo: (value: number | null) => void; + reset: () => void; +} + +export const useOrderFillterState = create((set) => { + + return { + username: null, + coupon: null, + state: null, + fromDate: null, + toDate: null, + totalFrom: null, + totalTo: null, + setUsername: (value) => set((state) => ({ ...state, username: value })), + setCoupon: (value) => set((state) => ({ ...state, coupon: value })), + setstate: (value) => set((state) => ({ ...state, state: value })), + setFromDate: (value) => set((state) => ({ ...state, fromDate: value })), + setToDate: (value) => set((state) => ({ ...state, toDate: value })), + setTotalFrom: (value) => set((state) => ({ ...state, totalFrom: value })), + setTotalTo: (value) => set((state) => ({ ...state, totalTo: value })), + reset: () => { + set({ + username: null, + coupon: null, + fromDate: null, + toDate: null, + totalFrom: null, + totalTo: null, + state:null + }); + }, + }; +});