first commit

main
حسین معصومی پور 2024-05-28 01:51:53 +03:30
parent b969247ced
commit b10a501bce
174 changed files with 22737 additions and 190 deletions

7
.env.production 100644
View File

@ -0,0 +1,7 @@
NODE_ENV="production"
NEXT_PUBLIC_SERVER_URL=https://api.vesmook.com
NEXT_PUBLIC_PUBLIC_URL=https://api.vesmook.com
NEXT_PUBLIC_API_URL=https://api.vesmook.com/api
NEXT_PUBLIC_STORAGE_URL=http://storage.vesmook.com
NEXT_PUBLIC_PACKAGE_VERSION=0.1.4

View File

@ -0,0 +1,7 @@
"use client";
import { createContext } from "react";
const AppContext = createContext({
state: {},
});
export default AppContext;

View File

@ -0,0 +1,148 @@
"use client";
import CardCart from "@comp/Cards/CardCart/page";
import NavBarDownCart from "@comp/Carts/component/NavBarDownCart/page";
import Navbar from "@comp/Navbar/page";
import AppContext from "@ctx/AppContext";
import { useRouter } from "next/navigation";
import Chapar from "plugins/Chapar";
import PersianNumber from "plugins/PersianNumber";
import { useContext, useEffect } from "react";
import { toast } from "react-toastify";
const CartData = () => {
const CTX = useContext(AppContext);
const router = useRouter();
const cart = CTX.state.cart;
const calculateTotalCost = cart.reduce(
(total, item) => total + parseInt(item.cost) * item.count,
0
);
const calculateTotalCostWithDiscount = cart.reduce(
(total, item) => total + parseInt(item.costWithDiscount) * item.count,
0
);
const handleGoCheckOut = async () => {
CTX.GoCheckOut();
};
useEffect(() => {
CTX.setBottomSheetCartOpen(false);
}, []);
return (
<>
<div className=" pb-20">
<Navbar theme={1} />
<div className="xs:w-full lg:w-4/12 mx-auto">
<div className="text-right flex rtl justify-between border-t-[1px] border-gray-200 my-3 px-4 ">
<p className="mb-0 text-sm font-semibold py-4">
محصولات انتخاب شده
</p>
<div className="bg-primary-200 w-fit h-fit relative my-3 p-1 rounded-lg">
<p className="mb-0 text-[11px] text-white rtl">
<PersianNumber number={cart?.length} style={"mx-1"} />
محصول
</p>
</div>
</div>
<div className="">
{cart?.map((e, index) => (
<CardCart key={index} data={e} />
))}
<div className="">
<div className="text-right flex rtl justify-between border-y-[1px] border-gray-200 my-3 px-4 ">
<p className="mb-0 text-sm font-medium py-4">حساب نهایی</p>
{/* <div className="bg-primary-200 w-fit h-fit relative my-3 p-1 rounded-lg">
<p className="mb-0 text-[11px] text-white rtl">
<PersianNumber number={cart?.length} style={"mx-1"} />
محصول
</p>
</div> */}
</div>
<div>
<div className="flex justify-between rtl px-4">
<p className="mb-0 text-[12px] text-gray-500">قیمت </p>
<div className="flex justify-center">
<p className="mb-0 ">
<PersianNumber
number={(calculateTotalCost / 10)?.toLocaleString()}
style={"!text-[14px] !font-medium"}
/>
</p>
<small className="text-gray-500 text-[12px] mt-1 mx-1">
{" "}
تومان
</small>
</div>
</div>
<div className="flex justify-between rtl my-2 px-4">
<p className="mb-0 text-[12px] text-gray-500">تخفیف محصول</p>
<div className="flex justify-center ">
<p className="mb-0 ">
<PersianNumber
number={(
(calculateTotalCost -
calculateTotalCostWithDiscount) /
10
)?.toLocaleString()}
style={"!text-[14px] !font-medium"}
/>
</p>
<small className="text-gray-500 text-[12px] mt-1 mx-1">
{" "}
تومان
</small>
</div>
</div>
<div className="flex justify-between bg-primary-100 p-3 rtl my-2">
<p className="mb-0 text-sm text-primary-600 font-bold">
قابل پرداخت
</p>
<div className="flex justify-center">
<p className="mb-0 ">
<PersianNumber
number={
calculateTotalCostWithDiscount !== 0
? (
calculateTotalCostWithDiscount / 10
)?.toLocaleString()
: 0
}
style={"!text-[14px] !font-medium text-primary-800"}
/>
</p>
<small className="text-gray-500 text-[12px] mt-1 mx-1">
{" "}
تومان
</small>
</div>
</div>
</div>
</div>
</div>
</div>
<NavBarDownCart
calculateTotalCost={calculateTotalCostWithDiscount / 10}
event={() => handleGoCheckOut()}
permissionGoPay={!!cart.length > 0}
/>
</div>
</>
);
};
export default CartData;

View File

@ -0,0 +1,255 @@
"use client";
import FilterCategory from "@comp/Category/FilterCategory/page";
import ListProdocts from "@comp/Category/ListProdocts/page";
import FilterCategoryMobile from "@comp/Category/Mobile/FilterCategoryMobile/page";
import ListProductsMobile from "@comp/Category/Mobile/ListProductsMobile/page";
import PaginationCategoory from "@comp/Category/PaginationCategoory/page";
import Footer from "@comp/Footer/page";
import Navbar from "@comp/Navbar/page";
import AppContext from "@ctx/AppContext";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useContext, useEffect, useMemo, useState } from "react";
import InfiniteScroll from "react-infinite-scroll-component";
export default function CategoriesData({ params, products }) {
const CTX = useContext(AppContext);
const searchParams = useSearchParams();
useEffect(() => {
if (
Number(searchParams.get("page")) === 0 ||
!Number(searchParams.get("page")) ||
CTX.state.stopProducts
) {
CTX.setProducts(products.products);
} else {
CTX.setProducts([...CTX.state.products, ...products.products]);
}
CTX.setStopProducts(
CTX.state.stopProducts || products?.products?.length < 20
);
CTX.setPager(products.pager);
CTX.setFilter(products.filters);
}, [products]);
const pageGetProducts = useMemo(
() => (searchParams.get("page") ? Number(searchParams.get("page")) : 0),
[searchParams]
);
const stopProducts = CTX.state.stopProducts;
const pager = products.pager;
const productsLength = CTX.state?.products?.length || 0;
const filter = CTX.state.filter;
const isChecked = useMemo(
() => Boolean(Number(searchParams.get("isActive"))),
[searchParams]
);
const specialOffer = useMemo(
() => Boolean(Number(searchParams.get("specialOffer"))),
[searchParams]
);
const selectedBrands = useMemo(
() =>
searchParams.get("brandIds")
? searchParams.get("brandIds").split(",")
: [],
[searchParams]
);
const rangePrice = useMemo(
() => [
searchParams.get("maxPrice")
? Number(searchParams.get("maxPrice"))
: filter?.price?.maximumValue,
searchParams.get("minPrice")
? Number(searchParams.get("minPrice"))
: filter?.price?.minimumValue,
],
[searchParams]
);
const isRangePrice = CTX.state.isRangePrice;
const sortBy = useMemo(
() => Number(searchParams.get("sortBy")),
[searchParams]
);
//
// "filters",
// filter,
// isChecked,
// selectedBrands,
// rangePrice,
// isRangePrice,
// sortBy
// );
const fetchBarnds = async () => {
const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/brand${
params.id[0] != 0 ? `?categoryId=${params.id[0]}` : ""
}`
);
const brands = await res.json();
CTX.setBrands(brands);
};
const decodedName = decodeURIComponent(params.id[1]);
const pathname = usePathname();
const router = useRouter();
const handleInfiniteNextFetchProducts = () => {
// Increment the page number
const nextPage = pageGetProducts + 1;
const params = new URLSearchParams(searchParams.toString());
params.set("page", nextPage);
router.push(`${pathname}?${params}`, { scroll: false });
// Fetch products for the next page
// CTX.fetchProducts(
// nextPage,
// params.id[0] != 0 ? params.id[0] : "",
// selectedBrands,
// isChecked,
// rangePrice,
// rangePrice,
// sortBy != -1 ? sortBy : "",
// isRangePrice
// );
// Update the pageGetProducts state for the next fetch
// CTX.setPageGetProducts(nextPage);
};
const [loading, setLoading] = useState(true);
const getData = async () => {
setLoading(true);
// await CTX.fetchProducts(0, params.id[0] != 0 ? params.id[0] : "");
await fetchBarnds();
setLoading(false);
};
useEffect(() => {
setLoading(false);
getData();
}, []);
return (
<>
<div className=" pb-20">
<Navbar theme={1} />
{!CTX.state.isMobile && (
<div className="xs:hidden lg:block">
<div className="text-right px-8 py-5">
<h1 className="font-medium ">{decodedName.replace(/-/g, " ")}</h1>
</div>
<div className="pl-20 pr-10 grid lg:grid-cols-8 xl:grid-cols-5 rtl mt-10 ">
<FilterCategory
id={params.id}
isChecked={isChecked}
selectedBrands={selectedBrands}
rangePrice={rangePrice}
sortBy={sortBy}
isRangePrice={isRangePrice}
filter={filter}
specialOffer={specialOffer}
/>
<div className="lg:col-span-6 xl:col-span-4 ">
{loading && <>در حال بارگیری</>}
{true ? (
<>
{!loading && (
<InfiniteScroll
dataLength={productsLength}
next={handleInfiniteNextFetchProducts}
hasMore={!stopProducts}
>
<ListProdocts
id={params.id}
isChecked={isChecked}
selectedBrands={selectedBrands}
rangePrice={rangePrice}
sortBy={sortBy}
isRangePrice={isRangePrice}
/>
</InfiniteScroll>
)}
</>
) : (
<div className="flex justify-center py-5">
<div className="bg-white shadow mt-5 w-fit rounded-full text-sm p-4">
چیزی یافت نشد
</div>
</div>
)}
</div>
</div>
</div>
)}
{CTX.state.isMobile && (
<div className="xs:block lg:hidden ">
<FilterCategoryMobile
id={params.id}
isChecked={isChecked}
selectedBrands={selectedBrands}
rangePrice={rangePrice}
sortBy={sortBy}
isRangePrice={isRangePrice}
specialOffer={specialOffer}
/>
<div className="text-right px-8 py-5">
<h1 className="font-medium text-sm ">
{decodedName.replace(/-/g, " ")}
</h1>
</div>
<div>
{loading && <>در حال بارگیری</>}
{true ? (
<>
{!loading && (
<InfiniteScroll
dataLength={productsLength}
next={handleInfiniteNextFetchProducts}
hasMore={!stopProducts}
scrollThreshold={0.5}
>
<ListProductsMobile
id={params.id}
isChecked={isChecked}
selectedBrands={selectedBrands}
rangePrice={rangePrice}
sortBy={sortBy}
isRangePrice={isRangePrice}
/>
</InfiniteScroll>
)}
</>
) : (
<div className="flex justify-center py-5">
<div className="bg-white shadow mt-5 w-fit rounded-full text-sm p-4">
چیزی یافت نشد
</div>
</div>
)}
</div>
</div>
)}
</div>
{pager?.totalPage > 1 && (
<PaginationCategoory
id={params.id}
isChecked={isChecked}
selectedBrands={selectedBrands}
rangePrice={rangePrice}
sortBy={sortBy}
isRangePrice={isRangePrice}
/>
)}
<Footer />
</>
);
}

View File

@ -0,0 +1,509 @@
"use client";
import NavBarDownCart from "@comp/Carts/component/NavBarDownCart/page";
import Navbar from "@comp/Navbar/page";
import PersianNumber from "plugins/PersianNumber";
import { useContext, useEffect, useState } from "react";
import AppContext from "@ctx/AppContext";
import ap from "@img/ap.png";
import zarin from "@img/zarin.png";
import Image from "next/image";
import { useRouter } from "next/navigation";
import Chapar from "plugins/Chapar";
import BottomSheetDiscount from "plugins/bottomSheet/BottomSheetDiscount";
import { toast } from "react-toastify";
const CheckoutData = () => {
const CTX = useContext(AppContext);
const [shippingData, setShippingData] = useState([]);
const [shippingId, setShippingID] = useState(null);
const [addressData, setAddressData] = useState([]);
const [addressId, setAddressId] = useState(null);
const [permissionGoPay, setPermissionGoPay] = useState(false);
const router = useRouter();
const checkOutData = CTX.state.checkOutData;
const body = {
addressId: addressData[addressId]?.id,
orderId: checkOutData?.id,
shippingId: shippingData[shippingId]?.id,
};
const GetShippingData = async () => {
try {
const data = await Chapar.get(
`${process.env.NEXT_PUBLIC_API_URL}/warehouse/shipping?page=0`
);
setShippingData(data);
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
}
};
const handleShippingID = async (index) => {
if (addressId !== null) {
setShippingID(index);
try {
const data = await Chapar.post(
`${process.env.NEXT_PUBLIC_API_URL}/order/bag/shipping/${checkOutData?.id}`,
JSON.stringify({
addressId: addressData[addressId]?.id,
orderId: checkOutData?.id,
shippingId: shippingData[index]?.id,
}),
{
headers: {
Authorization: localStorage.getItem("token"),
},
}
);
CTX.setCheckOutData(data);
setPermissionGoPay(true);
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
}
} else {
toast.error(`ابتدا آدرس را انتحاب کنید`, {
position: "bottom-right",
closeOnClick: true,
});
}
};
const handleGoPayment = async () => {
const token = localStorage.getItem("token").slice(7);
try {
const data = await Chapar.post(
`${process.env.NEXT_PUBLIC_API_URL}/order/bag/payment/${checkOutData?.id}?paymentMethod=1&access_token=${token}`
// {
// headers: {
// Authorization: token,
// },
// }
);
router.push(data?.paymentUrl);
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
}
};
useEffect(() => {
if (shippingData.length <= 0) {
GetShippingData();
}
CTX.fetchAddressUser();
}, [checkOutData]);
useEffect(() => {
setAddressData(CTX.state.addressData);
}, [CTX.state.addressData]);
useEffect(() => {
if (CTX.state.checkOutData.length <= 0) {
router.push("/cart");
}
setPermissionGoPay(false);
}, []);
return (
<>
<div className=" pb-20">
<Navbar theme={1} />
<div className="xs:w-full lg:w-4/12 mx-auto">
<div className="text-right flex rtl justify-between border-y-[1px] border-gray-100 mt-3 px-4 ">
<p className="mb-0 !text-sm font-medium py-4">آدرس ها</p>
{/* <div
className="bg-primary-200 w-fit h-fit relative my-3 p-1 rounded-lg"
onClick={() => CTX.setBottomSheetAddressOpen(true)}
>
<p className="mb-0 text-[11px] text-white rtl">
افزودن آدرس جدید
</p>
</div> */}
</div>
{addressData?.length > 0 ? (
<>
{addressData.map((e, index) => (
<div
onClick={() => setAddressId(index)}
className={`flex rtl justify-between cursor-pointer mx-2 relative ${
addressId == index
? "border-2 !border-green-600 rounded-lg bg-green-50"
: ""
}`}
>
<div className="flex rtl px-3 py-4 w-11/12" key={index}>
<div>
<svg
width="20"
height="20"
viewBox="0 0 188 264"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-70 mx-auto "
>
<path
d="M94 10.125C47.418 10.125 9.625 46.0957 9.625 90.3984C9.625 141.375 65.875 222.158 86.5293 250.061C87.3866 251.238 88.5103 252.197 89.8087 252.858C91.107 253.518 92.5432 253.863 94 253.863C95.4568 253.863 96.893 253.518 98.1913 252.858C99.4897 252.197 100.613 251.238 101.471 250.061C122.125 222.17 178.375 141.416 178.375 90.3984C178.375 46.0957 140.582 10.125 94 10.125Z"
stroke="black"
stroke-width="18.75"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M94 122.625C109.533 122.625 122.125 110.033 122.125 94.5C122.125 78.967 109.533 66.375 94 66.375C78.467 66.375 65.875 78.967 65.875 94.5C65.875 110.033 78.467 122.625 94 122.625Z"
stroke="black"
stroke-opacity="0.37"
stroke-width="18.75"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div className="mx-2">
<p className="mb-0 text-[12px] text-gray-500">
{" "}
{e.address}{" "}
</p>
</div>
</div>
<div
className={`w-5 h-5 rounded-full mt-4 mx-3 border-2 relative ${
addressId == index
? "border-green-400 bg-green-200"
: "bg-gray-100 border-gray-200 "
}`}
></div>
</div>
))}
</>
) : (
<div className=" p-5 rounded-lg">
<div className="flex justify-center py-5">
<div
className="bg-white shadow w-fit rounded-full text-sm p-4"
onClick={() => CTX.setBottomSheetAddressOpen(true)}
>
افزودن آدرس +{" "}
</div>
</div>
</div>
)}
<div className="text-right flex rtl justify-between border-y-[1px] border-gray-100 mt-3 px-4 ">
<p className="mb-0 text-sm font-medium py-4">زمان و نحوه ارسال</p>
<div className="border border-gray-300 w-fit h-fit relative my-3 p-1 rounded-lg">
<div className="flex">
<div>
<svg
width="15"
height="15"
viewBox="0 0 251 200"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-60"
>
<path
d="M105.625 143.75C110.625 148.75 117.083 151.2 125 151.1C132.917 151 138.75 148.133 142.5 142.5L212.5 37.5L107.5 107.5C101.875 111.25 98.9083 116.979 98.6 124.688C98.2917 132.396 100.633 138.75 105.625 143.75ZM125 0C137.292 0 149.117 1.71667 160.475 5.15C171.833 8.58334 182.508 13.7417 192.5 20.625L168.75 35.625C161.875 32.0833 154.742 29.4292 147.35 27.6625C139.958 25.8958 132.508 25.0083 125 25C97.2917 25 73.6958 34.7417 54.2125 54.225C34.7292 73.7083 24.9917 97.3 25 125C25 133.75 26.2 142.396 28.6 150.938C31 159.479 34.3833 167.5 38.75 175H211.25C216.042 167.083 219.533 158.854 221.725 150.312C223.917 141.771 225.008 132.917 225 123.75C225 116.25 224.113 108.958 222.338 101.875C220.563 94.7917 217.908 87.9167 214.375 81.25L229.375 57.5C235.625 67.2917 240.575 77.7083 244.225 88.75C247.875 99.7917 249.8 111.25 250 123.125C250.208 135 248.854 146.354 245.938 157.188C243.021 168.021 238.75 178.333 233.125 188.125C230.833 191.875 227.708 194.792 223.75 196.875C219.792 198.958 215.625 200 211.25 200H38.75C34.375 200 30.2083 198.958 26.25 196.875C22.2917 194.792 19.1667 191.875 16.875 188.125C11.4583 178.75 7.29167 168.804 4.375 158.288C1.45833 147.771 0 136.675 0 125C0 107.708 3.28334 91.5125 9.85 76.4125C16.4167 61.3125 25.375 48.0833 36.725 36.725C48.075 25.3667 61.35 16.4083 76.55 9.85C91.75 3.29167 107.9 0.00833333 125 0Z"
fill="black"
fill-opacity="0.61"
/>
</svg>
</div>
<p className="mb-0 text-[11px] rtl mr-2 text-gray-600">
سریع ترین زمان ارسال
</p>
</div>
</div>
</div>
<div>
{shippingData?.map((e, index) => (
<div
onClick={() => handleShippingID(index)}
className={`flex rtl justify-between cursor-pointer mx-2 ${
shippingId == index
? "border-2 !border-green-600 rounded-lg bg-green-50"
: ""
}`}
>
<div className="flex rtl px-3 py-4" key={index}>
<div>
<svg
width="25"
height="25"
viewBox="0 0 234 244"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto opacity-70 mt-2"
>
<path
d="M65.8246 162.813C66.1529 163.999 66.7117 165.11 67.4692 166.081C68.2267 167.052 69.168 167.864 70.2394 168.471C71.3107 169.078 72.4911 169.468 73.7133 169.619C74.9354 169.77 76.1752 169.678 77.3621 169.35C78.5489 169.022 79.6594 168.463 80.6303 167.705C81.6011 166.948 82.4133 166.007 83.0203 164.935C83.6274 163.864 84.0175 162.683 84.1683 161.461C84.3192 160.239 84.2279 158.999 83.8996 157.813L65.8246 162.813ZM11.9996 31.0625C10.8081 30.7145 9.55935 30.6066 8.32582 30.745C7.09228 30.8834 5.89851 31.2654 4.81377 31.8688C3.72903 32.4722 2.77491 33.285 2.00678 34.26C1.23864 35.2351 0.671788 36.353 0.3391 37.5488C0.00641134 38.7447 -0.0854865 39.9947 0.0687392 41.2264C0.222965 42.458 0.620244 43.6468 1.23752 44.7237C1.8548 45.8006 2.6798 46.7442 3.66463 47.4997C4.64947 48.2553 5.77454 48.8077 6.97458 49.125L11.9996 31.0625ZM224.35 168.563C225.57 168.28 226.722 167.756 227.737 167.021C228.752 166.286 229.609 165.355 230.257 164.284C230.906 163.212 231.334 162.021 231.515 160.781C231.695 159.541 231.626 158.278 231.31 157.065C230.994 155.853 230.438 154.716 229.676 153.722C228.913 152.728 227.959 151.897 226.869 151.278C225.78 150.659 224.578 150.264 223.333 150.118C222.089 149.971 220.828 150.076 219.625 150.425L224.35 168.563ZM99.4621 191.488C103.337 205.488 94.8371 220.275 79.7871 224.188L84.4996 242.325C109.212 235.913 124.312 211.05 117.537 186.488L99.4621 191.488ZM79.7871 224.188C64.6371 228.125 49.4371 219.325 45.5371 205.2L27.4621 210.2C34.2121 234.638 59.8871 248.725 84.4996 242.325L79.7871 224.188ZM45.5371 205.2C41.6621 191.2 50.1621 176.413 65.2121 172.5L60.4996 154.375C35.7871 160.788 20.6746 185.638 27.4621 210.2L45.5371 205.2ZM65.2121 172.5C80.3621 168.563 95.5621 177.363 99.4621 191.488L117.537 186.488C110.787 162.05 85.1121 147.963 60.4996 154.363L65.2121 172.5ZM83.8996 157.813L56.9996 60.4375L38.9246 65.4375L65.8246 162.813L83.8996 157.813ZM33.2996 36.9625L11.9996 31.0625L6.97458 49.125L28.2871 55.0375L33.2996 36.9625ZM56.9996 60.4375C55.4136 54.8107 52.3969 49.6907 48.2434 45.5766C44.0899 41.4625 38.9413 38.4948 33.2996 36.9625L28.3121 55.0375C33.6246 56.5125 37.5746 60.55 38.9246 65.4375L56.9996 60.4375ZM110.875 198.063L224.35 168.563L219.637 150.425L106.15 179.925L110.875 198.063Z"
fill="black"
/>
<path
d="M211.562 49.9502C205.5 28.0002 202.462 17.0252 193.562 12.0377C184.637 7.03772 173.325 9.98772 150.7 15.8752L126.7 22.1002C104.075 27.9752 92.7623 30.9252 87.6248 39.5752C82.4748 48.2127 85.4998 59.1877 91.5623 81.1252L97.9998 104.413C104.062 126.35 107.087 137.325 116 142.313C124.912 147.313 136.225 144.363 158.85 138.488L182.85 132.238C205.475 126.363 216.787 123.425 221.937 114.788C224.762 110.038 225.125 104.588 223.862 97.0002"
stroke="black"
stroke-opacity="0.44"
stroke-width="18.75"
stroke-linecap="round"
/>
</svg>
</div>
<div className="mx-2">
<h3 className="mb-0 text-sm text-right font-medium text-primary-500 ">
{e.name}{" "}
</h3>
<p className="mb-0 text-[12px] text-gray-500">
{" "}
هزینه ارسال
<PersianNumber
number={(e.deliveryCost / 10)?.toLocaleString()}
style={"text-gray-600 mx-1"}
/>
هزار تومان
</p>
</div>
</div>
<div
className={`w-5 h-5 rounded-full mt-6 mx-3 border-2 ${
shippingId == index
? "border-green-400 bg-green-200"
: "bg-gray-100 border-gray-200 "
}`}
></div>
</div>
))}
</div>
<div className="text-right flex rtl justify-between border-y-[1px] border-gray-100 mt-3 px-4 ">
<p className="mb-0 text-sm font-medium py-4">روش پرداخت</p>
</div>
<div>
<div
className={`flex rtl px-2 py-2 mx-2 border-2 border-transparent mt-5 ${
true ? "border-2 !border-green-600 rounded-lg bg-green-50" : ""
}`}
>
<div>
<Image src={zarin} className="w-[50px]" alt="زرین پال" />
</div>
<div className="mx-2">
<h3 className="mb-0 text-sm text-right font-medium text-primary-500 ">
پرداخت آنلاین
</h3>
<p className="mb-0 text-[12px] text-gray-500">زرین پال</p>
</div>
</div>
<div className="flex rtl px-2 py-1 mx-2 mt-5 opacity-40">
<div>
<Image src={ap} className="w-[45px]" alt="آپ" />
</div>
<div className="mx-2">
<h3 className="mb-0 text-sm text-right font-medium text-primary-500 ">
پرداخت آنلاین (به زودی)
</h3>
<p className="mb-0 text-[12px] text-gray-500">آسان پرداخت</p>
</div>
</div>
<div
className={`flex justify-between rtl px-3 mt-5 ${
checkOutData?.discountCode != "" ? "" : ""
}`}
onClick={() => {
if (checkOutData?.discountCode == "") {
CTX.setBottomSheetDiscountOpen(true);
}
}}
>
<div className="flex">
<div>
<svg
width="25"
height="25"
viewBox="0 0 244 194"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-70 mt-2"
>
<path
d="M122 93.875V100.125M122 47V53.25M122 140.75V147M209.5 184.5C216.13 184.5 222.489 181.866 227.178 177.178C231.866 172.489 234.5 166.13 234.5 159.5V122C227.87 122 221.511 119.366 216.822 114.678C212.134 109.989 209.5 103.63 209.5 97C209.5 90.3696 212.134 84.0107 216.822 79.3223C221.511 74.6339 227.87 72 234.5 72V34.5C234.5 27.8696 231.866 21.5107 227.178 16.8223C222.489 12.1339 216.13 9.5 209.5 9.5H34.5C27.8696 9.5 21.5107 12.1339 16.8223 16.8223C12.1339 21.5107 9.5 27.8696 9.5 34.5V72C16.1304 72 22.4893 74.6339 27.1777 79.3223C31.8661 84.0107 34.5 90.3696 34.5 97C34.5 103.63 31.8661 109.989 27.1777 114.678C22.4893 119.366 16.1304 122 9.5 122V159.5C9.5 166.13 12.1339 172.489 16.8223 177.178C21.5107 181.866 27.8696 184.5 34.5 184.5H209.5Z"
stroke="black"
stroke-opacity="0.54"
stroke-width="18.75"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div className="mx-2">
<h3 className="mb-0 text-sm text-right font-medium text-primary-500 ">
افزودن کد تخفیف{" "}
</h3>
<p className="mb-0 text-[12px] text-gray-500">
کد تخفیف خود را وارد کنید
</p>
</div>
</div>
{checkOutData?.discountCode == "" ? (
<div className="pl-3">
<span className="text-[30px] opacity-60">+</span>
</div>
) : (
<div className="text-right flex justify-end px-2 py-1 mx-2">
<p className="text-green-600 mb-0 text-[12px] ">
کد تخفیف ثبت شد{" "}
</p>
</div>
)}
</div>
</div>
<div className="">
<div className="text-right flex rtl justify-between border-y-[1px] border-gray-100 my-3 px-4 ">
<p className="mb-0 text-sm font-medium py-4">حساب نهایی</p>
{/* <div className="bg-primary-200 w-fit h-fit relative my-3 p-1 rounded-lg">
<p className="mb-0 text-[11px] text-white rtl">مشاهده اقلام</p>
</div> */}
</div>
<div>
<div className="flex justify-between rtl px-4">
<p className="mb-0 text-[12px] text-gray-500">قیمت </p>
<div className="flex justify-center">
<p className="mb-0 ">
<PersianNumber
number={(
checkOutData?.totalProductsPrice / 10
)?.toLocaleString()}
style={"!text-[14px] !font-medium"}
/>
</p>
<small className="text-gray-500 text-[12px] mt-1 mx-1">
{" "}
تومان
</small>
</div>
</div>
<div className="flex justify-between rtl my-2 px-4">
<p className="mb-0 text-[12px] text-gray-500">تخفیف محصول</p>
<div className="flex justify-center">
<p className="mb-0 ">
<PersianNumber
number={(
checkOutData?.discountPrice / 10
)?.toLocaleString()}
style={"!text-[14px] !font-medium"}
/>
</p>
<small className="text-gray-500 text-[12px] mt-1 mx-1">
{" "}
تومان
</small>
</div>
</div>
<div className="flex justify-between rtl my-2 px-4">
<p className="mb-0 text-[12px] text-gray-500">
هزینه بسته بندی
</p>
<div className="flex justify-center">
<p className="mb-0 ">
<PersianNumber
number={(
checkOutData?.packingPrice / 10
)?.toLocaleString()}
style={"!text-[14px] !font-medium"}
/>
</p>
<small className="text-gray-500 text-[12px] mt-1 mx-1">
{" "}
تومان
</small>
</div>
</div>
<div className="flex justify-between rtl my-2 px-4">
<p className="mb-0 text-[12px] text-gray-500">هزینه ارسال</p>
<div className="flex justify-center">
<p className="mb-0 ">
<PersianNumber
number={(
checkOutData?.deliveryPrice / 10
)?.toLocaleString()}
style={"!text-[14px] !font-medium"}
/>
</p>
<small className="text-gray-500 text-[12px] mt-1 mx-1">
{" "}
تومان
</small>
</div>
</div>
<div className="flex justify-between bg-primary-100 p-3 rtl my-2">
<p className="mb-0 text-sm text-primary-600 font-medium">
قابل پرداخت
</p>
<div className="flex justify-center">
<p className="mb-0 ">
<PersianNumber
number={(checkOutData?.totalPrice / 10)?.toLocaleString()}
style={"!text-[14px] !font-medium text-primary-800"}
/>
</p>
<small className="text-gray-500 text-[12px] mt-1 mx-1">
{" "}
تومان
</small>
</div>
</div>
</div>
</div>
</div>
<NavBarDownCart
calculateTotalCost={checkOutData.totalPrice / 10}
event={() => handleGoPayment()}
permissionGoPay={permissionGoPay}
/>
</div>
<BottomSheetDiscount orderId={checkOutData?.id} />
</>
);
};
export default CheckoutData;

View File

@ -0,0 +1,81 @@
"use client";
import Footer from "@comp/Footer/page";
import Navbar from "@comp/Navbar/page";
import { useEffect, useState } from "react";
const FaqData = () => {
const [faq, setFaq] = useState([]);
const [faqSelect, setFaqSelect] = useState(0);
const fetchNavData = async (id) => {
const res = await fetch(`https://jsonplaceholder.typicode.com/comments`);
const post = await res.json();
setFaq(post);
};
useEffect(() => {
fetchNavData();
}, []);
return (
<>
<div className="bg-contact-us ">
<div className=" pb-20">
<Navbar theme={0} />
<div>
<div className="flex justify-center xs:hidden lg:block">
<div className="absolute mr-[-1100px] mt-[-200px]">
<p className="mb-0 text-[300px] opacity-10 font-extrabold text-white ">
{" "}
,
</p>
</div>
</div>
</div>
<div className="my-[80px] ">
<div className="px-5">
<h1 className="text-white font-bold text-center xs:text-[20px] lg:text-[40px]">
پرسشهای متداول
</h1>
</div>
</div>
</div>
</div>
<div className=" xs:px-3 lg:px-20 rtl lg:m-10 xs:m-3 pb-20 ">
{faq?.map((e, index) => (
<div
className={` p-5 w-full rounded-lg my-2 tr03 cursor-pointer ${
faqSelect == index ? "bg-gray-100" : "bg-primary-100"
}`}
onClick={() => setFaqSelect(index)}
key={index}
>
<div className="flex">
<span className="mx-2 text-xl text-gray-900">
{faqSelect == index ? "-" : "+"}
</span>
<h2 className="mb-0 text-gray-700 text-sm text-right mt-1 font-semibold">
{e.name}
</h2>
</div>
{faqSelect == index && (
<>
<div className="h-[1px] bg-gray-300 w-[120px] mr-5 m-5 "></div>
<p className="mb-0 text-right text-gray-500 text-sm">
{e.body}
</p>
</>
)}
</div>
))}
</div>
<Footer />
</>
);
};
export default FaqData;

View File

@ -0,0 +1,407 @@
"use client";
import Footer from "@comp/Footer/page";
import Navbar from "@comp/Navbar/page";
import GalleryBox from "plugins/Gallery/page";
import { useEffect, useState } from "react";
import AddToCart from "@comp/Cards/Components/AddToCart/page";
import Image from "next/image";
import PersianNumber from "plugins/PersianNumber";
import logo from "../../../public/images/logo.png";
const ProductData = ({ params, data }) => {
const [product, setProduct] = useState([]);
const [specificationsHeader, setSpecificationsHeader] = useState([]);
const [productBarDetail, setProductBarDetail] = useState(0);
const fetchPost = async (id) => {
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/product/${id}`);
const post = await res.json();
setProduct(post.product);
};
const displaySpecifications = (specs) => {
let data = [];
if (specs?.length > 3) {
specs?.slice(0, 3).forEach((spec) => {
const { title, value } = spec;
data.push(`${title}: ${value}`);
});
} else {
specs?.forEach((spec) => {
const { title, value } = spec;
data.push(`${title}: ${value}`);
});
}
setSpecificationsHeader(data); // You can replace
};
const scrollToSection = (id) => {
const element = document.getElementById(id);
if (element) {
const offset = -80; // Adjust this value as needed
window.scrollTo({
top: element.offsetTop + offset,
behavior: "smooth",
});
}
};
useEffect(() => {
fetchPost(params.id[0]);
}, []);
useEffect(() => {
displaySpecifications(product?.specifications);
}, [product]);
return (
<>
<Navbar theme={1} />
<div className=" py-10">
<div className="grid xs:grid-cols-1 lg:grid-cols-8 rtl gap-6 lg:px-20">
<div className="lg:col-span-3 ">
<GalleryBox file={data?.product?.files} />
</div>
<div className="lg:col-span-3 xs:px-5 lg:px-0 ">
<div className="text-right mt-7">
<h1 className="text-lg font-medium ">
{data.product?.persianName}{" "}
</h1>
<p className="mb-0 text-sm text-gray-400">
{data?.product?.englishName}{" "}
</p>
</div>
<div className="flex my-4">
<div className="bg-primary-400 rounded-full py-1 px-3 ml-2">
<p className="mb-0 text-sm text-white ">اصالت کالای </p>
</div>
{data?.product?.hasDiscount && (
<div className="bg-danger-100 rounded-full py-1 px-3 ml-2">
<p className="mb-0 text-sm text-white ">بمب امروز </p>
</div>
)}
{!data?.product?.warranty == "" && (
<div className="bg-secondary-500 rounded-full py-1 px-3 ml-2">
<p className="mb-0 text-sm text-white ">
{product?.warranty}
</p>
</div>
)}
</div>
{/* <div className="flex my-5">
<div className="w-[30px] h-[30px] rounded-full bg-red-800 border-[5px] border-white shadow mr-2 cursor-pointer "></div>
<div className="w-[30px] h-[30px] rounded-full bg-red-700 border-[5px] border-white shadow mr-2 cursor-pointer "></div>
<div className="w-[30px] h-[30px] rounded-full bg-red-600 border-[5px] border-white shadow mr-2 cursor-pointer "></div>
<div className="w-[30px] h-[30px] rounded-full bg-red-500 border-[5px] border-green-300 scale-110 shadow mr-2 cursor-pointer "></div>
<div className="w-[30px] h-[30px] rounded-full bg-red-400 border-[5px] border-white shadow mr-2 cursor-pointer "></div>
<div className="w-[30px] h-[30px] rounded-full bg-red-300 border-[5px] border-white shadow mr-2 cursor-pointer "></div>
<div className="w-[30px] h-[30px] rounded-full bg-red-200 border-[5px] border-white shadow mr-2 cursor-pointer "></div>
</div> */}
<div>
<div className="text-right mt-3 flex justify-between">
<h2 className="mb-0 text-gray-400 text-sm">
{data?.product?.summery}
</h2>
</div>
</div>
<ul className="mt-3 px-3">
{specificationsHeader.map((e, index) => (
<li className=" flex my-2" key={index}>
<div className="w-[10px] h-[10px] relative rounded-full bg-primary-500 mt-1"></div>
<p className="mb-0 w-full text-sm text-gray-700 mx-2 ">
{e}
</p>
</li>
))}
</ul>
</div>
{/* xs:sticky lg:relative xs:top-[60px] lg:top-0 ==> sticky for price=================== */}
<div className=" w-9/12 lg:col-span-2 sticky top-[80px] xs:hidden lg:block ">
<div className="p-3 h-fit border-[1px] border-gray-300 rounded-xl ">
<div className="flex justify-center">
<div className="w-[130px]">
{data?.product?.files?.length > 0 ? (
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${
product.files && product.files[0].fileLocation
}`}
width={350}
height={350}
className=" mx-auto !object-cover"
onClick={() => CTX.setIsOpenLightBox(true)}
alt={`${product.persianName} - ${product.englishName}`}
property
loading="eager"
/>
) : (
<div className="xs:!w-[85px] lg:!w-[85px] my-10 ">
<Image
src={logo}
className="xs:!w-[70px] lg:!w-[70px] mx-auto !object-cover opacity-25 mt-5"
alt="وسمه"
/>
</div>
)}
</div>
</div>
<div className="text-center">
<p className="mb-0 text-sm text-gray-500">
{data?.product?.persianName}{" "}
</p>
</div>
<div className="w-6/12 mx-auto h-[1px] bg-gray-200 mt-4"></div>
<div className="flex justify-center mt-3">
<div>
<svg
width="15"
height="15"
viewBox="0 0 226 264"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="ml-1 mt-[2px]"
>
<path
d="M94.25 137.531L69.9687 113.25L56.75 126.469L94.25 163.969L169.25 88.9687L156.031 75.75L94.25 137.531Z"
fill="black"
/>
<path
d="M113 263.25L55.1001 232.378C38.5938 223.597 24.7904 210.486 15.1712 194.454C5.552 178.421 0.48019 160.072 0.500058 141.375V19.5C0.505022 14.5287 2.48206 9.76246 5.99729 6.24723C9.51252 2.732 14.2788 0.754964 19.2501 0.75H206.75C211.721 0.754964 216.488 2.732 220.003 6.24723C223.518 9.76246 225.495 14.5287 225.5 19.5V141.375C225.52 160.072 220.448 178.421 210.829 194.454C201.21 210.486 187.406 223.597 170.9 232.378L113 263.25ZM19.2501 19.5V141.375C19.2345 156.673 23.3854 171.687 31.2572 184.804C39.129 197.922 50.4245 208.648 63.9313 215.831L113 241.997L162.069 215.841C175.577 208.656 186.873 197.929 194.745 184.81C202.617 171.69 206.767 156.675 206.75 141.375V19.5H19.2501Z"
fill="black"
/>
</svg>
</div>
<p className="mb-0 text-[12px] font-bold">
گارانتی{" "}
<small className=" text-primary-500 text-[12px]">اصالت</small>{" "}
و{" "}
<small className=" text-primary-500 text-[12px]">
سلامت فیزیکی کالا
</small>
</p>
</div>
<div className="w-6/12 mx-auto h-[1px] bg-gray-200 mt-4"></div>
<div className=" mt-4 flex justify-between ">
{true ? (
<div className="flex justify-end">
<div className="mb-0 font-bold text-sm absolute mt-[-11px] ml-[0px] right-0 mr-[13px] text-red-600 flex rtl">
<del>
<PersianNumber
number={(data?.product?.cost / 10).toLocaleString()}
style={"text-[13px] opacity-40 "}
/>
</del>
</div>
<div className="flex rtl mt-[8px]">
{" "}
<p className="mb-0 font-bold">
<PersianNumber
number={(
data?.product?.costWithDiscount / 10
).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[3px]">تومان</small>
</div>
</div>
) : (
<div className="flex rtl mt-[3px]">
{" "}
<p className="mb-0 font-bold text-lg">
<PersianNumber
number={(data?.cost / 10).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[6px]">تومان</small>
</div>
)}
<AddToCart data={data?.product} theme={2} />
</div>
</div>
</div>
<div className="lg:col-span-6">
<div className="xs:px-[15px] lg:px-[100px]">
<div className="bg-gray-200 rounded-full xs:p-1 lg:p-3 flex w-fit sticky top-0 ">
<div
className={` rounded-full xs:p-2 lg:p-3 cursor-pointer tr03 ${
productBarDetail == 0 ? "bg-primary-500 text-gray-100" : ""
}`}
onClick={() => {
setProductBarDetail(0);
scrollToSection("section0");
}}
>
<p className=" xs:hidden lg:block mb-0 text-[12px] ">
مشخصات محصول
</p>
<p className=" xs:block lg:hidden mb-0 text-[12px]">مشخصات</p>
</div>
<div
className={` rounded-full xs:p-2 lg:p-3 cursor-pointer tr03 ${
productBarDetail == 1 ? "bg-primary-500 text-gray-100" : ""
}`}
onClick={() => {
setProductBarDetail(1);
scrollToSection("section1");
}}
>
<p className="mb-0 text-[13px] ">روش استفاده</p>
</div>
<div
className={` rounded-full xs:p-2 lg:p-3 cursor-pointer tr03 ${
productBarDetail == 2 ? "bg-primary-500 text-gray-100" : ""
}`}
onClick={() => {
setProductBarDetail(2);
scrollToSection("section2");
}}
>
<p className="mb-0 text-[13px] ">نقد و بررسی</p>
</div>
<div
className={` rounded-full xs:p-2 lg:p-3 cursor-pointer tr03 ${
productBarDetail == 3 ? "bg-primary-500 text-gray-100" : ""
}`}
onClick={() => {
setProductBarDetail(3);
scrollToSection("section3");
}}
>
<p className=" xs:hidden lg:block mb-0 text-[13px] ">
دیدگاه مخاطبان
</p>
<p className=" xs:block lg:hidden mb-0 text-[13px] ">
مخاطبان
</p>
</div>
</div>
<div id="section0">
<h3 className=" text-sm text-gray-400 mt-7 mb-2">
مشخصات محصول
</h3>
<div className="min-w-[200px] mt-5 rounded-xl overflow-hidden border rtl ">
{product?.specifications?.map((e, index) => (
<div
className={
index % 2 === 0 ? "bg-gray-50 p-3" : "bg-gray-100 p-3"
}
key={index}
>
<p className="mb-0 text-sm text-gray-600">
{e.title}:
<small className="text-sm text-gray-800 font-bold ">
{" "}
{e.value}{" "}
</small>
</p>
</div>
))}
</div>
</div>
<div id="section1">
<h3 className=" text-sm text-gray-400 mt-7 mb-2">
روش استفاده
</h3>
<div className="border p-5 rounded-lg">
<div className="flex justify-center py-5">
<div className="bg-white shadow w-fit rounded-full text-sm p-4">
چیزی یافت نشد
</div>
</div>
</div>{" "}
</div>
<div id="section2">
<h3 className=" text-sm text-gray-400 mt-7 mb-2">
نقد و برسی{" "}
</h3>
<div className="border p-5 rounded-lg">
<div className="flex justify-center py-5">
<div className="bg-white shadow w-fit rounded-full text-sm p-4">
چیزی یافت نشد
</div>
</div>
</div>{" "}
</div>
<div id="section3">
<h3 className=" text-sm text-gray-400 mt-7 mb-2">
دیدگاه مخاطبان{" "}
</h3>
<div className="border p-5 rounded-lg">
<div className="flex justify-center py-5">
<div className="bg-white shadow w-fit rounded-full text-sm p-4">
چیزی یافت نشد
</div>
</div>
</div>{" "}
</div>
</div>
<div className="xs:block lg:hidden sticky bottom-0 ">
<div className="w-full bg-[white] p-2 border-t-[1px] border-gray-100 mt-[30px]">
<div className="py-4 flex ltr justify-between px-4 relative">
{product?.hasDiscount ? (
<>
<p className="mb-0 font-bold text-sm absolute ml-[33px] opacity-30 mt-[-5px] text-red-600">
<del>
<PersianNumber
number={(data?.product?.cost / 10).toLocaleString()}
style="!text-[11px]"
/>
</del>
</p>
<div className="flex rtl mt-[8px]">
{" "}
<p className="mb-0 font-bold">
<PersianNumber
number={(
data?.product?.costWithDiscount / 10
).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[3px]">تومان</small>
</div>
</>
) : (
<div className="flex rtl mt-[3px]">
{" "}
<p className="mb-0 font-bold text-lg">
<PersianNumber
number={(data?.product?.cost / 10).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[6px]">تومان</small>
</div>
)}
<AddToCart data={data?.product} theme={2} />
</div>
</div>
</div>
</div>
</div>
</div>
<Footer />
</>
);
};
export default ProductData;

View File

@ -0,0 +1,583 @@
"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;

View File

@ -0,0 +1,35 @@
import Image from "next/image";
import Link from "next/link";
import PersianNumber from "plugins/PersianNumber";
import React from "react";
const Cart = ({ mainImage, title, categoryName, slug, id, summery }) => {
return (
<Link href={`/blogs/${id}/${slug}`}>
<div className="bg-gray-100 rounded-3xl p-2 ">
<div className="w-full h-[200px] overflow-hidden rounded-3xl">
<div>
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/Images/Med/${mainImage}`}
width={500}
height={500}
className="w-full h-[200px] object-cover"
/>
</div>
</div>
<div className="mt-3 text-right">
<h3 className=" text-gray-500 font-medium">{title} </h3>
<p className="mb-0 text-gray-400 text-sm text-right">{summery}</p>
<div className="flex">
<div className="bg-primary-200 rounded-2xl p-1 px-4 mt-3">
<p className="mb-0 text-sm text-gray-200">{categoryName}</p>
</div>
</div>
</div>
</div>
</Link>
);
};
export default Cart;

View File

@ -0,0 +1,120 @@
"use client";
import AppContext from "@ctx/AppContext";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import PersianNumber from "plugins/PersianNumber";
import { useContext, useEffect, useState } from "react";
const PaginationBlogs = ({ totalPage }) => {
const CTX = useContext(AppContext);
const searchParams = useSearchParams();
const pager = totalPage;
const pathname = usePathname();
const router = useRouter();
const [currentPageIndex, setCurrentPageIndex] = useState(
Number(searchParams.get("page")) ? Number(searchParams.get("page")) : 0
);
useEffect(() => {
setCurrentPageIndex(
Number(searchParams.get("page")) ? Number(searchParams.get("page")) : 0
);
}, [searchParams]);
const renderPaginationButtons = () => {
const buttons = [];
const totalPages = pager?.totalPage;
const maxButtonsToShow = 7; // Maximum buttons to show
// If total pages are greater than maxButtonsToShow
if (totalPages > maxButtonsToShow) {
// Show buttons for the first page
buttons.push(renderPageButton(0));
// If current page is not too close to the start, show ellipsis
if (currentPageIndex > 2) {
buttons.push(renderEllipsis());
}
// Calculate the start index for buttons
const start = Math.max(1, currentPageIndex - 2);
// Calculate the end index for buttons
const end = Math.min(currentPageIndex + 3, totalPages - 1);
// Show buttons for pages within range
for (let i = start; i <= end; i++) {
buttons.push(renderPageButton(i));
}
// If current page is not too close to the end, show ellipsis
if (currentPageIndex < totalPages - 4) {
buttons.push(renderEllipsis());
}
// Show button for the last page
buttons.push(renderPageButton(totalPages - 1));
} else {
// Show buttons for all pages
for (let i = 0; i < totalPages; i++) {
buttons.push(renderPageButton(i));
}
}
return buttons;
};
const renderPageButton = (pageIndex) => (
<div
key={pageIndex}
className={`w-[25px] h-[25px] rounded-full tr03 bg-${
currentPageIndex === pageIndex ? "secondary-500" : "primary-200"
} mx-1 cursor-pointer`}
onClick={() => handlePageClick(pageIndex)}
>
<p className="mb-0 text-center pt-[2px] text-white">
<PersianNumber number={pageIndex + 1} style=" !text-[14px] " />
</p>
</div>
);
const renderEllipsis = () => (
<div key="ellipsis" className="mx-1">
...
</div>
);
const handlePageClick = (pageIndex) => {
setCurrentPageIndex(pageIndex);
//
// CTX.fetchProducts(
// pageIndex,
// props.id[0] != 0 ? props.id[0] : "",
// props.selectedBrands,
// props.isChecked,
// props.rangePrice,
// props.rangePrice,
// props.sortBy != -1 ? props.sortBy : "",
// props.isRangePrice,
// true //pagination say or not
// );
const nextPage = pageIndex;
const params = new URLSearchParams(searchParams.toString());
params.set("page", nextPage);
router.push(`${pathname}?${params}`);
// CTX.setStopProducts(true);
// Your fetchProducts function call here
};
return (
<div className="flex justify-center rtl mb-10">
<div className="w-[25px] h-[25px] rounded-full bg-primary-300 mx-2">
{/* Previous page button */}
</div>
{renderPaginationButtons()}
<div className="w-[25px] h-[25px] rounded-full bg-primary-300 mx-2">
{/* Next page button */}
</div>
</div>
);
};
export default PaginationBlogs;

View File

@ -0,0 +1,20 @@
h2 {
color: rgb(0, 49, 155);
font-weight: 700;
margin-top: 15px;
margin-bottom: 2px;
}
p {
color: rgb(54, 54, 54);
font-weight: 400;
}
h3 {
color: rgb(216, 16, 16);
font-weight: 600;
margin-top: 15px;
margin-bottom: 2px;
margin-right: 10px;
}

View File

@ -0,0 +1,36 @@
"use client";
import Image from "next/image";
import React, { useEffect, useState } from "react";
import Footer from "@comp/Footer/page";
import Navbar from "@comp/Navbar/page";
const BlogData = ({ data }) => {
return (
<div>
<Navbar />
<div className="xs:px-3 md:px-5 md:container md:mx-auto mb-10">
<div className="grid grid-cols-1 gap-7 rtl">
<div className=" mt-10 ">
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/Images/Med/${data.mainImage}`}
width={500}
height={500}
className="w-[400px]"
/>
<h1 className=" font-bold text-right xs:text-[20px] lg:text-[40px]">
{data.title}
</h1>
<div></div>
<div dangerouslySetInnerHTML={{ __html: data.content }} />
</div>
</div>
</div>
<Footer />
</div>
);
};
export default BlogData;

View File

@ -0,0 +1,81 @@
"use client";
import Footer from "@comp/Footer/page";
import Navbar from "@comp/Navbar/page";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import PersianNumber from "plugins/PersianNumber";
import React from "react";
import Cart from "../BlogComponents/Cart";
import PaginationBlogs from "../BlogComponents/PaginationBlogs";
const BlogsData = ({ dataCaetgories, data }) => {
const pathname = usePathname();
const searchParams = useSearchParams();
const router = useRouter();
const searchParamsCurrentId = searchParams.get("blogCategoryId");
const handleGoCategories = (id) => {
// CTX.setIsChecked(!isChecked);
const params = new URLSearchParams(searchParams.toString());
params.set("blogCategoryId", id);
params.set("page", "0");
router.push(`${pathname}?${params}`);
};
return (
<div>
<Navbar />
<div className="xs:px-3 md:px-5 md:container md:mx-auto mb-10">
<div className="grid xs:grid-cold-1 md:grid-cols-4 gap-7 ltr mt-10">
<div className="xs:xol-span-1 lg:col-span-3">
<div className="grid xs:grid-cold-1 md:grid-cols-3 gap-7 rtl ">
{data?.blogs?.map((e) => (
<Cart
categoryName={e.categoryName}
title={e.title}
mainImage={e.mainImage}
slug={e.slug}
id={e.id}
summery={e.summery}
/>
))}
</div>
<div className="mt-20">
<PaginationBlogs totalPage={data?.pager} />
</div>
</div>
<div className="bg-gray-100 rounded-2xl p-5 relative h-fit rtl xs:w-full">
<h3 className="text-center font-medium mb-5"> دسته بندی ها</h3>
<div>
{dataCaetgories?.map((e) => (
<div onClick={() => handleGoCategories(e.id)}>
<div className="flex p-2">
<div className="w-3 h-3 rounded-full bg-secondary-900 mt-1 ml-2"></div>
<p className="mb-0"> {e.name}</p>
<small className="text-sm mx-2 mt-[2px]">
(
<PersianNumber
number={e.blogCount}
style="text-primary-900 "
/>
)
</small>
</div>
</div>
))}
</div>
</div>
</div>
</div>
<Footer />
</div>
);
};
export default BlogsData;

View File

@ -0,0 +1,85 @@
"use client";
import AppContext from "@ctx/AppContext";
import Image from "next/image";
import Link from "next/link";
import PersianNumber from "plugins/PersianNumber";
import { useContext } from "react";
import logo from "../../../public/images/logo.png";
import AddToCart from "../Components/AddToCart/page";
import hyphenateString from "plugins/HyphenateString/page";
const CardCart = ({ data }) => {
const CTX = useContext(AppContext);
const hyphenatedName = hyphenateString(data.persianName);
return (
<div className="group border-t-[1px] border-gray-100 w-full hover:bg-white z-40 tr03 flex rtl pt-2">
<Link href={`/products/${data.id}/${hyphenatedName}`}>
<div className=" h-fit ">
{!!data.mainImage ? (
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${data.mainImage}`}
width={100}
height={100}
className="xs:!w-[110px] lg:!w-[130px] mx-auto !object-cover"
alt={`${data.persianName} - ${data.englishName}`}
/>
) : (
<div className="xs:!w-[85px] lg:!w-[85px] ">
<Image
src={logo}
className="xs:!w-[70px] lg:!w-[70px] mx-auto !object-cover opacity-25 mt-5"
alt="وسمه"
/>
</div>
)}
</div>
</Link>
<div className="p-3 text-right w-full">
<Link href={`/products/${data.id}/${hyphenatedName}`}>
<p className="mb-0 xs:text-[12px] lg:text-[11px] xl:text-[15px] max-h-[50px] tr03 ">
{data?.persianName}
</p>
</Link>
<div className=" rounded-full flex ltr pt-2 mt-2 w-full">
<AddToCart data={data} theme={1} />
<div className="w-full text-right rounded-full">
{data?.hasDiscount ? (
<div className="flex justify-end relative">
<p className="mb-0 font-bold text-sm absolute opacity-40 mt-[-7px] ml-[20px] text-red-600">
<del>
<PersianNumber
number={(data?.cost / 10).toLocaleString()}
style={"text-[13px]"}
/>
</del>
</p>
<div className="flex rtl mt-[8px]">
{" "}
<p className="mb-0 font-bold">
<PersianNumber
number={(data?.costWithDiscount / 10).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[3px]">تومان</small>
</div>
</div>
) : (
<div className="flex rtl mt-[3px]">
{" "}
<p className="mb-0 font-bold text-lg">
<PersianNumber number={(data?.cost / 10).toLocaleString()} />
</p>
<small className="mr-1 mt-[6px]">تومان</small>
</div>
)}
</div>
</div>
</div>
</div>
);
};
export default CardCart;

View File

@ -0,0 +1,124 @@
"use client";
import AppContext from "@ctx/AppContext";
import Image from "next/image";
import Link from "next/link";
import PersianNumber from "plugins/PersianNumber";
import { useContext } from "react";
import logo from "../../../public/images/logo.png";
import AddToCart from "../Components/AddToCart/page";
import hyphenateString from "plugins/HyphenateString/page";
const CardCategories = ({ data }) => {
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
const hyphenatedName = hyphenateString(data.persianName);
return (
<div className="group border border-gray-50 w-full hover:bg-white z-40 tr03">
<>
<div
className={` tr03 py-2 overflow-hidden xs:h-[200px] lg:h-[230px] ${
1 == 1 ? " rounded-xl" : " opacity-70"
}`}
// key={index}
// onClick={() => handleRoutineShiftPlanWithDay(index)}
>
{data.hasDiscount && (
<div className="absolute m-3 ">
<div className="w-fit rounded-lg bg-red-600 overflow-hidden px-1 ">
<p className="mb-0 text-[10px] text-white pt-[3px] ">
<PersianNumber
number={data.discountPercent}
style={"!text-[12px]"}
/>
<small className="text-[10px] ml-1">%</small>
</p>
</div>
</div>
)}
{data.hasDiscount && (
<div className=" m-3 ">
<div className="absolute mt-[30px] ">
<div className="w-fit rounded-lg bg-secondary-600 overflow-hidden px-2 !py-0 h-fit ">
<p className="mb-0 text-white text-[10px] ">اصالت کالا</p>
</div>
</div>{" "}
</div>
)}
<Link href={`/products/${data.id}/${hyphenatedName}`}>
<div className="w-full h-fit flex justify-center ">
{!!data.mainImage ? (
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${data.mainImage}`}
width={200}
height={200}
className="xs:!w-[110px] lg:!w-[130px] mx-auto"
alt={`${data.persianName} - ${data.englishName}`}
/>
) : (
<div className="xs:!w-[85px] lg:!w-[85px] h-[90px] mt-10 ">
<Image
src={logo}
className="xs:!w-[70px] lg:!w-[70px] mx-auto opacity-25 mt-5"
alt="وسمه"
/>
</div>
)}
</div>
<div className="p-3 text-right">
<p className="mb-0 xs:text-[12px] lg:text-[12px] xl:text-[15px] max-h-[50px] tr03 ">
{data.persianName}{" "}
</p>
{data.stock <= 3 && data.stock !== 0 && (
<p className="mb-0 text-[11px] text-red-600 font-medium">
{data.stock} عدد موجود انبار
</p>
)}
</div>
</Link>
</div>
</>
<div className=" rounded-full flex ltr p-3 mt-2">
<div className="flex w-full">
<AddToCart data={data} theme={1} />
</div>
<div className="w-full text-right rounded-full">
{data?.hasDiscount ? (
<div className="flex justify-end">
<p className="mb-0 font-bold text-sm absolute opacity-40 mt-[-7px] ml-[20px] text-red-600">
<del>
<PersianNumber
number={(data?.cost / 10).toLocaleString()}
style={"text-[13px]"}
/>
</del>
</p>
<div className="flex rtl mt-[8px]">
{" "}
<p className="mb-0 font-bold">
<PersianNumber
number={(data?.costWithDiscount / 10).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[3px]">تومان</small>
</div>
</div>
) : (
<div className="flex rtl mt-[3px]">
{" "}
<p className="mb-0 font-bold text-lg">
<PersianNumber number={(data?.cost / 10).toLocaleString()} />
</p>
<small className="mr-1 mt-[6px]">تومان</small>
</div>
)}
</div>
</div>
</div>
);
};
export default CardCategories;

View File

@ -0,0 +1,100 @@
"use client";
import AppContext from "@ctx/AppContext";
import Image from "next/image";
import Link from "next/link";
import PersianNumber from "plugins/PersianNumber";
import { useContext } from "react";
import logo from "../../../public/images/logo.png";
import AddToCart from "../Components/AddToCart/page";
import hyphenateString from "plugins/HyphenateString/page";
const CardCategoriesMobile = ({ data }) => {
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
const hyphenatedName = hyphenateString(data.persianName);
return (
<div className="group border-t-[1px] border-gray-200 w-full hover:bg-white z-40 tr03 flex rtl pt-2 px-3">
<Link href={`/products/${data.id}/${hyphenatedName}`}>
<div className=" h-fit ">
{!!data.mainImage ? (
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${data.mainImage}`}
width={200}
height={200}
className="xs:!w-[110px] lg:!w-[130px] mx-auto "
alt={`${data.persianName} - ${data.englishName}`}
/>
) : (
<div className="xs:!w-[85px] lg:!w-[85px] ">
<Image
src={logo}
className="xs:!w-[70px] lg:!w-[70px] mx-auto opacity-25 mt-5"
alt="وسمه"
/>
</div>
)}
</div>
</Link>
<div className="p-3 text-right w-full">
{" "}
<Link href={`/products/${data.id}/${hyphenatedName}`}>
<p className="mb-0 xs:text-[12px] lg:text-[11px] xl:text-[15px] max-h-[50px] tr03 ">
{data?.persianName}
</p>
</Link>
{data.stock <= 3 && data.stock !== 0 && (
<p className="mb-0 text-[11px] text-red-600 font-medium">
{data.stock} عدد موجود انبار
</p>
)}
<div className=" rounded-full flex ltr pt-2 mt-2 w-full">
<AddToCart data={data} theme={1} />{" "}
<div className="w-full text-right rounded-lg">
{data?.hasDiscount ? (
<div className="flex justify-end">
<div className="mb-0 font-bold text-sm absolute mt-[-7px] ml-[20px] text-red-600 flex rtl">
<del>
<PersianNumber
number={(data?.cost / 10).toLocaleString()}
style={"text-[13px] opacity-40 "}
/>
</del>
<span className="bg-red-500 mb-0 px-1 text-[9px] text-white rounded-full mx-2 h-fit ">
<PersianNumber
number={data?.discountPercent}
style={"text-white !text-[10px] mr-1 "}
/>
%
</span>
</div>
<div className="flex rtl mt-[8px]">
{" "}
<p className="mb-0 font-bold">
<PersianNumber
number={(data?.costWithDiscount / 10).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[3px]">تومان</small>
</div>
</div>
) : (
<div className="flex rtl mt-[3px]">
{" "}
<p className="mb-0 font-bold text-lg">
<PersianNumber number={(data?.cost / 10).toLocaleString()} />
</p>
<small className="mr-1 mt-[6px]">تومان</small>
</div>
)}
</div>
</div>
</div>
</div>
);
};
export default CardCategoriesMobile;

View File

@ -0,0 +1,122 @@
"use client";
import React, { useContext } from "react";
import { SwiperSlide } from "swiper/react";
import logo from "../../../public/images/logo.png";
import Image from "next/image";
import PersianNumber from "plugins/PersianNumber";
import AppContext from "@ctx/AppContext";
import AddToCart from "../Components/AddToCart/page";
import Link from "next/link";
import hyphenateString from "plugins/HyphenateString/page";
const CardNormal = ({ data, priority }) => {
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
// const hyphenatedName = hyphenateString(data.persianName);
return (
<>
{" "}
<>
<Link href={`/products/${data.id}`}>
<div
className={` tr03 py-2 overflow-hidden xs:h-[270px] lg:h-[270px] border border-gray-200 ${
1 == 1 ? "bg-white rounded-xl rounded-tl-[40px]" : " opacity-70"
}`}
// key={index}
// onClick={() => handleRoutineShiftPlanWithDay(index)}
>
{data.hasDiscount && (
<div className="absolute m-3 ">
<div className="w-fit rounded-lg bg-red-600 overflow-hidden px-1 ">
<p className="mb-0 text-[10px] text-white pt-[3px] ">
<PersianNumber
number={data.discountPercent}
style={"!text-[10px]"}
/>
<small className="text-[10px] ml-1">%</small>
</p>
</div>
</div>
)}
<div className="w-full h-fit flex justify-center ">
{!!data.mainImage ? (
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${data.mainImage}`}
width={200}
height={200}
className="xs:!w-[110px] lg:!w-[130px] mx-auto"
priority={!!priority}
alt={`${data.persianName} - ${data.englishName}`}
/>
) : (
<div className="xs:!w-[85px] lg:!w-[85px] h-[90px] xs:mt-5 lg:mt-10 ">
<Image
src={logo}
className="xs:!w-[70px] lg:!w-[70px] mx-auto opacity-25 mt-5"
alt="وسمه"
/>
</div>
)}
</div>
<div className="p-3 text-right">
<p className="mb-0 text-[14px] max-h-[44px] overflow-hidden ">
{data.persianName}
</p>
{data.stock <= 3 && data.stock !== 0 && (
<p className="mb-0 text-[11px] text-red-600 font-medium">
{data.stock} عدد موجود انبار
</p>
)}
</div>
</div>
</Link>
</>
<div className="absolute w-full bottom-0 ">
<div className="bg-gray-100 rounded-t-3xl flex ltr mt-2 border border-gray-100 p-2 ">
<div className="flex w-full">
<AddToCart data={data} theme={1} />
</div>
<div className="w-full text-right rounded-full pr-2">
{data?.hasDiscount ? (
<>
<p className="mb-0 font-bold text-sm absolute right-3 opacity-30 mt-[-5px] text-red-600">
<del>
<PersianNumber
number={(data?.cost / 10).toLocaleString()}
style="!text-[11px]"
/>
</del>
</p>
<div className="flex rtl mt-[8px]">
{" "}
<p className="mb-0 font-bold">
<PersianNumber
number={(data?.costWithDiscount / 10).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[3px]">تومان</small>
</div>
</>
) : (
<div className="flex rtl mt-[3px]">
{" "}
<p className="mb-0 font-bold text-lg">
<PersianNumber number={(data?.cost / 10).toLocaleString()} />
</p>
<small className="mr-1 mt-[6px]">تومان</small>
</div>
)}
</div>
</div>
</div>
</>
);
};
export default CardNormal;

View File

@ -0,0 +1,140 @@
"use client";
import { useContext } from "react";
import logo from "../../../public/images/logo.png";
import AppContext from "@ctx/AppContext";
import Image from "next/image";
import Link from "next/link";
import PersianNumber from "plugins/PersianNumber";
import AddToCart from "../Components/AddToCart/page";
import hyphenateString from "plugins/HyphenateString/page";
const CardSurprise = ({ data, priority }) => {
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
const hyphenatedName = hyphenateString(data.persianName);
return (
<>
{" "}
<>
<div
className={` tr03 py-2 overflow-hidden xs:h-[340px] lg:h-[340px] border border-gray-100 relative ${
1 == 1 ? "bg-white rounded-xl rounded-tl-[40px]" : " opacity-70"
}`}
// key={index}
// onClick={() => handleRoutineShiftPlanWithDay(index)}
>
{data.hasDiscount && (
<div className="absolute m-3 ">
<div className="w-fit rounded-lg bg-red-600 overflow-hidden px-1 ">
<p className="mb-0 text-[10px] text-white pt-[3px] ">
<PersianNumber
number={data.discountPercent}
style={"!text-[10px]"}
/>
<small className="text-[10px] ml-1">%</small>
</p>
</div>
</div>
)}
<>
<Link href={`/products/${data.id}/${hyphenatedName}`}>
<div className="w-full h-fit flex justify-center mt-5 ">
{!!data.mainImage ? (
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${data.mainImage}`}
width={100}
height={100}
className="xs:!w-[110px] lg:!w-[130px] mx-auto !object-cover"
alt={`${data.persianName} - ${data.englishName}`}
priority={!!priority}
/>
) : (
<div className="xs:!w-[85px] lg:!w-[85px] h-[90px] mt-10 ">
<Image
src={logo}
className="xs:!w-[70px] lg:!w-[70px] mx-auto !object-cover opacity-25 mt-5"
alt="وسمه"
/>
</div>
)}
</div>
<div className="p-3 text-right">
<p className="mb-0 text-[14px] max-h-[44px] overflow-hidden ">
{data.persianName} asdsadsadadasd asdadasdas
</p>
{data.stock <= 3 && data.stock !== 0 && (
<p className="mb-0 text-[11px] text-red-600 font-medium">
{data.stock} عدد موجود انبار
</p>
)}
</div>
</Link>
</>
<div className="px-2 mt-2 ">
<div className="bg-gray-300 p-2 rounded-full w-full"></div>
<div className="absolute w-full mt-[-16px]">
<div className="bg-green-700 p-2 rounded-full w-3/12"></div>
</div>
<p className="mb-0 text-[11px] mt-1 text-red-500 mr-2">
<PersianNumber number={21} style={"!text-[11px] ml-1"} />
عدد در انبار وجود دارد
</p>
</div>
<div className="absolute w-full bottom-0 ">
<div className="bg-gray-100 rounded-t-3xl flex ltr mt-2 border border-gray-100 p-2 ">
<div className="flex w-full">
<AddToCart data={data} theme={1} />
</div>
<div className="w-full text-right rounded-full pr-2">
{data?.hasDiscount ? (
<>
<p className="mb-0 font-bold text-sm absolute right-3 opacity-30 mt-[-5px] text-red-600">
<del>
<PersianNumber
number={(data?.cost / 10).toLocaleString()}
style="!text-[11px]"
/>
</del>
</p>
<div className="flex rtl mt-[8px]">
{" "}
<p className="mb-0 font-bold">
<PersianNumber
number={(
data?.costWithDiscount / 10
).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[3px]">تومان</small>
</div>
</>
) : (
<div className="flex rtl mt-[3px]">
{" "}
<p className="mb-0 font-bold text-lg">
<PersianNumber
number={(data?.cost / 10).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[6px]">تومان</small>
</div>
)}
</div>
</div>
</div>
</div>
</>
</>
);
};
export default CardSurprise;

View File

@ -0,0 +1,110 @@
"use client";
import AppContext from "@ctx/AppContext";
import PersianNumber from "plugins/PersianNumber";
import { useContext } from "react";
const AddToCart = ({ data, theme }) => {
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
const handleAddItemToCart = (id) => {
CTX.AddItemToCart(
data?.id,
data?.persianName,
data?.cost,
data?.costWithDiscount,
data?.mainImage,
data?.hasDiscount,
data?.maxOrderCount
);
};
return (
<>
{theme == 1 && (
<>
{" "}
{data?.stock == 0 ? (
<div className="bg-gray-200 w-full h-fit p-2 rounded-xl">
<p className="mb-0 text-[12px] text-center ">اتمام موجودی</p>
</div>
) : (
<div className="flex">
{!cart.find((item) => item.id === data?.id) ? (
<div className="w-[25px] h-[25px] bg-gray-100 overflow-hidden rounded-lg text-center p-1 m-1 cursor-pointer">
<div onClick={() => handleAddItemToCart()}>
<p className="mb-0 text-[25px] mt-[-10px]">+</p>
</div>
</div>
) : (
<div className="flex rtl bg-gray-50 p-1 h-fit rounded-lg">
<div
className="w-[25px] h-[25px] bg-gray-200 overflow-hidden rounded-lg text-center cursor-pointer "
onClick={() => handleAddItemToCart()}
>
<p className="mb-0 text-[20px] mt-[-2px]">+</p>
</div>
<p className="mb-0 mx-2 mt-1 text-sm ">
<PersianNumber
number={cart.find((item) => item.id === data?.id).count}
/>
</p>
<div
className="w-[25px] h-[25px] bg-red-200 overflow-hidden rounded-lg text-center cursor-pointer "
onClick={() => CTX.RemoveItemFromCart(data?.id)}
>
<p className="mb-0 text-[20px] mt-[-2px]">-</p>
</div>
</div>
)}
</div>
)}
</>
)}
{theme == 2 && (
<>
{" "}
{data?.stock == 0 ? (
<div className="bg-gray-200 w-fit px-5 h-fit p-2 rounded-xl">
<p className="mb-0 text-[12px] text-center ">اتمام موجودی</p>
</div>
) : (
<div className="flex">
{!cart.find((item) => item.id === data?.id) ? (
<div className=" bg-primary-500 overflow-hidden rounded-lg text-center p-1 px-5 cursor-pointer">
<div onClick={() => handleAddItemToCart()}>
<p className="mb-0 text-sm text-white xs:mt-[6px] lg:mt-[2px]">
افزودن به سبد
</p>
</div>
</div>
) : (
<div className="flex rtl bg-gray-50 p-1 h-fit rounded-lg">
<div
className="w-[25px] h-[25px] bg-gray-200 overflow-hidden rounded-lg text-center cursor-pointer "
onClick={() => handleAddItemToCart()}
>
<p className="mb-0 text-[20px] mt-[-2px]">+</p>
</div>
<p className="mb-0 mx-2 mt-1 text-sm ">
<PersianNumber
number={cart.find((item) => item.id === data?.id).count}
/>
</p>
<div
className="w-[25px] h-[25px] bg-red-200 overflow-hidden rounded-lg text-center cursor-pointer "
onClick={() => CTX.RemoveItemFromCart(data?.id)}
>
<p className="mb-0 text-[20px] mt-[-2px]">-</p>
</div>
</div>
)}
</div>
)}
</>
)}
</>
);
};
export default AddToCart;

View File

@ -0,0 +1,43 @@
"use client";
import PersianNumber from "plugins/PersianNumber";
const NavBarDownCart = ({ calculateTotalCost, event, permissionGoPay }) => {
return (
<div className="relative ">
<div className="fixed w-full bottom-[0] p-4 bg-body-100 border-t-[1px] border-gray-200 flex rtl">
{/* <Link href={"/cart/checkout"} className="w-full"> */}
{permissionGoPay ? (
<button
className="btn btn-primary rounded-lg text-sm w-full"
onClick={event}
>
ادامه فرایند خرید
</button>
) : (
<button className="btn btn-primary rounded-lg text-sm w-full opacity-40">
ادامه فرایند خرید
</button>
)}
{/* </Link> */}
<div className="w-full mx-2">
<p className="mb-0 text-sm font-semibold text-primary-500 text-center">
قابل پرداخت{" "}
</p>
<div className="flex justify-center">
<p className="mb-0 ">
<PersianNumber number={calculateTotalCost?.toLocaleString()} />
</p>
<small className="text-gray-500 text-[12px] mt-1 mx-1">
{" "}
تومان
</small>
</div>
</div>
</div>
</div>
);
};
export default NavBarDownCart;

View File

@ -0,0 +1,299 @@
"use client";
import AppContext from "@ctx/AppContext";
import { Switch } from "@headlessui/react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import PersianNumber from "plugins/PersianNumber";
import RangeSlider from "plugins/RangeSlider/page";
import { useContext, useEffect, useRef } from "react";
const FilterCategory = ({
id,
selectedBrands,
isChecked,
rangePrice,
sortBy,
isRangePrice,
theme,
specialOffer,
filter,
}) => {
const pathname = usePathname();
const searchParams = useSearchParams();
const CTX = useContext(AppContext);
const brands = CTX.state.brands;
const pageGetProducts = CTX.state.pageGetProducts;
const isFirstRender = useRef(true);
const router = useRouter();
const handleCheckboxChange = () => {
// CTX.setIsChecked(!isChecked);
const params = new URLSearchParams(searchParams.toString());
if (!isChecked) {
params.set("isActive", Number(!isChecked));
} else {
params.delete("isActive");
}
params.set("page", "0");
router.push(`${pathname}?${params}`);
};
const handleSpecialOfferChange = () => {
// CTX.setIsChecked(!isChecked);
const params = new URLSearchParams(searchParams.toString());
if (!specialOffer) {
params.set("specialOffer", Number(!specialOffer));
} else {
params.delete("specialOffer");
}
params.set("page", "0");
router.push(`${pathname}?${params}`);
};
const handleRangeChange = (values) => {
// CTX.setIsRangePrice(true);
// CTX.setRangePrice(values);
//
const params = new URLSearchParams(searchParams.toString());
params.set("minPrice", values[0]);
params.set("maxPrice", values[1]);
params.set("page", "0");
router.push(`${pathname}?${params}`, { scroll: false });
};
const handleFilterBrand = (name, id) => {
const params = new URLSearchParams(searchParams.toString());
let brandIds = params.get("brandIds")
? Array.from(params.get("brandIds").split(",") ?? [])
: [];
//
if (brandIds.includes(id)) {
brandIds = brandIds.filter((brandId) => brandId !== id);
if (brandIds.length === 0) {
params.delete("brandIds");
router.push(`${pathname}?${params}`);
return;
}
} else {
brandIds.push(id);
}
params.set("brandIds", brandIds.join(","));
params.set("page", "0");
router.push(`${pathname}?${params}`);
// Check if the brand is already selected
// const isBrandSelected = selectedBrands.some((brand) => brand.id === id);
// if (!isBrandSelected) {
// // If the brand is not already selected, add it to the state
// CTX.setSelectedBrands((prevBrands) => [...prevBrands, { name, id }]);
// } else {
// // If the brand is already selected, remove it from the state
// CTX.setSelectedBrands((prevBrands) =>
// prevBrands.filter((brand) => brand.id !== id)
// );
// }
};
const handleRangePriceFilter = () => {
CTX.fetchProducts(
0,
id[0],
selectedBrands,
isChecked,
rangePrice[0],
rangePrice[1],
sortBy != -1 ? sortBy : "",
isRangePrice
);
};
// useEffect(() => {
// if (isFirstRender.current) {
// isFirstRender.current = false;
// return;
// }
// CTX.fetchProducts(
// 0,
// id[0] != 0 ? id[0] : "",
// selectedBrands,
// isChecked,
// rangePrice[0],
// rangePrice[1],
// sortBy != -1 ? sortBy : "",
// isRangePrice
// );
// }, [CTX.state.selectedBrands, CTX.state.isChecked]);
// useEffect(() => {
// CTX.setRangePrice([
// filter?.price?.minimumValue,
// filter?.price?.maximumValue,
// ]);
// }, [filter]);
return (
<div
className={` rtl ${
theme == 2 ? "col-span-full" : "lg:col-span-2 xl:col-span-1 ml-4"
}`}
>
<div className="sticky top-20 ...">
<div className=" w-full">
<div
className={` border-gray-300 rounded-lg ${
theme == 2 ? "bg-gray-100" : "bg-gray-50"
} `}
>
<div className=" p-5 flex justify-between">
<p className="mb-0 lg:text-sm xl:text-base">برند</p>
<div>
<svg
width="15"
height="15"
viewBox="0 0 151 89"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mt-1"
>
<path
d="M13.1436 14.2219L76.3596 75.9976L138.135 12.7815"
stroke="black"
stroke-width="25"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</div>
<div className="h-[300px] overflow-y-auto p-5 scroll-1 overflow-hidden">
{brands?.map((e, index) => (
<div
key={index}
onClick={() => handleFilterBrand(e.persianName, e.id)}
>
<div className="flex my-2 cursor-pointer">
<div
className={` w-[30px] h-[30px] rounded-lg border ml-3 tr03 ${
selectedBrands.find((id) => id == e.id)
? "bg-primary-200 p-1"
: ""
} `}
></div>
<p className="mb-0 text-gray-600 text-sm mt-1">
{e.persianName}
</p>
</div>
</div>
))}
</div>
</div>
<div
className={`p-5 border-gray-300 rounded-lg mt-3 flex justify-between ${
theme == 2 ? "bg-gray-100" : "bg-gray-50"
} `}
>
<p className="mb-0 lg:text-sm xl:text-base">فقط محصولات موجود </p>
<Switch
checked={Boolean(Number(searchParams.get("isActive")))}
onChange={handleCheckboxChange}
className={`${
isChecked ? "bg-primary-500" : "bg-gray-400"
} relative inline-flex h-6 w-[50px] items-center rounded-full`}
>
<span className="sr-only">Enable notifications</span>
<span
className={`${
isChecked ? "translate-x-[-5px]" : "translate-x-[-30px]"
} inline-block h-4 w-4 transform rounded-full bg-white transition`}
/>
</Switch>
</div>
<div
className={`p-5 border-gray-300 rounded-lg mt-3 flex justify-between ${
theme == 2 ? "bg-gray-100" : "bg-gray-50"
} `}
>
<p className="mb-0 lg:text-sm xl:text-base">
فقط پیشنهاد های ویژه{" "}
</p>
<Switch
checked={Boolean(Number(searchParams.get("specialOffer")))}
onChange={handleSpecialOfferChange}
className={`${
specialOffer ? "bg-primary-500" : "bg-gray-400"
} relative inline-flex h-6 w-[50px] items-center rounded-full`}
>
<span className="sr-only">Enable notifications</span>
<span
className={`${
specialOffer ? "translate-x-[-5px]" : "translate-x-[-30px]"
} inline-block h-4 w-4 transform rounded-full bg-white transition`}
/>
</Switch>
</div>
{/* <div
className={` p-5 border-gray-300 rounded-lg mt-3 ${
theme == 2 ? "bg-gray-100" : "bg-gray-50"
} `}
>
<div className="flex justify-between ">
<p className="mb-0">محدوده قیمت</p>
<div>
<svg
width="15"
height="15"
viewBox="0 0 151 89"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mt-1"
>
<path
d="M13.1436 14.2219L76.3596 75.9976L138.135 12.7815"
stroke="black"
stroke-width="25"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</div>
<div className="mt-10 px-5">
<RangeSlider
values={rangePrice}
min={filter?.price?.minimumValue}
max={filter?.price?.maximumValue}
onChange={(e) => handleRangeChange(e)}
/>
</div>
<div className="flex mt-5">
<div className="w-full text-center">
<p className="mb-0 text-sm">تا قیمت</p>
<p className="mb-0">
<PersianNumber number={rangePrice[0]} style="font-bold" />
</p>
</div>
<div className="w-full text-center">
<p className="mb-0 text-sm">از قیمت</p>
<p className="mb-0">
<PersianNumber number={rangePrice[1]} style="font-bold" />
</p>
</div>
</div>
</div> */}
</div>
</div>
</div>
);
};
export default FilterCategory;

View File

@ -0,0 +1,139 @@
"use client";
import CardCategories from "@comp/Cards/CardCategories/page";
import AppContext from "@ctx/AppContext";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import PersianNumber from "plugins/PersianNumber";
import { useContext, useEffect } from "react";
const ListProdocts = ({
sortBy,
rangePrice,
selectedBrands,
isChecked,
id,
isRangePrice,
}) => {
const CTX = useContext(AppContext);
const products = CTX.state.products;
const pager = CTX.state.pager;
const stopProducts = CTX.state.stopProducts;
const pageGetProducts = CTX.state.pageGetProducts;
const searchParams = useSearchParams();
const pathname = usePathname();
const router = useRouter();
const sort = (by) => {
const params = new URLSearchParams(searchParams.toString());
params.set("sortBy", by);
params.set("page", "0");
router.push(`${pathname}?${params}`);
};
return (
<div>
<div className=" px-10 ">
<div className=" border-b-[1px] border-gray-50 pb-6">
<div className="flex justify-between">
<div className="flex">
<div>
<p className="mb-0 lg:text-sm xl:text-base"> فیلتر بر اساس :</p>
</div>
<div className="flex">
<div
className={`w-fit rounded-full px-2 mx-2 tr03 ${
sortBy == 1 ? "bg-primary-600" : " opacity-60 "
}`}
onClick={() => sort(1)}
>
<p
className={`mb-0 lg:text-sm xl:text-base ${
sortBy == 1 ? "text-white" : ""
}`}
>
پربازدید ترین
</p>
</div>
<div
className={`w-fit rounded-full px-2 mx-2 tr03 ${
sortBy == 2 ? "bg-primary-600" : " opacity-60 "
}`}
onClick={() => sort(2)}
>
<p
className={`mb-0 lg:text-sm xl:text-base ${
sortBy == 2 ? "text-white" : ""
}`}
>
محبوب ترین
</p>
</div>
<div
className={`w-fit rounded-full px-2 mx-2 tr03 ${
sortBy == 3 ? "bg-primary-600" : " opacity-60 "
}`}
onClick={() => sort(3)}
>
<p
className={`mb-0 lg:text-sm xl:text-base ${
sortBy == 3 ? "text-white" : ""
}`}
>
گران ترین
</p>
</div>
<div
className={`w-fit rounded-full px-2 mx-2 tr03 ${
sortBy == 4 ? "bg-primary-600" : " opacity-60 "
}`}
onClick={() => sort(4)}
>
<p
className={`mb-0 lg:text-sm xl:text-base ${
sortBy == 4 ? "text-white" : ""
}`}
>
ارزان ترین
</p>
</div>
<div
className={`w-fit rounded-full px-2 mx-2 tr03 ${
sortBy == 5 ? "bg-primary-600" : " opacity-60 "
}`}
onClick={() => sort(1)}
>
<p
className={`mb-0 lg:text-sm xl:text-base ${
sortBy == 5 ? "text-white" : ""
}`}
>
پرفروش ترین
</p>
</div>
</div>
</div>
<div className="">
<p className="mb-0 text-base lg:text-sm xl:text-base">
<PersianNumber
number={pager?.totalItems}
style="text-[16px] mx-2 font-bold"
/>
کالا
</p>
</div>
</div>
</div>
<div className="grid xs:grid-cols-1 lg:grid-cols-4 xl:grid-cols-5">
{products?.map((e, index) => (
<CardCategories key={index} data={e} />
))}
</div>
</div>
</div>
);
};
export default ListProdocts;

View File

@ -0,0 +1,152 @@
"use client";
import ResultSearchBar from "@comp/Navbar/ResultSearchBar/page";
import AppContext from "@ctx/AppContext";
import { useContext, useEffect, useRef, useState } from "react";
const SearchSideBar = () => {
const CTX = useContext(AppContext);
const [searchValue, setSearchValue] = useState("");
const isSearched = CTX.state.isSearched;
const inputRef = useRef(null);
const handleRemoveSearch = () => {
CTX.setSearchResultData([]);
setSearchValue("");
CTX.setIsSearched(false);
};
useEffect(() => {
if (CTX.state.closeNavbar) {
inputRef.current.focus();
}
setSearchValue("");
}, [CTX.state.closeNavbar]);
const handleInputChange = (event) => {
setSearchValue(event.target.value);
};
useEffect(() => {
// Define a function to send the request
const sendRequest = async () => {
CTX.fetchSearchResult(searchValue);
};
// Set a timer to send the request after 2000 milliseconds of inactivity
const timer = setTimeout(() => {
if (searchValue.trim() !== "") {
sendRequest();
CTX.setIsSearched(true);
}
if (searchValue == "") {
CTX.setIsSearched(false);
}
}, 1000);
// Clean up function to clear the timer on component unmount or when searchTerm changes
return () => clearTimeout(timer);
}, [searchValue]);
return (
<>
<div className="mt-5 px-3">
<div className="absolute right-0 mr-[15px] mt-[0px]">
<div
className="bg-gray-100 rounded-r-lg h-[47px] w-[40px] border-l-[1px] mt-[2px] "
onClick={() => {
CTX.setCloseNavbar(true);
}}
>
<div className="pt-[9px] ">
<svg
width="25"
height="28"
viewBox="0 0 235 124"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto"
>
<path
d="M145.5 124L145.5 93.4995L235 93.4995L235 124L145.5 124ZM75.5 26.4998L75.5 0.499997L235 0.499997L235 26.4998L75.5 26.4998ZM0.499998 72.4996L0.499997 47.4996L235 47.4996L235 72.4996L0.499998 72.4996Z"
fill="black"
fill-opacity="0.73"
/>
</svg>
</div>
</div>
</div>
<input
type="text"
ref={inputRef}
className="form-control bg-gray-100 !border-[0px] border-gray-100 rounded-lg text-right focus:!border-[0px] !text-sm !pr-[60px] "
placeholder="دستت برای جست و جو بازه"
onFocus={() => CTX.setCloseNavbar(true)}
value={searchValue}
onChange={(e) => handleInputChange(e)}
/>
{!isSearched ? (
<div className="absolute mt-[-46px] ml-[6px]">
<div className="w-[40px] h-[40px] bg-gray-200 rounded-lg pt-2">
<svg
width="17"
height="17"
viewBox="0 0 275 275"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto mt-1"
>
<path
d="M215.913 215.913L265 265M250.832 130.822C250.832 197.553 196.915 251.644 130.424 251.644C63.9166 251.644 10 197.552 10 130.838C10 64.0759 63.9166 10 130.408 10C196.915 10 250.832 64.0919 250.832 130.822Z"
stroke="black"
stroke-width="18.75"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</div>
) : (
<div
className="absolute mt-[-46px] ml-[6px]"
onClick={() => handleRemoveSearch()}
>
<div className="w-[40px] h-[40px] bg-gray-200 rounded-lg pt-2">
<svg
width="10"
height="10"
viewBox="0 0 214 214"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto mt-[7px] "
>
<path
d="M4.42496 8.34954L6.24996 6.24955C9.42467 3.07411 13.6335 1.1434 18.1112 0.80849C22.589 0.473578 27.0382 1.7567 30.65 4.42455L32.75 6.24955L107 80.4745L181.25 6.22455C182.98 4.43456 185.05 3.00714 187.338 2.02557C189.626 1.04399 192.087 0.527921 194.576 0.507469C197.066 0.487016 199.535 0.962591 201.839 1.90644C204.142 2.8503 206.235 4.24353 207.995 6.00484C209.755 7.76615 211.146 9.86026 212.087 12.165C213.029 14.4697 213.502 16.9389 213.48 19.4285C213.457 21.9181 212.938 24.3783 211.955 26.6654C210.971 28.9525 209.542 31.0208 207.75 32.7495L133.525 107L207.775 181.25C210.947 184.427 212.873 188.638 213.203 193.116C213.533 197.593 212.246 202.041 209.575 205.65L207.75 207.75C204.575 210.925 200.366 212.856 195.889 213.191C191.411 213.526 186.962 212.242 183.35 209.575L181.25 207.75L107 133.525L32.75 207.775C31.0195 209.565 28.9498 210.992 26.6618 211.974C24.3738 212.955 21.9132 213.471 19.4236 213.492C16.9339 213.512 14.4652 213.036 12.1613 212.093C9.85749 211.149 7.76468 209.756 6.00503 207.994C4.24538 206.233 2.85412 204.139 1.91244 201.834C0.970764 199.529 0.497518 197.06 0.520318 194.571C0.543117 192.081 1.06151 189.621 2.04524 187.334C3.02897 185.047 4.45835 182.978 6.24996 181.25L80.475 107L6.22496 32.7495C3.05326 29.5717 1.12717 25.3612 0.796856 20.8836C0.466538 16.4059 1.75392 11.9584 4.42496 8.34954Z"
fill="black"
/>
</svg>
</div>
</div>
)}
</div>
{/* {true && (
<div
className={`relative !z-[100] tr03 ${
true ? "opacity-100" : "opacity-100"
} `}
// onClick={() => setSearchResultShow(!searchResultShow)}
>
<ResultSearchBar
searchResultProductData={searchResultProductData}
searchResultCategoryData={searchResultCategoryData}
/>
</div>
)} */}
</>
);
};
export default SearchSideBar;

View File

@ -0,0 +1,188 @@
"use client";
import AppContext from "@ctx/AppContext";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import BottomSheetFilter from "plugins/bottomSheet/BottomSheetFilter";
import { useContext, useEffect, useState } from "react";
const FilterCategoryMobile = (props) => {
const CTX = useContext(AppContext);
const pageGetProducts = CTX.state.pageGetProducts;
const [trendFilter, setTrendFilter] = useState(false);
// useEffect(() => {
// if (props.sortBy != -1) {
// CTX.fetchProducts(
// 0,
// props.id[0] != 0 ? props.id[0] : "",
// props.selectedBrands,
// props.isChecked,
// props.rangePrice,
// props.rangePrice,
// props.sortBy != -1 ? props.sortBy : "",
// props.isRangePrice
// );
// }
// }, [props.sortBy]);
const searchParams = useSearchParams();
const pathname = usePathname();
const router = useRouter();
const sort = (by) => {
const params = new URLSearchParams(searchParams.toString());
params.set("sortBy", by);
params.set("page", "0");
router.push(`${pathname}?${params}`);
};
return (
<>
<div className="flex mb-3 mt-5 px-3">
<div
className="w-full flex rtl justify-center"
onClick={() => CTX.setBottomSheetFilterOpen(true)}
>
<div>
<svg
width="20"
height="20"
viewBox="0 0 238 214"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-2 opacity-30"
>
<path
d="M31.5 107V7M206.5 207V169.5M31.5 207V157M206.5 119.5V7M119 44.5V7M119 207V94.5"
stroke="black"
stroke-width="12.5"
stroke-linecap="round"
/>
<path
d="M31.5 157C45.3071 157 56.5 145.807 56.5 132C56.5 118.193 45.3071 107 31.5 107C17.6929 107 6.5 118.193 6.5 132C6.5 145.807 17.6929 157 31.5 157Z"
stroke="black"
stroke-width="12.5"
stroke-linecap="round"
/>
<path
d="M119 94.5C132.807 94.5 144 83.3071 144 69.5C144 55.6929 132.807 44.5 119 44.5C105.193 44.5 94 55.6929 94 69.5C94 83.3071 105.193 94.5 119 94.5Z"
stroke="black"
stroke-width="12.5"
stroke-linecap="round"
/>
<path
d="M206.5 169.5C220.307 169.5 231.5 158.307 231.5 144.5C231.5 130.693 220.307 119.5 206.5 119.5C192.693 119.5 181.5 130.693 181.5 144.5C181.5 158.307 192.693 169.5 206.5 169.5Z"
stroke="black"
stroke-width="12.5"
stroke-linecap="round"
/>
</svg>
</div>
<p className="mb-0 text-sm text-gray-500">فیلتر ها</p>
</div>
<div
className="w-full flex rtl justify-center"
onClick={() => setTrendFilter(!trendFilter)}
>
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 16 16"
className="mx-2 opacity-30"
fill="none"
>
<path
fill="currentColor"
d="M3.5 2.5a.5.5 0 0 0-1 0v8.793l-1.146-1.147a.5.5 0 0 0-.708.708l2 1.999l.007.007a.497.497 0 0 0 .7-.006l2-2a.5.5 0 0 0-.707-.708L3.5 11.293zm3.5 1a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5M7.5 6a.5.5 0 0 0 0 1h5a.5.5 0 0 0 0-1zm0 3a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1zm0 3a.5.5 0 0 0 0 1h1a.5.5 0 0 0 0-1z"
/>
</svg>
</div>
<p className="mb-0 text-sm text-gray-500"> مرتب سازی</p>
</div>
</div>
{trendFilter ? (
<div className=" flex overflow-auto whitespace-nowrap rtl px-2 mb-5 mt-5 hide-scrollBar ">
<div
className={`w-fit rounded-full px-2 mx-1 tr03 ${
props.sortBy == 1 ? "bg-primary-600" : " opacity-60 "
}`}
onClick={() => sort(1)}
>
<p
className={`mb-0 lg:text-sm xl:text-base text-sm ${
props.sortBy == 1 ? "text-white" : " text-gray-500"
}`}
>
پربازدید ترین
</p>
</div>
<div
className={`w-fit rounded-full px-2 mx-1 tr03 ${
props.sortBy == 2 ? "bg-primary-600" : " opacity-60 "
}`}
onClick={() => sort(2)}
>
<p
className={`mb-0 lg:text-sm xl:text-base text-sm ${
props.sortBy == 2 ? "text-white" : " text-gray-500"
}`}
>
محبوب ترین
</p>
</div>
<div
className={`w-fit rounded-full px-2 mx-1 tr03 ${
props.sortBy == 3 ? "bg-primary-600" : " opacity-60 "
}`}
onClick={() => sort(3)}
>
<p
className={`mb-0 lg:text-sm xl:text-base text-sm ${
props.sortBy == 3 ? "text-white" : " text-gray-500"
}`}
>
گران ترین
</p>
</div>
<div
className={`w-fit rounded-full px-2 mx-1 tr03 ${
props.sortBy == 4 ? "bg-primary-600" : " opacity-60 "
}`}
onClick={() => sort(4)}
>
<p
className={`mb-0 lg:text-sm xl:text-base text-sm ${
props.sortBy == 4 ? "text-white" : " text-gray-500"
}`}
>
ارزان ترین
</p>
</div>
<div
className={`w-fit rounded-full px-2 mx-1 tr03 ${
props.sortBy == 5 ? "bg-primary-600" : " opacity-60 "
}`}
onClick={() => sort(5)}
>
<p
className={`mb-0 lg:text-sm xl:text-base text-sm ${
props.sortBy == 5 ? "text-white" : " text-gray-500"
}`}
>
پرفروش ترین
</p>
</div>
</div>
) : (
""
)}
<BottomSheetFilter data={props} />
</>
);
};
export default FilterCategoryMobile;

View File

@ -0,0 +1,22 @@
"use client";
import CardCategoriesMobile from "@comp/Cards/CardCategoriesMobile/page";
import AppContext from "@ctx/AppContext";
import { useContext } from "react";
const ListProductsMobile = (props) => {
const CTX = useContext(AppContext);
const products = CTX.state.products;
const stopProducts = CTX.state.stopProducts;
return (
<>
<div className="grid xs:grid-cols-1 lg:grid-cols-4 xl:grid-cols-5">
{products?.map((e, index) => (
<CardCategoriesMobile key={index} data={e} />
))}
</div>
</>
);
};
export default ListProductsMobile;

View File

@ -0,0 +1,120 @@
"use client";
import AppContext from "@ctx/AppContext";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import PersianNumber from "plugins/PersianNumber";
import { useContext, useEffect, useState } from "react";
const PaginationCategoory = (props) => {
const CTX = useContext(AppContext);
const searchParams = useSearchParams();
const pager = CTX.state.pager;
const pathname = usePathname();
const router = useRouter();
const [currentPageIndex, setCurrentPageIndex] = useState(
Number(searchParams.get("page")) ? Number(searchParams.get("page")) : 0
);
useEffect(() => {
setCurrentPageIndex(
Number(searchParams.get("page")) ? Number(searchParams.get("page")) : 0
);
}, [searchParams]);
const renderPaginationButtons = () => {
const buttons = [];
const totalPages = pager?.totalPage;
const maxButtonsToShow = 7; // Maximum buttons to show
// If total pages are greater than maxButtonsToShow
if (totalPages > maxButtonsToShow) {
// Show buttons for the first page
buttons.push(renderPageButton(0));
// If current page is not too close to the start, show ellipsis
if (currentPageIndex > 2) {
buttons.push(renderEllipsis());
}
// Calculate the start index for buttons
const start = Math.max(1, currentPageIndex - 2);
// Calculate the end index for buttons
const end = Math.min(currentPageIndex + 3, totalPages - 1);
// Show buttons for pages within range
for (let i = start; i <= end; i++) {
buttons.push(renderPageButton(i));
}
// If current page is not too close to the end, show ellipsis
if (currentPageIndex < totalPages - 4) {
buttons.push(renderEllipsis());
}
// Show button for the last page
buttons.push(renderPageButton(totalPages - 1));
} else {
// Show buttons for all pages
for (let i = 0; i < totalPages; i++) {
buttons.push(renderPageButton(i));
}
}
return buttons;
};
const renderPageButton = (pageIndex) => (
<div
key={pageIndex}
className={`w-[25px] h-[25px] rounded-full tr03 bg-${
currentPageIndex === pageIndex ? "secondary-500" : "primary-200"
} mx-1 cursor-pointer`}
onClick={() => handlePageClick(pageIndex)}
>
<p className="mb-0 text-center pt-[2px] text-white">
<PersianNumber number={pageIndex + 1} style=" !text-[14px] " />
</p>
</div>
);
const renderEllipsis = () => (
<div key="ellipsis" className="mx-1">
...
</div>
);
const handlePageClick = (pageIndex) => {
setCurrentPageIndex(pageIndex);
//
// CTX.fetchProducts(
// pageIndex,
// props.id[0] != 0 ? props.id[0] : "",
// props.selectedBrands,
// props.isChecked,
// props.rangePrice,
// props.rangePrice,
// props.sortBy != -1 ? props.sortBy : "",
// props.isRangePrice,
// true //pagination say or not
// );
const nextPage = pageIndex;
const params = new URLSearchParams(searchParams.toString());
params.set("page", nextPage);
router.push(`${pathname}?${params}`);
CTX.setStopProducts(true);
// Your fetchProducts function call here
};
return (
<div className="flex justify-center rtl mb-10">
<div className="w-[25px] h-[25px] rounded-full bg-primary-300 mx-2">
{/* Previous page button */}
</div>
{renderPaginationButtons()}
<div className="w-[25px] h-[25px] rounded-full bg-primary-300 mx-2">
{/* Next page button */}
</div>
</div>
);
};
export default PaginationCategoory;

View File

@ -0,0 +1,299 @@
import Image from "next/image";
import Link from "next/link";
import logo from "../../public/images/logo.png";
import bale from "@img/bale.png";
const Footer = () => {
return (
<>
<div className="bg-gray-100 p-5 pb-10 lg:flex rtl lg:px-20">
<div className=" p-3 xs:w-full lg:w-8/12 mx-2 flex rtl">
<div className="xs:w-[70px] lg:w-[100px]">
<Image src={logo} alt=" وسمه vesmeh" />
</div>
<div className="mr-3">
<h3>
فروشگاه لوازم آرایشی و بهداشتی{" "}
<small className="text-base mr1 bg-sky-300 px-1 rounded-full">
وسمه{" "}
</small>
</h3>
</div>
</div>
<div className=" xs:w-full lg:w-4/12 mx-2 flex xs:mt-5 lg:mt-0">
<div className="w-8/12">
<input
type="text"
className="form-control !rounded-full !border-[1px] text-sm"
placeholder="شماره تماس برای تحفیف ها"
/>
</div>
<button className="btn btn-primary py-1 relative rounded-full z-10 left-[40px] !font-normal w-4/12 text-sm">
{" "}
ثبت شماره
</button>
</div>
</div>
<div className="bg-gray-200">
<div className=" xs:px-5 lg:px-20 xs:py-3 lg:py-5 ">
<div className="grid xs:grid-cols-1 lg:grid-cols-2 gap-10 rtl">
<div className="grid xs:grid-cols-1 lg:grid-cols-3 gap-10 rtl">
<div className="col-span-2">
<div className="grid xs:grid-cols-1 lg:grid-cols-2"></div>
<div className=" ">
<div>
<p className="mb-0">محصولات</p>
<div className="h-[1px] w-full bg-gray-200 mt-2"></div>
</div>
<div className="grid xs:grid-cols-2 lg:grid-cols-2">
<div>
<ul>
<Link
href={`/categories/bdf6b13c-4be5-4a93-bcdb-612440bdbd6e/کرم مرطوب کننده دست و پا`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
کرم مرطوب کننده دست و پا{" "}
</li>
</Link>
<Link
href={`/categories/20dce1e7-1dfe-4b2a-9764-6f3ddf46fdb2/مرطوب کننده و آبرسان صورت`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
مرطوب کننده و آبرسان صورت{" "}
</li>
</Link>
<Link
href={`/categories/16bcdc90-6842-4201-9d5c-54cd8f565148/شوینده سطوح`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
شوینده سطوح
</li>
</Link>
<Link
href={`/categories/b7549222-87f7-4b0b-8938-210539b3a395/بهداشت دهان و دندان`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
بهداشت دهان و دندان
</li>
</Link>
<Link
href={`/categories/f3e79ed0-d608-470d-8656-7a98ff933c1e/نرم کننده مو`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
نرم کننده مو
</li>
</Link>
</ul>
</div>
<div>
<ul>
<Link
href={`/categories/b909db09-2188-4a4d-8578-e1f7102947bc/کیت رنگ مو`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
کیت رنگ مو{" "}
</li>
</Link>
<Link
href={`/categories/effe5d98-d4b7-47e1-9bfb-4d3c77ab3347/بهداشت خانه و آشپرخانه`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
بهداشت خانه و آشپرخانه{" "}
</li>
</Link>
<Link
href={`/categories/debf7aad-4f08-4d03-ba70-6663ae1aa90d/سرم مو`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
سرم مو{" "}
</li>
</Link>
<Link
href={`/categories/8bf20569-c3e3-457f-b9ad-140ef449741b/ژل بهداشتی بانوان`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
ژل بهداشتی بانوان{" "}
</li>
</Link>
<Link href={`/blogs?page=0`}>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
مجله زیبایی وسمه{" "}
</li>
</Link>
</ul>
</div>
</div>
</div>
</div>
<div className=" ">
<div>
<p className="mb-0">درباره ما</p>
<div className="h-[1px] w-full bg-gray-200 mt-2"></div>
</div>
<div>
<ul>
<Link href={`/faq`}>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
سوالات متداول{" "}
</li>
</Link>
<Link href={`/contact-us`}>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
تماس باما{" "}
</li>
</Link>
<Link href={`/terms-and-conditions`}>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
قوانین سایت
</li>
</Link>
<Link href={`/about-us`}>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
درباره ما{" "}
</li>
</Link>
</ul>
</div>
</div>
</div>
<div>
<div>
<p className="mb-0">چرا وسمه</p>
<div className="h-[1px] w-full bg-gray-200 mt-2"></div>
</div>
<p className="mb-0 text-sm text-gray-600 mt-3">
وسمه تعهد داره تجربه خرید لوازم آرایشی و بهداشتی رو متحول کنه.
این تحول میتونه برای مشتری احساس قسمتی از خانواده وسمه بودن رو
داشته باشه. وسمه با برطرف کردن دغدغههای خرید لوازم آرایشی و
بهداشتی به ساختن لایف استایل شخصی خانمهای ایرانی کمک میکنه و
زندگی راحتتری پیش روی مشتریانش قرار میده. از سال 1400 ما تمام
انرژیمون رو به کار گرفتیم تا با تمرکز برکیفیت کالا، سرعت ارسال و
قیمت کالا ، نیاز افراد رو برطرف کنیم و تجربه جدیدی از لذت خرید
به وجود بیاریم.
</p>
<div className="lg:flex ltr lg:justify-between mt-5 ">
<div className=" flex flex-wrap mx-auto xs:justify-center lg:justify-end xs:ml-0 ">
<div className="bg-white w-[100px] h-[100px] rounded-3xl mx-2 xs:mt-3 lg:mt-0">
<a
referrerpolicy="origin"
target="_blank"
href="https://trustseal.enamad.ir/?id=274373&Code=FSm0y9hlccuslQp7UNJT"
>
<img
referrerpolicy="origin"
src="https://trustseal.enamad.ir/logo.aspx?id=274373&Code=FSm0y9hlccuslQp7UNJT"
alt=""
style={{ cursor: "pointer" }}
Code="FSm0y9hlccuslQp7UNJT"
/>
</a>
</div>
<div className="bg-white w-[100px] h-[100px] rounded-3xl mx-2 xs:mt-3 lg:mt-0"></div>
</div>
<div className="flex xs:justify-center lg:justify-normal rtl xs:mt-5 lg:mt-0">
<a href={`https://www.instagram.com/vesmehcom`}>
<div className="bg-white p-2 h-fit rounded-2xl mx-1">
<svg
width="25"
height="25"
viewBox="0 0 226 227"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-60"
>
<path
d="M112.987 55.2129C97.658 55.2129 82.9563 61.3025 72.1167 72.1421C61.2771 82.9817 55.1875 97.6834 55.1875 113.013C55.1875 128.342 61.2771 143.044 72.1167 153.884C82.9563 164.723 97.658 170.813 112.987 170.813C128.317 170.813 143.019 164.723 153.858 153.884C164.698 143.044 170.787 128.342 170.787 113.013C170.787 97.6834 164.698 82.9817 153.858 72.1421C143.019 61.3025 128.317 55.2129 112.987 55.2129ZM112.987 150.55C108.056 150.55 103.174 149.579 98.6177 147.692C94.062 145.805 89.9225 143.039 86.4356 139.552C82.9488 136.065 80.1829 131.926 78.2958 127.37C76.4088 122.814 75.4375 117.932 75.4375 113C75.4375 108.069 76.4088 103.186 78.2958 98.6306C80.1829 94.0749 82.9488 89.9354 86.4356 86.4485C89.9225 82.9617 94.062 80.1958 98.6177 78.3087C103.174 76.4216 108.056 75.4504 112.987 75.4504C122.946 75.4504 132.497 79.4065 139.539 86.4485C146.581 93.4905 150.538 103.042 150.538 113C150.538 122.959 146.581 132.51 139.539 139.552C132.497 146.594 122.946 150.55 112.987 150.55Z"
fill="black"
/>
<path
d="M173.075 66.5623C180.517 66.5623 186.55 60.5293 186.55 53.0873C186.55 45.6453 180.517 39.6123 173.075 39.6123C165.633 39.6123 159.6 45.6453 159.6 53.0873C159.6 60.5293 165.633 66.5623 173.075 66.5623Z"
fill="black"
/>
<path
d="M219.663 39.3875C216.769 31.9148 212.347 25.1285 206.68 19.4632C201.012 13.7979 194.224 9.37839 186.75 6.4875C178.005 3.20446 168.765 1.42926 159.425 1.2375C147.388 0.712499 143.575 0.5625 113.05 0.5625C82.5254 0.5625 78.6129 0.562499 66.6754 1.2375C57.3428 1.41946 48.1099 3.19502 39.3754 6.4875C31.8996 9.37502 25.1099 13.7934 19.4421 19.4591C13.7742 25.1248 9.35325 31.9128 6.46289 39.3875C3.1792 48.1327 1.40807 57.373 1.22539 66.7125C0.687891 78.7375 0.525391 82.55 0.525391 113.087C0.525391 143.612 0.525391 147.5 1.22539 159.462C1.41289 168.812 3.17539 178.037 6.46289 186.8C9.36136 194.272 13.7866 201.057 19.4558 206.722C25.1251 212.387 31.9137 216.807 39.3879 219.7C48.1058 223.115 57.3425 225.017 66.7004 225.325C78.7379 225.85 82.5504 226.012 113.075 226.012C143.6 226.012 147.513 226.012 159.45 225.325C168.789 225.135 178.028 223.364 186.775 220.088C194.247 217.19 201.033 212.766 206.7 207.1C212.367 201.433 216.79 194.647 219.688 187.175C222.975 178.425 224.738 169.2 224.925 159.85C225.463 147.825 225.625 144.013 225.625 113.475C225.625 82.9375 225.625 79.0625 224.925 67.1C224.78 57.6284 223 48.2531 219.663 39.3875ZM204.438 158.537C204.357 165.741 203.042 172.878 200.55 179.637C198.673 184.498 195.799 188.913 192.114 192.596C188.428 196.279 184.012 199.151 179.15 201.025C172.466 203.506 165.405 204.821 158.275 204.912C146.4 205.462 143.05 205.6 112.6 205.6C82.1254 205.6 79.0129 205.6 66.9129 204.912C59.787 204.825 52.7295 203.51 46.0504 201.025C41.1715 199.162 36.7379 196.296 33.0365 192.612C29.3351 188.928 26.4483 184.508 24.5629 179.637C22.106 172.951 20.7918 165.898 20.6754 158.775C20.1379 146.9 20.0129 143.55 20.0129 113.1C20.0129 82.6375 20.0129 79.525 20.6754 67.4125C20.7562 60.2128 22.0711 53.0802 24.5629 46.325C28.3754 36.4625 36.1879 28.7 46.0504 24.925C52.7328 22.4517 59.7882 21.137 66.9129 21.0375C78.8004 20.5 82.1379 20.35 112.6 20.35C143.063 20.35 146.188 20.35 158.275 21.0375C165.406 21.1233 172.467 22.4384 179.15 24.925C184.012 26.8034 188.427 29.6775 192.113 33.3629C195.798 37.0482 198.672 41.4634 200.55 46.325C203.007 53.0119 204.321 60.0645 204.438 67.1875C204.975 79.075 205.113 82.4125 205.113 112.875C205.113 143.325 205.113 146.6 204.575 158.55L204.438 158.537Z"
fill="black"
/>
</svg>
</div>
</a>
<a href={`https://t.me/vesmehhcom`}>
<div className="bg-white p-2 h-fit rounded-2xl mx-1">
<svg
width="25"
height="25"
viewBox="0 0 300 300"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-60"
>
<g clip-path="url(#clip0_633_2)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M247.213 55.3746C250.302 54.0745 253.683 53.6261 257.004 54.076C260.325 54.526 263.465 55.8579 266.097 57.9331C268.728 60.0083 270.756 62.751 271.968 65.8756C273.18 69.0002 273.532 72.3926 272.988 75.6996L244.638 247.662C241.888 264.25 223.688 273.762 208.476 265.5C195.751 258.587 176.851 247.937 159.851 236.825C151.351 231.262 125.313 213.45 128.513 200.775C131.263 189.937 175.013 149.212 200.013 125C209.826 115.487 205.351 110 193.763 118.75C164.988 140.475 118.788 173.512 103.513 182.812C90.0381 191.012 83.013 192.412 74.613 191.012C59.288 188.462 45.0756 184.512 33.4756 179.7C17.8006 173.2 18.5631 151.65 33.4631 145.375L247.213 55.3746Z"
fill="black"
/>
</g>
<defs>
<clipPath id="clip0_633_2">
<rect width="300" height="300" fill="white" />
</clipPath>
</defs>
</svg>
</div>
</a>
<a href={`https://web.bale.ai/flow/search?uid=5560485550`}>
<div className="bg-white p-2 h-fit rounded-2xl mx-1">
<div className="w-[25px]">
<Image
src={bale}
className="opacity-60"
alt="پیام رسان بله وسمه"
/>
</div>
</div>
</a>
<a href={`https://twitter.com/vesmehcom`}>
<div className="bg-white p-2 h-fit rounded-2xl mx-1">
<svg
width="25"
height="25"
viewBox="0 0 300 244"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-60"
>
<path
d="M94.2375 243.763C207.45 243.763 269.381 149.957 269.381 68.7505C269.406 66.113 269.369 63.4755 269.269 60.838C281.322 52.1051 291.728 41.2996 300 28.9255C288.733 33.8806 276.8 37.1531 264.581 38.638C277.455 30.945 287.096 18.8382 291.712 4.56925C279.624 11.7453 266.385 16.7757 252.581 19.438C243.303 9.55719 231.026 3.01145 217.652 0.814699C204.277 -1.38206 190.551 0.892774 178.6 7.28682C166.649 13.6809 157.14 23.8373 151.546 36.1829C145.952 48.5285 144.585 62.3742 147.656 75.5755C123.181 74.3541 99.2371 67.9989 77.378 56.9223C55.519 45.8458 36.2339 30.2957 20.775 11.2817C12.9296 24.8407 10.5366 40.8765 14.0814 56.1352C17.6262 71.3939 26.8433 84.7325 39.8625 93.4442C30.1014 93.1288 20.5536 90.5074 12 85.7942V86.638C12.0239 100.839 16.9466 114.597 25.9373 125.589C34.928 136.582 47.436 144.135 61.35 146.976C56.0676 148.431 50.6106 149.157 45.1313 149.132C41.2672 149.172 37.4094 148.814 33.6187 148.063C37.5449 160.294 45.2021 170.988 55.5157 178.645C65.8293 186.302 78.2816 190.537 91.125 190.757C69.3019 207.875 42.3609 217.166 14.625 217.138C9.73685 217.175 4.85149 216.893 0 216.294C28.1517 234.247 60.8487 243.777 94.2375 243.763Z"
fill="black"
/>
</svg>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
<p className="mb-0 text-gray-400 text-sm text-center py-5 rtl bg-gray-100">
استفاده از مطالب فروشگاه وسمه فقط برای مقاصد غیرتجاری و باذکر منبع
بلامانع است. کلیه حقوق این سایت متعلق به شرکت وسمه می باشد. ورژن
{process.env.NEXT_PUBLIC_PACKAGE_VERSION}
</p>
</div>
</>
);
};
export default Footer;

View File

@ -0,0 +1,80 @@
import CardNormal from "@comp/Cards/CardNormal/page";
import Link from "next/link";
import { Swiper, SwiperSlide } from "swiper/react";
const BeautySection = ({ data }) => {
return (
<section className="mb-10 pb-10 xs:bg-sky-500 lg:bg-transparent xs:mx-3 lg:mx-0 xs:px-5 lg:px-0 xs:rounded-3xl lg:rounded-[0px] xs:mt-0 lg:mt-20">
<div className=" relative xs:hidden lg:block ">
<div className="w-full flex justify-end absolute ">
<svg
width="700"
height="400"
viewBox="0 0 1037 590"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mr-[20px]"
>
<path
d="M25.6693 0H1012C1025.81 0 1037 11.1929 1037 25V565C1037 578.807 1025.81 590 1012 590H371.096C362.569 590 354.631 585.654 350.036 578.472L4.60942 38.4715C-6.03513 21.8311 5.91551 0 25.6693 0Z"
fill="#219EBC"
/>
</svg>
</div>
</div>
<div className="xs:px-0 lg:px-20">
<div className="w-full rtl relative ">
<div className="pt-5 flex relative justify-between">
<h2 className="mb-0 text-white font-bold xs:text-sm lg:text-2xl xl:text-2xl">
آرایش صورت وسمه{" "}
</h2>
</div>
</div>
<Swiper
spaceBetween={50}
slidesPerView={6.2}
// onSlideChange={() => console.log("slide change")}
className="rtl relative mt-5"
// dir="rtl"
breakpoints={{
320: {
slidesPerView: 1.3,
},
480: {
slidesPerView: 2,
},
768: {
slidesPerView: 3,
},
1024: {
slidesPerView: 4.5,
},
1440: {
slidesPerView: 6,
},
}}
>
{data?.map((e, index) => (
<SwiperSlide key={index}>
<CardNormal data={e} priority />
</SwiperSlide>
))}
</Swiper>
<Link
href={"/categories/7e92af7d-0370-451f-9770-5e26b5c8dc63/آرایش-صورت"}
className="z-90 relative"
>
<div className="mx-5 mt-8">
<p className="mb-0 text-sm text-gray-600 xs:text-white md:text-black">
مشاهده بیشتر{" "}
</p>
</div>
</Link>
</div>
</section>
);
};
export default BeautySection;

View File

@ -0,0 +1,95 @@
import Image from "next/image";
import Link from "next/link";
const BetweenSexualSection = () => {
return (
<section>
<div className="mt-10 xs:px-5 lg:px-20">
<div className="grid xs:grid-cols-1 lg:grid-cols-3 rtl ">
<div className="relative z-10 overflow-hidden rounded-3xl">
<div className="w-full">
<Image
src={between}
className="object-cover "
alt="بهداشت جنسی آقایان و بانوان"
/>
</div>
</div>
<div className="bg-gray-100 relative xs:left-[0px] lg:left-[30px] xs:top-[-35px] lg:top-0 col-span-2 z-0 rounded-3xl xs:pr-5 lg:pr-[55px] xs:pt-[55px] lg:pt-10 pl-5">
<div className="xs:block lg:flex">
<h2 className="font-bold xs:text-2xl lg:text-3xl">
لوازم بهداشتی وسمه
</h2>
<p className="px-3 py-1 mb-0 rounded-full w-fit bg-sky-200 xs:mr-0 lg:mr-2 xs:mt-2 lg:mt-0 xs:text-sm lg:text-base ">
به صرفه زیبا شـــــــــــــو
</p>
</div>
{/* <p className="mt-3 mb-0 text-sm text-gray-500">
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با
استفاده از طراحان گرافیک است
</p> */}
<div className="mt-10 xs:block lg:flex">
<Link
href={`/categories/8bf20569-c3e3-457f-b9ad-140ef449741b/ژل-بهداشتی-بانوان-و-آقایان`}
className="w-full mx-3"
>
<div className="w-full p-3 mx-1 bg-pink-300 rounded-3xl lg:my-0 ">
<div className="flex justify-end ">
<div className="absolute mt-[-43px] ">
<div className="xs:w-[140px] lg:w-[150px]">
<Image
src={between1}
className=" object-cover xs:w-[140px] lg:w-[150px]"
alt="لوازم بهداشت بانوان وسمه"
/>
</div>
</div>
</div>
<h3 className="xs:text-lg lg:text-xl ">
بهداشت روزانه بانوان
</h3>
<p className="px-3 py-1 mt-2 mb-0 text-sm rounded-full w-fit bg-sky-200">
شروع خرید{" "}
</p>
</div>
</Link>
<Link
href={`/categories/70cffd9e-f475-4245-87bb-5f175d286901/لوازم-اصلاح`}
className="w-full mx-3"
>
<div className="w-full p-3 mx-1 bg-sky-300 rounded-3xl xs:my-3 lg:my-0 ">
<div className="flex justify-end">
<div className="absolute mt-[-43px]">
<div className="xs:w-[140px] lg:w-[150px]">
<Image
src={between2}
className="object-cover "
alt="لوازم بهداشت آقایان وسمه"
/>
</div>
</div>
</div>
<h3 className="xs:text-lg lg:text-xl ">
بهداشت روزانه آقایان
</h3>
<p className="px-3 py-1 mt-2 mb-0 text-sm rounded-full w-fit bg-sky-200">
شروع خرید{" "}
</p>
</div>
</Link>
</div>
</div>
</div>
</div>
</section>
);
};
export default BetweenSexualSection;

View File

@ -0,0 +1,13 @@
import MovingLogos from "plugins/MovingLogos/page";
const BrandsLogoSection = () => {
return (
<section>
<div className=" p-5 relative overflow-hidden lg:mt-20">
<MovingLogos />
</div>
</section>
);
};
export default BrandsLogoSection;

View File

@ -0,0 +1,891 @@
import Image from "next/image";
import Link from "next/link";
import cat1 from "../../../public/images/cat1.jpg";
import cat2 from "../../../public/images/cat2.jpg";
import cat3 from "../../../public/images/cat3.jpg";
import cat11 from "../../../public/images/cat11.png";
import cat12 from "../../../public/images/cat12.png";
import cat13 from "../../../public/images/cat13.png";
import cat14 from "../../../public/images/cat14.png";
import cat15 from "../../../public/images/cat15.png";
import PersianNumber from "@plugins/PersianNumber";
import { Swiper, SwiperSlide } from "swiper/react";
import CardNormal from "@comp/Cards/CardNormal/page";
import CardSurprise from "@comp/Cards/CardSurprise/page";
import NavbarTransparent from "@comp/Navbar/NavbarTransparent";
const HeroSection = ({ data }) => {
console.log(data);
return (
<div className=" ">
<div className=" relative bg-primary-800 xs:h-auto lg:h-[600px] xs:mb-[60px] lg:mb-[190px] rounded-b-[50px] bg-hero-pattern">
<div className="relative h-[150px]">
<NavbarTransparent />
</div>
<div className="xs:pt-10 lg:pt-20">
<h1 className="text-center font-bold text-white xs:text-[30px] lg:text-[60px]">
فروشگاه آشپرخانه بونسای{" "}
</h1>
<p className="mb-0 text-center text-gray-400">
بونسای نبض آرام آشپزخانه
</p>
</div>
<div className=" pt-20">
<div className=" xs:hidden lg:block xs:w-10/12 lg:w-12/12 xl:11/12 mx-auto bg-header-1 xs:rounded-[60px] lg:rounded-[110px] h-[500px] group relative">
<div className="">
<svg
class="absolute inset-x-0 mx-auto h-[50px] rotate-180 block bottom-0 "
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 740 155.61"
>
<path
fill="white"
d="M532.54 85.81c69.58,-54.09 138.74,-82.63 207.46,-85.62l-740 0c73.71,3.21 147.93,35.81 222.63,97.82 28.75,23.85 45.98,38.3 83.91,49.54 20.26,6.01 41.42,8.74 63.46,8.18 28.55,0.73 55.61,-4.06 81.17,-14.35 36.28,-14.61 51.98,-32.73 81.37,-55.57z"
></path>
</svg>
<div></div>
<div className="flex justify-center w-full">
<div className="absolute flex bottom-2">
<span className=" w-[10px] h-[10px] rounded-full block bg-red-100 bottom-0 inset-x-0 mx-[1px] "></span>{" "}
<span className=" w-[30px] h-[10px] rounded-full block bg-red-300 bottom-0 inset-x-0 mx-[1px]"></span>{" "}
<span className=" w-[10px] h-[10px] rounded-full block bg-red-100 bottom-0 inset-x-0 mx-[1px] "></span>{" "}
</div>
</div>
</div>
</div>
</div>
{/* <div className=" xs:w-full lg:w-7/12 mx-auto">
<div className="grid xs:grid-cols-1 lg:grid-cols-4 my-[60px] rtl">
<div className="flex rtl ">
<div className="ml-1">
<svg
width="40"
height="40"
viewBox="0 0 195 234"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-55"
>
<path
d="M97.5 223C108.859 223 120.107 220.855 130.602 216.686C141.097 212.518 150.632 206.409 158.665 198.707C166.697 191.005 173.069 181.861 177.416 171.798C181.763 161.735 184 150.949 184 140.057V93.9407C184.001 73.5647 176.18 53.9012 162.029 38.7007M11 112.354V140.057C10.9942 156.385 16.0145 172.351 25.4316 185.955C34.8487 199.559 48.2438 210.195 63.938 216.53M140.75 22.1121C120.883 11.1136 97.2729 8.13312 75.1139 13.8262C52.955 19.5192 34.062 33.4194 22.591 52.4692C17.8677 60.2912 14.5352 68.8126 12.73 77.6839"
stroke="black"
stroke-width="21.4286"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M88.5037 59.1046C94.8666 57.838 101.445 57.9569 107.753 59.4527C114.062 60.9484 119.94 63.7828 124.954 67.7469C129.968 71.711 133.99 76.7037 136.724 82.3569C139.458 88.01 140.834 94.1794 140.75 100.41V127.118M129.678 161.954C123.791 168.241 116.043 172.654 107.469 174.603C98.8954 176.551 89.9055 175.943 81.7025 172.858C73.4996 169.773 66.475 164.359 61.5688 157.341C56.6626 150.323 54.109 142.035 54.2497 133.587V100.41C54.2168 94.7128 55.394 89.0687 57.7097 83.8216M97.4997 102.235V129.938"
stroke="black"
stroke-opacity="0.46"
stroke-width="21.4286"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div className="text-right">
<p className="mb-0 font-medium">امنیت در خرید</p>
<small className="mb-0 relative top-[-5px] text-gray-500">
همه ساعت روز هفت روز
</small>
</div>
</div>
<div className="flex rtl mx-8">
<div className="ml-1">
<svg
width="40"
height="40"
viewBox="0 0 234 245"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-55"
>
<path
d="M65.8285 163.318C66.1568 164.505 66.7156 165.616 67.4731 166.587C68.2306 167.557 69.1719 168.37 70.2433 168.977C71.3146 169.584 72.4951 169.974 73.7172 170.125C74.9393 170.276 76.1792 170.184 77.366 169.856C78.5528 169.528 79.6633 168.969 80.6342 168.211C81.605 167.454 82.4172 166.512 83.0242 165.441C83.6313 164.37 84.0214 163.189 84.1722 161.967C84.3231 160.745 84.2318 159.505 83.9035 158.318L65.8285 163.318ZM12.0035 31.5684C10.812 31.2204 9.56326 31.1124 8.32972 31.2508C7.09619 31.3892 5.90242 31.7712 4.81768 32.3746C3.73293 32.978 2.77882 33.7908 2.01068 34.7659C1.24255 35.7409 0.675695 36.8588 0.343006 38.0547C0.0103176 39.2505 -0.0815803 40.5006 0.0726454 41.7322C0.226871 42.9639 0.62415 44.1526 1.24143 45.2295C1.85871 46.3064 2.6837 47.25 3.66854 48.0056C4.65338 48.7611 5.77845 49.3136 6.97848 49.6309L12.0035 31.5684ZM224.353 169.068C225.574 168.786 226.726 168.262 227.741 167.527C228.755 166.792 229.613 165.861 230.261 164.789C230.91 163.718 231.338 162.527 231.518 161.287C231.699 160.047 231.63 158.783 231.314 157.571C230.998 156.359 230.442 155.222 229.679 154.228C228.917 153.234 227.963 152.403 226.873 151.783C225.784 151.164 224.582 150.77 223.337 150.624C222.093 150.477 220.832 150.582 219.628 150.931L224.353 169.068ZM99.466 191.993C103.341 205.993 94.841 220.781 79.791 224.693L84.5035 242.831C109.216 236.418 124.316 211.556 117.541 186.993L99.466 191.993ZM79.791 224.693C64.641 228.631 49.441 219.831 45.541 205.706L27.466 210.706C34.216 235.143 59.891 249.231 84.5035 242.831L79.791 224.693ZM45.541 205.706C41.666 191.706 50.166 176.918 65.216 173.006L60.5035 154.881C35.791 161.293 20.6785 186.143 27.466 210.706L45.541 205.706ZM65.216 173.006C80.366 169.068 95.566 177.868 99.466 191.993L117.541 186.993C110.791 162.556 85.116 148.468 60.5035 154.868L65.216 173.006ZM83.9035 158.318L57.0035 60.9434L38.9285 65.9434L65.8285 163.318L83.9035 158.318ZM33.3035 37.4684L12.0035 31.5684L6.97848 49.6309L28.291 55.5434L33.3035 37.4684ZM57.0035 60.9434C55.4175 55.3165 52.4008 50.1965 48.2473 46.0825C44.0938 41.9684 38.9452 39.0006 33.3035 37.4684L28.316 55.5434C33.6285 57.0184 37.5785 61.0559 38.9285 65.9434L57.0035 60.9434ZM110.878 198.568L224.353 169.068L219.641 150.931L106.153 180.431L110.878 198.568Z"
fill="black"
/>
<path
d="M211.565 50.4561C205.503 28.5061 202.465 17.5311 193.565 12.5436C184.64 7.54358 173.328 10.4936 150.703 16.3811L126.703 22.6061C104.078 28.4811 92.7652 31.4311 87.6277 40.0811C82.4777 48.7186 85.5027 59.6936 91.5652 81.6311L98.0027 104.919C104.065 126.856 107.09 137.831 116.003 142.819C124.915 147.819 136.228 144.869 158.853 138.994L182.853 132.744C205.478 126.869 216.79 123.931 221.94 115.294C224.765 110.544 225.128 105.094 223.865 97.5061"
stroke="black"
stroke-opacity="0.44"
stroke-width="18.75"
stroke-linecap="round"
/>
</svg>
</div>
<div className="text-right">
<p className="mb-0 font-medium">ارسال رایگان</p>
<small className="mb-0 relative top-[-5px] text-gray-500">
بدون محدودیت قیمت{" "}
</small>
</div>
</div>
<div className="flex rtl mx-8">
<div className="ml-1">
<svg
width="40"
height="40"
viewBox="0 0 251 251"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-55"
>
<path
d="M106.893 21.3234C109.238 18.7046 112.108 16.6097 115.318 15.1755C118.527 13.7413 122.003 13 125.518 13C129.033 13 132.509 13.7413 135.718 15.1755C138.927 16.6097 141.798 18.7046 144.143 21.3234L152.893 31.0984C155.394 33.8921 158.491 36.0875 161.955 37.5221C165.419 38.9567 169.162 39.5936 172.905 39.3859L186.03 38.6609C189.541 38.4674 193.053 39.0165 196.337 40.2724C199.621 41.5283 202.603 43.4628 205.088 45.9495C207.574 48.4362 209.507 51.4192 210.761 54.7037C212.016 57.9883 212.563 61.5004 212.368 65.0109L211.643 78.1234C211.437 81.865 212.075 85.6051 213.509 89.067C214.944 92.5289 217.138 95.624 219.93 98.1234L229.705 106.873C232.326 109.218 234.423 112.09 235.858 115.3C237.294 118.511 238.036 121.988 238.036 125.505C238.036 129.021 237.294 132.499 235.858 135.709C234.423 138.919 232.326 141.791 229.705 144.136L219.93 152.886C217.137 155.387 214.941 158.484 213.507 161.948C212.072 165.412 211.435 169.155 211.643 172.898L212.368 186.023C212.561 189.534 212.012 193.046 210.756 196.33C209.5 199.614 207.566 202.596 205.079 205.081C202.593 207.567 199.61 209.5 196.325 210.754C193.04 212.009 189.528 212.556 186.018 212.361L172.905 211.636C169.164 211.43 165.424 212.068 161.962 213.502C158.5 214.937 155.405 217.131 152.905 219.923L144.155 229.698C141.81 232.319 138.939 234.416 135.729 235.851C132.518 237.287 129.041 238.029 125.524 238.029C122.007 238.029 118.53 237.287 115.32 235.851C112.109 234.416 109.238 232.319 106.893 229.698L98.1429 219.923C95.6421 217.13 92.545 214.934 89.0808 213.5C85.6166 212.065 81.8741 211.428 78.1304 211.636L65.0054 212.361C61.4948 212.554 57.9829 212.005 54.699 210.749C51.4151 209.493 48.433 207.559 45.9475 205.072C43.4619 202.586 41.5289 199.603 40.2745 196.318C39.0201 193.034 38.4727 189.521 38.6679 186.011L39.3929 172.898C39.5987 169.157 38.9608 165.417 37.5263 161.955C36.0918 158.493 33.8974 155.398 31.1054 152.898L21.3304 144.148C18.7095 141.803 16.6129 138.932 15.1774 135.722C13.742 132.511 13 129.034 13 125.517C13 122 13.742 118.523 15.1774 115.313C16.6129 112.102 18.7095 109.231 21.3304 106.886L31.1054 98.1359C33.8991 95.6351 36.0945 92.538 37.5291 89.0738C38.9636 85.6096 39.6006 81.8671 39.3929 78.1234L38.6679 64.9984C38.4762 61.4888 39.0267 57.9783 40.2834 54.6959C41.5401 51.4135 43.4749 48.433 45.9614 45.9488C48.4479 43.4647 51.4303 41.5328 54.7139 40.2791C57.9975 39.0255 61.5085 38.4784 65.0179 38.6734L78.1304 39.3984C81.872 39.6042 85.6121 38.9663 89.074 37.5318C92.5358 36.0973 95.6309 33.9029 98.1304 31.1109L106.88 21.3359L106.893 21.3234Z"
stroke="black"
stroke-width="25"
/>
<path
d="M94.2676 94.2607H94.3926V94.3857H94.2676V94.2607ZM156.768 156.761H156.893V156.886H156.768V156.761Z"
stroke="black"
stroke-width="37.5"
stroke-linejoin="round"
/>
<path
d="M163.018 88.0107L88.0176 163.011"
stroke="black"
stroke-width="25"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div className="text-right">
<p className="mb-0 font-medium">اصالت کالا</p>
<small className="mb-0 relative top-[-5px] text-gray-500">
تضمین برگشت پول{" "}
</small>
</div>
</div>
<div className="flex rtl mx-8">
{" "}
<div className="ml-1">
<svg
width="40"
height="40"
viewBox="0 0 263 225"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-55"
>
<path
d="M32.8125 0C24.1101 0 15.7641 3.45702 9.61056 9.61056C3.45702 15.7641 0 24.1101 0 32.8125V154.688C0 172.8 14.7 187.5 32.8125 187.5H75.6562C74.7665 181.282 74.7665 174.968 75.6562 168.75H32.8125C29.0829 168.75 25.506 167.268 22.8688 164.631C20.2316 161.994 18.75 158.417 18.75 154.688V32.8125C18.75 29.0829 20.2316 25.506 22.8688 22.8688C25.506 20.2316 29.0829 18.75 32.8125 18.75H229.688C233.417 18.75 236.994 20.2316 239.631 22.8688C242.268 25.506 243.75 29.0829 243.75 32.8125V118.819C250.781 122.156 257.119 126.694 262.5 132.188V32.8125C262.5 24.1101 259.043 15.7641 252.889 9.61056C246.736 3.45702 238.39 0 229.688 0H32.8125ZM122.175 115.125C121.674 111.248 119.778 107.685 116.841 105.104C113.904 102.523 110.128 101.1 106.219 101.1H53.5875C49.3208 101.1 45.2289 102.795 42.2119 105.812C39.1949 108.829 37.5 112.921 37.5 117.188C37.5006 124.17 39.8353 130.953 44.1329 136.456C48.4305 141.96 54.4444 145.869 61.2187 147.562L62.2125 147.825C68.4937 149.381 74.9062 150.113 81.3375 149.981C85.3102 141.629 90.9986 134.208 98.0319 128.203C105.065 122.197 113.304 117.741 122.175 115.125ZM150 65.625C150 63.1386 150.988 60.754 152.746 58.9959C154.504 57.2377 156.889 56.25 159.375 56.25H215.625C218.111 56.25 220.496 57.2377 222.254 58.9959C224.012 60.754 225 63.1386 225 65.625C225 68.1114 224.012 70.496 222.254 72.2541C220.496 74.0123 218.111 75 215.625 75H159.375C156.889 75 154.504 74.0123 152.746 72.2541C150.988 70.496 150 68.1114 150 65.625ZM79.8938 88.3875C83.2351 88.3875 86.5437 87.7294 89.6307 86.4507C92.7176 85.172 95.5225 83.2979 97.8852 80.9352C100.248 78.5725 102.122 75.7676 103.401 72.6806C104.679 69.5937 105.338 66.2851 105.338 62.9437C105.338 59.6024 104.679 56.2938 103.401 53.2068C102.122 50.1199 100.248 47.315 97.8852 44.9523C95.5225 42.5896 92.7176 40.7155 89.6307 39.4368C86.5437 38.1581 83.2351 37.5 79.8938 37.5C73.1457 37.5 66.6739 40.1807 61.9023 44.9523C57.1307 49.7239 54.45 56.1956 54.45 62.9437C54.45 69.6918 57.1307 76.1636 61.9023 80.9352C66.6739 85.7068 73.1457 88.3875 79.8938 88.3875ZM140.625 131.25C128.193 131.25 116.27 136.189 107.479 144.979C98.6886 153.77 93.75 165.693 93.75 178.125C93.75 190.557 98.6886 202.48 107.479 211.271C116.27 220.061 128.193 225 140.625 225H150C152.486 225 154.871 224.012 156.629 222.254C158.387 220.496 159.375 218.111 159.375 215.625C159.375 213.139 158.387 210.754 156.629 208.996C154.871 207.238 152.486 206.25 150 206.25H140.625C133.166 206.25 126.012 203.287 120.738 198.012C115.463 192.738 112.5 185.584 112.5 178.125C112.5 170.666 115.463 163.512 120.738 158.238C126.012 152.963 133.166 150 140.625 150H150C152.486 150 154.871 149.012 156.629 147.254C158.387 145.496 159.375 143.111 159.375 140.625C159.375 138.139 158.387 135.754 156.629 133.996C154.871 132.238 152.486 131.25 150 131.25H140.625ZM206.25 131.25C203.764 131.25 201.379 132.238 199.621 133.996C197.863 135.754 196.875 138.139 196.875 140.625C196.875 143.111 197.863 145.496 199.621 147.254C201.379 149.012 203.764 150 206.25 150H215.625C223.084 150 230.238 152.963 235.512 158.238C240.787 163.512 243.75 170.666 243.75 178.125C243.75 185.584 240.787 192.738 235.512 198.012C230.238 203.287 223.084 206.25 215.625 206.25H206.25C203.764 206.25 201.379 207.238 199.621 208.996C197.863 210.754 196.875 213.139 196.875 215.625C196.875 218.111 197.863 220.496 199.621 222.254C201.379 224.012 203.764 225 206.25 225H215.625C228.057 225 239.98 220.061 248.771 211.271C257.561 202.48 262.5 190.557 262.5 178.125C262.5 165.693 257.561 153.77 248.771 144.979C239.98 136.189 228.057 131.25 215.625 131.25H206.25ZM140.625 168.75C138.139 168.75 135.754 169.738 133.996 171.496C132.238 173.254 131.25 175.639 131.25 178.125C131.25 180.611 132.238 182.996 133.996 184.754C135.754 186.512 138.139 187.5 140.625 187.5H215.625C218.111 187.5 220.496 186.512 222.254 184.754C224.012 182.996 225 180.611 225 178.125C225 175.639 224.012 173.254 222.254 171.496C220.496 169.738 218.111 168.75 215.625 168.75H140.625Z"
fill="black"
/>
</svg>
</div>
<div className="text-right">
<p className="mb-0 font-medium">پشتیبانی حرفه ای</p>
<small className="mb-0 relative top-[-5px] text-gray-500">
همه ساعت روز هفت روز
</small>
</div>
</div>
</div>
</div> */}
</div>
{/* <div className="xs:px-3 md:px-10 md:container md:mx-auto mb-10 ">
<div className="grid xs:grid-cols-1 lg:grid-cols-4 mb-5 gap-4 mt-[240px]">
<div className="bg-white rounded-3xl overflow-hidden relative">
<div className="">
<svg
class="absolute inset-x-0 mx-auto h-[30px] rotate-180 block bottom-0 "
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 740 155.61"
>
<path
fill="white"
d="M532.54 85.81c69.58,-54.09 138.74,-82.63 207.46,-85.62l-740 0c73.71,3.21 147.93,35.81 222.63,97.82 28.75,23.85 45.98,38.3 83.91,49.54 20.26,6.01 41.42,8.74 63.46,8.18 28.55,0.73 55.61,-4.06 81.17,-14.35 36.28,-14.61 51.98,-32.73 81.37,-55.57z"
></path>
</svg>
<div></div>
<div className="flex justify-center w-full">
<div className="absolute flex bottom-0 ">
<div className="w-5 h-5 rounded-full bg-primary-600"></div>
</div>
</div>
</div>
<Image src={cat1} className="object-cover w-full" />
</div>
<div className="bg-white rounded-3xl overflow-hidden relative">
<div className="">
<svg
class="absolute inset-x-0 mx-auto h-[30px] rotate-180 block bottom-0 "
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 740 155.61"
>
<path
fill="white"
d="M532.54 85.81c69.58,-54.09 138.74,-82.63 207.46,-85.62l-740 0c73.71,3.21 147.93,35.81 222.63,97.82 28.75,23.85 45.98,38.3 83.91,49.54 20.26,6.01 41.42,8.74 63.46,8.18 28.55,0.73 55.61,-4.06 81.17,-14.35 36.28,-14.61 51.98,-32.73 81.37,-55.57z"
></path>
</svg>
<div></div>
<div className="flex justify-center w-full">
<div className="absolute flex bottom-0 ">
<div className="w-5 h-5 rounded-full bg-primary-600"></div>
</div>
</div>
</div>
<Image src={cat2} className="object-cover w-full" />
</div>
<div className="bg-white rounded-3xl overflow-hidden relative">
<div className="">
<svg
class="absolute inset-x-0 mx-auto h-[30px] rotate-180 block bottom-0 "
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 740 155.61"
>
<path
fill="white"
d="M532.54 85.81c69.58,-54.09 138.74,-82.63 207.46,-85.62l-740 0c73.71,3.21 147.93,35.81 222.63,97.82 28.75,23.85 45.98,38.3 83.91,49.54 20.26,6.01 41.42,8.74 63.46,8.18 28.55,0.73 55.61,-4.06 81.17,-14.35 36.28,-14.61 51.98,-32.73 81.37,-55.57z"
></path>
</svg>
<div></div>
<div className="flex justify-center w-full">
<div className="absolute flex bottom-0 ">
<div className="w-5 h-5 rounded-full bg-primary-600"></div>
</div>
</div>
</div>
<Image src={cat3} className="object-cover w-full" />
</div>
<div className="bg-white rounded-3xl overflow-hidden relative">
<div className="">
<svg
class="absolute inset-x-0 mx-auto h-[30px] rotate-180 block bottom-0 "
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 740 155.61"
>
<path
fill="white"
d="M532.54 85.81c69.58,-54.09 138.74,-82.63 207.46,-85.62l-740 0c73.71,3.21 147.93,35.81 222.63,97.82 28.75,23.85 45.98,38.3 83.91,49.54 20.26,6.01 41.42,8.74 63.46,8.18 28.55,0.73 55.61,-4.06 81.17,-14.35 36.28,-14.61 51.98,-32.73 81.37,-55.57z"
></path>
</svg>
<div></div>
<div className="flex justify-center w-full">
<div className="absolute flex bottom-0 ">
<div className="w-5 h-5 rounded-full bg-primary-600"></div>
</div>
</div>
</div>
<Image src={cat1} className="object-cover w-full" />
</div>
</div>
</div> */}
<div className="lg:mt-[450px] ">
<div className="text-center relative">
<div className="absolute xs:mt-[-30px] lg:mt-[-45px] w-full z-0">
<p className="xs:text-[40px] lg:text-[80px] bet-text font-bold">
Category Bonsai
</p>
</div>
<h2 className="xs:text-[20px] lg:text-[40px] font-bold relative z-10">
دسته بندی های <span className="text-green-800"> بونسای</span>
</h2>
<p className="mb-0 xs:text-[12px] lg:text-sm text-gray-400">
با تصمین کمترین قیمت در تمامی دستنه بندی ها خرید کنید{" "}
</p>
</div>
<div className="xs:px-3 md:px-20 md:container md:mx-auto xs:mt-5 lg:mt-10 mb-20 ">
<div className="grid xs:grid-cols-2 lg:grid-cols-5">
<div className=" mx-auto mt-10 group cursor-pointer">
<div className=" tr03 group-hover:-rotate-2 group-hover:scale-110 group-hover:contrast-150">
<Image src={cat12} />
</div>
<div className="flex justify-center relative">
<div className="bg-sky-900 p-1 rounded-full rtl absolute top-[-15px] px-5 ">
<p className="mb-0 text-center text-gray-200 text-sm font-light">
+
<PersianNumber number={25} />
{" "} محصول
</p>
</div>
</div>
<p className="mb-0 text-center mt-4 text-gray-600 font-medium">
سینی های روسی{" "}
</p>
</div>
<div className=" mx-auto mt-10 group cursor-pointer">
<div className=" tr03 group-hover:-rotate-2 group-hover:scale-110 group-hover:contrast-150">
<Image src={cat11} />
</div>
<div className="flex justify-center relative">
<div className="bg-sky-900 p-1 rounded-full rtl absolute top-[-15px] px-5 ">
<p className="mb-0 text-center text-gray-200 text-sm font-light">
+
<PersianNumber number={25} />
{" "} محصول
</p>
</div>
</div>
<p className="mb-0 text-center mt-4 text-gray-600 font-medium">
سینی های روسی{" "}
</p>
</div>
<div className=" mx-auto mt-10 group cursor-pointer">
<div className=" tr03 group-hover:-rotate-2 group-hover:scale-110 group-hover:contrast-150">
<Image src={cat13} />
</div>
<div className="flex justify-center relative">
<div className="bg-sky-900 p-1 rounded-full rtl absolute top-[-15px] px-5 ">
<p className="mb-0 text-center text-gray-200 text-sm font-light">
+
<PersianNumber number={25} />
{" "} محصول
</p>
</div>
</div>
<p className="mb-0 text-center mt-4 text-gray-600 font-medium">
سینی های روسی{" "}
</p>
</div>
<div className=" mx-auto mt-10 group cursor-pointer">
<div className=" tr03 group-hover:-rotate-2 group-hover:scale-110 group-hover:contrast-150">
<Image src={cat14} />
</div>
<div className="flex justify-center relative">
<div className="bg-sky-900 p-1 rounded-full rtl absolute top-[-15px] px-5 ">
<p className="mb-0 text-center text-gray-200 text-sm font-light">
+
<PersianNumber number={25} />
{" "} محصول
</p>
</div>
</div>
<p className="mb-0 text-center mt-4 text-gray-600 font-medium">
سینی های روسی{" "}
</p>
</div>
<div className=" mx-auto mt-10 group cursor-pointer">
<div className=" tr03 group-hover:-rotate-2 group-hover:scale-110 group-hover:contrast-150">
<Image src={cat15} />
</div>
<div className="flex justify-center relative">
<div className="bg-sky-900 p-1 rounded-full rtl absolute top-[-15px] px-5 ">
<p className="mb-0 text-center text-gray-200 text-sm font-light">
+
<PersianNumber number={25} />
{" "} محصول
</p>
</div>
</div>
<p className="mb-0 text-center mt-4 text-gray-600 font-medium">
سینی های روسی{" "}
</p>
</div>
<div className=" mx-auto mt-10 group cursor-pointer">
<div className=" tr03 group-hover:-rotate-2 group-hover:scale-110 group-hover:contrast-150">
<Image src={cat12} />
</div>
<div className="flex justify-center relative">
<div className="bg-sky-900 p-1 rounded-full rtl absolute top-[-15px] px-5 ">
<p className="mb-0 text-center text-gray-200 text-sm font-light">
+
<PersianNumber number={25} />
{" "} محصول
</p>
</div>
</div>
<p className="mb-0 text-center mt-4 text-gray-600 font-medium">
سینی های روسی{" "}
</p>
</div>
<div className=" mx-auto mt-10 group cursor-pointer">
<div className=" tr03 group-hover:-rotate-2 group-hover:scale-110 group-hover:contrast-150">
<Image src={cat11} />
</div>
<div className="flex justify-center relative">
<div className="bg-sky-900 p-1 rounded-full rtl absolute top-[-15px] px-5 ">
<p className="mb-0 text-center text-gray-200 text-sm font-light">
+
<PersianNumber number={25} />
{" "} محصول
</p>
</div>
</div>
<p className="mb-0 text-center mt-4 text-gray-600 font-medium">
سینی های روسی{" "}
</p>
</div>
<div className=" mx-auto mt-10 group cursor-pointer">
<div className=" tr03 group-hover:-rotate-2 group-hover:scale-110 group-hover:contrast-150">
<Image src={cat13} />
</div>
<div className="flex justify-center relative">
<div className="bg-sky-900 p-1 rounded-full rtl absolute top-[-15px] px-5 ">
<p className="mb-0 text-center text-gray-200 text-sm font-light">
+
<PersianNumber number={25} />
{" "} محصول
</p>
</div>
</div>
<p className="mb-0 text-center mt-4 text-gray-600 font-medium">
سینی های روسی{" "}
</p>
</div>
<div className=" mx-auto mt-10 group cursor-pointer">
<div className=" tr03 group-hover:-rotate-2 group-hover:scale-110 group-hover:contrast-150">
<Image src={cat14} />
</div>
<div className="flex justify-center relative">
<div className="bg-sky-900 p-1 rounded-full rtl absolute top-[-15px] px-5 ">
<p className="mb-0 text-center text-gray-200 text-sm font-light">
+
<PersianNumber number={25} />
{" "} محصول
</p>
</div>
</div>
<p className="mb-0 text-center mt-4 text-gray-600 font-medium">
سینی های روسی{" "}
</p>
</div>
<div className=" mx-auto mt-10 group cursor-pointer">
<div className=" tr03 group-hover:-rotate-2 group-hover:scale-110 group-hover:contrast-150">
<Image src={cat15} />
</div>
<div className="flex justify-center relative">
<div className="bg-sky-900 p-1 rounded-full rtl absolute top-[-15px] px-5 ">
<p className="mb-0 text-center text-gray-200 text-sm font-light">
+
<PersianNumber number={25} />
{" "} محصول
</p>
</div>
</div>
<p className="mb-0 text-center mt-4 text-gray-600 font-medium">
سینی های روسی{" "}
</p>
</div>
</div>
</div>
</div>
<div className="relative mt-[120px]">
<div className=" absolute bottom-[-10px] w-full" data-negative="true">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1000 100"
preserveAspectRatio="none"
>
<path
fill="#14532d"
d="M500,97C126.7,96.3,0.8,19.8,0,0v100l1000,0V1C1000,19.4,873.3,97.8,500,97z"
></path>
</svg>{" "}
</div>
</div>
<div className="relative ">
<div className="">
<svg
class="absolute inset-x-0 mx-auto h-[30px] block top-0 "
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 740 155.61"
>
<path
fill="white"
d="M532.54 85.81c69.58,-54.09 138.74,-82.63 207.46,-85.62l-740 0c73.71,3.21 147.93,35.81 222.63,97.82 28.75,23.85 45.98,38.3 83.91,49.54 20.26,6.01 41.42,8.74 63.46,8.18 28.55,0.73 55.61,-4.06 81.17,-14.35 36.28,-14.61 51.98,-32.73 81.37,-55.57z"
></path>
</svg>
<div></div>
<div className="flex justify-center w-full">
<div className="absolute flex top-0 ">
<div className="w-5 h-5 rounded-full bg-green-900"></div>
</div>
</div>
</div>
<div className=" bg-green-900 pb-20 xs:px-5 lg:px-20">
<div className="text-center relative pt-[120px]">
<div className="absolute xs:mt-[-30px] lg:mt-[-45px] w-full z-0">
<p className="xs:text-[40px] lg:text-[80px] bet-text-green font-bold">
Suprise Bonsai
</p>
</div>
<h2 className="xs:text-[20px] lg:text-[40px] font-bold relative z-10 text-white">
پیشنهادات ویژه <span className="text-primary-400"> بونسای</span>
</h2>
<p className="mb-0 xs:text-[12px] lg:text-sm text-gray-400">
هر روز از ساعت شش عصر تا 12 شب ویژه های بونسایی را مشاهده کنید{" "}
</p>
</div>
<div className="mt-20">
<Swiper
spaceBetween={50}
slidesPerView={6.2}
// onSlideChange={() => console.log("slide change")}
className="rtl relative mt-5"
// dir="rtl"
breakpoints={{
320: {
slidesPerView: 1.4,
},
480: {
slidesPerView: 2,
},
768: {
slidesPerView: 3,
},
1024: {
slidesPerView: 4.5,
},
1440: {
slidesPerView: 6,
},
}}
>
{data?.products?.map((e, index) => (
<SwiperSlide key={index}>
<CardSurprise data={e} priority />
</SwiperSlide>
))}
</Swiper>
</div>
</div>
</div>
<div className="mt-[120px]">
<div className="xs:px-3 md:px-10 md:container md:mx-auto mb-10 ">
<div className="text-center relative mb-20">
<div className="absolute xs:mt-[-30px] lg:mt-[-45px] w-full z-0">
<p className="xs:text-[40px] lg:text-[80px] bet-text font-bold">
affordable gift
</p>
</div>
<h2 className="xs:text-[30px] lg:text-[40px] font-bold relative z-10">
هدیه های به صرفه
<span className="text-green-800"> بونسای</span>
</h2>
<p className="mb-0 text-sm text-gray-400">
با تصمین کمترین قیمت در تمامی دستنه بندی ها خرید کنید{" "}
</p>
</div>
<div className="grid xs:grid-cols-2 lg:grid-cols-5 gap-5">
{data?.products?.map((e) => (
<div className="relative">
<CardNormal data={e} priority />
</div>
))}
</div>
</div>
</div>
<div className="relative mt-20">
<div className="">
<svg
class="absolute inset-x-0 mx-auto h-[30px] block top-0 "
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 740 155.61"
>
<path
fill="white"
d="M532.54 85.81c69.58,-54.09 138.74,-82.63 207.46,-85.62l-740 0c73.71,3.21 147.93,35.81 222.63,97.82 28.75,23.85 45.98,38.3 83.91,49.54 20.26,6.01 41.42,8.74 63.46,8.18 28.55,0.73 55.61,-4.06 81.17,-14.35 36.28,-14.61 51.98,-32.73 81.37,-55.57z"
></path>
</svg>
<div></div>
</div>
<div className=" bg-gray-100 pb-20 px-20"></div>
</div>
<div className="bg-gray-200">
<div className=" xs:px-5 lg:px-20 xs:py-3 lg:py-5 ">
<div className="grid xs:grid-cols-1 lg:grid-cols-2 gap-10 rtl ">
<div className="grid xs:grid-cols-1 lg:grid-cols-3 gap-10 ">
<div className="col-span-2">
<div className="grid xs:grid-cols-1 lg:grid-cols-2"></div>
<div className=" ">
<div>
<p className="mb-0">محصولات</p>
<div className="h-[1px] w-full bg-gray-200 mt-2"></div>
</div>
<div className="grid xs:grid-cols-2 lg:grid-cols-2">
<div>
<ul>
<Link
href={`/categories/bdf6b13c-4be5-4a93-bcdb-612440bdbd6e/کرم مرطوب کننده دست و پا`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
کرم مرطوب کننده دست و پا{" "}
</li>
</Link>
<Link
href={`/categories/20dce1e7-1dfe-4b2a-9764-6f3ddf46fdb2/مرطوب کننده و آبرسان صورت`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
مرطوب کننده و آبرسان صورت{" "}
</li>
</Link>
<Link
href={`/categories/16bcdc90-6842-4201-9d5c-54cd8f565148/شوینده سطوح`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
شوینده سطوح
</li>
</Link>
<Link
href={`/categories/b7549222-87f7-4b0b-8938-210539b3a395/بهداشت دهان و دندان`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
بهداشت دهان و دندان
</li>
</Link>
<Link
href={`/categories/f3e79ed0-d608-470d-8656-7a98ff933c1e/نرم کننده مو`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
نرم کننده مو
</li>
</Link>
</ul>
</div>
<div>
<ul>
<Link
href={`/categories/b909db09-2188-4a4d-8578-e1f7102947bc/کیت رنگ مو`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
کیت رنگ مو{" "}
</li>
</Link>
<Link
href={`/categories/effe5d98-d4b7-47e1-9bfb-4d3c77ab3347/بهداشت خانه و آشپرخانه`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
بهداشت خانه و آشپرخانه{" "}
</li>
</Link>
<Link
href={`/categories/debf7aad-4f08-4d03-ba70-6663ae1aa90d/سرم مو`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
سرم مو{" "}
</li>
</Link>
<Link
href={`/categories/8bf20569-c3e3-457f-b9ad-140ef449741b/ژل بهداشتی بانوان`}
>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
ژل بهداشتی بانوان{" "}
</li>
</Link>
<Link href={`/blogs?page=0`}>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
مجله زیبایی وسمه{" "}
</li>
</Link>
</ul>
</div>
</div>
</div>
</div>
<div className=" ">
<div>
<p className="mb-0">درباره ما</p>
<div className="h-[1px] w-full bg-gray-200 mt-2"></div>
</div>
<div>
<ul>
<Link href={`/faq`}>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
سوالات متداول{" "}
</li>
</Link>
<Link href={`/contact-us`}>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
تماس باما{" "}
</li>
</Link>
<Link href={`/terms-and-conditions`}>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
قوانین سایت
</li>
</Link>
<Link href={`/about-us`}>
<li className="text-sm text-gray-600 mt-2 xs:py-2 lg:py-0">
درباره ما{" "}
</li>
</Link>
</ul>
</div>
</div>
</div>
<div>
<div>
<p className="mb-0">چرا بونسای</p>
<div className="h-[1px] w-full bg-gray-200 mt-2"></div>
</div>
<p className="mb-0 text-sm text-gray-600 mt-3">
وسمه تعهد داره تجربه خرید لوازم آرایشی و بهداشتی رو متحول کنه.
این تحول میتونه برای مشتری احساس قسمتی از خانواده وسمه بودن رو
داشته باشه. وسمه با برطرف کردن دغدغههای خرید لوازم آرایشی و
بهداشتی به ساختن لایف استایل شخصی خانمهای ایرانی کمک میکنه و
زندگی راحتتری پیش روی مشتریانش قرار میده. از سال 1400 ما تمام
انرژیمون رو به کار گرفتیم تا با تمرکز برکیفیت کالا، سرعت ارسال و
قیمت کالا ، نیاز افراد رو برطرف کنیم و تجربه جدیدی از لذت خرید
به وجود بیاریم.
</p>
<div className="lg:flex ltr lg:justify-between mt-5 ">
<div className=" flex flex-wrap mx-auto xs:justify-center lg:justify-end xs:ml-0 ">
<div className="bg-white w-[100px] h-[100px] rounded-3xl mx-2 xs:mt-3 lg:mt-0">
<a
referrerpolicy="origin"
target="_blank"
href="https://trustseal.enamad.ir/?id=274373&Code=FSm0y9hlccuslQp7UNJT"
>
<img
referrerpolicy="origin"
src="https://trustseal.enamad.ir/logo.aspx?id=274373&Code=FSm0y9hlccuslQp7UNJT"
alt=""
style={{ cursor: "pointer" }}
Code="FSm0y9hlccuslQp7UNJT"
/>
</a>
</div>
<div className="bg-white w-[100px] h-[100px] rounded-3xl mx-2 xs:mt-3 lg:mt-0"></div>
</div>
<div className="flex xs:justify-center lg:justify-normal rtl xs:mt-5 lg:mt-0">
<a href={`https://www.instagram.com/vesmehcom`}>
<div className="bg-white p-2 h-fit rounded-2xl mx-1">
<svg
width="25"
height="25"
viewBox="0 0 226 227"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-60"
>
<path
d="M112.987 55.2129C97.658 55.2129 82.9563 61.3025 72.1167 72.1421C61.2771 82.9817 55.1875 97.6834 55.1875 113.013C55.1875 128.342 61.2771 143.044 72.1167 153.884C82.9563 164.723 97.658 170.813 112.987 170.813C128.317 170.813 143.019 164.723 153.858 153.884C164.698 143.044 170.787 128.342 170.787 113.013C170.787 97.6834 164.698 82.9817 153.858 72.1421C143.019 61.3025 128.317 55.2129 112.987 55.2129ZM112.987 150.55C108.056 150.55 103.174 149.579 98.6177 147.692C94.062 145.805 89.9225 143.039 86.4356 139.552C82.9488 136.065 80.1829 131.926 78.2958 127.37C76.4088 122.814 75.4375 117.932 75.4375 113C75.4375 108.069 76.4088 103.186 78.2958 98.6306C80.1829 94.0749 82.9488 89.9354 86.4356 86.4485C89.9225 82.9617 94.062 80.1958 98.6177 78.3087C103.174 76.4216 108.056 75.4504 112.987 75.4504C122.946 75.4504 132.497 79.4065 139.539 86.4485C146.581 93.4905 150.538 103.042 150.538 113C150.538 122.959 146.581 132.51 139.539 139.552C132.497 146.594 122.946 150.55 112.987 150.55Z"
fill="black"
/>
<path
d="M173.075 66.5623C180.517 66.5623 186.55 60.5293 186.55 53.0873C186.55 45.6453 180.517 39.6123 173.075 39.6123C165.633 39.6123 159.6 45.6453 159.6 53.0873C159.6 60.5293 165.633 66.5623 173.075 66.5623Z"
fill="black"
/>
<path
d="M219.663 39.3875C216.769 31.9148 212.347 25.1285 206.68 19.4632C201.012 13.7979 194.224 9.37839 186.75 6.4875C178.005 3.20446 168.765 1.42926 159.425 1.2375C147.388 0.712499 143.575 0.5625 113.05 0.5625C82.5254 0.5625 78.6129 0.562499 66.6754 1.2375C57.3428 1.41946 48.1099 3.19502 39.3754 6.4875C31.8996 9.37502 25.1099 13.7934 19.4421 19.4591C13.7742 25.1248 9.35325 31.9128 6.46289 39.3875C3.1792 48.1327 1.40807 57.373 1.22539 66.7125C0.687891 78.7375 0.525391 82.55 0.525391 113.087C0.525391 143.612 0.525391 147.5 1.22539 159.462C1.41289 168.812 3.17539 178.037 6.46289 186.8C9.36136 194.272 13.7866 201.057 19.4558 206.722C25.1251 212.387 31.9137 216.807 39.3879 219.7C48.1058 223.115 57.3425 225.017 66.7004 225.325C78.7379 225.85 82.5504 226.012 113.075 226.012C143.6 226.012 147.513 226.012 159.45 225.325C168.789 225.135 178.028 223.364 186.775 220.088C194.247 217.19 201.033 212.766 206.7 207.1C212.367 201.433 216.79 194.647 219.688 187.175C222.975 178.425 224.738 169.2 224.925 159.85C225.463 147.825 225.625 144.013 225.625 113.475C225.625 82.9375 225.625 79.0625 224.925 67.1C224.78 57.6284 223 48.2531 219.663 39.3875ZM204.438 158.537C204.357 165.741 203.042 172.878 200.55 179.637C198.673 184.498 195.799 188.913 192.114 192.596C188.428 196.279 184.012 199.151 179.15 201.025C172.466 203.506 165.405 204.821 158.275 204.912C146.4 205.462 143.05 205.6 112.6 205.6C82.1254 205.6 79.0129 205.6 66.9129 204.912C59.787 204.825 52.7295 203.51 46.0504 201.025C41.1715 199.162 36.7379 196.296 33.0365 192.612C29.3351 188.928 26.4483 184.508 24.5629 179.637C22.106 172.951 20.7918 165.898 20.6754 158.775C20.1379 146.9 20.0129 143.55 20.0129 113.1C20.0129 82.6375 20.0129 79.525 20.6754 67.4125C20.7562 60.2128 22.0711 53.0802 24.5629 46.325C28.3754 36.4625 36.1879 28.7 46.0504 24.925C52.7328 22.4517 59.7882 21.137 66.9129 21.0375C78.8004 20.5 82.1379 20.35 112.6 20.35C143.063 20.35 146.188 20.35 158.275 21.0375C165.406 21.1233 172.467 22.4384 179.15 24.925C184.012 26.8034 188.427 29.6775 192.113 33.3629C195.798 37.0482 198.672 41.4634 200.55 46.325C203.007 53.0119 204.321 60.0645 204.438 67.1875C204.975 79.075 205.113 82.4125 205.113 112.875C205.113 143.325 205.113 146.6 204.575 158.55L204.438 158.537Z"
fill="black"
/>
</svg>
</div>
</a>
<a href={`https://t.me/vesmehhcom`}>
<div className="bg-white p-2 h-fit rounded-2xl mx-1">
<svg
width="25"
height="25"
viewBox="0 0 300 300"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-60"
>
<g clip-path="url(#clip0_633_2)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M247.213 55.3746C250.302 54.0745 253.683 53.6261 257.004 54.076C260.325 54.526 263.465 55.8579 266.097 57.9331C268.728 60.0083 270.756 62.751 271.968 65.8756C273.18 69.0002 273.532 72.3926 272.988 75.6996L244.638 247.662C241.888 264.25 223.688 273.762 208.476 265.5C195.751 258.587 176.851 247.937 159.851 236.825C151.351 231.262 125.313 213.45 128.513 200.775C131.263 189.937 175.013 149.212 200.013 125C209.826 115.487 205.351 110 193.763 118.75C164.988 140.475 118.788 173.512 103.513 182.812C90.0381 191.012 83.013 192.412 74.613 191.012C59.288 188.462 45.0756 184.512 33.4756 179.7C17.8006 173.2 18.5631 151.65 33.4631 145.375L247.213 55.3746Z"
fill="black"
/>
</g>
<defs>
<clipPath id="clip0_633_2">
<rect width="300" height="300" fill="white" />
</clipPath>
</defs>
</svg>
</div>
</a>
<a href={`https://web.bale.ai/flow/search?uid=5560485550`}>
<div className="bg-white p-2 h-fit rounded-2xl mx-1">
<div className="w-[25px]">
<Image
// src={bale}
className="opacity-60"
alt="پیام رسان بله وسمه"
/>
</div>
</div>
</a>
<a href={`https://twitter.com/vesmehcom`}>
<div className="bg-white p-2 h-fit rounded-2xl mx-1">
<svg
width="25"
height="25"
viewBox="0 0 300 244"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-60"
>
<path
d="M94.2375 243.763C207.45 243.763 269.381 149.957 269.381 68.7505C269.406 66.113 269.369 63.4755 269.269 60.838C281.322 52.1051 291.728 41.2996 300 28.9255C288.733 33.8806 276.8 37.1531 264.581 38.638C277.455 30.945 287.096 18.8382 291.712 4.56925C279.624 11.7453 266.385 16.7757 252.581 19.438C243.303 9.55719 231.026 3.01145 217.652 0.814699C204.277 -1.38206 190.551 0.892774 178.6 7.28682C166.649 13.6809 157.14 23.8373 151.546 36.1829C145.952 48.5285 144.585 62.3742 147.656 75.5755C123.181 74.3541 99.2371 67.9989 77.378 56.9223C55.519 45.8458 36.2339 30.2957 20.775 11.2817C12.9296 24.8407 10.5366 40.8765 14.0814 56.1352C17.6262 71.3939 26.8433 84.7325 39.8625 93.4442C30.1014 93.1288 20.5536 90.5074 12 85.7942V86.638C12.0239 100.839 16.9466 114.597 25.9373 125.589C34.928 136.582 47.436 144.135 61.35 146.976C56.0676 148.431 50.6106 149.157 45.1313 149.132C41.2672 149.172 37.4094 148.814 33.6187 148.063C37.5449 160.294 45.2021 170.988 55.5157 178.645C65.8293 186.302 78.2816 190.537 91.125 190.757C69.3019 207.875 42.3609 217.166 14.625 217.138C9.73685 217.175 4.85149 216.893 0 216.294C28.1517 234.247 60.8487 243.777 94.2375 243.763Z"
fill="black"
/>
</svg>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
<p className="mb-0 text-gray-400 text-sm text-center py-5 rtl bg-gray-100">
استفاده از مطالب فروشگاه وسمه فقط برای مقاصد غیرتجاری و باذکر منبع
بلامانع است. کلیه حقوق این سایت متعلق به شرکت وسمه می باشد. ورژن
</p>
</div>
</div>
);
};
export default HeroSection;

View File

@ -0,0 +1,81 @@
import CardNormal from "@comp/Cards/CardNormal/page";
import Image from "next/image";
import { Swiper, SwiperSlide } from "swiper/react";
import khane from "../../../public/images/khane.jpg";
import CardSurprise from "@comp/Cards/CardSurprise/page";
import Link from "next/link";
const HomeSection = ({ data }) => {
return (
<section className="xs:mb-0 lg:mb-20">
<div className=" xs:px-5 lg:px-20 mt-10">
<div className="grid xs:grid-cols-1 lg:grid-cols-3 rtl ">
<div className="rounded-3xl overflow-hidden relative z-10 h-fit">
<div className="w-full">
<Image
src={khane}
className="object-cover"
alt="لوازم بهداشتی منزل وسمه"
/>
</div>
</div>
<div className="relative xs:left-[0px] lg:left-[30px] xs:top-[-35px] lg:top-0 col-span-2 z-0 rounded-3xl xs:pr-5 lg:pr-[55px] xs:pt-[55px] lg:pt-3 xl:pt-10 pl-5 xs:pb-10 lg:pb-0">
<div className="xs:block lg:flex">
<h2 className="xs:text-2xl lg:text-xl xl:text-3xl font-bold">
لوازم بهداشتی منزل وسمه
</h2>
<p className="mb-0 w-fit bg-sky-200 rounded-full py-1 px-3 xs:mr-0 lg:mr-2 xs:mt-2 lg:mt-0 xs:text-sm lg:text-sm xl:text-base ">
به صرفه شـــــــــــــو
</p>
</div>
<Swiper
spaceBetween={50}
slidesPerView={6.2}
// onSlideChange={() => console.log("slide change")}
// onSwiper={(swiper) => console.log(swiper)}
className="rtl relative mt-4"
breakpoints={{
320: {
slidesPerView: 1.3,
},
480: {
slidesPerView: 2,
},
768: {
slidesPerView: 3,
},
1024: {
slidesPerView: 3.4,
},
1440: {
slidesPerView: 3.8,
},
}}
>
{data?.map((e, index) => (
<SwiperSlide key={index}>
<CardSurprise data={e} priority />
</SwiperSlide>
))}
</Swiper>
</div>
</div>
<Link
href={"/categories/89631880-a1a3-4759-8fcd-d9284a8f97ed/شوینده-ظروف"}
className="z-90 relative"
>
<div className="mx-5">
<p className="mb-0 text-sm text-gray-600 xs:text-white md:text-black">
مشاهده بیشتر{" "}
</p>
</div>
</Link>
</div>
</section>
);
};
export default HomeSection;

View File

@ -0,0 +1,85 @@
import CardNormal from "@comp/Cards/CardNormal/page";
import TimerDown from "@comp/TimerDown/TimerDown";
import Link from "next/link";
import { Swiper, SwiperSlide } from "swiper/react";
const SurpriseSection = ({ data }) => {
return (
<section
className="mb-10 pb-10 xs:bg-red-500 lg:bg-transparent xs:mx-3 lg:mx-0 xs:px-5 lg:px-0 xs:rounded-3xl lg:rounded-[0px] mt-20"
id="offer"
>
<div className=" relative xs:hidden lg:block ">
<div className="w-full flex justify-end absolute ">
<svg
width="700"
height="400"
viewBox="0 0 1037 590"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mr-[20px]"
>
<path
d="M25.6693 0H1012C1025.81 0 1037 11.1929 1037 25V565C1037 578.807 1025.81 590 1012 590H371.096C362.569 590 354.631 585.654 350.036 578.472L4.60942 38.4715C-6.03513 21.8311 5.91551 0 25.6693 0Z"
fill="#EF3D59"
/>
</svg>
</div>
</div>
<div className="xs:px-0 lg:px-20">
<div className="w-full rtl relative ">
<div className="pt-5 flex relative justify-between">
<p className="mb-0 text-white font-bold xs:text-sm lg:text-2xl xl:text-2xl">
پیشنهاد های ویژه امروز{" "}
</p>
<TimerDown />
</div>
</div>
<Swiper
spaceBetween={50}
slidesPerView={6.2}
// onSlideChange={() =>
// onSwiper={(swiper) =>
className="rtl relative mt-5"
breakpoints={{
320: {
slidesPerView: 1.4,
},
480: {
slidesPerView: 2,
},
768: {
slidesPerView: 3,
},
1024: {
slidesPerView: 4.5,
},
1440: {
slidesPerView: 6,
},
}}
>
{data?.map((e, index) => (
<SwiperSlide key={index}>
<CardNormal data={e} priority />
</SwiperSlide>
))}
</Swiper>
<Link
href={"/categories/0/همه%20محصولات?page=0&specialOffer=1"}
className="z-90 relative"
>
<div className="mx-5 mt-8">
<p className="mb-0 text-sm text-gray-600 xs:text-white md:text-black">
مشاهده بیشتر{" "}
</p>
</div>
</Link>
</div>
</section>
);
};
export default SurpriseSection;

View File

@ -0,0 +1,41 @@
"use client";
const LoginStep = ({ phoneNumber, setPhoneNumber, ConfirmPhoneNumber }) => {
return (
<div className="text-center mt-5">
<p className="mb-0 text-gray-300 text-base">ورود / ثبت نام</p>
<p className="mb-0 text-gray-600 text-lg mt-2">
شماره موبایل خود را وارد کنید
</p>
<div className="mt-2">
<input
type="text"
className="form-control !border-0 !bg-gray-200"
onChange={(e) => setPhoneNumber(e.target.value)}
/>
<div className="">
<button
className="btn btn-primary w-full rounded-xl py-3 mt-3"
onClick={() => ConfirmPhoneNumber()}
>
ورود و ثبت نام
</button>
</div>
<div className="mt-4">
<p className="mb-0 text-sm px-4 rtl">
با ورود و یا ثبت نام در وسمه شما{" "}
<small className="text-primary-400 text-sm font-semibold">
شرایط و قوانین
</small>{" "}
استفاده از سرویس های سایت وسمه و قوانین حریم خصوصی آن را می پذیرید.
</p>
</div>
</div>
</div>
);
};
export default LoginStep;

View File

@ -0,0 +1,48 @@
const SignUp = ({ setLastName, setFirstName, SignUpLogin }) => {
return (
<div className="text-center mt-5">
<p className="mb-0 text-gray-600 text-lg mt-2">مشخصات را وارد کنید </p>
<div className="mt-2">
<div className="form-group text-right my-2">
<label className=" px-2 text-sm"> نام </label>
<input
type="text"
className="form-control !border-0 !bg-gray-200 text-right"
onChange={(e) => setFirstName(e.target.value)}
/>
</div>
<div className="form-group text-right my-4 ">
<label className=" px-2 text-sm">نام خانوادگی </label>
<input
type="text"
className="form-control !border-0 !bg-gray-200 text-right"
onChange={(e) => setLastName(e.target.value)}
/>
</div>
<div className="">
<button
className="btn btn-primary w-full rounded-xl py-3 mt-3"
onClick={() => SignUpLogin()}
>
ورود و ثبت نام
</button>
</div>
<div className="mt-4">
<p className="mb-0 text-sm px-4 rtl">
با ورود و یا ثبت نام در وسمه شما{" "}
<small className="text-primary-400 text-sm font-semibold">
شرایط و قوانین
</small>{" "}
استفاده از سرویس های سایت وسمه و قوانین حریم خصوصی آن را می پذیرید.
</p>
</div>
</div>
</div>
);
};
export default SignUp;

View File

@ -0,0 +1,41 @@
"use client";
import PersianNumber from "plugins/PersianNumber";
const VerifyCodeStep = ({
LoginWhitVerifyCode,
setVerifyCode,
verifyCode,
phoneNumber,
}) => {
return (
<div className="px-5 mt-6">
<p className="mb-0 text-textMain-100 mt-1 text-right text-sm">
{" "}
پیامک حاوی کد تایید برای شماره
<strong className="mx-1">
<PersianNumber number={phoneNumber} />
</strong>
ارسال شده است
</p>
<div className="mt-3">
<input
placeholder="کد ارسال شده را وارد کنید"
type={"number"}
className="form-control !border-0 !bg-gray-200 text-center"
onChange={(e) => setVerifyCode(e.target.value)}
/>
</div>
<div className="">
<button
className="btn btn-primary w-full rounded-xl py-3 mt-3"
onClick={() => LoginWhitVerifyCode()}
>
ورود و ثبت نام
</button>
</div>
</div>
);
};
export default VerifyCodeStep;

View File

@ -0,0 +1,103 @@
"use client";
import CardCart from "@comp/Cards/CardCart/page";
import AppContext from "@ctx/AppContext";
import Link from "next/link";
import PersianNumber from "plugins/PersianNumber";
import { useContext, useState } from "react";
const CartNavbar = ({ isScrolled }) => {
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
const [smallBasket, setSmallBasket] = useState(false);
return (
<div
className={` ${
isScrolled
? " fixed w-fit !z-[100] mt-[-40px] left-0 ml-[100px] "
: "mr-2"
}`}
>
<div
className={`bg-secondary-600 rounded-xl text-sm flex cursor-pointer px-5 ${
isScrolled ? "p-1" : "py-2"
} `}
onClick={() => setSmallBasket(!smallBasket)}
>
<p className="mb-0 text-white">سبد خرید</p>
</div>
<div className="flex justify-end">
<div
className={`absolute mr-[3px] ${
isScrolled ? "mt-[-40px]" : "mt-[-50px]"
}`}
>
<div
className={`bg-white border-[1px] rounded-full text-center ${
isScrolled ? "w-[20px] h-[20px]" : "w-[25px] h-[25px] "
}`}
>
<PersianNumber
number={cart?.length}
style={` ${
isScrolled ? "!text-[10px] relative top-[-3px]" : "!text-sm"
}`}
/>{" "}
</div>
</div>
</div>
{smallBasket && (
<div
className={`relative !z-[100] tr03 ${
smallBasket ? "opacity-100" : "opacity-0"
} `}
>
<div className="absolute w-[400px] bg-white border-[3px] border-gray-100 rounded-xl mt-2 max-h-[450px] overflow-auto mr-[-310px] scroll-1">
<div className="text-center p-3">
<p className="mb-0 text-sm pb-3">
<PersianNumber
number={cart?.length}
style="text-xl font-bold text-base font-bold mx-2 !text-primary-500"
/>
محصول موجود در سبد
</p>
{/* <div className="w-5/12 mx-auto h-[1px] bg-gray-200 my-3"></div> */}
<div>
{cart.map((e, index) => (
<CardCart key={index} data={e} />
))}
</div>
</div>
<div className="w-full p-3 ">
{/* <div className="">
<p className="mb-0 text-sm p-3">
جمع کل :
<PersianNumber
number={2546385}
style="text-lg mr-2 font-bold text-gray-500"
/>
<small className="mr-1 mt-[6px]">تومان</small>
</p>
</div> */}
<Link href={"/cart"}>
<button
className="btn btn-primary text-sm w-full py-3 rounded-3xl"
onClick={() => CTX.fetchOrderBagCheck()}
>
{" "}
ثبت خرید
</button>
</Link>
</div>
</div>
</div>
)}
</div>
);
};
export default CartNavbar;

View File

@ -0,0 +1,463 @@
"use client";
// import { useSubscriber } from "@ctx/SubscriberContext";
import Image from "next/image";
import Link from "next/link";
import { useContext, useEffect, useRef, useState } from "react";
import { motion } from "framer-motion";
import { useRouter } from "next/navigation";
import AppContext from "../../Contexts/AppContext";
import logo from "@img/logo.png";
import PersianNumber from "@plugins/PersianNumber";
const NavbarTransparent = () => {
const router = useRouter();
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
const openNavBarServices = CTX.state.openNavBarServices;
const NavBarData = CTX.state.navData;
const [closeNavbar, setClosNavbar] = useState(false);
const [activeStepNavbar, setActiveStepNavbar] = useState(null);
const [isScrolled, setIsScrolled] = useState(false);
// const [hoverItemNavbar, setHoverItemNavbar] = useState(-1);
const [responsiveNavBarItemStep, setResponsiveNavBarItemStep] =
useState(false);
const ref = useRef(null);
const handleResetFramer = () => {
setRestFramer(false);
setTimeout(() => {
setRestFramer(true);
}, 100);
};
const toLeft = {
visible: (custom) => ({
opacity: ["0", "1"],
// y: ["-30%", "0%"],
transition: { delay: custom * 0.06 },
}),
};
useEffect(() => {
const handleScroll = () => {
const scrollTop = window.scrollY;
setIsScrolled(scrollTop > 200);
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
return (
<>
{/* <div className="bg-sky-900 p-3 flex">
<p className="mb-0 text-white"> salam</p>
</div> */}
<div
className={` max-[1023px]:hidden lg:block tr03 ${
isScrolled ? "fixed w-full !z-[1000] top-0 tr" : "pt-10 px-20 "
} `}
>
<nav
className={` rtl flex justify-between w-full pr-20 ${
isScrolled ? " bg-gray-100 " : " rounded-2xl"
}`}
>
<div className="w-9/12 flex ">
<div className="w-[50px] h-[50px] rounded-xl rounded-tl-[25px] bg-white mt-3">
<div className="w-[40px] mx-auto mt-1 ">
<Image
src={logo}
width={500}
height={500}
alt="حامیان عدالت"
className="mx-auto "
/>
</div>
</div>
{NavBarData.map((e, index) => (
<>
<div
key={index}
className={` mx-2 px-4 w-fit text-sm p-7 ${
1
? "bg-visa2-200 rounded-full !text-white text-shadow pb-1"
: ""
} `}
onMouseEnter={() => {
// setHoverItemNavbar(index);
setActiveStepNavbar(e.id);
}}
onMouseLeave={() => {
// setHoverItemNavbar(-1);
setActiveStepNavbar(null);
}}
// onClick={() => context.setOpenNavBarServices(false)}
>
<Link
href={`${e.url}`}
className={` ${isScrolled ? "text-black" : "!text-white"}`}
>
{e.name}
{e.children.length > 0 && ""}
</Link>
{e.children.length > 0 && e.id == activeStepNavbar && (
<div
className="relative flex justify-center"
// onMouseLeave={() => {
// setHoverItemNavbar(-1);
// }}
>
<div class="absolute text-sm z-40 w-[204px] top-[17px] bg-gray-200 rounded-[26px] p-3 ">
<svg
class="absolute w-20 h-7 -top-[7px] inset-x-0 mx-auto"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 740 155.61"
>
<path
fill={`${isScrolled ? "#f3f4f6" : "#14532D "}`}
d="M532.54 85.81c69.58,-54.09 138.74,-82.63 207.46,-85.62l-740 0c73.71,3.21 147.93,35.81 222.63,97.82 28.75,23.85 45.98,38.3 83.91,49.54 20.26,6.01 41.42,8.74 63.46,8.18 28.55,0.73 55.61,-4.06 81.17,-14.35 36.28,-14.61 51.98,-32.73 81.37,-55.57z"
></path>
</svg>
<span class="absolute w-[14px] h-[14px] rounded-full block bg-gray-200 -top-[6px] inset-x-0 mx-auto"></span>
<div>
<ul>
{e.children.map((s, index) => (
<li key={index}>
{/* <Link href={s.url}> */}
<div className="flex py-2 hover:bg-sky-50 p-2 rounded-2xl cursor-pointer ">
<div className="w-3 h-3 rounded-full bg-green-900 ml-1 mt-1"></div>
<p className="mb-0 text-black text-sm ">
{s.name}
</p>
</div>
{/* </Link> */}
</li>
))}
</ul>
</div>
</div>
</div>
)}
</div>
</>
))}
</div>
<div className="w-3/12 ltr p-4 ">
<div className="flex">
<div className=" mx-2 w-fit px-4 text-sm bg-secondary-400 p-3 rounded-2xl rounded-tl-[30px]">
<a
href={`tel:${process.env.NEXT_PUBLIC_PHONE_NUMBER}`}
className="text-sm font-medium text-black"
>
پشتیبانی سریع خرید
</a>
</div>
<div className="mr-2 w-fit px-3 text-sm bg-white rounded-xl ">
<svg
width="25"
height="25"
viewBox="0 0 290 294"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mt-2 opacity-80"
>
<path
d="M145.214 175.429C171.842 175.429 193.429 153.842 193.429 127.214C193.429 100.586 171.842 79 145.214 79C118.586 79 97 100.586 97 127.214C97 153.842 118.586 175.429 145.214 175.429Z"
stroke="black"
stroke-width="21.4286"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M230.429 282.681C222.316 266.941 210.027 253.739 194.907 244.522C179.787 235.305 162.422 230.429 144.714 230.429C127.007 230.429 109.641 235.305 94.5215 244.522C79.4019 253.739 67.1122 266.941 59 282.681"
stroke="black"
stroke-width="21.4286"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M251.214 226.416C266.421 206.582 275.774 182.888 278.216 158.015C280.658 133.142 276.092 108.082 265.034 85.6691C253.975 63.2561 236.866 44.3846 215.64 31.189C194.415 17.9933 169.921 11 144.929 11C119.936 11 95.4419 17.9933 74.2168 31.189C52.9916 44.3846 35.8823 63.2561 24.8238 85.6691C13.7653 108.082 9.19884 133.142 11.641 158.015C14.0831 182.888 23.4364 206.582 38.6429 226.416"
stroke="black"
stroke-width="21.4286"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div className=" mr-2 w-fit px-3 text-sm bg-white rounded-xl ">
<div className="flex justify-end">
<div
className={`absolute mr-[15px] ${
isScrolled ? "mt-[-9px]" : "mt-[-10px]"
}`}
>
<div
className={`bg-primary-500 border-[1px] rounded-full text-center ${
isScrolled ? "w-[18px] h-[18px]" : "w-[20px] h-[20px] "
}`}
>
<PersianNumber
number={cart?.length}
style={` ${
isScrolled
? "!text-[10px] relative top-[-3px]"
: "!text-sm"
}`}
/>{" "}
</div>
</div>
</div>
<svg
width="25"
height="25"
viewBox="0 0 123 110"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mt-2 opacity-80"
>
<path
d="M112.45 45.7875C108.794 26.2812 106.963 16.525 100.019 10.7625C93.0816 5 83.1566 5 63.3129 5H58.8066C38.9566 5 29.0379 5 22.0941 10.7625C15.1504 16.525 13.3191 26.2812 9.65664 45.7875C4.51914 73.2187 1.94414 86.9313 9.44414 95.9688C16.9379 105 30.8879 105 58.8004 105H63.3066C91.2129 105 105.169 105 112.669 95.9688C117.019 90.7188 117.982 83.9062 117.013 73.75"
stroke="black"
stroke-width="9.375"
stroke-linecap="round"
/>
<path
d="M43.3125 30C44.6038 33.6596 46.9984 36.8285 50.1662 39.0701C53.3341 41.3116 57.1193 42.5153 61 42.5153C64.8807 42.5153 68.6659 41.3116 71.8338 39.0701C75.0016 36.8285 77.3962 33.6596 78.6875 30"
stroke="black"
stroke-width="9.375"
stroke-linecap="round"
/>
</svg>
</div>
</div>
</div>
</nav>
</div>
{/* reponsive navbar */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
{/* responsive part */}
<div
className={`sm:block lg:hidden ${
isScrolled & !closeNavbar ? "fixed top-0 z-[100] w-full" : " pt-2"
}`}
>
<div
className={`bg-gray-100 flex justify-between rtl p-3 ${
isScrolled
? " rounded-bl-xl rounded-br-[40px]"
: "mx-2 rounded-xl rounded-br-[40px]"
}`}
>
{/* <Link href={"/"} className="w-full"> */}
<div className=" w-full mx-1 flex ">
<div className="xs:w-[40px] md:w-[100px] mt-[12px] ">
<Image
src={logo}
width={500}
height={500}
alt="حامیان عدالت"
className="mx-auto"
/>
</div>
<h4 className="mr-2 font-bold mt-6 text-sm "> فروشگاه بونسای </h4>
</div>
{/* </Link> */}
<div
className=" p-3 w-full mx-1 text-left"
onClick={() => setClosNavbar(true)}
>
<svg
width="30"
height="30"
viewBox="0 0 235 124"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mr-auto opacity-65"
>
<path
d="M160.75 124C152.328 124 145.5 117.172 145.5 108.75V108.75C145.5 100.327 152.328 93.4995 160.75 93.4995L219.75 93.4995C228.172 93.4995 235 100.327 235 108.75V108.75C235 117.172 228.172 124 219.75 124L160.75 124ZM88.4999 26.4998C81.3202 26.4998 75.5 20.6795 75.5 13.4999V13.4999C75.5 6.32025 81.3202 0.499997 88.4999 0.499997L222 0.499997C229.18 0.499997 235 6.32025 235 13.4999V13.4999C235 20.6795 229.18 26.4998 222 26.4998L88.4999 26.4998ZM13 72.4996C6.09643 72.4996 0.499998 66.9031 0.499997 59.9996V59.9996C0.499997 53.096 6.09643 47.4996 13 47.4996L222.5 47.4996C229.404 47.4996 235 53.096 235 59.9996V59.9996C235 66.9031 229.404 72.4996 222.5 72.4996L13 72.4996Z"
fill="black"
fill-opacity="0.73"
/>
</svg>
</div>
</div>
</div>
{closeNavbar && (
<div className="absolute w-full h-screen top-0 opacity-90 z-[80]">
<div className="bg-gray-900 h-screen fixed w-full p-4 "></div>
</div>
)}
<div className="sm:block lg:hidden ">
<div
className={`fixed w-[250px] top-0 left-0 tr03 !z-[200] ${
closeNavbar ? "" : "-translate-x-full"
} `}
>
<div
className={`absolute mt-2 tr03 z-5 ${
closeNavbar ? "ml-[255px] " : "ml-[-30px]"
}`}
>
<div
className="bg-white w-10 h-10 rounded-full pt-3"
onClick={() => setClosNavbar(false)}
>
<svg
width="13"
height="13"
viewBox="0 0 167 168"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto opacity-60"
>
<path
d="M95.5795 83.3674L164.663 14.2841C166.028 12.6899 166.741 10.6393 166.66 8.54198C166.579 6.44468 165.71 4.45519 164.226 2.97107C162.742 1.48695 160.752 0.617511 158.655 0.536501C156.558 0.455492 154.507 1.16888 152.913 2.5341L83.8295 71.6174L14.7462 2.45076C13.177 0.881567 11.0487 0 8.82953 0C6.61035 0 4.48206 0.881567 2.91286 2.45076C1.34366 4.01996 0.462098 6.14825 0.462098 8.36743C0.462098 10.5866 1.34366 12.7149 2.91286 14.2841L72.0795 83.3674L2.91286 152.451C2.04051 153.198 1.33201 154.117 0.831818 155.151C0.331624 156.185 0.050539 157.311 0.00620993 158.459C-0.0381192 159.606 0.15526 160.751 0.574214 161.82C0.993169 162.889 1.62865 163.861 2.44078 164.673C3.2529 165.485 4.22413 166.12 5.2935 166.539C6.36288 166.958 7.50732 167.152 8.65497 167.107C9.80263 167.063 10.9287 166.782 11.9626 166.282C12.9965 165.782 13.9158 165.073 14.6629 164.201L83.8295 95.1174L152.913 164.201C154.507 165.566 156.558 166.279 158.655 166.198C160.752 166.117 162.742 165.248 164.226 163.764C165.71 162.28 166.579 160.29 166.66 158.193C166.741 156.096 166.028 154.045 164.663 152.451L95.5795 83.3674Z"
fill="black"
/>
</svg>
</div>
</div>
<div className=" bg-white h-[100vh] !relative !overflow-auto tr03 shadow pt-2 rounded-tr-[60px] !z-90 ">
<div className="text-center">
<div className=" bg-dark rounded-full mx-auto ">
<div className="text-center">
{/* <Link href="/"> */}
<div className="text-center mt-[15px] ">
<Image
src={logo}
width={50}
height={50}
alt="فروشگاه بونسای"
className="mx-auto"
/>
</div>
<h4 className="mt-2 font-bold"> فروشگاه بونسای</h4>
{/* </Link> */}
<div className="w-[100px] h-[1px] bg-gray-300 mx-auto mt-4 opacity-50"></div>
</div>
</div>
<div className="mx-3">
<div>
{NavBarData.map((e, index) => (
<>
<motion.div
custom={index}
animate="visible"
variants={toLeft}
key={index}
>
{/* <Link href={e.url}> */}
<>
<div
className="text-center mt-2 text-sm bg-gray-100 rounded-xl shadow-sm p-2 rtl"
onClick={() => {
if (e.children.length > 0) {
setResponsiveNavBarItemStep(index);
setActiveStepNavbar(e.id);
}
}}
>
<span>
{e.name}
<small className="absolute left-0 mx-7 ">
{e.children.length > 0 ? (
<div>
<svg
width="7"
height="7"
viewBox="0 0 151 89"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mt-[6px]"
>
<path
d="M13.0444 13.1674L75.3606 75.8506L138.044 13.5345"
stroke="#424242"
stroke-opacity="0.81"
stroke-width="25"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
) : (
""
)}
</small>
</span>
</div>
</>
{/* </Link>{" "} */}
</motion.div>
{responsiveNavBarItemStep === index &&
e.children.length > 0 &&
e.id == activeStepNavbar && (
<div>
<div className="my-3 ">
{e.children.map((s, index) => (
// <Link href={s.url} key={index}>
<div className="bg-primary-50 rounded-lg my-1 p-2 ">
<p className="mb-0 text-sm">{s.name}</p>
</div>
// </Link>
))}
</div>
</div>
)}
</>
))}
</div>
</div>
</div>
</div>
</div>
</div>
</>
);
};
export default NavbarTransparent;

View File

@ -0,0 +1,152 @@
import Image from "next/image";
import Link from "next/link";
import React, { useContext } from "react";
import logoBlack from "../../../public/images/logo.png";
import AppContext from "@ctx/AppContext";
const ResultSearchBar = ({
searchResultProductData,
searchResultCategoryData,
}) => {
const CTX = useContext(AppContext);
return (
<>
<div>
<div className="mt-2 mb-4">
<div className="flex">
<div>
<svg
width="17"
height="17"
viewBox="0 0 225 277"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="ml-2"
>
<path
d="M68.3533 92.4443L68.3283 92.4568L68.2908 92.4818L68.3533 92.4443ZM192.778 90.1068C191.909 89.2678 190.944 88.5337 189.903 87.9193C188.43 87.0521 186.795 86.4962 185.099 86.286C183.402 86.0758 181.681 86.2158 180.04 86.6973C178.4 87.1788 176.876 87.9916 175.563 89.0854C174.249 90.1793 173.174 91.5309 172.403 93.0568C168.098 101.543 162.16 109.096 154.928 115.282C156.037 109.051 156.597 102.735 156.603 96.4068C156.627 77.1586 151.55 58.2477 141.889 41.5997C132.228 24.9516 118.327 11.161 101.603 1.63183C99.7603 0.584693 97.6814 0.0233984 95.5618 0.000715882C93.4423 -0.0219666 91.3518 0.494708 89.4869 1.50217C87.622 2.50963 86.0439 3.97479 84.9009 5.7599C83.758 7.54501 83.0878 9.59145 82.9533 11.7068C82.2534 23.5581 79.155 35.1439 73.8458 45.7624C68.5365 56.381 61.1269 65.8112 52.0658 73.4818L49.1908 75.8193C39.7109 82.1974 31.3202 90.0606 24.3408 99.1068C13.4942 112.771 5.98064 128.774 2.39598 145.847C-1.18868 162.921 -0.745824 180.595 3.68944 197.467C8.1247 214.339 16.4303 229.946 27.9476 243.05C39.4649 256.153 53.877 266.393 70.0408 272.957C71.9385 273.729 73.997 274.023 76.0351 273.813C78.0732 273.603 80.0285 272.895 81.7287 271.752C83.4289 270.609 84.822 269.065 85.7854 267.256C86.7487 265.448 87.2528 263.431 87.2533 261.382C87.2429 260.058 87.0321 258.743 86.6283 257.482C83.8316 246.97 83.026 236.028 84.2533 225.219C96.0842 247.527 115.073 265.207 138.166 275.419C140.983 276.679 144.168 276.848 147.103 275.894C165.347 270.005 181.781 259.549 194.846 245.519C207.91 231.49 217.171 214.353 221.748 195.737C226.324 177.121 226.065 157.644 220.995 139.156C215.925 120.668 206.211 103.784 192.778 90.1068ZM143.966 250.494C133.069 244.973 123.457 237.22 115.754 227.74C108.05 218.26 102.428 207.265 99.2533 195.469C98.2826 191.497 97.5314 187.474 97.0033 183.419C96.6476 180.837 95.4936 178.431 93.7028 176.537C91.912 174.643 89.574 173.356 87.0158 172.857C86.2292 172.704 85.4295 172.629 84.6283 172.632C82.432 172.63 80.2739 173.206 78.3714 174.303C76.4688 175.401 74.8889 176.98 73.7908 178.882C63.4214 196.772 58.2079 217.185 58.7283 237.857C49.6052 230.766 41.9805 221.934 36.296 211.874C30.6115 201.814 26.9803 190.726 25.6129 179.252C24.2456 167.779 25.1692 156.148 28.3304 145.034C31.4915 133.92 36.8272 123.543 44.0283 114.507C49.496 107.405 56.0919 101.248 63.5533 96.2818C63.8798 96.0724 64.1929 95.8428 64.4908 95.5943C64.4908 95.5943 68.1908 92.5318 68.3158 92.4693C86.1308 77.4074 98.8028 57.1627 104.566 34.5568C118.184 47.1489 127.263 63.8851 130.393 82.1664C133.524 100.448 130.531 119.251 121.878 135.657C120.733 137.847 120.263 140.327 120.527 142.783C120.79 145.24 121.776 147.564 123.36 149.461C124.944 151.358 127.054 152.742 129.425 153.44C131.795 154.138 134.319 154.118 136.678 153.382C155.825 147.377 172.672 135.651 184.953 119.782C192.337 130.685 197.165 143.114 199.077 156.142C200.989 169.17 199.935 182.462 195.995 195.027C192.055 207.591 185.331 219.105 176.322 228.709C167.313 238.313 156.253 245.76 143.966 250.494Z"
fill="#570000"
/>
</svg>
</div>
<div>
<p className="mb-0 text-sm font-bold">جستجو های پرطرفدار</p>
</div>
</div>
<div className=" overflow-x-auto flex whitespace-nowrap hide-scrollBar ">
<Link
href={`/categories/fac3ee2d-19dd-4229-a412-28a1d09cc948/شامپو-بدن`}
>
<div
className="border-2 border-gray-300 py-1 px-3 rounded-full mt-1 mb-2 mx-[2px] cursor-pointer"
onClick={() => CTX.setCloseNavbar(false)}
>
<p className="mb-0 text-[12px]">شامپو بدن</p>
</div>
</Link>
<Link
href={`categories/bdf6b13c-4be5-4a93-bcdb-612440bdbd6e/کرم-مرطوب-کننده-دست-و-پا`}
>
<div
className="border-2 border-gray-300 py-1 px-3 rounded-full mt-1 mb-2 mx-[2px] cursor-pointer"
onClick={() => CTX.setCloseNavbar(false)}
>
<p className="mb-0 text-[12px]">کرم مرطوب کننده دست و پا</p>
</div>
</Link>
<Link
href={`categories/4d3c984d-a867-495c-a0b5-302316f39fb1/شوینده-ظروف`}
>
<div
className="border-2 border-gray-300 py-1 px-3 rounded-full mt-1 mb-2 mx-[2px] cursor-pointer"
onClick={() => CTX.setCloseNavbar(false)}
>
<p className="mb-0 text-[12px]">شوینده ظروف</p>
</div>
</Link>
</div>
</div>
{searchResultCategoryData?.length > 0 &&
searchResultProductData?.length > 0 ? (
<>
{searchResultCategoryData?.map((e, index) => (
<Link
key={index}
href={`/categories/${e.id}/${e.name.split(" ").join("-")}`}
>
<div
className="flex "
onClick={() => CTX.setCloseNavbar(false)}
>
<div className="w-[20px] h-[40px] rounded-2xl bg-gray-200 ml-2 mt-3">
{" "}
</div>
<div className="my-2">
<p className="mb-0 text-sm ">{e.name}</p>
<small className="text-[12px] text-gray-500">
دسته بندی
</small>
</div>
</div>
</Link>
))}
<div className="w-10 h-1 bg-primary-200 rounded-full opacity-35 my-3"></div>
{searchResultProductData?.map((e, index) => (
<Link
key={index}
href={`/products/${e.id}/${e.persianName.split(" ").join("-")}`}
>
<div
className="flex relative "
onClick={() => CTX.setCloseNavbar(false)}
>
<div className="h-fit relative">
<div className="w-[50px] h-[50px] rounded-2xl bg-gray-200 ml-2 mt-3 overflow-hidden relative ">
{!!e.mainImage ? (
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${e.mainImage}`}
width={200}
height={200}
className="xs:!w-[60px] lg:!w-[60px] mx-auto object-cover "
alt={`${e.persianName} - ${e.englishName}`}
/>
) : (
<div className="">
<Image
src={logoBlack}
className="xs:!w-[30px] lg:!w-[30px] mx-auto opacity-25 mt-5"
alt="وسمه"
/>
</div>
)}
</div>
</div>
<div className="my-2 w-full relative text-right">
<p className="mb-0 text-sm ">{e.persianName}</p>
<small className="text-[12px] text-gray-500 !text-right">
محصول{" "}
</small>
</div>
</div>
</Link>
))}
</>
) : (
<div className="flex justify-center py-5">
<div className="bg-white shadow mt-5 w-fit rounded-full text-sm p-4">
چیزی یافت نشد
</div>
</div>
)}
</div>
</>
);
};
export default ResultSearchBar;

View File

@ -0,0 +1,173 @@
"use client";
import AppContext from "@ctx/AppContext";
import Image from "next/image";
import Link from "next/link";
import { useContext, useState } from "react";
import logo from "../../../public/images/logo.png";
import Navbar from "../page";
import SearchSideBar from "@comp/Category/Mobile/Component/SearchSideBar/page";
import ResultSearchBar from "../ResultSearchBar/page";
const SideBarNavBarMobile = () => {
const CTX = useContext(AppContext);
const [firstChild, setFirstChild] = useState([]);
const [firstChildIndex, setFirstChildIndex] = useState(-1);
const dataNav = CTX.state.navData;
const isSearched = CTX.state.isSearched;
const searchResultCategoryData = CTX.state.searchResultData.categories;
const searchResultProductData = CTX.state.searchResultData.products;
const closeNavbar = CTX.state.closeNavbar;
return (
<>
<div className="sm:block lg:hidden ">
<div
className={`fixed w-full top-0 right-0 z-50 tr03 ${
closeNavbar ? "" : "translate-x-full"
} `}
>
<div
className={`absolute mt-2 tr03 z-50 ${closeNavbar ? " " : ""}`}
>
<div
className="rounded-full text-center m-2 "
onClick={() => {
CTX.setCloseNavbar(false);
setFirstChildIndex(-1);
}}
>
<svg
width="15"
height="15"
viewBox="0 0 88 151"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto opacity-70"
>
<path
d="M12.9525 138.35L75.249 75.6471L12.5462 13.3506"
stroke="black"
stroke-opacity="0.81"
stroke-width="25"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</div>
<div className=" bg-white h-[100vh] relative tr03 shadow pt-2 overflow-auto ">
<div className="text-center">
<div className=" bg-dark rounded-full mx-auto ">
<div className="text-center">
<Link href="/">
<div className="text-center mt-5 ">
<Image
src={logo}
width={60}
height={60}
alt="وسمه"
className="mx-auto"
/>
</div>
</Link>
<SearchSideBar />
<div className="w-[100px] h-[1px] bg-gray-300 mx-auto mt-4 opacity-50"></div>
{isSearched ? (
<div className="rtl p-5">
<ResultSearchBar
searchResultProductData={searchResultProductData}
searchResultCategoryData={searchResultCategoryData}
/>
</div>
) : (
<div>
<ul className="text-right px-5">
{dataNav?.map((e, index) => (
<li
onClick={() => {
setFirstChild(dataNav[index].children);
setFirstChildIndex(index);
}}
key={index}
>
<div className="py-3 flex justify-between rtl bg-gray-50 px-1 rounded-lg my-1">
<p className="text-sm mb-0 font-bold ">
{e.name}
</p>
<div>
<svg
width="12"
height="12"
viewBox="0 0 88 151"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto opacity-70 rotate-180 mt-1"
>
<path
d="M12.9525 138.35L75.249 75.6471L12.5462 13.3506"
stroke="black"
stroke-opacity="0.81"
stroke-width="25"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</div>
{firstChildIndex == index && (
<>
<ul>
<li>
<Link
href={`/categories/${e.id}/${e.name
.split(" ")
.join("-")}`}
onClick={() => CTX.setCloseNavbar(false)}
>
<p className="mb-0 text-sm py-3 px-1 text-gray-700">
همه موارد
</p>
</Link>
</li>{" "}
{firstChild.map((e, index) => (
<li key={index}>
<Link
href={`/categories/${e.id}/${e.name
.split(" ")
.join("-")}`}
onClick={() =>
CTX.setCloseNavbar(false)
}
>
<div className="py-3 flex justify-between rtl px-1 rounded-lg my-1 text-gray-700">
<p className="mb-0 text-sm">
{e.name}
</p>
</div>
</Link>
</li>
))}
</ul>
</>
)}
</li>
))}
</ul>
</div>
)}
</div>
</div>
</div>
</div>
</div>
</div>
</>
);
};
export default SideBarNavBarMobile;

View File

@ -0,0 +1,683 @@
"use client";
import Image from "next/image";
import { useContext, useEffect, useState } from "react";
import cover from "../../public/images/navbar/n1.jpg";
import divider from "../../public/images/divider.png";
import logoWhite from "../../public/images/logo-white.png";
import logoBlack from "../../public/images/logo.png";
import SearchSideBar from "@comp/Category/Mobile/Component/SearchSideBar/page";
import AppContext from "@ctx/AppContext";
import Link from "next/link";
import PersianNumber from "plugins/PersianNumber";
import BottomSheetCart from "plugins/bottomSheet/BottomSheetCart";
import CartNavbar from "./CartNavbar/page";
import { debounce } from "lodash";
import { useRouter } from "next/navigation";
import ResultSearchBar from "./ResultSearchBar/page";
const Navbar = ({ theme }) => {
const [open, setOpen] = useState(false);
const CTX = useContext(AppContext);
const router = useRouter();
const dataNav = CTX.state.navData;
const profile = CTX.state.profile;
const cart = CTX.state.cart;
const searchResultCategoryData = CTX.state.searchResultData.categories;
const searchResultProductData = CTX.state.searchResultData.products;
const [navItemHover, setNavItemHover] = useState(null);
const [isDesktop, setIsDesktop] = useState(null);
const [closeNavbar, setClosNavbar] = useState(false);
const [isScrolled, setIsScrolled] = useState(false);
const [smallDashboard, setSmallDashboard] = useState(false);
const [searchResultShow, setSearchResultShow] = useState(false);
const [searchValue, setSearchValue] = useState("");
const handleItemNavber = (index) => {
setNavItemHover(index);
};
const handleRemoveSearch = () => {
CTX.setSearchResultData([]);
setSearchValue("");
setSearchResultShow(false);
};
useEffect(() => {
const handleResize = () => {
setIsDesktop(window.innerWidth > 1000); // You can adjust the width threshold as needed
};
// Set initial window size
handleResize();
// Add event listener to handle window resize
window.addEventListener("resize", handleResize);
// Remove event listener on component unmount
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
useEffect(() => {
const handleScroll = () => {
const scrollTop = window.scrollY;
setIsScrolled(scrollTop > 200);
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
useEffect(() => {
// Define a function to send the request
const sendRequest = async () => {
CTX.fetchSearchResult(searchValue);
setSearchResultShow(true);
};
// Set a timer to send the request after 2000 milliseconds of inactivity
const timer = setTimeout(() => {
if (searchValue.trim() !== "") {
sendRequest();
}
}, 1000);
// Clean up function to clear the timer on component unmount or when searchTerm changes
return () => clearTimeout(timer);
}, [searchValue]);
const handleInputChange = (event) => {
setSearchValue(event.target.value);
};
return (
<>
{isDesktop && (
<div className=" pt-10 tr03">
<div className="flex justify-between rtl px-20 ">
<div
className={`w-[100px] mt-0 py-5 border-b-[2px] relative z-10 ${
theme == 0 ? "border-white" : "border-black"
} `}
>
<Link href={"/"}>
<Image
src={theme == 0 ? logoWhite : logoBlack}
alt="وسمه vesmeh"
/>
</Link>
</div>
<div className={`flex rtl py-5 `}>
<>
<div className=" px-3 ltr">
<input
type="text"
className="form-control !py-[10px] bg-gray-100 !border-[0px] border-gray-100 !rounded-2xl text-right focus:!border-[0px] !text-sm !pl-[60px] !w-[375px] "
placeholder="دستت برای جست و جو بازه"
value={searchValue}
onChange={(e) => handleInputChange(e)}
/>
{!searchResultShow ? (
<div className="absolute mt-[-36px] ml-[6px] z-90">
<div className="w-[30px] h-[30px] bg-gray-300 !rounded-xl pt-2">
<svg
width="12"
height="12"
viewBox="0 0 275 275"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto "
>
<path
d="M215.913 215.913L265 265M250.832 130.822C250.832 197.553 196.915 251.644 130.424 251.644C63.9166 251.644 10 197.552 10 130.838C10 64.0759 63.9166 10 130.408 10C196.915 10 250.832 64.0919 250.832 130.822Z"
stroke="black"
stroke-width="18.75"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</div>
) : (
<div
className="absolute mt-[-36px] ml-[6px] z-90"
onClick={() => handleRemoveSearch()}
>
<div className="w-[30px] h-[30px] bg-gray-300 !rounded-xl pt-2">
<svg
width="9"
height="9"
viewBox="0 0 214 214"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto mt-[2px] "
>
<path
d="M4.42496 8.34954L6.24996 6.24955C9.42467 3.07411 13.6335 1.1434 18.1112 0.80849C22.589 0.473578 27.0382 1.7567 30.65 4.42455L32.75 6.24955L107 80.4745L181.25 6.22455C182.98 4.43456 185.05 3.00714 187.338 2.02557C189.626 1.04399 192.087 0.527921 194.576 0.507469C197.066 0.487016 199.535 0.962591 201.839 1.90644C204.142 2.8503 206.235 4.24353 207.995 6.00484C209.755 7.76615 211.146 9.86026 212.087 12.165C213.029 14.4697 213.502 16.9389 213.48 19.4285C213.457 21.9181 212.938 24.3783 211.955 26.6654C210.971 28.9525 209.542 31.0208 207.75 32.7495L133.525 107L207.775 181.25C210.947 184.427 212.873 188.638 213.203 193.116C213.533 197.593 212.246 202.041 209.575 205.65L207.75 207.75C204.575 210.925 200.366 212.856 195.889 213.191C191.411 213.526 186.962 212.242 183.35 209.575L181.25 207.75L107 133.525L32.75 207.775C31.0195 209.565 28.9498 210.992 26.6618 211.974C24.3738 212.955 21.9132 213.471 19.4236 213.492C16.9339 213.512 14.4652 213.036 12.1613 212.093C9.85749 211.149 7.76468 209.756 6.00503 207.994C4.24538 206.233 2.85412 204.139 1.91244 201.834C0.970764 199.529 0.497518 197.06 0.520318 194.571C0.543117 192.081 1.06151 189.621 2.04524 187.334C3.02897 185.047 4.45835 182.978 6.24996 181.25L80.475 107L6.22496 32.7495C3.05326 29.5717 1.12717 25.3612 0.796856 20.8836C0.466538 16.4059 1.75392 11.9584 4.42496 8.34954Z"
fill="black"
/>
</svg>
</div>
</div>
)}
</div>
{searchResultShow && (
<div
className={`relative !z-[100] tr03 ${
searchResultShow ? "opacity-100" : "opacity-100"
} `}
onClick={() => setSearchResultShow(!searchResultShow)}
>
<div className="absolute w-[370px] bg-gray-100 max-h-[450px] rounded-xl mr-[-385px] mt-[45px] p-5 overflow-auto scroll-1 ">
<ResultSearchBar
searchResultProductData={searchResultProductData}
searchResultCategoryData={searchResultCategoryData}
/>
</div>
</div>
)}
</>
{profile?.length <= 0 ? (
<div className="flex">
<Link href={"/login"}>
<div className="bg-gray-100 py-2 px-5 rounded-xl text-sm ">
ورود / عضویت{" "}
</div>
</Link>
</div>
) : (
<div className="flex">
<div>
<div
className="bg-gray-100 py-2 px-5 rounded-xl text-sm flex cursor-pointer "
onClick={() => setSmallDashboard(!smallDashboard)}
>
<p className="mb-0">
{profile?.firstName} {profile?.lastName}
</p>
<div className="w-[20px] h-[20px] rounded-full bg-primary-500 mr-2"></div>
</div>
{smallDashboard && (
<div
className={`relative !z-[100] tr03 ${
smallDashboard ? "opacity-100" : "opacity-0"
} `}
onMouseEnter={() => setSmallDashboard(true)}
onMouseLeave={() => setSmallDashboard(false)}
>
<div className="absolute w-[270px] bg-gray-100 rounded-xl mt-2 mr-[-87px] overflow-hidden">
<div>
<ul className="p-2 ">
<li className="group cursor-pointer">
<Link href={"/profile"}>
<div className="flex justify-between p-2 rounded-full group-hover:bg-primary-200 tr03">
<p className="mb-0 text-sm text-gray-500 group-hover:text-black tr03">
داشبورد
</p>
<div className="w-[20px] h-[20px] rounded-full bg-primary-200 group-hover:bg-primary-500 tr03 "></div>
</div>
</Link>
</li>
<li className="group cursor-pointer">
<Link href={"/profile/orders"}>
<div className="flex justify-between p-2 rounded-full group-hover:bg-primary-200 tr03">
<p className="mb-0 text-sm text-gray-500 group-hover:text-black tr03">
پیگیری سفارش
</p>
<div className="w-[20px] h-[20px] rounded-full bg-primary-200 group-hover:bg-primary-500 tr03 "></div>
</div>
</Link>
</li>
<li className="group cursor-pointer">
<Link href={"/profile/address"}>
<div className="flex justify-between p-2 rounded-full group-hover:bg-primary-200 tr03">
<p className="mb-0 text-sm text-gray-500 group-hover:text-black tr03">
آدرس ها{" "}
</p>
<div className="w-[20px] h-[20px] rounded-full bg-primary-200 group-hover:bg-primary-500 tr03 "></div>
</div>
</Link>
</li>
<li className="group cursor-pointer">
<Link href={"/profile/saleCooperationSystem"}>
<div className="flex justify-between p-2 rounded-full group-hover:bg-primary-200 tr03">
<p className="mb-0 text-sm text-gray-500 group-hover:text-black tr03">
همکاری در فروش{" "}
</p>
<div className="w-[20px] h-[20px] rounded-full bg-primary-200 group-hover:bg-primary-500 tr03 "></div>
</div>
</Link>
</li>
<li
className="flex justify-between p-2 rounded-full group hover:bg-red-200 tr03 cursor-pointer"
onClick={() =>
CTX.setBottomSheetLogOutOpen(true)
}
>
<p className="mb-0 text-sm text-red-500 group-hover: ">
خروج{" "}
</p>
<div className="w-[20px] h-[20px] rounded-full bg-red-200 group-hover:bg-red-500 tr03 "></div>
</li>
</ul>
</div>
</div>
</div>
)}
</div>
</div>
)}
<CartNavbar isScrolled={isScrolled} />
</div>
</div>
<div className="px-20">
<div
className={`w-full h-[2px] mt-4 relative top-[-17px] rounded-full overflow-hidden opacity-10 ${
theme == 0 ? "bg-gray-300" : "bg-gray-500"
} `}
></div>
</div>
<div
className={`flex justify-center rtl pt-3 tr03 z-50 tr03 ${
navItemHover != null ? "bg-white rounded-xl " : "bg-transparent"
}${
isScrolled
? " !fixed top-0 w-full bg-white "
: " relative top-[-18px] "
}
${theme == 0 ? "" : "!bg-gray-100"}`}
>
<div className="flex rtl">
{dataNav?.map((e, index) => (
<p
className={`mb-0 pt-2 pb-3 px-2 tr03 cursor-pointer ${
navItemHover == index
? " border-y-[5px] border-b-primary-800 border-t-transparent text-primary-900"
: "border-y-[5px] border-y-transparent text-black"
}
${theme == 0 ? "text-gray-400" : "text-gray-900"}
${theme == 0 && isScrolled ? "text-gray-900" : ""}`}
onMouseEnter={() => handleItemNavber(index)}
onMouseLeave={() => setNavItemHover(null)}
key={index}
>
{e.name}{" "}
</p>
))}
</div>
{/* <div
onClick={() => {
const element = document.getElementById("offer");
if (element) {
const offset = -80; // Adjust this value as needed
window.scrollTo({
top: element.offsetTop + offset,
behavior: "smooth",
});
}
}}
>
<div className="bg-red-600 mb-4 px-4 mt-3 h-fit mr-2 rounded-full cursor-pointer">
<p className="mb-0 text-white">بمب امروز </p>
</div>
</div> */}
</div>
<div
className="flex justify-center "
onMouseEnter={() => setNavItemHover(navItemHover)}
onMouseLeave={() => setNavItemHover(null)}
>
<div
className={` w-3/4 mr-0 z-50 ${
isScrolled ? "fixed top-10 mt-[29px]" : "relative top-[-3px]"
} `}
>
<div
className={`flex ${
navItemHover != null ? " opacity-100" : "hidden opacity-0"
}`}
>
<div className="w-[60px] absolute left-0 rotate-180 ml-[-60px] mt-[-15px] ">
<Image src={divider} alt="" />
</div>
<div
className={`block absolute w-full bg-gray-100 bottom-[-435px] h-[450px] p-4 rounded-b-2xl tr03 z-50 over`}
>
<div className="flex rtl">
<div className=" mx-2 p-5 w-full ">
<ul className="flex flex-col flex-wrap max-h-96 list-none ">
{navItemHover != null &&
dataNav &&
dataNav[navItemHover].children.map((e, index) => (
<li className=" my-2" key={index}>
<div className="flex">
<div className="w-[10px] h-[10px] rounded-full bg-primary-500 mt-1 mx-2"></div>
<Link
href={`/categories/${e.id}/${e.name
.split(" ")
.join("-")}`}
>
<p className="mb-0 font-bold text-sm hover:text-primary-500 tr03 cursor-pointer">
{e.name}
</p>
</Link>
{e.children.length > 0 && (
<div>
<svg
width="10"
height="10"
viewBox="0 0 923 1697"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-1 mt-[3px]"
>
<path
d="M714 209L209.293 848.115L714 1487.23"
stroke="blue"
stroke-width="200"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
)}
</div>
{/* ======hear==== */}
{e.children && e.children.length > 0 && (
<div>
{e.children.map((child, index) => (
<Link
key={index}
href={`/categories/${child.id}/${e.name
.split(" ")
.join("-")}`}
>
<p
key={child.id}
className="mb-0 mt-2 text-[14px] mr-2 hover:bg-primary-400 hover:text-white w-fit rounded-full px-2 tr03 cursor-pointer"
>
{child.name}
</p>
</Link>
))}
</div>
)}
</li>
))}
</ul>
</div>
<div className=" w-[250px] ">
<div className="absolute left-5 ">
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${dataNav[navItemHover]?.mainImage}`}
className=" !w-[250px] h-[250px] rounded-xl object-cover "
width={600}
height={600}
alt={`${dataNav[navItemHover]?.name} وسمه`}
/>
</div>
{/* <div className=" mt-[90px] w-[230px] relative">
<div className="flex justify-center">
<div className="w-[50px] h-[50px] rounded-full bg-white mt-5 ">
<svg
width="20"
height="20"
viewBox="0 0 356 357"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto mt-4 mr-3 opacity-30"
>
<path
d="M0 1.17188L1.17509 356.17L354.586 177.499L0 1.17188Z"
fill="black"
/>
</svg>
</div>
</div>
<p className="mb-0 w-full text-primary-500 bg-primary-100 mt-3 text-center">
چرا آرایشی وسمه ؟
</p>
</div> */}
</div>
</div>
</div>
<div className="w-[60px] absolute right-0 rotate-90 mr-[-60px] mt-[-15px] ">
<Image src={divider} alt="" />
</div>
</div>
</div>
</div>
</div>
)}
{!isDesktop && (
<>
<div
className={`flex justify-between rtl z-[50] rounded-bl-3xl ${
isScrolled
? " !sticky top-0 w-full bg-gray-100 p-5"
: " relative px-5 pt-5 "
} `}
>
{" "}
<Link href={"/"}>
<div className="w-[70px] mt-[6px] z-10 ">
{isScrolled ? (
<Image
src={theme == 0 ? logoBlack : logoBlack}
alt="وسمه vesmeh"
/>
) : (
<Image
src={theme == 0 ? logoWhite : logoBlack}
alt="وسمه vesmeh"
/>
)}
</div>
</Link>
<div className="flex">
<div className="flex">
{profile?.length <= 0 ? (
<div className="flex">
<Link href={"/login"}>
<div className="bg-gray-100 py-2 px-3 rounded-xl text-sm ">
ورود / عضویت{" "}
</div>
</Link>
</div>
) : (
<div className="flex">
<div>
<div
className="bg-gray-100 py-2 px-3 rounded-xl text-sm flex cursor-pointer "
onClick={() => setSmallDashboard(!smallDashboard)}
>
<p className="mb-0">
{profile?.firstName} {profile?.lastName}
</p>{" "}
</div>
{smallDashboard && (
<div
className={`relative !z-[100] tr03 ${
smallDashboard ? "opacity-100" : "opacity-0"
} `}
onMouseEnter={() => setSmallDashboard(true)}
onMouseLeave={() => setSmallDashboard(false)}
>
<div className="absolute w-[270px] bg-gray-100 rounded-xl mt-2 mr-[-87px] overflow-hidden">
<div>
<ul className="p-2 ">
<li className="group cursor-pointer">
<Link href={"/profile"}>
<div className="flex justify-between p-2 rounded-full group-hover:bg-primary-200 tr03">
<p className="mb-0 text-sm text-gray-500 group-hover:text-black tr03">
داشبورد
</p>
<div className="w-[20px] h-[20px] rounded-full bg-primary-200 group-hover:bg-primary-500 tr03 "></div>
</div>
</Link>
</li>
<li className="group cursor-pointer">
<Link href={"/profile/orders"}>
<div className="flex justify-between p-2 rounded-full group-hover:bg-primary-200 tr03">
<p className="mb-0 text-sm text-gray-500 group-hover:text-black tr03">
پیگیری سفارش
</p>
<div className="w-[20px] h-[20px] rounded-full bg-primary-200 group-hover:bg-primary-500 tr03 "></div>
</div>
</Link>
</li>
<li className="group cursor-pointer">
<Link href={"/profile/address"}>
<div className="flex justify-between p-2 rounded-full group-hover:bg-primary-200 tr03">
<p className="mb-0 text-sm text-gray-500 group-hover:text-black tr03">
آدرس ها{" "}
</p>
<div className="w-[20px] h-[20px] rounded-full bg-primary-200 group-hover:bg-primary-500 tr03 "></div>
</div>
</Link>
</li>
<li className="group cursor-pointer">
<Link href={"/profile/saleCooperationSystem"}>
<div className="flex justify-between p-2 rounded-full group-hover:bg-primary-200 tr03">
<p className="mb-0 text-sm text-gray-500 group-hover:text-black tr03">
همکاری در فروش{" "}
</p>
<div className="w-[20px] h-[20px] rounded-full bg-primary-200 group-hover:bg-primary-500 tr03 "></div>
</div>
</Link>
</li>
<li
className="flex justify-between p-2 rounded-full group hover:bg-red-200 tr03 cursor-pointer"
onClick={() =>
CTX.setBottomSheetLogOutOpen(true)
}
>
<p className="mb-0 text-sm text-red-500 group-hover: ">
خروج{" "}
</p>
<div className="w-[20px] h-[20px] rounded-full bg-red-200 group-hover:bg-red-500 tr03 "></div>
</li>
</ul>
</div>
</div>
</div>
)}
</div>
</div>
)}
</div>
<div
className="mx-2 "
onClick={() => CTX.setBottomSheetCartOpen(true)}
>
{/* <div className="absolute mt-[-16px] mr-[6px] ">
{cart?.length > 0 && (
<div className="">
<PersianNumber
number={cart?.length}
style={`!text-[10px] text-primary-900 font-bold ${
theme == 1
? "text-primary-500"
: isScrolled
? "text-primary-500"
: "text-white"
}`}
/>
</div>
)}
</div>
<svg
width="20"
height="20"
viewBox="0 0 248 232"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-80"
>
<path
d="M18.4371 138.212C9.46208 96.3 4.96208 75.3375 16.2246 61.425C27.4746 47.5 48.9121 47.5 91.7746 47.5H156.225C199.1 47.5 220.512 47.5 231.775 61.425C243.025 75.35 238.537 96.3 229.562 138.212L224.2 163.212C218.112 191.625 215.075 205.825 204.762 214.163C194.45 222.5 179.925 222.5 150.875 222.5H97.1246C68.0746 222.5 53.5496 222.5 43.2496 214.163C32.9246 205.825 29.8746 191.625 23.7996 163.212L18.4371 138.212Z"
stroke={
isScrolled ? "black" : theme == 1 ? "black" : "white"
}
stroke-width="18.75"
/>
<path
opacity="0.6"
d="M199 85L161.5 10M49 85L86.5 10"
stroke={
isScrolled ? "black" : theme == 1 ? "black" : "white"
}
stroke-width="18.75"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg> */}
<div className="absolute mt-[-8px] mr-[6px] bg-white w-[15px] h-[15px] rounded-full text-center ">
{cart?.length > 0 && (
<div className="">
<PersianNumber
number={cart?.length}
style={`!text-[10px] text-primary-900 font-bold text-center relative top-[-5px] ${
theme == 1
? "text-primary-500"
: isScrolled
? "text-primary-500"
: "text-white"
}`}
/>
</div>
)}
</div>
<div
className="bg-secondary-600 py-2 px-3 rounded-xl text-sm flex cursor-pointer "
onClick={() => CTX.setBottomSheetCartOpen(true)}
>
<p className="mb-0 text-white text-[12px]">سبد خرید</p>
</div>
</div>
</div>
</div>
<SearchSideBar />
<BottomSheetCart />
</>
)}
</>
);
};
export default Navbar;

View File

@ -0,0 +1,103 @@
"use client";
import Link from "next/link";
import PersianNumber from "plugins/PersianNumber";
import { useEffect, useState } from "react";
const TimerDown = () => {
const [timeRemaining, setTimeRemaining] = useState({
days: 0,
hours: 0,
minutes: 0,
seconds: 0,
milliseconds: 0,
});
useEffect(() => {
const calculateTimeRemaining = () => {
// Get current date and time
const now = new Date();
// Calculate yesterday's date
const yesterday = new Date(now);
yesterday.setDate(now.getDate() - 1);
yesterday.setHours(23, 59, 0, 0); // Set time to 23:59:00
// Calculate tomorrow's date
const tomorrow = new Date(now);
tomorrow.setDate(now.getDate() + 1);
tomorrow.setHours(23, 59, 0, 0); // Set time to 23:59:00
// Calculate time difference
const difference = tomorrow - now;
// Convert time difference to days, hours, minutes, seconds, and milliseconds
const days = Math.floor(difference / (1000 * 60 * 60 * 24));
const hours = Math.floor(
(difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
);
const minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((difference % (1000 * 60)) / 1000);
const milliseconds = difference % 1000;
// Update state
setTimeRemaining({ days, hours, minutes, seconds, milliseconds });
};
// Call calculateTimeRemaining once to set initial state
calculateTimeRemaining();
// Update time remaining every second
const intervalId = setInterval(calculateTimeRemaining, 1000);
// Clean up interval on component unmount
return () => clearInterval(intervalId);
}, []);
return (
<div className=" justify-center ltr realtive mr-5 px-2 mt-[-30px] xs:hidden lg:flex ">
<div className=" rounded-full bg-red-100 w-[50px] h-[50px] mx-1">
<p className="mb-0 = text-center text-red-900 font-bold pt-3 ">
<PersianNumber
number={timeRemaining.days}
style={"text-[27px] text-red-900 "}
/>
</p>
<p className="text-[10px] pt-4 text-center text-gray-600 ">روز</p>
</div>
<div className=" rounded-full bg-red-100 w-[50px] h-[50px] mx-1">
<p className="mb-0 text-center text-red-900 font-bold pt-3 ">
<PersianNumber
number={timeRemaining.hours}
style={"text-[27px] text-red-900 "}
/>
</p>
<p className="text-[10px] pt-4 text-center text-gray-600 ">ساعت</p>
</div>
<div className=" rounded-full bg-red-100 w-[50px] h-[50px] mx-1">
<p className="mb-0 text-center text-red-900 font-bold pt-3 ">
<PersianNumber
number={timeRemaining.minutes}
style={"text-[27px] text-red-900 "}
/>
</p>
<p className="text-[10px] pt-4 text-center text-gray-600 ">دقیقه</p>
</div>
<div className=" rounded-full bg-red-100 w-[50px] h-[50px] mx-1">
<Link href="/login">
{" "}
<p className="mb-0 text-center text-red-900 font-bold pt-3 ">
<PersianNumber
number={timeRemaining.seconds}
style={"text-[27px] text-red-900 "}
/>
</p>
<p className="text-[10px] pt-4 text-center text-gray-600 ">ثانیه</p>
</Link>
</div>
</div>
);
};
export default TimerDown;

2570
iranCities.js 100644

File diff suppressed because it is too large Load Diff

221
iranProvince.js 100644
View File

@ -0,0 +1,221 @@
export const iranProvince = () => {
return [
{
id: 4,
title: "آذربايجان شرقي",
slug: "East Azarbaijan",
latitude: 37.9035733,
longitude: 46.2682109,
},
{
id: 5,
title: "آذربايجان غربي",
slug: "Western Azerbaijan",
latitude: 37.9035733,
longitude: 46.2682109,
},
{
id: 25,
title: "اردبيل",
slug: "Ardabil",
latitude: 38.4853276,
longitude: 47.8911209,
},
{
id: 11,
title: "اصفهان",
slug: "Esfahan",
latitude: 32.6546275,
longitude: 51.6679826,
},
{
id: 31,
title: "البرز",
slug: "Alborz",
latitude: 35.9960467,
longitude: 50.9289246,
},
{
id: 17,
title: "ايلام",
slug: "Ilam",
latitude: 33.2957618,
longitude: 46.670534,
},
{
id: 19,
title: "بوشهر",
slug: "Bushehr",
latitude: 28.9233837,
longitude: 50.820314,
},
{
id: 24,
title: "تهران",
slug: "Tehran",
latitude: 35.696111,
longitude: 51.423056,
},
{
id: 30,
title: "خراسان جنوبي",
slug: "South Khorasan",
latitude: 32.5175643,
longitude: 59.1041758,
},
{
id: 10,
title: "خراسان رضوئ",
slug: "Khorasan Razavi",
latitude: 32.5175643,
longitude: 59.1041758,
},
{
id: 29,
title: "خراسان شمالي",
slug: "North Khorasan",
latitude: 37.4710353,
longitude: 57.1013188,
},
{
id: 7,
title: "خوزستان",
slug: "Khuzestan",
latitude: 31.4360149,
longitude: 49.041312,
},
{
id: 20,
title: "زنجان",
slug: "Zanjan",
latitude: 36.5018185,
longitude: 48.3988186,
},
{
id: 21,
title: "سمنان",
slug: "Semnan",
latitude: 35.2255585,
longitude: 54.4342138,
},
{
id: 12,
title: "سيستان وبلوچستان",
slug: "Sistan and Baluchistan",
latitude: 27.5299906,
longitude: 60.5820676,
},
{
id: 8,
title: "فارس",
slug: "Fars",
latitude: 29.1043813,
longitude: 53.045893,
},
{
id: 27,
title: "قزوين",
slug: "Qazvin",
latitude: 36.0881317,
longitude: 49.8547266,
},
{
id: 26,
title: "قم",
slug: "Qom",
latitude: 34.6399443,
longitude: 50.8759419,
},
{
id: 13,
title: "كردستان",
slug: "Kurdistan",
latitude: 31.4360149,
longitude: 49.041312,
},
{
id: 9,
title: "كرمان",
slug: "Kerman",
latitude: 30.2839379,
longitude: 57.0833628,
},
{
id: 6,
title: "کرمانشاه",
slug: "Kermanshah",
latitude: 34.314167,
longitude: 47.065,
},
{
id: 18,
title: "كهگيلويه وبويراحمد",
slug: "Kohgiloyeh Boyerahmad",
latitude: 30.6509479,
longitude: 51.60525,
},
{
id: 28,
title: "گلستان",
slug: "Golestan",
latitude: 37.2898123,
longitude: 55.1375834,
},
{
id: 2,
title: "گيلان",
slug: "Gilan",
latitude: 37.2809,
longitude: 49.5924,
},
{
id: 16,
title: "لرستان",
slug: "Lorestan",
latitude: 31.4360149,
longitude: 49.041312,
},
{
id: 3,
title: "مازندران",
slug: "Mazandaran",
latitude: 36.2262393,
longitude: 52.5318604,
},
{
id: 1,
title: "مرکزی",
slug: "Markazi",
latitude: 34.6123,
longitude: 49.8547,
},
{
id: 23,
title: "هرمزگان",
slug: "Hormozgan",
latitude: 30.2839379,
longitude: 57.0833628,
},
{
id: 14,
title: "همدان",
slug: "Hamedan",
latitude: 27.138723,
longitude: 55.1375834,
},
{
id: 15,
title: "چهارمحال وبختياری",
slug: "Chaharmahal and Bakhtiari ",
latitude: 31.9614348,
longitude: 50.8456323,
},
{
id: 22,
title: "یزد",
slug: "Yazd",
latitude: 0,
longitude: 0,
},
];
};

View File

@ -1,7 +1,18 @@
{
"compilerOptions": {
"baseUrl": ".",
"module": "commonjs",
"target": "es2020",
"paths": {
"@/*": ["./src/*"]
}
"@comp/*": ["components/*"],
"@styles/*": ["styles/*"],
"@assets/*": ["assets/*"],
"@ctx/*": ["Contexts/*"],
"@img/*": ["public/images/*"],
"@layout/*": ["layout/*"],
"@plugins/*": ["plugins/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.js", "**/*.jsx"],
"exclude": ["node_modules"]
}

View File

@ -1,4 +1,16 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
const nextConfig = {
reactStrictMode: false, // React Strict Mode is off
images: {
minimumCacheTTL: 2592000,
domains: ["storage.vesmeh.com"],
remotePatterns: [
{
protocol: "https",
hostname: "storage.vesmeh.com",
},
],
},
};
export default nextConfig;

5879
package-lock.json generated 100644

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,19 @@
"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "14.1.1"
"next": "14.1.1",
"axios": "^1.6.5",
"framer-motion": "^10.16.16",
"@headlessui/react": "^1.7.17",
"jalali-moment": "^3.3.11",
"react-image-lightbox": "^5.1.4",
"react-infinite-scroll-component": "^6.1.0",
"react-spring-bottom-sheet": "^3.4.1",
"react-toastify": "^9.1.3",
"simple-react-validator": "^1.6.2",
"swiper": "^11.0.5",
"nextjs-toploader": "^1.6.6",
"rc-slider": "^10.5.0"
},
"devDependencies": {
"autoprefixer": "^10.0.1",

View File

@ -0,0 +1,43 @@
import axios from "axios";
export const getToken = () => {
return localStorage.token;
};
const Chapar = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
timeout: 10000,
headers: {
common: {
"Content-type": "application/json",
"Access-Control-Allow-Origin": "*",
...(typeof window !== "undefined" &&
localStorage.token && {
Authorization: getToken(),
}),
},
},
});
Chapar.interceptors.response.use(
function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response.data;
},
function (error, status) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
// ;
// if (error.response.status === 401) {
// localStorage.removeItem("token");
// window.location.href = "/login";
// }
return Promise.reject({ error, status: error?.response?.status });
}
);
export default Chapar;

View File

@ -0,0 +1,80 @@
"use client ";
import AppContext from "@ctx/AppContext";
import Image from "next/image";
import { useContext } from "react";
import Lightbox from "react-image-lightbox";
import logo from "../../public/images/logo.png";
const GalleryBox = ({ file }) => {
const CTX = useContext(AppContext);
const isOpenLightBox = CTX.state.isOpenLightBox;
return (
<div className=" w-full rounded-3xl">
<div className="flex justify-center xs:pb-[10px] ">
<div className="">
{file?.length > 0 ? (
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${
file && file[0].fileLocation
}`}
width={350}
height={350}
className=" mx-auto !object-cover"
onClick={() => CTX.setIsOpenLightBox(true)}
alt={file[0].fileName}
priority
loading="eager"
/>
) : (
<div className="xs:!w-[85px] lg:!w-[85px] ">
<Image
src={logo}
className="xs:!w-[70px] lg:!w-[70px] mx-auto !object-cover opacity-25 mt-5"
alt="وسمه"
/>
</div>
)}
</div>
</div>
<div className="flex overflow-x-auto p-3 " id="swich-scrollbar">
{file?.map((e) => (
<div
className="rounded-3xl bg-white border shadow-sm p-3 ml-2"
key={e.id}
onClick={() => CTX.setIsOpenLightBox(true)}
>
<div className="xs:w-[50px] lg:w-[50px]">
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${e.fileLocation}`}
alt={e.fileName}
width={50}
height={50}
priority
loading="eager"
/>
</div>
</div>
))}
</div>
<div>
{isOpenLightBox && (
<Lightbox
mainSrc={`http://storage.vesmeh.com/${
file && file[0].fileLocation
}`}
onCloseRequest={() => CTX.setIsOpenLightBox(false)}
// onImageLoadError={(e) =>
imageLoadErrorMessage={"باز نمیشه ؟!!!"}
/>
)}
</div>
</div>
);
};
export default GalleryBox;

View File

@ -0,0 +1,19 @@
import Script from "next/script";
export default function Goftino() {
const getGoftiono = () => {
return {
__html: ` !function(){var i="Gk1Yld",a=window,d=document;function g(){var g=d.createElement("script"),s="https://www.goftino.com/widget/"+i,l=localStorage.getItem("goftino_"+i);g.async=!0,g.src=l?s+"?o="+l:s;d.getElementsByTagName("head")[0].appendChild(g);}"complete"===d.readyState?g():a.attachEvent?a.attachEvent("onload",g):a.addEventListener("load",g,!1);}();
`,
};
};
return (
<>
<Script
strategy="afterInteractive"
dangerouslySetInnerHTML={getGoftiono()}
/>
</>
);
}

View File

@ -0,0 +1,5 @@
const HasPermission = (per, permissions) => {
return permissions?.includes(per);
};
export default HasPermission;

View File

@ -0,0 +1,4 @@
const hyphenateString = (str) => {
return str.split(" ").join("-");
};
export default hyphenateString;

View File

@ -0,0 +1,102 @@
const Input = ({
id,
lable,
name,
type,
textarea,
mt,
disabled,
theme,
inputEvent,
inputFocus,
style,
value,
readOnly,
validator,
validatorData,
select,
selectData,
defaultValue,
}) => {
return (
<div
class={`relative ${mt ? `mt-${mt}` : "mt-8"} ${
disabled ? "opacity-40" : ""
}`}
>
{textarea ? (
<textarea
type="text"
className={`peer w-full border-b placeholder:text-transparent relative rtl ${
theme == 1 ? "form-control-white" : "form-control"
}`}
placeholder={name}
disabled={disabled ? true : false}
readOnly={readOnly ? true : false}
value={value}
onChange={inputEvent}
/>
) : select ? (
<select
className={`peer w-full border-b placeholder:text-transparent rtl ${
theme == 1 ? "form-control-white" : "form-control"
} ${style ? style : ""} relative`}
placeholder={name}
disabled={disabled ? true : false}
readOnly={readOnly ? true : false}
value={value}
onChange={inputEvent}
id={id}
defaultValue=""
>
{defaultValue && (
<option value="" disabled hidden>
{defaultValue}
</option>
)}
{selectData &&
selectData.map((e, index) => (
<option key={index} value={e.value}>
{e.key}
</option>
))}
</select>
) : (
<input
type={type}
id={id}
className={`peer w-full border-b placeholder:text-transparent rtl ${
theme == 1 ? "form-control-white" : "form-control"
} ${style ? style : ""} relative`}
placeholder={name}
disabled={disabled ? true : false}
readOnly={readOnly ? true : false}
value={value}
onChange={inputEvent}
onFocus={inputFocus}
/>
)}
<div className="flex justify-start w-full absolute mt-[-2px]">
<small className="absolute ">
{" "}
{validator ? <>{validatorData}</> : ""}
</small>
</div>
<label
htmlFor={id}
className={`absolute right-0 mr-3 px-1 -translate-y-3 ${
theme == 1 ? "bg-white" : "bg-body-100"
} text-sm duration-100 ease-linear peer-placeholder-shown:translate-y-[15px] peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-500 peer-focus:mr-6 peer-focus:-translate-y-3 peer-focus:px-1 peer-focus:text-sm`}
>
{lable}
</label>
{/* <small>رمز اشتباه</small> */}
</div>
);
};
export default Input;

View File

@ -0,0 +1,7 @@
const iranPhoneRegex = new RegExp("^(\\+98|0)?9\\d{9}$");
const validateIranPhone = (phoneNumber) => {
return iranPhoneRegex.test(phoneNumber);
};
export default validateIranPhone;

View File

@ -0,0 +1,23 @@
"use client";
import AppContext from "@ctx/AppContext";
import { useContext } from "react";
const Loading = ({ rateId }) => {
const CTX = useContext(AppContext);
const loading = CTX.state.loading;
return (
<>
<div
className={`fixed w-full tr03 z-50 ${
loading ? "bottom-5 " : "bottom-[-100px] "
} `}
>
<div className="bg-primary-300 w-fit rounded-full px-1 py-2 flex rtl m-3 ">
<p className="mb-0 text-white mx-2 blacj ">لطفا صبر کنید</p>
</div>
</div>
</>
);
};
export default Loading;

View File

@ -0,0 +1,98 @@
// MovingLogos.js
"use client";
import { useEffect } from "react";
import Image from "next/image";
import logobrand2 from "../../public/images/logobrand/2.png";
import logobrand3 from "../../public/images/logobrand/3.png";
import logobrand4 from "../../public/images/logobrand/4.png";
import logobrand5 from "../../public/images/logobrand/5.png";
import logobrand6 from "../../public/images/logobrand/6.png";
import logobrand7 from "../../public/images/logobrand/7.png";
// import styles from "./MovingLogos.module.css";
const MovingLogos = () => {
const logos = [
{ id: 1, logo: logobrand5 },
{ id: 2, logo: logobrand4 },
{ id: 3, logo: logobrand3 },
{ id: 4, logo: logobrand6 },
{ id: 5, logo: logobrand5 },
{ id: 6, logo: logobrand4 },
{ id: 7, logo: logobrand3 },
{ id: 8, logo: logobrand2 },
{ id: 9, logo: logobrand5 },
{ id: 10, logo: logobrand4 },
{ id: 11, logo: logobrand3 },
{ id: 12, logo: logobrand6 },
{ id: 13, logo: logobrand5 },
{ id: 14, logo: logobrand4 },
{ id: 15, logo: logobrand6 },
{ id: 16, logo: logobrand2 },
{ id: 17, logo: logobrand7 },
{ id: 18, logo: logobrand4 },
{ id: 19, logo: logobrand3 },
{ id: 20, logo: logobrand2 },
{ id: 21, logo: logobrand7 },
{ id: 22, logo: logobrand4 },
{ id: 23, logo: logobrand3 },
{ id: 24, logo: logobrand5 },
{ id: 25, logo: logobrand2 },
{ id: 26, logo: logobrand7 },
];
useEffect(() => {
const moveLogos = () => {
logos.forEach((logo) => {
const logoElement = document.getElementById(`logo-${logo.id}`);
if (logoElement) {
logoElement.style.transform = "translateX(-10px)"; // Adjust the value based on your preference
}
});
};
const intervalId = setInterval(moveLogos, 100); // Adjust the interval duration based on your preference
return () => clearInterval(intervalId);
}, [logos]);
return (
<div className="">
{/* {logos.map((e) => (
<div className="w-[100px]">
<Image
key={e.id}
id={`logo-${e.id}`}
src={e.logo}
alt={`Logo ${e.id}`}
// className={styles.logo}
/>
</div>
))} */}
<div className="xs:w-4/5 lg:w-3/5 mx-auto">
<div className="w-full inline-flex flex-nowrap overflow-hidden [mask-image:_linear-gradient(to_right,transparent_0,_black_100px,_black_calc(100%-100px),transparent_100%)]">
<ul
x-ref="logos"
className="flex items-center justify-center md:justify-start [&_li]:mx-5 [&_img]:max-w-none animate-infinite-scroll hover:animate-infinite-scroll2"
>
{logos.map((e, index) => (
<li className="w-[]" key={index}>
<Image
key={e.id}
id={`logo-${e.id}`}
src={e.logo}
alt={`Logo ${e.id}`}
className="xs:w-[60px] lg:w-[100px]"
/>
</li>
))}
</ul>
</div>
</div>
</div>
);
};
export default MovingLogos;

View File

@ -0,0 +1,19 @@
const PersianNumber = ({ number, isCost, size, bold, style }) => {
if (number || number === 0) {
const persianMap = "۰۱۲۳۴۵۶۷۸۹".split("");
const formatNumber = isCost
? number.toLocaleString().replace(/\d/g, (m) => persianMap[parseInt(m)])
: number.toString().replace(/\d/g, (m) => persianMap[parseInt(m)]);
return (
<span
className={`text-[${size ? size : ""}px] ${
bold ? "font-bold" : ""
} text-sm ${style}`}
>
{formatNumber}
</span>
);
} else return null;
};
export default PersianNumber;

View File

@ -0,0 +1,34 @@
import Slider from "rc-slider";
import "rc-slider/assets/index.css";
const RangeSlider = ({ min, max, onChange, values }) => {
const handleStyleMin = {
borderColor: "#2189A8",
height: 25,
width: 25,
marginTop: -9,
backgroundColor: "white",
// left: 0,
};
const trackStyle = [{ backgroundColor: "#2189A8", height: 8 }];
const railStyle = { backgroundColor: "#e6e6e6", height: 8 };
return (
<Slider
range
min={min}
max={max}
allowCross={false}
value={values ?? [min, max]}
// defaultValue={[min, max]}
onChangeComplete={onChange}
handleStyle={[handleStyleMin, handleStyleMin]}
trackStyle={trackStyle}
railStyle={railStyle}
/>
);
};
export default RangeSlider;

View File

@ -0,0 +1,28 @@
import Script from "next/script";
export default function Yektanet() {
const getYektanet = () => {
return {
__html: ` !function (t, e, n) {
t.yektanetAnalyticsObject = n, t[n] = t[n] || function () {
t[n].q.push(arguments)
}, t[n].q = t[n].q || [];
var a = new Date, r = a.getFullYear().toString() + "0" + a.getMonth() + "0" + a.getDate() + "0" + a.getHours(),
c = e.getElementsByTagName("script")[0], s = e.createElement("script");
s.id = "ua-script-rqSC1axy"; s.dataset.analyticsobject = n;
s.async = 1; s.type = "text/javascript";
s.src = "https://cdn.yektanet.com/rg_woebegone/scripts_v3/rqSC1axy/rg.complete.js?v=" + r, c.parentNode.insertBefore(s, c)
}(window, document, "yektanet");
`,
};
};
return (
<>
<Script
strategy="afterInteractive"
dangerouslySetInnerHTML={getYektanet()}
/>
</>
);
}

View File

@ -0,0 +1,405 @@
"use client";
import AppContext from "@ctx/AppContext";
import { iranCities } from "iranCities";
import { iranProvince } from "iranProvince";
import Chapar from "plugins/Chapar";
import validateIranPhone from "plugins/IranPhoneRegex";
import { useContext, useEffect, useRef, useState } from "react";
import { BottomSheet } from "react-spring-bottom-sheet";
import { toast } from "react-toastify";
import SimpleReactValidator from "simple-react-validator";
const BottomSheetAddress = () => {
const CTX = useContext(AppContext);
const provinceData = iranProvince();
const citiesData = iranCities();
const [province, setProvince] = useState(null);
const [city, setCity] = useState(null);
const [cityData, setCityData] = useState([]);
const [plaque, setPlaque] = useState("");
const [address, setAddress] = useState("");
const [buildingUnit, setBuildingUnit] = useState("");
const [postalCode, setPostalCode] = useState("");
const [receiverFullName, setReceiverFullName] = useState("");
const [receiverPhoneNumber, setReceiverPhoneNumber] = useState("");
const validator = useRef(
new SimpleReactValidator({
messages: {
required: "پر کردن این فیلد الزامی میباشد",
},
element: (message) => (
<>
<div className="text-right px-1 ">
<small className="text-red-600 t-ig-small ">{message}</small>
</div>
</>
),
})
);
const body = {
address,
province: provinceData?.find((e) => e.id == province)?.title,
city: citiesData?.find((e) => e.id == city)?.title,
plaque,
buildingUnit,
receiverFullName,
receiverPhoneNumber,
postalCode,
};
const handleCreateAddress = async () => {
if (validateIranPhone(receiverPhoneNumber)) {
if (validator.current.allValid()) {
try {
const data = await Chapar.post(
`${process.env.NEXT_PUBLIC_API_URL}/user/address`,
JSON.stringify(body),
{
headers: {
Authorization: localStorage.getItem("token"),
},
}
);
toast.success(`آدرس اضافه شد`, {
position: "bottom-right",
closeOnClick: true,
});
CTX.setBottomSheetAddressOpen(false);
CTX.fetchAddressUser();
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
}
} else {
toast.error("پرکردن همه ی فیلد ها واجب است", {
position: "bottom-right",
autoClose: 2000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
}
} else {
toast.error("شماره تماس را درست وارد کنید", {
position: "bottom-right",
autoClose: 2000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
}
};
useEffect(() => {
setCityData(citiesData.filter((city) => city.province_id == province));
}, [province]);
return (
<BottomSheet
open={CTX.state.bottomSheetAddressOpen}
onDismiss={() => CTX.setBottomSheetAddressOpen(false)}
className={"z-50 relative "}
>
<div className="xs:w-full lg:w-4/12 mx-auto">
<div className="text-center p-3">
<p className="mb-0 text-sm pb-3">اقزودن آدرس جدید </p>
</div>
<div className="p-3">
<label className="float-right mx-3 text-sm my-2 rtl">
استان
<small className="text-red-500 mx-1">*</small>
</label>
<select
type="text"
name="province"
className="form-control bg-white !border-[1px] focus:!border-[1px] border-gray-400 focus:!border-gray-300 rounded-lg text-right !text-sm tr03 "
placeholder="نام استان"
onChange={(e) => {
setProvince(e.target.value);
validator.current.showMessageFor("province");
}}
defaultValue=""
>
<option value="" disabled hidden>
انتخاب کنید
</option>
{provinceData?.map((c, index) => (
<option key={index} value={c.id}>
{c.title}
</option>
))}
</select>
<div className="flex justify-start w-full">
<small className=" ">
{" "}
{validator ? (
<>
{validator.current.message("province", province, "required")}
</>
) : (
""
)}
</small>
</div>
</div>
<div className="p-3">
<label className="float-right mx-3 text-sm my-2 rtl">
شهر
<small className="text-red-500 mx-1">*</small>
</label>
<select
type="text"
name="city"
className="form-control bg-white !border-[1px] focus:!border-[1px] border-gray-400 focus:!border-gray-300 rounded-lg text-right !text-sm tr03 "
placeholder="نام استان"
onChange={(e) => {
setCity(e.target.value);
validator.current.showMessageFor("city");
}}
>
{cityData?.map((c, index) => (
<option key={index} value={c.id}>
{c.title}
</option>
))}
</select>
<div className="flex justify-start w-full">
<small className=" ">
{" "}
{validator ? (
<>{validator.current.message("city", city, "required")}</>
) : (
""
)}
</small>
</div>
</div>
<div className="p-3">
<label className="float-right mx-3 text-sm my-2 rtl">
آدرس
<small className="text-red-500 mx-1">*</small>
</label>
<input
type="text"
name="address"
className="form-control bg-white !border-[1px] focus:!border-[1px] border-gray-400 focus:!border-gray-300 rounded-lg text-right !text-sm tr03 "
placeholder="اسم محله , خیابان , کوچه"
onChange={(e) => {
setAddress(e.target.value);
validator.current.showMessageFor("address");
}}
/>
<div className="flex justify-start w-full">
<small className=" ">
{" "}
{validator ? (
<>{validator.current.message("address", address, "required")}</>
) : (
""
)}
</small>
</div>
</div>
<div className="p-3">
<label className="float-right mx-3 text-sm my-2 rtl">
پلاک
<small className="text-red-500 mx-1">*</small>
</label>
<input
type="text"
name="plaque"
className="form-control bg-white !border-[1px] focus:!border-[1px] border-gray-400 focus:!border-gray-300 rounded-lg text-right !text-sm tr03 "
placeholder=" 10"
onChange={(e) => {
setPlaque(e.target.value);
validator.current.showMessageFor("plaque");
}}
/>
<div className="flex justify-start w-full">
<small className=" ">
{" "}
{validator ? (
<>{validator.current.message("plaque", plaque, "required")}</>
) : (
""
)}
</small>
</div>
</div>
<div className="p-3">
<label className="float-right mx-3 text-sm my-2 rtl">
واحد
<small className="text-red-500 mx-1">*</small>
</label>
<input
type="text"
name="buildingUnit"
className="form-control bg-white !border-[1px] focus:!border-[1px] border-gray-400 focus:!border-gray-300 rounded-lg text-right !text-sm tr03 "
placeholder="2"
onChange={(e) => {
setBuildingUnit(e.target.value);
validator.current.showMessageFor("buildingUnit");
}}
/>
<div className="flex justify-start w-full">
<small className=" ">
{" "}
{validator ? (
<>
{validator.current.message(
"buildingUnit",
buildingUnit,
"required"
)}
</>
) : (
""
)}
</small>
</div>
</div>
<div className="p-3">
<label className="float-right mx-3 text-sm my-2 rtl">
کد پستی
<small className="text-red-500 mx-1">*</small>
</label>
<input
type="text"
name="postalCode"
className="form-control bg-white !border-[1px] focus:!border-[1px] border-gray-400 focus:!border-gray-300 rounded-lg text-right !text-sm tr03 "
placeholder="2"
onChange={(e) => {
setPostalCode(e.target.value);
validator.current.showMessageFor("postalCode");
}}
/>
<div className="flex justify-start w-full">
<small className=" ">
{" "}
{validator ? (
<>
{validator.current.message(
"postalCode",
postalCode,
"required"
)}
</>
) : (
""
)}
</small>
</div>
</div>
<div className="p-3">
<label className="float-right mx-3 text-sm my-2 rtl">
نام گرینده
<small className="text-red-500 mx-1">*</small>
</label>
<input
type="text"
name="receiverFullName"
className="form-control bg-white !border-[1px] focus:!border-[1px] border-gray-400 focus:!border-gray-300 rounded-lg text-right !text-sm tr03 "
placeholder="علی احمدی"
onChange={(e) => {
setReceiverFullName(e.target.value);
validator.current.showMessageFor("receiverFullName");
}}
/>
<div className="flex justify-start w-full">
<small className=" ">
{" "}
{validator ? (
<>
{validator.current.message(
"receiverFullName",
receiverFullName,
"required"
)}
</>
) : (
""
)}
</small>
</div>
</div>
<div className="p-3">
<label className="float-right mx-3 text-sm my-2 rtl">
شماره گرینده
<small className="text-red-500 mx-1">*</small>
</label>
<input
type="text"
name="receiverPhoneNumber"
onChange={(e) => {
setReceiverPhoneNumber(e.target.value);
validator.current.showMessageFor("receiverPhoneNumber");
}}
className="form-control bg-white !border-[1px] focus:!border-[1px] border-gray-400 focus:!border-gray-300 rounded-lg text-right !text-sm tr03 "
placeholder="0912......"
/>
<div className="flex justify-start w-full">
<small className=" ">
{" "}
{validator ? (
<>
{validator.current.message(
"receiverPhoneNumber",
receiverPhoneNumber,
"required"
)}
</>
) : (
""
)}
</small>
</div>
</div>
<div className="w-full p-3 ">
<button
className="btn btn-primary text-sm w-full py-3 rounded-3xl"
onClick={() => handleCreateAddress()}
>
ساخت آدرس جدید{" "}
</button>
</div>
</div>
</BottomSheet>
);
};
export default BottomSheetAddress;

View File

@ -0,0 +1,59 @@
"use client";
import CardCart from "@comp/Cards/CardCart/page";
import AppContext from "@ctx/AppContext";
import Link from "next/link";
import PersianNumber from "plugins/PersianNumber";
import { useContext } from "react";
import { BottomSheet } from "react-spring-bottom-sheet";
const BottomSheetCart = (props) => {
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
return (
<BottomSheet
open={CTX.state.bottomSheetCartOpen}
onDismiss={() => CTX.setBottomSheetCartOpen(false)}
className={"z-50 relative"}
>
<div className="text-center p-3">
<p className="mb-0 text-sm pb-3">
<PersianNumber
number={cart?.length}
style="text-xl font-bold text-base font-bold mx-2 !text-primary-500"
/>
محصول موجود در سبد
</p>
{/* <div className="w-5/12 mx-auto h-[1px] bg-gray-200 my-3"></div> */}
<div>
{cart.map((e, index) => (
<CardCart key={index} data={e} />
))}
</div>
</div>
<div className="w-full p-3 ">
{/* <div className="">
<p className="mb-0 text-sm p-3">
جمع کل :
<PersianNumber
number={2546385}
style="text-lg mr-2 font-bold text-gray-500"
/>
<small className="mr-1 mt-[6px]">تومان</small>
</p>
</div> */}
<Link href={"/cart"}>
<button className="btn btn-primary text-sm w-full py-3 rounded-3xl">
{" "}
ثبت خرید
</button>
</Link>
</div>
</BottomSheet>
);
};
export default BottomSheetCart;

View File

@ -0,0 +1,47 @@
"use client";
import AppContext from "@ctx/AppContext";
import { useContext } from "react";
import { BottomSheet } from "react-spring-bottom-sheet";
import { toast } from "react-toastify";
const BottomSheetDeleteAddress = ({ id }) => {
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
const handleDelete = async (id) => {
try {
const data = await Chapar.post(
`${process.env.NEXT_PUBLIC_API_URL}/user/address/${id}`
);
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
}
};
return (
<BottomSheet
open={CTX.state.bottomSheetDeleteAddressOpen}
onDismiss={() => CTX.setBottomSheetDeleteAddressOpen(false)}
className={"z-50 relative"}
>
<div className="text-center p-3">
<p className="mb-0 text-sm pb-3">آیا از حذف آدرس اطمینان دارید ؟ </p>
</div>
<div className="xs:w-full lg:w-3/12 mx-auto p-3 ">
<button
className="btn bg-red-500 text-white text-sm w-full py-3 rounded-3xl"
onClick={() => handleDelete()}
>
حذف آدرس
</button>
</div>
</BottomSheet>
);
};
export default BottomSheetDeleteAddress;

View File

@ -0,0 +1,74 @@
"use client";
import AppContext from "@ctx/AppContext";
import Chapar from "plugins/Chapar";
import { useContext, useState } from "react";
import { BottomSheet } from "react-spring-bottom-sheet";
import { toast } from "react-toastify";
const BottomSheetDiscount = ({ orderId }) => {
// const [item, setItem] = useState();
const CTX = useContext(AppContext);
const [discountCode, setDiscountCode] = useState(null);
const body = { orderId, discountCode };
// Function to handle discount operation asynchronously
const handleDiscount = async () => {
// Retrieve token from localStorage asynchronously
const token = localStorage.getItem("token");
try {
// Send a POST request to the API endpoint to apply discount
const data = await Chapar.post(
`${process.env.NEXT_PUBLIC_API_URL}/order/bag/discount/${orderId}?discountCode=${discountCode}`,
{
// Include the token in the Authorization header
headers: {
Authorization: token,
},
}
);
// Update the checkout data with the response
CTX.setCheckOutData(data);
// Close the bottom sheet for discount
CTX.setBottomSheetDiscountOpen(false);
} catch ({ error, status }) {
// If there's an error, display an error message using toast
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
}
};
return (
<BottomSheet
open={CTX.state.bottomSheetDiscountOpen}
onDismiss={() => CTX.setBottomSheetDiscountOpen(false)}
className={"z-50 relative"}
>
<div className="text-center p-3">
<p className="mb-0 text-sm pb-3">افزودن کد تخفیف </p>
</div>
<div className="p-3">
<input
type="text"
className="form-control bg-white !border-[1px] focus:!border-[1px] border-gray-400 focus:!border-gray-300 rounded-lg text-right !text-sm tr03 "
placeholder="کد را وارد کنید"
onChange={(e) => setDiscountCode(e.target.value)}
/>
</div>
<div className="w-full p-3 ">
<button
className="btn btn-primary text-sm w-full py-3 rounded-3xl"
onClick={() => handleDiscount()}
>
برسی کد تخفیف{" "}
</button>
</div>
</BottomSheet>
);
};
export default BottomSheetDiscount;

View File

@ -0,0 +1,38 @@
"use client";
import FilterCategory from "@comp/Category/FilterCategory/page";
import AppContext from "@ctx/AppContext";
import { useContext } from "react";
import { BottomSheet } from "react-spring-bottom-sheet";
const BottomSheetFilter = ({ data }) => {
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
return (
<BottomSheet
open={CTX.state.bottomSheetFilterOpen}
onDismiss={() => CTX.setBottomSheetFilterOpen(false)}
className={"z-50 relative"}
>
<div className="text-center p-3">
<FilterCategory
id={data.id}
isChecked={data.isChecked}
setIsChecked={data.setIsChecked}
selectedBrands={data.selectedBrands}
setSelectedBrands={data.setSelectedBrands}
rangePrice={data.rangePrice}
setRangePrice={data.setRangePrice}
sortBy={data.sortBy}
setIsRangePrice={data.setIsRangePrice}
isRangePrice={data.isRangePrice}
theme={2}
specialOffer={data.specialOffer}
/>
</div>
</BottomSheet>
);
};
export default BottomSheetFilter;

View File

@ -0,0 +1,44 @@
"use client";
import AppContext from "@ctx/AppContext";
import { useRouter } from "next/navigation";
import { useContext } from "react";
import { BottomSheet } from "react-spring-bottom-sheet";
const BottomSheetLogOut = ({ id }) => {
const CTX = useContext(AppContext);
const cart = CTX.state.cart;
const router = useRouter();
const handleLogOut = async () => {
localStorage.removeItem("token");
CTX.setProfile([]);
CTX.setBottomSheetLogOutOpen(false);
router.push("/");
};
return (
<BottomSheet
open={CTX.state.bottomSheetLogOutOpen}
onDismiss={() => CTX.setBottomSheetLogOutOpen(false)}
className={"z-50 relative"}
>
<div className="text-center p-3">
<p className="mb-0 text-sm pb-3">
آیا از خروج حساب کاربری اطمینان دارید ؟{" "}
</p>
</div>
<div className="xs:w-full lg:w-3/12 mx-auto p-3 ">
<button
className="btn bg-red-500 text-white text-sm w-full py-3 rounded-3xl"
onClick={() => handleLogOut()}
>
خروج{" "}
</button>
</div>
</BottomSheet>
);
};
export default BottomSheetLogOut;

View File

@ -0,0 +1,151 @@
"use client";
import CardCart from "@comp/Cards/CardCart/page";
import AppContext from "@ctx/AppContext";
import Image from "next/image";
import Link from "next/link";
import Chapar from "plugins/Chapar";
import PersianNumber from "plugins/PersianNumber";
import { useContext, useState } from "react";
import { BottomSheet } from "react-spring-bottom-sheet";
import { toast } from "react-toastify";
import logo from "@img/logo.png";
const BottomSheetSeeOrder = ({ id }) => {
const CTX = useContext(AppContext);
const [bag, setBag] = useState([]);
const handleOpen = async (e) => {
if (e.type == "OPEN") {
try {
const data = await Chapar.get(
`${process.env.NEXT_PUBLIC_API_URL}/order/${id}`,
{
headers: {
Authorization: localStorage.getItem("token"),
},
}
);
setBag(data);
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
}
}
};
return (
<BottomSheet
onSpringStart={(e) => handleOpen(e)}
open={CTX.state.bottomSheetSeeOrderOpen}
onDismiss={() => CTX.setBottomSheetSeeOrderOpen(false)}
className={"z-50 relative"}
>
{/* {bag && bag.length > 0 && ( */}
<div className="h-[900px]">
{bag.orderProducts?.map((e) => (
<div className="text-center p-3">
<p className="mb-0 text-sm pb-3 rtl">
<PersianNumber
number={bag.orderProducts?.length}
style="text-xl font-bold text-base font-bold mx-2 !text-primary-500"
/>
محصول موجود در سبد
</p>
{/* <div className="w-5/12 mx-auto h-[1px] bg-gray-200 my-3"></div> */}
<div>
{bag.orderProducts.map((e, index) => (
<div className="group border-t-[1px] border-gray-100 w-full hover:bg-white z-40 tr03 flex rtl pt-2">
<Link href={`/products/${e.id}/${e.persianName}`}>
<div className=" h-fit ">
{!!e.mainImage ? (
<Image
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${e.mainImage}`}
width={100}
height={100}
className="xs:!w-[110px] lg:!w-[130px] mx-auto !object-cover"
alt={`${e.productName} - ${e.productName}`}
/>
) : (
<div className="xs:!w-[85px] lg:!w-[85px] ">
<Image
src={logo}
className="xs:!w-[70px] lg:!w-[70px] mx-auto !object-cover opacity-25 mt-5"
alt="وسمه"
/>
</div>
)}
</div>
</Link>
<div className="p-3 text-right w-full">
<Link href={`/products/${e.id}/${e.productName}`}>
<p className="mb-0 xs:text-[12px] lg:text-[11px] xl:text-[15px] max-h-[50px] tr03 ">
{e?.productName}
</p>
</Link>
<div className=" rounded-full flex ltr w-full">
<div className="mt-3">
<p className="mb-0 rtl text-sm">
<PersianNumber
number={e?.count}
style={"text-sm ml-1"}
/>
عدد
</p>
</div>
<div className="w-full text-right rounded-full">
{e?.hasDiscount ? (
<div className="flex justify-end relative">
<p className="mb-0 font-bold text-sm absolute opacity-40 mt-[-7px] ml-[20px] text-red-600">
<del>
<PersianNumber
number={(
data?.productFee / 10
).toLocaleString()}
style={"text-[13px]"}
/>
</del>
</p>
<div className="flex rtl mt-[8px]">
{" "}
<p className="mb-0 font-bold">
<PersianNumber
number={(
e?.productFeeWithDiscount / 10
).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[3px]">تومان</small>
</div>
</div>
) : (
<div className="flex rtl mt-[3px]">
{" "}
<p className="mb-0 font-bold text-lg">
<PersianNumber
number={(e?.productFee / 10).toLocaleString()}
/>
</p>
<small className="mr-1 mt-[6px]">تومان</small>
</div>
)}
</div>
</div>
</div>
</div>
))}
</div>
</div>
))}
</div>
{/* )} */}
</BottomSheet>
);
};
export default BottomSheetSeeOrder;

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/mstile-150x150.png"/>
<TileColor>#2ab0da</TileColor>
</tile>
</msapplication>
</browserconfig>

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/favicon.ico 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/images/1.gif 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

BIN
public/images/2.jpg 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
public/images/3.jpg 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Some files were not shown because too many files have changed in this diff Show More