diff --git a/src/pages/shop/section/intro/Intro.tsx b/src/pages/shop/section/intro/Intro.tsx index 6d76660..497499d 100644 --- a/src/pages/shop/section/intro/Intro.tsx +++ b/src/pages/shop/section/intro/Intro.tsx @@ -4,21 +4,20 @@ import Rocket3D from "../../../../assets/ui/Rocket.png"; const Intro = () => { return ( -
-
+
+

بزرگترین فروشگاه - کاهش پینگ - {" "} - در ایران + کاهش پینگ در ایران +

سال ها تجربه پشت یک کانفیگ شماست

- +
-
+
intro { const [activeId, setActiveId] = useState(1); - const ProductsList = [ - { id: 1, title: "سرویس اشتراکی" }, - { id: 2, title: "سرویس گیمینگ" }, - { id: 3, title: "سرویس مولتی" }, - ]; + const axios = useAxios(); + const { data, error, isLoading, isFetching } = useQuery({ + queryKey: ["categories"], + queryFn: () => { + return axios.get("/home/categories"); + }, + }); return (
@@ -17,7 +21,10 @@ const ProductList = () => { شود diff --git a/src/pages/shop/section/productList/components/ButtonList.tsx b/src/pages/shop/section/productList/components/ButtonList.tsx index 73aa5e1..2915d6d 100644 --- a/src/pages/shop/section/productList/components/ButtonList.tsx +++ b/src/pages/shop/section/productList/components/ButtonList.tsx @@ -1,25 +1,53 @@ +import React from "react"; +import { Skeleton } from "@mui/material"; import Button from "../../../../../components/button"; import { ButtonListProps } from "../../../../../types/props"; +import Alert from "../../../../../components/alert/Alert"; -const ButtonList = ({ +const ButtonList: React.FC = ({ ProductsList, + isLoading, + isFetching, + error, activeId, setActiveId, -}: ButtonListProps) => { +}) => { + if (isLoading || isFetching) { + return ( +
+ {Array(3) + .fill(null) + .map((_, i) => ( + + ))} +
+ ); + } + + if (error) { + return ( +
+ {error.message} +
+ ); + } return ( -
- {ProductsList?.map((i) => { - return ( - - ); - })} +
+ {ProductsList?.map((product) => ( + + ))}
); }; diff --git a/src/pages/shop/section/productList/components/ListAllProduct.tsx b/src/pages/shop/section/productList/components/ListAllProduct.tsx index b8336c7..2bb78be 100644 --- a/src/pages/shop/section/productList/components/ListAllProduct.tsx +++ b/src/pages/shop/section/productList/components/ListAllProduct.tsx @@ -1,89 +1,87 @@ -import { Fragment, useEffect, useState } from "react"; -import ProductBox from "../../../../../components/productBox"; +import { useQuery } from "@tanstack/react-query"; +import useAxios from "../../../../../hooks/useAxios"; +import Alert from "../../../../../components/alert/Alert"; +import Button from "../../../../../components/button"; +import ModalBuy from "./ModalBuy"; +import { useState } from "react"; const ListAllProduct = ({ activeId }: { activeId: number }) => { - const Product = [ - { - id: 1, - data: [ - { id: 1, title: "مولتی سرور ۱", users: 2, price: "100/000", space: 40 }, - { id: 2, title: "مولتی سرور ۲", users: 2, price: "200/000", space: 60 }, - { - id: 3, - title: "مولتی سرور ۳", - users: 1, - price: "300/000", - space: 100, - }, - { id: 4, title: "مولتی سرور ۴", users: 3, price: "400/000", space: 50 }, - ], + const axios = useAxios(); + const [isOpen, setIsOpen] = useState(false); + const [configId, setConfigId] = useState(1); + const { data, error, isLoading, isFetching } = useQuery({ + queryKey: ["configs", activeId], + queryFn: () => { + return axios.get(`/home/config/${activeId}`); }, - { - id: 2, - data: [ - { - id: 1, - title: " کاهش پینگ ۱", - users: 2, - price: "1/000/000", - space: 40, - }, - { id: 2, title: "کاهش پینگ ۲", users: 2, price: "500/000", space: 60 }, - { - id: 3, - title: "کاهش پینگ ۳", - users: 1, - price: "800/000", - space: 100, - }, - { id: 4, title: "کاهش پینگ ۴", users: 3, price: "200/000", space: 50 }, - ], - }, - { - id: 3, - data: [ - { id: 1, title: " سرور بازی ۱", users: 2, price: "50/000", space: 40 }, - { id: 2, title: "سرور بازی ۲", users: 2, price: "100/000", space: 60 }, - { - id: 3, - title: "سرور بازی ۳", - users: 1, - price: "700/000", - space: 100, - }, - { id: 4, title: "سرور بازی ۴", users: 3, price: "350/000", space: 50 }, - ], - }, - ]; - const [dataProduct, setDataProduct] = useState( - Product?.filter((i) => i.id === activeId) - ); - useEffect(() => { - setDataProduct(Product?.filter((i) => i.id === activeId)); - }, [activeId]); - + }); + if (isLoading || isFetching) { + return ( +
+ + + + + +
+ ); + } + if (error) { + return ( +
+ + {error.message} + +
+ ); + } return ( -
- {dataProduct?.map((item) => { - return ( - - {item.data?.map((i) => { - return ( - - ); - })} - - ); - })} -
+ <> + +
+ {data?.data?.result?.map((item: Record) => { + return ( +
+ {item.title} +
+ +
+
+ ); + })} +
+ ); }; diff --git a/src/pages/shop/section/productList/components/ModalBuy.tsx b/src/pages/shop/section/productList/components/ModalBuy.tsx new file mode 100644 index 0000000..256531f --- /dev/null +++ b/src/pages/shop/section/productList/components/ModalBuy.tsx @@ -0,0 +1,288 @@ +import MuiModal from "../../../../../common/modal"; +import Button from "../../../../../components/button"; +import { BuyConfigDataProps, ModalBuyProps } from "../../../../../types/props"; +import { useMutation, useQuery } from "@tanstack/react-query"; +import * as Yup from "yup"; +import useAxios from "../../../../../hooks/useAxios"; +import toast from "react-hot-toast"; +import Alert from "../../../../../components/alert/Alert"; +import { useFormik } from "formik"; +import Input from "../../../../../components/input"; +import { BiMinus, BiPlus } from "react-icons/bi"; +import { queryClient } from "../../../../../main"; +import { AxiosError, AxiosResponse } from "axios"; +import { useCallback, useEffect, useState } from "react"; +import { debounce } from "@mui/material"; + +const ModalBuy = ({ isOpen, setIsOpen, configId }: ModalBuyProps) => { + const axios = useAxios(); + const separateByThree = (num: number): string => { + return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); + }; + const { data, error, isLoading, isFetching } = useQuery({ + queryKey: ["configSee", configId], + queryFn: () => { + return axios.get(`/home/config/${configId}/see`); + }, + }); + const [price, setPrice] = useState(0); + + const formik = useFormik({ + initialValues: { + count: 1, + discount: "", + status: "view", + }, + validationSchema: Yup.object({ + count: Yup.number().min(1, "حداقل یک کانفیگ باید باشد"), + discount: Yup.string(), + status: Yup.string(), + }), + onSubmit: (values) => { + console.log(values); + }, + }); + useEffect(() => { + if (!isOpen) { + formik.setFieldValue("count", 1); + formik.setFieldValue("discount", ""); + setPrice(0); + } + }, [isOpen]); + const mutation = useMutation({ + mutationKey: ["buyConfig"], + mutationFn: (values: BuyConfigDataProps) => { + return axios.post(`home/config/${configId}/buy`, values); + }, + onSuccess: (data) => { + queryClient.invalidateQueries({ + queryKey: ["configSee"], + }); + console.log(data); + }, + onError: (err) => { + queryClient.invalidateQueries({ + queryKey: ["configSee"], + }); + console.log(err); + }, + }); + const discountHandler = () => { + toast.promise(mutation.mutateAsync(formik.values), { + loading: "درحال بررسی...", + success: (res: AxiosResponse) => { + setPrice(res?.data?.result?.price); + return `${res.data.alert}`; + }, + error: (err: AxiosError) => { + formik.setFieldValue("discount", ""); + let errorMessage = "یک خطای غیرمنتظره رخ داد"; + if ( + err.response?.data && + typeof err.response.data === "object" && + "alert" in err.response.data + ) { + errorMessage = (err.response.data as { alert: string }).alert; + } + return errorMessage; + }, + }); + }; + const chnageCountDebouncedMutation = useCallback( + debounce((values) => { + toast.promise(mutation.mutateAsync(values), { + loading: "درحال بررسی...", + success: (res: AxiosResponse) => { + setPrice(res?.data?.result?.price); + return `${res.data.alert}`; + }, + error: (err: AxiosError) => { + let errorMessage = "یک خطای غیرمنتظره رخ داد"; + if ( + err.response?.data && + typeof err.response.data === "object" && + "alert" in err.response.data + ) { + errorMessage = (err.response.data as { alert: string }).alert; + } + return errorMessage; + }, + }); + }, 1000), + [] + ); + const chnageCountHandler = (status: "inc" | "dec") => { + if (status === "inc") { + formik.setFieldValue("count", formik.values.count + 1); + chnageCountDebouncedMutation({ + count: formik.values.count + 1, + status: formik.values.status, + }); + } else if (status === "dec") { + formik.setFieldValue("count", formik.values.count - 1); + chnageCountDebouncedMutation({ + count: formik.values.count - 1, + status: formik.values.status, + }); + } + }; + + const submitHandler = () => { + console.log(formik.values); + toast.promise(mutation.mutateAsync({ ...formik.values, status: "buy" }), { + loading: "درحال انتقال به درگاه پرداخت...", + success: (res: AxiosResponse) => { + window.location.href = res?.data?.result?.action; + return `${res.data.alert}`; + }, + error: (err: AxiosError) => { + formik.setFieldValue("discount", ""); + let errorMessage = "یک خطای غیرمنتظره رخ داد"; + if ( + err.response?.data && + typeof err.response.data === "object" && + "alert" in err.response.data + ) { + errorMessage = (err.response.data as { alert: string }).alert; + } + return errorMessage; + }, + }); + }; + + return ( + +
+ {error && ( + + {" "} + {error.message}{" "} + + )} + {isLoading || isFetching ? ( +
+ + + + + +
+ ) : ( +
+

+ مبلغ قابل پرداخت :{" "} + + {separateByThree( + price === 0 ? data?.data?.result?.price : price + )} + +

+

+ در صورت نداشتن کد تخفیف پرداخت رو بزنید +

+
+
+ + +
+
+ + + +
+
+
+
+

حجم

+

{`${data?.data?.result?.traffic} GB`}

+
+
+

محدودیت کاربر

+

{data?.data?.result?.limit}

+
+ {/*
+

مدت زمان

+

{data?.data?.result?.}

+
*/} +
+
+ )} +
+
+ ); +}; + +export default ModalBuy;