584 lines
17 KiB
JavaScript
584 lines
17 KiB
JavaScript
"use client";
|
|
import AppContext from "@ctx/AppContext";
|
|
import Chapar from "plugins/Chapar";
|
|
import Loading from "plugins/Loading/page";
|
|
import BottomSheetAddress from "plugins/bottomSheet/BottomSheetAddress";
|
|
import BottomSheetLogOut from "plugins/bottomSheet/BottomSheetLogOut";
|
|
import { useEffect, useState } from "react";
|
|
// import "react-image-gallery/styles/css/image-gallery.css";
|
|
import "react-image-lightbox/style.css";
|
|
import "react-spring-bottom-sheet/dist/style.css";
|
|
import { ToastContainer, toast } from "react-toastify";
|
|
import "react-toastify/dist/ReactToastify.css";
|
|
import "swiper/css";
|
|
import "../../../style/fontiran.css";
|
|
import "../../../style/globals.css";
|
|
import { useRouter } from "next/navigation";
|
|
import NextTopLoader from "nextjs-toploader";
|
|
import SideBarNavBarMobile from "@comp/Navbar/SideBarNavBarMobile/page";
|
|
import Goftino from "plugins/Goftino/page";
|
|
import Yektanet from "plugins/Yektanet/page";
|
|
|
|
const RootData = ({ children }) => {
|
|
const [cart, setCart] = useState([]);
|
|
const [products, setProducts] = useState([]);
|
|
const [pager, setPager] = useState([]);
|
|
const [filter, setFilter] = useState([]);
|
|
const [navData, setNavData] = useState([]);
|
|
const [brands, setBrands] = useState([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [closeNavbar, setCloseNavbar] = useState(false);
|
|
const [bottomSheetCartOpen, setBottomSheetCartOpen] = useState(false);
|
|
const [bottomSheetFilterOpen, setBottomSheetFilterOpen] = useState(false);
|
|
const [bottomSheetDiscountOpen, setBottomSheetDiscountOpen] = useState(false);
|
|
const [bottomSheetAddressOpen, setBottomSheetAddressOpen] = useState(false);
|
|
const [bottomSheetLogOutOpen, setBottomSheetLogOutOpen] = useState(false);
|
|
const [bottomSheetSeeOrderOpen, setBottomSheetSeeOrderOpen] = useState(false);
|
|
const [bottomSheetDeleteAddressOpen, setBottomSheetDeleteAddressOpen] =
|
|
useState(false);
|
|
const [checkOutData, setCheckOutData] = useState([]);
|
|
const [addressData, setAddressData] = useState([]);
|
|
const [orderUser, setOrderUser] = useState([]);
|
|
const [profile, setProfile] = useState([]);
|
|
const [stopProducts, setStopProducts] = useState(false);
|
|
const [pageGetProducts, setPageGetProducts] = useState(0);
|
|
const [isMobile, setIsMobile] = useState(false);
|
|
const [isOpenLightBox, setIsOpenLightBox] = useState(false);
|
|
const [
|
|
cooperationSystemProfileContractData,
|
|
setCooperationSystemProfileContractData,
|
|
] = useState("");
|
|
const [cooperationSystemProfileData, setCooperationSystemProfileData] =
|
|
useState([]);
|
|
const [searchResultData, setSearchResultData] = useState([]);
|
|
const [isSearched, setIsSearched] = useState(false);
|
|
|
|
const [isChecked, setIsChecked] = useState(false);
|
|
const [selectedBrands, setSelectedBrands] = useState([]);
|
|
const [rangePrice, setRangePrice] = useState([1000, 100]);
|
|
const [isRangePrice, setIsRangePrice] = useState(false);
|
|
const [sortBy, setSortBy] = useState(-1);
|
|
|
|
const router = useRouter();
|
|
|
|
const AddItemToCart = (
|
|
id,
|
|
persianName,
|
|
cost,
|
|
costWithDiscount,
|
|
mainImage,
|
|
hasDiscount,
|
|
maxOrderCount
|
|
) => {
|
|
setCart((prevCart) => {
|
|
// Check if the item is already in the cart
|
|
const existingItem = prevCart.find((item) => item.id === id);
|
|
let updatedCart;
|
|
if (existingItem) {
|
|
// If the item is already in the cart, update its count
|
|
if (existingItem.count < maxOrderCount || maxOrderCount == 0) {
|
|
updatedCart = prevCart.map((item) =>
|
|
item.id === id ? { ...item, count: item.count + 1 } : item
|
|
);
|
|
} else {
|
|
// Notify user if maxOrderCount is exceeded
|
|
toast.error(
|
|
`
|
|
نمیتوانید بیشتراز
|
|
${" "}
|
|
${maxOrderCount}
|
|
${" "}
|
|
عدد ثبت کنید `,
|
|
{
|
|
position: "bottom-right",
|
|
closeOnClick: true,
|
|
}
|
|
);
|
|
updatedCart = prevCart;
|
|
}
|
|
} else {
|
|
// If the item is not in the cart, add it with a count of 1
|
|
updatedCart = [
|
|
...prevCart,
|
|
{
|
|
id,
|
|
count: 1,
|
|
persianName,
|
|
cost,
|
|
costWithDiscount,
|
|
mainImage,
|
|
hasDiscount,
|
|
maxOrderCount,
|
|
},
|
|
];
|
|
}
|
|
// Store the updated cart in local storage
|
|
localStorage.setItem("cart", JSON.stringify(updatedCart));
|
|
|
|
// Return the updated cart
|
|
return updatedCart;
|
|
});
|
|
};
|
|
|
|
const RemoveItemFromCart = (id) => {
|
|
setCart((prevCart) => {
|
|
// Check if the item is already in the cart
|
|
const existingItem = prevCart.find((item) => item.id === id);
|
|
|
|
if (existingItem) {
|
|
// If the item is already in the cart
|
|
if (existingItem.count === 1) {
|
|
// If the item count is 1, remove it from the cart
|
|
const updatedCart = prevCart.filter((item) => item.id !== id);
|
|
|
|
// Store the updated cart in local storage
|
|
localStorage.setItem("cart", JSON.stringify(updatedCart));
|
|
|
|
// Return the updated cart
|
|
return updatedCart;
|
|
} else {
|
|
// If the item count is greater than 1, update its count
|
|
const updatedCart = prevCart.map((item) =>
|
|
item.id === id ? { ...item, count: item.count - 1 } : item
|
|
);
|
|
|
|
// Store the updated cart in local storage
|
|
localStorage.setItem("cart", JSON.stringify(updatedCart));
|
|
|
|
// Return the updated cart
|
|
return updatedCart;
|
|
}
|
|
} else {
|
|
// If the item is not in the cart, do nothing
|
|
return prevCart;
|
|
}
|
|
});
|
|
};
|
|
|
|
const fetchNavData = async (id) => {
|
|
const res = await fetch(
|
|
`${process.env.NEXT_PUBLIC_API_URL}/product/category?sortByMain=true`
|
|
);
|
|
const post = await res.json();
|
|
setNavData(post);
|
|
};
|
|
|
|
const fetchProducts = async (
|
|
pageGetProducts,
|
|
id,
|
|
selectedBrands,
|
|
isChecked,
|
|
minPrice,
|
|
maxPrice,
|
|
sort,
|
|
isRangePrice,
|
|
paginationSay
|
|
) => {
|
|
const brandIds = selectedBrands?.map((brand) => brand.id);
|
|
// const query = {
|
|
// page:pageGetProducts,
|
|
// categoryId:categoryId
|
|
// }
|
|
const queryString = `${`page=${pageGetProducts}`}${
|
|
id ? `&categoryId=${id}` : ""
|
|
}${
|
|
brandIds?.length > 0 ? `&brandIds=${brandIds?.join("&brandIds=")}` : ""
|
|
}${isChecked ? `&isActive=${isChecked}` : ""}${
|
|
isRangePrice ? `&minPrice=${minPrice}` : ""
|
|
}${isRangePrice ? `&maxPrice=${maxPrice}` : ""}${
|
|
!!sort ? `&sortBy=${sort}` : ""
|
|
}`;
|
|
|
|
const cleanQueryString = decodeURIComponent(
|
|
queryString.replace(/\%20/g, " ")
|
|
);
|
|
const res = await fetch(
|
|
`${process.env.NEXT_PUBLIC_API_URL}/product?${cleanQueryString}`
|
|
);
|
|
const post = await res.json();
|
|
|
|
setPager(post.pager);
|
|
setFilter(post.filters);
|
|
|
|
if (paginationSay) {
|
|
// If it's a paginated request (not the first Page)
|
|
window.scrollTo({
|
|
top: 0,
|
|
behavior: "smooth", // Optional: smooth scrolling behavior
|
|
});
|
|
|
|
setProducts(post.products);
|
|
|
|
setStopProducts(true); // Assuming this stops pagination
|
|
}
|
|
|
|
if (post.products.length <= 19) {
|
|
// If the length of fetched products is less than or equal to 19, indicating the last Page
|
|
setStopProducts(true); // Assuming this stops pagination
|
|
}
|
|
if (!paginationSay && pageGetProducts == 0) {
|
|
// If it's not a paginated request and it's the first Page
|
|
setProducts(post.products);
|
|
} else if (!paginationSay && pageGetProducts != 0) {
|
|
// If it's not a paginated request and it's not the first Page
|
|
setProducts((data) => [...(data ? data : []), ...post.products]);
|
|
}
|
|
};
|
|
|
|
const fetchAddressUser = async () => {
|
|
try {
|
|
const data = await Chapar.get(
|
|
`${process.env.NEXT_PUBLIC_API_URL}/user/address`,
|
|
{
|
|
headers: {
|
|
Authorization: localStorage.getItem("token"),
|
|
},
|
|
}
|
|
);
|
|
|
|
setAddressData(data);
|
|
} catch ({ error, status }) {
|
|
toast.error(`${error?.response?.data?.message}`, {
|
|
position: "bottom-right",
|
|
closeOnClick: true,
|
|
});
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const fetchOrderUser = async () => {
|
|
try {
|
|
const data = await Chapar.get(
|
|
`${process.env.NEXT_PUBLIC_API_URL}/user/order`,
|
|
{
|
|
headers: {
|
|
Authorization: localStorage.getItem("token"),
|
|
},
|
|
}
|
|
);
|
|
|
|
setOrderUser(data);
|
|
} catch ({ error, status }) {
|
|
toast.error(`${error?.response?.data?.message}`, {
|
|
position: "bottom-right",
|
|
closeOnClick: true,
|
|
});
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const fetchUserInfo = async () => {
|
|
try {
|
|
const data = await Chapar.get(
|
|
`${process.env.NEXT_PUBLIC_API_URL}/user/info`,
|
|
{
|
|
headers: {
|
|
Authorization: localStorage.getItem("token"),
|
|
},
|
|
}
|
|
);
|
|
|
|
setProfile(data);
|
|
} catch ({ error, status }) {
|
|
localStorage.removeItem("token");
|
|
toast.error(`${error?.response?.data?.message}`, {
|
|
position: "bottom-right",
|
|
closeOnClick: true,
|
|
});
|
|
}
|
|
};
|
|
|
|
const fetchOrderBagCheck = async () => {
|
|
const productsToSend = cart.map((item) => ({
|
|
productId: item.id,
|
|
count: parseInt(item.count),
|
|
}));
|
|
|
|
try {
|
|
const data = await Chapar.post(
|
|
`${process.env.NEXT_PUBLIC_API_URL}/order/bag/check`,
|
|
|
|
JSON.stringify(productsToSend)
|
|
);
|
|
|
|
const updatedCart = cart
|
|
.map((item) => {
|
|
const updatedCartItem = data.find(
|
|
(updatedItem) => updatedItem.productId === item.id
|
|
);
|
|
if (updatedCartItem) {
|
|
if (updatedCartItem.isRemoved || !updatedCartItem.isEnable) {
|
|
// Item is removed or not enabled, remove from cart
|
|
return null;
|
|
} else {
|
|
return {
|
|
...item,
|
|
cost: updatedCartItem.cost,
|
|
costWithDiscount: updatedCartItem.costWithDiscount,
|
|
};
|
|
}
|
|
} else {
|
|
return item;
|
|
}
|
|
})
|
|
.filter(Boolean); // Filter out null entries (removed items)
|
|
|
|
setCart(updatedCart);
|
|
localStorage.setItem("cart", JSON.stringify(updatedCart)); // Save updatedCart to localStorage
|
|
} catch ({ error, status }) {
|
|
toast.error(`${error?.response?.data?.message}`, {
|
|
position: "bottom-right",
|
|
closeOnClick: true,
|
|
});
|
|
}
|
|
};
|
|
|
|
const GoCheckOut = async () => {
|
|
// Check if the user is authorized based on the presence of a token in local storage
|
|
const token = localStorage.getItem("token");
|
|
|
|
if (token) {
|
|
// If token exists, proceed to checkout
|
|
const productsToSend = cart.map((item) => ({
|
|
productId: item.id,
|
|
count: parseInt(item.count),
|
|
}));
|
|
|
|
try {
|
|
const data = await Chapar.post(
|
|
`${process.env.NEXT_PUBLIC_API_URL}/order/bag/submit`,
|
|
|
|
JSON.stringify(productsToSend),
|
|
|
|
{
|
|
headers: {
|
|
Authorization: localStorage.getItem("token"),
|
|
},
|
|
}
|
|
);
|
|
|
|
setCheckOutData(data);
|
|
} catch ({ error, status }) {
|
|
toast.error(`${error?.response?.data?.message}`, {
|
|
position: "bottom-right",
|
|
closeOnClick: true,
|
|
});
|
|
}
|
|
router.push("/cart/checkout"); // Redirect to the checkout Page
|
|
} else {
|
|
// If token does not exist, redirect to login
|
|
router.push("/login"); // Redirect to the login Page
|
|
}
|
|
};
|
|
|
|
const fetchCooperationSystemProfile = async () => {
|
|
try {
|
|
const data = await Chapar.get(
|
|
`${process.env.NEXT_PUBLIC_API_URL}/marketer/profile`,
|
|
{
|
|
headers: {
|
|
Authorization: localStorage.getItem("token"),
|
|
},
|
|
}
|
|
);
|
|
|
|
setCooperationSystemProfileData(data);
|
|
} catch ({ error, status }) {
|
|
toast.error(`${error?.response?.data?.message}`, {
|
|
position: "bottom-right",
|
|
closeOnClick: true,
|
|
});
|
|
}
|
|
};
|
|
|
|
const fetchCooperationSystemProfileContract = async () => {
|
|
try {
|
|
const data = await Chapar.get(
|
|
`${process.env.NEXT_PUBLIC_API_URL}/marketer/signup/contract`,
|
|
{
|
|
headers: {
|
|
Authorization: localStorage.getItem("token"),
|
|
},
|
|
}
|
|
);
|
|
|
|
setCooperationSystemProfileContractData(data);
|
|
} catch ({ error, status }) {
|
|
toast.error(`${error?.response?.data?.message}`, {
|
|
position: "bottom-right",
|
|
closeOnClick: true,
|
|
});
|
|
}
|
|
};
|
|
|
|
const fetchSearchResult = async (searchValue) => {
|
|
try {
|
|
const data = await Chapar.get(
|
|
`${process.env.NEXT_PUBLIC_API_URL}/search/thumb?name=${searchValue}`,
|
|
{
|
|
headers: {
|
|
Authorization: localStorage.getItem("token"),
|
|
},
|
|
}
|
|
);
|
|
|
|
setSearchResultData(data);
|
|
} catch ({ error, status }) {
|
|
toast.error(`${error?.response?.data?.message}`, {
|
|
position: "bottom-right",
|
|
closeOnClick: true,
|
|
});
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
const storedCart = localStorage.getItem("cart");
|
|
const token = localStorage.getItem("token");
|
|
if (storedCart) {
|
|
setCart(JSON.parse(storedCart));
|
|
}
|
|
|
|
if (token) {
|
|
fetchUserInfo();
|
|
}
|
|
|
|
fetchNavData();
|
|
// fetchCooperationSystemProfile();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const mediaQuery = window.matchMedia("(max-width: 768px)"); // Adjust the width according to your mobile breakpoint
|
|
|
|
const checkDeviceType = (mediaQuery) => {
|
|
if (mediaQuery.matches) {
|
|
setIsMobile(true);
|
|
} else {
|
|
setIsMobile(false);
|
|
}
|
|
};
|
|
|
|
// Initial check
|
|
checkDeviceType(mediaQuery);
|
|
|
|
// Listen for changes in media query
|
|
const listener = () => checkDeviceType(mediaQuery);
|
|
mediaQuery.addEventListener("change", listener);
|
|
|
|
// Clean up
|
|
return () => {
|
|
mediaQuery.removeEventListener("change", listener);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<AppContext.Provider
|
|
value={{
|
|
state: {
|
|
cart,
|
|
products,
|
|
navData,
|
|
loading,
|
|
brands,
|
|
closeNavbar,
|
|
bottomSheetCartOpen,
|
|
bottomSheetFilterOpen,
|
|
bottomSheetDiscountOpen,
|
|
bottomSheetAddressOpen,
|
|
bottomSheetDeleteAddressOpen,
|
|
bottomSheetLogOutOpen,
|
|
checkOutData,
|
|
addressData,
|
|
profile,
|
|
stopProducts,
|
|
pageGetProducts,
|
|
pager,
|
|
isMobile,
|
|
isOpenLightBox,
|
|
filter,
|
|
sortBy,
|
|
isRangePrice,
|
|
rangePrice,
|
|
selectedBrands,
|
|
isChecked,
|
|
orderUser,
|
|
bottomSheetSeeOrderOpen,
|
|
cooperationSystemProfileContractData,
|
|
cooperationSystemProfileData,
|
|
searchResultData,
|
|
isSearched,
|
|
},
|
|
setCart,
|
|
setProducts,
|
|
setNavData,
|
|
setLoading,
|
|
setBrands,
|
|
setBottomSheetCartOpen,
|
|
setBottomSheetFilterOpen,
|
|
setBottomSheetDiscountOpen,
|
|
setBottomSheetAddressOpen,
|
|
setBottomSheetDeleteAddressOpen,
|
|
setBottomSheetLogOutOpen,
|
|
setCheckOutData,
|
|
setStopProducts,
|
|
setProfile,
|
|
setPageGetProducts,
|
|
setPager,
|
|
setIsMobile,
|
|
setIsOpenLightBox,
|
|
setFilter,
|
|
setSortBy,
|
|
setIsRangePrice,
|
|
setRangePrice,
|
|
setSelectedBrands,
|
|
setBottomSheetSeeOrderOpen,
|
|
setIsChecked,
|
|
setOrderUser,
|
|
setCooperationSystemProfileContractData,
|
|
setCooperationSystemProfileData,
|
|
setIsSearched,
|
|
AddItemToCart,
|
|
RemoveItemFromCart,
|
|
fetchNavData,
|
|
fetchProducts,
|
|
setCloseNavbar,
|
|
setAddressData,
|
|
fetchAddressUser,
|
|
fetchOrderBagCheck,
|
|
fetchOrderUser,
|
|
GoCheckOut,
|
|
fetchCooperationSystemProfile,
|
|
fetchCooperationSystemProfileContract,
|
|
setSearchResultData,
|
|
fetchSearchResult,
|
|
}}
|
|
>
|
|
{children}
|
|
<ToastContainer position="bottom-right" closeOnClick={true} rtl />
|
|
<Loading />
|
|
<BottomSheetAddress />
|
|
<BottomSheetLogOut />
|
|
<NextTopLoader
|
|
color="#2189A8"
|
|
initialPosition={0.08}
|
|
crawlSpeed={200}
|
|
height={8}
|
|
crawl={true}
|
|
showSpinner={true}
|
|
easing="ease"
|
|
speed={200}
|
|
shadow="0 0 10px #2299DD,0 0 5px #2299DD"
|
|
template='<div class="bar" role="bar"><div class="peg"></div></div>
|
|
<div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'
|
|
zIndex={1600}
|
|
showAtBottom={false}
|
|
/>
|
|
|
|
<Goftino />
|
|
<Yektanet />
|
|
<SideBarNavBarMobile />
|
|
</AppContext.Provider>
|
|
);
|
|
};
|
|
|
|
export default RootData;
|