add offer blog page
parent
9f165a79fb
commit
167439c97a
|
@ -6,4 +6,4 @@ NEXT_PUBLIC_PUBLIC_URL=https://api.vesmeh.com
|
||||||
NEXT_PUBLIC_API_URL=https://api.vesmeh.com/api
|
NEXT_PUBLIC_API_URL=https://api.vesmeh.com/api
|
||||||
NEXT_PUBLIC_STORAGE_URL=http://storage.vesmeh.com
|
NEXT_PUBLIC_STORAGE_URL=http://storage.vesmeh.com
|
||||||
STORAGE_URL=http://storage.vesmeh.com
|
STORAGE_URL=http://storage.vesmeh.com
|
||||||
NEXT_PUBLIC_PACKAGE_VERSION=0.31.3
|
NEXT_PUBLIC_PACKAGE_VERSION=0.32.31
|
|
@ -0,0 +1,18 @@
|
||||||
|
FROM node:20-alpine3.18 AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
ARG NODE_ENV=production
|
||||||
|
COPY public ./public
|
||||||
|
COPY .next ./.next
|
||||||
|
COPY node_modules ./node_modules
|
||||||
|
COPY package.json ./package.json
|
||||||
|
COPY .env.production ./.env.production
|
||||||
|
COPY next.config.js ./next.config.js
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
ENV PORT 3000
|
||||||
|
CMD ["node_modules/.bin/next", "start"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# docker build -f Dockerfile.x -t registry.vnfco.ir/netinashop/vesmeh:0.32.31 .
|
|
@ -10,6 +10,7 @@ import PersianNumber from "plugins/PersianNumber";
|
||||||
import logo from "../../../public/images/logo.png";
|
import logo from "../../../public/images/logo.png";
|
||||||
|
|
||||||
const ProductData = ({ params, data }) => {
|
const ProductData = ({ params, data }) => {
|
||||||
|
console.log("data", data);
|
||||||
const [product, setProduct] = useState([]);
|
const [product, setProduct] = useState([]);
|
||||||
const [specificationsHeader, setSpecificationsHeader] = useState([]);
|
const [specificationsHeader, setSpecificationsHeader] = useState([]);
|
||||||
const [productBarDetail, setProductBarDetail] = useState(0);
|
const [productBarDetail, setProductBarDetail] = useState(0);
|
||||||
|
@ -128,10 +129,10 @@ const ProductData = ({ params, data }) => {
|
||||||
|
|
||||||
{/* xs:sticky lg:relative xs:top-[60px] lg:top-0 ==> sticky for price=================== */}
|
{/* 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=" w-11/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="p-3 h-fit border-[1px] border-gray-300 rounded-xl ">
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
<div className="w-[130px]">
|
<div className="w-[110px]">
|
||||||
{data?.product?.files?.length > 0 ? (
|
{data?.product?.files?.length > 0 ? (
|
||||||
<Image
|
<Image
|
||||||
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${
|
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${
|
||||||
|
@ -157,7 +158,7 @@ const ProductData = ({ params, data }) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<p className="mb-0 text-sm text-gray-500">
|
<p className="mb-0 text-sm text-gray-500 my-2">
|
||||||
{data?.product?.persianName}{" "}
|
{data?.product?.persianName}{" "}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -332,13 +333,24 @@ const ProductData = ({ params, data }) => {
|
||||||
<h3 className=" text-sm text-gray-400 mt-7 mb-2">
|
<h3 className=" text-sm text-gray-400 mt-7 mb-2">
|
||||||
نقد و برسی{" "}
|
نقد و برسی{" "}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
{!!data?.product.expertCheck ? (
|
||||||
|
<div className="border p-5 rounded-lg">
|
||||||
|
<div
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: data?.product.expertCheck,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<div className="border p-5 rounded-lg">
|
<div className="border p-5 rounded-lg">
|
||||||
<div className="flex justify-center py-5">
|
<div className="flex justify-center py-5">
|
||||||
<div className="bg-white shadow w-fit rounded-full text-sm p-4">
|
<div className="bg-white shadow w-fit rounded-full text-sm p-4">
|
||||||
چیزی یافت نشد
|
چیزی یافت نشد
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>{" "}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="section3">
|
<div id="section3">
|
||||||
|
|
|
@ -53,6 +53,10 @@ const RootData = ({ children }) => {
|
||||||
const [searchResultData, setSearchResultData] = useState([]);
|
const [searchResultData, setSearchResultData] = useState([]);
|
||||||
const [isSearched, setIsSearched] = useState(false);
|
const [isSearched, setIsSearched] = useState(false);
|
||||||
|
|
||||||
|
const [specialOfferData, setSpecialOfferData] = useState([]);
|
||||||
|
const [cosmeticData, setCosmeticData] = useState([]);
|
||||||
|
const [HomeCosmeticData, setHomeCosmeticData] = useState([]);
|
||||||
|
|
||||||
const [isChecked, setIsChecked] = useState(false);
|
const [isChecked, setIsChecked] = useState(false);
|
||||||
const [selectedBrands, setSelectedBrands] = useState([]);
|
const [selectedBrands, setSelectedBrands] = useState([]);
|
||||||
const [rangePrice, setRangePrice] = useState([1000, 100]);
|
const [rangePrice, setRangePrice] = useState([1000, 100]);
|
||||||
|
@ -431,6 +435,30 @@ const RootData = ({ children }) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchSpecialOffer = async () => {
|
||||||
|
const res = await fetch(
|
||||||
|
`${process.env.NEXT_PUBLIC_API_URL}/product?page=0&specialOffer=true`
|
||||||
|
);
|
||||||
|
const specialOffer = await res.json();
|
||||||
|
setSpecialOfferData(specialOffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchCosmetic = async () => {
|
||||||
|
const res = await fetch(
|
||||||
|
`${process.env.NEXT_PUBLIC_API_URL}/product?page=0&categoryId=553af942-7a14-4757-9a03-a3ebec6c865a`
|
||||||
|
);
|
||||||
|
const Cosmetic = await res.json();
|
||||||
|
setCosmeticData(Cosmetic);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchHomeCosmetic = async () => {
|
||||||
|
const res = await fetch(
|
||||||
|
`${process.env.NEXT_PUBLIC_API_URL}/product?page=0&categoryId=effe5d98-d4b7-47e1-9bfb-4d3c77ab3347`
|
||||||
|
);
|
||||||
|
const HomeCosmetic = await res.json();
|
||||||
|
setHomeCosmeticData(HomeCosmetic);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const storedCart = localStorage.getItem("cart");
|
const storedCart = localStorage.getItem("cart");
|
||||||
const token = localStorage.getItem("token");
|
const token = localStorage.getItem("token");
|
||||||
|
@ -506,6 +534,9 @@ const RootData = ({ children }) => {
|
||||||
cooperationSystemProfileData,
|
cooperationSystemProfileData,
|
||||||
searchResultData,
|
searchResultData,
|
||||||
isSearched,
|
isSearched,
|
||||||
|
cosmeticData,
|
||||||
|
HomeCosmeticData,
|
||||||
|
specialOfferData,
|
||||||
},
|
},
|
||||||
setCart,
|
setCart,
|
||||||
setProducts,
|
setProducts,
|
||||||
|
@ -550,6 +581,12 @@ const RootData = ({ children }) => {
|
||||||
fetchCooperationSystemProfileContract,
|
fetchCooperationSystemProfileContract,
|
||||||
setSearchResultData,
|
setSearchResultData,
|
||||||
fetchSearchResult,
|
fetchSearchResult,
|
||||||
|
setHomeCosmeticData,
|
||||||
|
setCosmeticData,
|
||||||
|
setSpecialOfferData,
|
||||||
|
fetchHomeCosmetic,
|
||||||
|
fetchCosmetic,
|
||||||
|
fetchSpecialOffer,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
import TimerDownBlog from "@comp/TimerDown/TimerDown";
|
||||||
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
|
import hyphenateString from "plugins/HyphenateString/page";
|
||||||
|
import PersianNumber from "plugins/PersianNumber";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
const SliderProductsOffer = ({ data }) => {
|
||||||
|
const [currentIndex, setCurrentIndex] = useState(0);
|
||||||
|
|
||||||
|
// Filter to get the latest 10 products
|
||||||
|
const latestProducts = data?.products?.slice(-10) || [];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
setCurrentIndex((prevIndex) => (prevIndex + 1) % latestProducts.length);
|
||||||
|
}, 10000); // 10 seconds
|
||||||
|
|
||||||
|
return () => clearInterval(interval); // Clean up on unmount
|
||||||
|
}, [latestProducts.length]);
|
||||||
|
|
||||||
|
const handleDotClick = (index) => {
|
||||||
|
setCurrentIndex(index);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="sticky top-20">
|
||||||
|
{" "}
|
||||||
|
{data?.products?.map((e, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`slider-item ${
|
||||||
|
index === currentIndex ? "block" : "hidden"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<Link href={`/products/${e.id}/${hyphenateString(e.persianName)}`}>
|
||||||
|
<div className="bg-contact-us h-[260px] rounded-2xl">
|
||||||
|
<div>
|
||||||
|
<div className="flex p-3">
|
||||||
|
<div className="w-3/12">
|
||||||
|
<div className="bg-white h-20 w-20 rounded-2xl overflow-hidden">
|
||||||
|
{/* Uncomment and adjust the Image component as needed */}
|
||||||
|
<Image
|
||||||
|
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/${e?.mainImage}`}
|
||||||
|
width={350}
|
||||||
|
height={350}
|
||||||
|
className="mx-auto !object-cover w-20 h-20"
|
||||||
|
alt={e?.persianName}
|
||||||
|
priority
|
||||||
|
loading="eager"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative w-9/12 px-2 mt-4">
|
||||||
|
<p className="mb-0 text-white h-[50px] overflow-hidden font-medium px-3">
|
||||||
|
{e?.persianName}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p className="mb-0 text-center">
|
||||||
|
<PersianNumber
|
||||||
|
number={(e?.cost / 10).toLocaleString()}
|
||||||
|
style="text-white !text-[25px] font-medium"
|
||||||
|
/>
|
||||||
|
<small className="mx-1 text-white">تومان</small>
|
||||||
|
</p>
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<div className="bg-white rounded-full py-1 px-2 ml-2">
|
||||||
|
<p className="mb-0 text-[11px] text-green-900 font-medium">
|
||||||
|
تضمین بهترین قیمت
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<div className="relative bottom-[-70px]">
|
||||||
|
<TimerDownBlog />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full">
|
||||||
|
<svg
|
||||||
|
className="absolute h-[20px] block top-0 rotate-90 mr-[-38px] mt-[168px]"
|
||||||
|
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="flex justify-end w-full">
|
||||||
|
<svg
|
||||||
|
className="absolute h-[20px] block top-0 -rotate-90 ml-[-38px] mt-[168px]"
|
||||||
|
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="absolute w-full mt-[13px]">
|
||||||
|
<div className="h-3 w-full border-t-[4px] opacity-15 border-white border-dashed"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="flex justify-center mt-2">
|
||||||
|
{latestProducts.map((_, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
onClick={() => handleDotClick(index)}
|
||||||
|
className={`w-3 h-3 mx-[1px] mt-1 rounded-full cursor-pointer ${
|
||||||
|
index === currentIndex
|
||||||
|
? "bg-contact-us w-7"
|
||||||
|
: "bg-primary-200 opacity-80"
|
||||||
|
}`}
|
||||||
|
></div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SliderProductsOffer;
|
|
@ -1,20 +1,39 @@
|
||||||
h2 {
|
#blog-content > h2 {
|
||||||
color: rgb(0, 49, 155);
|
color: rgb(0, 49, 155);
|
||||||
|
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
p {
|
#blog-content > p {
|
||||||
color: rgb(54, 54, 54);
|
color: rgb(54, 54, 54);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
@apply leading-8 text-base;
|
||||||
|
}
|
||||||
|
#blog-content > li {
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
font-weight: 400;
|
||||||
|
@apply leading-8 text-base;
|
||||||
|
}
|
||||||
|
#blog-content > a {
|
||||||
|
color: rgb(54, 54, 54);
|
||||||
|
font-weight: 400;
|
||||||
|
@apply leading-8 text-base text-blue-700 hover:text-blue-900;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
#blog-content > h3 {
|
||||||
color: rgb(216, 16, 16);
|
color: rgb(216, 16, 16) !important;
|
||||||
|
font-weight: 400;
|
||||||
font-weight: 600;
|
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
margin-right: 10px;
|
font-size: 20px;
|
||||||
|
/* margin-right: 10px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
#blog-content > img {
|
||||||
|
@apply rounded-xl mx-auto shadow-lg my-8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#blog-content > iframe {
|
||||||
|
@apply rounded-xl mx-auto shadow-lg my-8;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,52 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import Footer from "@comp/Footer/page";
|
import Footer from "@comp/Footer/page";
|
||||||
import Navbar from "@comp/Navbar/page";
|
import Navbar from "@comp/Navbar/page";
|
||||||
|
import "../BlogComponents/styleBlog.css";
|
||||||
|
import TimerDown from "@comp/TimerDown/TimerDown";
|
||||||
|
import TimerDownBlog from "@comp/TimerDown/TimerDown";
|
||||||
|
import PersianNumber from "plugins/PersianNumber";
|
||||||
|
import SliderProductsOffer from "../BlogComponents/SliderProductsOffer/page";
|
||||||
|
import AppContext from "@ctx/AppContext";
|
||||||
const BlogData = ({ data }) => {
|
const BlogData = ({ data }) => {
|
||||||
|
const CTX = useContext(AppContext);
|
||||||
|
|
||||||
|
const specialOfferData = CTX.state.specialOfferData;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (specialOfferData.length <= 0) {
|
||||||
|
CTX.fetchSpecialOffer();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<div className="xs:px-3 md:px-5 md:container md:mx-auto mb-10">
|
<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="grid xs:grid-cols-1 lg:grid-cols-6 gap-7 rtl">
|
||||||
|
<div className="lg:col-span-4 mt-10 rtl">
|
||||||
<div className=" mt-10 ">
|
<div className=" mt-10 ">
|
||||||
<Image
|
<Image
|
||||||
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/Images/Med/${data.mainImage}`}
|
src={`${process.env.NEXT_PUBLIC_STORAGE_URL}/Images/Med/${data.mainImage}`}
|
||||||
width={500}
|
width={500}
|
||||||
height={500}
|
height={500}
|
||||||
className="w-[400px]"
|
className="xs:w-full lg:w-6/12 rounded-3xl mb-3"
|
||||||
/>
|
/>
|
||||||
<h1 className=" font-bold text-right xs:text-[20px] lg:text-[40px]">
|
<h1 className=" font-bold text-right xs:text-[20px] lg:text-[40px]">
|
||||||
{data.title}
|
{data.title}
|
||||||
</h1>
|
</h1>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div dangerouslySetInnerHTML={{ __html: data.content }} />
|
<div
|
||||||
|
id="blog-content"
|
||||||
|
dangerouslySetInnerHTML={{ __html: data.content }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="lg:col-span-2 mt-10 rtl ">
|
||||||
|
<SliderProductsOffer data={specialOfferData} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,6 +9,7 @@ import Cart from "../BlogComponents/Cart";
|
||||||
import PaginationBlogs from "../BlogComponents/PaginationBlogs";
|
import PaginationBlogs from "../BlogComponents/PaginationBlogs";
|
||||||
|
|
||||||
const BlogsData = ({ dataCaetgories, data }) => {
|
const BlogsData = ({ dataCaetgories, data }) => {
|
||||||
|
console.log("data", data);
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Link from "next/link";
|
||||||
import PersianNumber from "plugins/PersianNumber";
|
import PersianNumber from "plugins/PersianNumber";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
const TimerDown = () => {
|
const TimerDownBlog = () => {
|
||||||
const [timeRemaining, setTimeRemaining] = useState({
|
const [timeRemaining, setTimeRemaining] = useState({
|
||||||
days: 0,
|
days: 0,
|
||||||
hours: 0,
|
hours: 0,
|
||||||
|
@ -54,50 +54,50 @@ const TimerDown = () => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className=" justify-center ltr realtive mr-5 px-2 mt-[-30px] xs:hidden lg:flex ">
|
<div className=" justify-center ltr realtive mr-5 px-2 mt-[-30px] flex ">
|
||||||
<div className=" rounded-full bg-red-100 w-[50px] h-[50px] mx-1">
|
<div className=" rounded-2xl bg-white w-[40px] h-[40px] mx-1">
|
||||||
<p className="mb-0 = text-center text-red-900 font-bold pt-3 ">
|
<p className="mb-0 = text-center text-primary-300 font-bold pt-[10px] ">
|
||||||
<PersianNumber
|
<PersianNumber
|
||||||
number={timeRemaining.days}
|
number={timeRemaining.days}
|
||||||
style={"text-[27px] text-red-900 "}
|
style={"!text-[15px] pt-[-5px] text-primary-900 "}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="text-[10px] pt-4 text-center text-gray-600 ">روز</p>
|
<p className="text-[10px] pt-2 text-center text-white ">روز</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className=" rounded-full bg-red-100 w-[50px] h-[50px] mx-1">
|
<div className=" rounded-2xl bg-white w-[40px] h-[40px] mx-1">
|
||||||
<p className="mb-0 text-center text-red-900 font-bold pt-3 ">
|
<p className="mb-0 text-center text-primary-300 font-bold pt-[10px] ">
|
||||||
<PersianNumber
|
<PersianNumber
|
||||||
number={timeRemaining.hours}
|
number={timeRemaining.hours}
|
||||||
style={"text-[27px] text-red-900 "}
|
style={"!text-[15px] pt-[-5px] text-primary-900 "}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p className="text-[10px] pt-4 text-center text-gray-600 ">ساعت</p>
|
<p className="text-[10px] pt-2 text-center text-white ">ساعت</p>
|
||||||
</div>
|
</div>
|
||||||
<div className=" rounded-full bg-red-100 w-[50px] h-[50px] mx-1">
|
<div className=" rounded-2xl bg-white w-[40px] h-[40px] mx-1">
|
||||||
<p className="mb-0 text-center text-red-900 font-bold pt-3 ">
|
<p className="mb-0 text-center text-primary-300 font-bold pt-[10px] ">
|
||||||
<PersianNumber
|
<PersianNumber
|
||||||
number={timeRemaining.minutes}
|
number={timeRemaining.minutes}
|
||||||
style={"text-[27px] text-red-900 "}
|
style={"!text-[15px] pt-[-5px] text-primary-900 "}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p className="text-[10px] pt-4 text-center text-gray-600 ">دقیقه</p>
|
<p className="text-[10px] pt-2 text-center text-white ">دقیقه</p>
|
||||||
</div>
|
</div>
|
||||||
<div className=" rounded-full bg-red-100 w-[50px] h-[50px] mx-1">
|
<div className=" rounded-2xl bg-white w-[40px] h-[40px] mx-1">
|
||||||
<Link href="/login">
|
<Link href="/login">
|
||||||
{" "}
|
{" "}
|
||||||
<p className="mb-0 text-center text-red-900 font-bold pt-3 ">
|
<p className="mb-0 text-center text-primary-300 font-bold pt-[10px] ">
|
||||||
<PersianNumber
|
<PersianNumber
|
||||||
number={timeRemaining.seconds}
|
number={timeRemaining.seconds}
|
||||||
style={"text-[27px] text-red-900 "}
|
style={"!text-[15px] pt-[-5px] text-primary-900 "}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p className="text-[10px] pt-4 text-center text-gray-600 ">ثانیه</p>
|
<p className="text-[10px] pt-2 text-center text-white ">ثانیه</p>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TimerDown;
|
export default TimerDownBlog;
|
||||||
|
|
|
@ -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;
|
|
@ -4649,6 +4649,30 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-spring-bottom-sheet/node_modules/react-dom": {
|
||||||
|
"version": "17.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
|
||||||
|
"integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"scheduler": "^0.20.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "17.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-spring-bottom-sheet/node_modules/scheduler": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-toastify": {
|
"node_modules/react-toastify": {
|
||||||
"version": "9.1.3",
|
"version": "9.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz",
|
||||||
|
@ -5547,6 +5571,20 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.4.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||||
|
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||||
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/unbox-primitive": {
|
"node_modules/unbox-primitive": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
||||||
|
|
|
@ -2,7 +2,9 @@ import BlogData from "@comp/Blog/BlogData/page";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
async function getData(id) {
|
async function getData(id) {
|
||||||
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/blog/${id}`);
|
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/blog/${id}`, {
|
||||||
|
cache: "no-cache",
|
||||||
|
});
|
||||||
const post = await res.json();
|
const post = await res.json();
|
||||||
return post;
|
return post;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,18 @@ async function getData(sParams) {
|
||||||
|
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${process.env.NEXT_PUBLIC_API_URL}/blog?` +
|
`${process.env.NEXT_PUBLIC_API_URL}/blog?` +
|
||||||
new URLSearchParams({ ...query })
|
new URLSearchParams({ ...query }),
|
||||||
|
{
|
||||||
|
cache: "no-cache",
|
||||||
|
}
|
||||||
// ?page=${params.page ?? 0}
|
// ?page=${params.page ?? 0}
|
||||||
// { cache: "no-cache" }
|
// { cache: "no-cache" }
|
||||||
);
|
);
|
||||||
const post = await res.json();
|
const post = await res.json();
|
||||||
//
|
//
|
||||||
|
|
||||||
|
console.log("post", post);
|
||||||
|
|
||||||
return post;
|
return post;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,10 @@ const fetchProducts = async (categoryId, searchParams) => {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${process.env.NEXT_PUBLIC_API_URL}/product?` +
|
`${process.env.NEXT_PUBLIC_API_URL}/product?` +
|
||||||
new URLSearchParams({ ...query }) +
|
new URLSearchParams({ ...query }) +
|
||||||
brandIdsQuery
|
brandIdsQuery,
|
||||||
|
{
|
||||||
|
cache: "no-cache",
|
||||||
|
}
|
||||||
);
|
);
|
||||||
if (!res.ok) return [];
|
if (!res.ok) return [];
|
||||||
const products = await res.json();
|
const products = await res.json();
|
||||||
|
|
|
@ -7,41 +7,21 @@ import HeroSection from "@comp/LandingPage/HeroSection/page";
|
||||||
import HomeSection from "@comp/LandingPage/HomeSection/page";
|
import HomeSection from "@comp/LandingPage/HomeSection/page";
|
||||||
import SurpriseSection from "@comp/LandingPage/SurpriseSection/page";
|
import SurpriseSection from "@comp/LandingPage/SurpriseSection/page";
|
||||||
import Navbar from "@comp/Navbar/page";
|
import Navbar from "@comp/Navbar/page";
|
||||||
|
import AppContext from "@ctx/AppContext";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const [specialOfferData, setSpecialOfferData] = useState([]);
|
const CTX = useContext(AppContext);
|
||||||
const [cosmeticData, setCosmeticData] = useState([]);
|
|
||||||
const [HomeCosmeticData, setHomeCosmeticData] = useState([]);
|
|
||||||
const fetchSpecialOffer = async () => {
|
|
||||||
const res = await fetch(
|
|
||||||
`${process.env.NEXT_PUBLIC_API_URL}/product?page=0&specialOffer=true`
|
|
||||||
);
|
|
||||||
const specialOffer = await res.json();
|
|
||||||
setSpecialOfferData(specialOffer);
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchCosmetic = async () => {
|
const specialOfferData = CTX.state.specialOfferData;
|
||||||
const res = await fetch(
|
const cosmeticData = CTX.state.cosmeticData;
|
||||||
`${process.env.NEXT_PUBLIC_API_URL}/product?page=0&categoryId=553af942-7a14-4757-9a03-a3ebec6c865a`
|
const HomeCosmeticData = CTX.state.HomeCosmeticData;
|
||||||
);
|
|
||||||
const Cosmetic = await res.json();
|
|
||||||
setCosmeticData(Cosmetic);
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchHomeCosmetic = async () => {
|
|
||||||
const res = await fetch(
|
|
||||||
`${process.env.NEXT_PUBLIC_API_URL}/product?page=0&categoryId=effe5d98-d4b7-47e1-9bfb-4d3c77ab3347`
|
|
||||||
);
|
|
||||||
const HomeCosmetic = await res.json();
|
|
||||||
setHomeCosmeticData(HomeCosmetic);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchSpecialOffer();
|
CTX.fetchSpecialOffer();
|
||||||
fetchCosmetic();
|
CTX.fetchCosmetic();
|
||||||
fetchHomeCosmetic();
|
CTX.fetchHomeCosmetic();
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import ProductData from "@comp/AppsComponent/ProductData/page";
|
import ProductData from "@comp/AppsComponent/ProductData/page";
|
||||||
|
|
||||||
async function getData(id) {
|
async function getData(id) {
|
||||||
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/product/${id}`);
|
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/product/${id}`, {
|
||||||
|
cache: "no-cache",
|
||||||
|
});
|
||||||
const post = await res.json();
|
const post = await res.json();
|
||||||
|
console.log("object11", post);
|
||||||
return post;
|
return post;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue