This commit is contained in:
moaz_dw 2024-07-13 16:26:20 +03:00
parent 174e4ad147
commit 86f3045cce
15 changed files with 120 additions and 66 deletions

View File

@ -0,0 +1,15 @@
import HomeSlider from "../../Components/Home/CategoriesSlider";
import { useTranslation } from 'react-i18next';
const Categories = () => {
const {t} = useTranslation();
return (
<div className='category_page'>
<h1>{t("What do you like")}?</h1>
<HomeSlider />
</div>
)
}
export default Categories

View File

@ -12,15 +12,18 @@ import { useGetCategories } from "../../api/Categories";
import { Category } from "../../types/item"; import { Category } from "../../types/item";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { addBaseUrlToSrc } from "../../utils/addBaseUrlToSrc"; import { addBaseUrlToSrc } from "../../utils/addBaseUrlToSrc";
import { languageObject } from "../../utils/languageObject";
import Loading from "../Utils/Loading/Loading";
const CategoriesSlider = () => { const CategoriesSlider = () => {
const { data } = useGetCategories(); const { data , isLoading} = useGetCategories();
const categories = (data?.categories as Category[]) || ([] as []); const categories = (data?.categories as Category[]) || ([] as []);
const navigate = useNavigate(); const navigate = useNavigate();
const handelNavigate = (data: Category) => { const handelNavigate = (data: Category) => {
navigate(`/categories?category=${data?.id}`); navigate(`/categories?category=${data?.id}`);
}; };
console.log(categories);
return ( return (
<div className="CategoriesSlider"> <div className="CategoriesSlider">
@ -47,7 +50,7 @@ const CategoriesSlider = () => {
}, },
}} }}
> >
{categories?.map((item: Category, index: number) => { {isLoading ?<Loading/> :categories?.map((item: Category, index: number) => {
return ( return (
<SwiperSlide key={index}> <SwiperSlide key={index}>
<div className="CategoriesSlider_image"> <div className="CategoriesSlider_image">
@ -56,6 +59,7 @@ const CategoriesSlider = () => {
src={addBaseUrlToSrc(item?.photo)} src={addBaseUrlToSrc(item?.photo)}
alt={`category ${index + 1}`} alt={`category ${index + 1}`}
/> />
<p className="truncate-text">{languageObject(item?.name)}</p>
</div> </div>
</SwiperSlide> </SwiperSlide>
); );

View File

@ -78,16 +78,7 @@ const ProductCard = ({ item }: { item: Product }) => {
<div className="ProductCard"> <div className="ProductCard">
<CustomImage src={item?.main_photo} onClick={() => handle_click(item?.base_product_id)} /> <CustomImage src={item?.main_photo} onClick={() => handle_click(item?.base_product_id)} />
<h4 className="truncate-text">{languageObject(item?.name)}</h4> <h4 className="truncate-text">{languageObject(item?.name)}</h4>
<h5 className="desc">Description: {result}</h5> <h5 className="desc">{t("Description")}: {result}</h5>
{/* <p>{Currency} {oldPrice}</p>
<div>
<p>{price}</p>
<p>
{randomRate} <FaStar />
</p>
</div> */}
{/* <span>{discountAmount}%</span> */}
<article> <article>
<button className="button" onClick={() => handleAddToCart(item)}> <button className="button" onClick={() => handleAddToCart(item)}>
<FaCartPlus /> <FaCartPlus />

View File

@ -1,4 +1,3 @@
import { useRef, useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react'; import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css'; import 'swiper/css';
import 'swiper/css/free-mode'; import 'swiper/css/free-mode';
@ -8,46 +7,40 @@ import { Product } from '../../types/item';
import { A11y, Autoplay, Navigation, Pagination, Scrollbar } from 'swiper/modules'; import { A11y, Autoplay, Navigation, Pagination, Scrollbar } from 'swiper/modules';
import { Spin } from 'antd'; import { Spin } from 'antd';
const ProductSwiper = ({ data, isLoading }: any) => {
const ProductSwiper = ({data,isLoading}:any) => {
const language = localStorage.getItem('language') ;
const [swiperDirection, setSwiperDirection] = useState(language === "ar" ? "rtl" : "ltr");
const swiperRef = useRef<any>(null);
const BaseProducts = (data?.products as Product[]) || ([] as []); const BaseProducts = (data?.products as Product[]) || ([] as []);
return ( return (
<div className='productSwiper'> <div className='productSwiper'>
<Swiper <Swiper
dir={swiperDirection} dir={"ltr"}
slidesPerView={5} slidesPerView={5}
spaceBetween={50} spaceBetween={20}
breakpoints={{ breakpoints={{
0: { slidesPerView: 1 }, 0: { slidesPerView: 1 },
400: { slidesPerView: 1 }, 400: { slidesPerView: 1 },
600: { slidesPerView: 2 }, 600: { slidesPerView: 2 },
900: { slidesPerView: 4 }, 900: { slidesPerView: 4 },
1200: { slidesPerView: 4 }, 1200: { slidesPerView: 4 },
1500: { slidesPerView: 4 }, 1500: { slidesPerView: 4 },
}} }}
modules={[Navigation, Pagination, Scrollbar, A11y, Autoplay]} modules={[Navigation, Pagination, Scrollbar, A11y, Autoplay]}
pagination={{ clickable: true }} pagination={{ clickable: true }}
className="mySwiper" className="mySwiper"
onSwiper={(swiper:any) => (swiperRef.current = swiper)} // Store swiper instance
> >
{ {
isLoading ? <Spin/> : isLoading ? <Spin /> :
BaseProducts?.map((item:Product, index:number) => ( BaseProducts?.map((item: Product, index: number) => (
<SwiperSlide key={index}> <SwiperSlide key={index}>
<ProductCard key={index} item={item} /> <ProductCard key={index} item={item} />
</SwiperSlide> </SwiperSlide>
)) ))
} }
</Swiper> </Swiper>
</div> </div>
); );
} };
export default ProductSwiper; export default ProductSwiper;

View File

@ -9,12 +9,13 @@ import NoiseCancellation from "../../Components/Home/NoiseCancellation";
import BatteryLife from "../../Components/Home/BatteryLife"; import BatteryLife from "../../Components/Home/BatteryLife";
import PerfectSound from "../../Components/Home/PerfectSound"; import PerfectSound from "../../Components/Home/PerfectSound";
import BestSale from "../../Components/Home/BestSale"; import BestSale from "../../Components/Home/BestSale";
import Categories from "../../Components/Home/Categories";
const Page = () => { const Page = () => {
return ( return (
<div className="home_page"> <div className="home_page">
<HeroSection /> <HeroSection />
<HomeSlider /> <Categories />
{/* <ProductsOnSale/> */} {/* <ProductsOnSale/> */}
<Products /> <Products />
<PremiumDesign /> <PremiumDesign />

View File

@ -38,11 +38,10 @@ const Page = () => {
const [MainImage, setMainImage] = useState(product?.main_photo); const [MainImage, setMainImage] = useState(product?.main_photo);
useEffect(() => {
const handelImage = (item: any) => { setMainImage(product?.main_photo)
// setMainImage(item); }, [product?.main_photo])
};
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const handelChangeFavorite = (item: Product) => { const handelChangeFavorite = (item: Product) => {
@ -87,13 +86,14 @@ const Page = () => {
toast.success(`${languageObject(item?.name)}` + " added to cart"); toast.success(`${languageObject(item?.name)}` + " added to cart");
}; };
const info = jsonObjectToArray(product?.info) const info = jsonObjectToArray(product?.info)
const handleChangeImage = (imagePath: string) => { const handleChangeImage = (imagePath: string) => {
setMainImage(imagePath); setMainImage(imagePath);
}; };
if(isLoading){ if(isLoading){
return <div className="loading_state"> <Spin/> </div> return <div className="loading_state"> <Spin/> </div>
} }
return ( return (
<div className="Product"> <div className="Product">
<header> <header>

View File

@ -135,6 +135,9 @@
.ant-pagination .ant-pagination-item a{ .ant-pagination .ant-pagination-item a{
color: var(--white); color: var(--white);
} }
.swiper{
direction: ltr !important;
}
@media screen and (max-width: 1000px) { @media screen and (max-width: 1000px) {
.show_on_responsive { .show_on_responsive {
display: inline; display: inline;
@ -271,4 +274,15 @@
} }
.category_page{
@include Flex; flex-direction: column;
h1{
font-weight: bold;
}
}
.CategoriesSlider{
margin-block: 50px !important;
}

View File

@ -54,7 +54,7 @@
} }
.CategoriesSlider { .CategoriesSlider {
width: var(--padding-page); width: calc(var(--padding-page));
margin-inline: auto; margin-inline: auto;
margin-block: var(--margin-block); margin-block: var(--margin-block);
@ -64,19 +64,35 @@
.CategoriesSlider_image { .CategoriesSlider_image {
padding: 10px 30px; padding: 10px 30px;
width: 152px; width: 160px;
height: 160px; min-height: 150px;
border: 1px solid #d9d9d9; border: 1px solid #d9d9d9;
border-radius: 10px; border-radius: 10px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
flex-direction: column;
p{
font-size: 10px !important;
font-weight: 500;
margin-bottom: 0 !important;
text-align: center !important;
padding-top: 3px;
color: var(--primary ) !important;
}
.truncate-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
img { img {
min-width: 140px;
max-width: 140px;
height: 150px;
border-radius: 10px; border-radius: 10px;
width: 150px;
height: 160px;
cursor: pointer;
aspect-ratio: 1;
object-fit: cover !important;
} }
} }
} }
@ -386,8 +402,7 @@
width: 110px; width: 110px;
height: 110px; height: 110px;
img { img {
min-width: 100px; width: 100px;
max-width: 100px;
height: 100px; height: 100px;
} }
@ -581,4 +596,10 @@
padding: 4px; padding: 4px;
border-radius: 10px; border-radius: 10px;
font-size: 30px; font-size: 30px;
}
.swiper-button-disabled{
display: none;
} }

View File

@ -101,7 +101,7 @@
border-radius: 4px; border-radius: 4px;
} }
.swiper-backface-hidden .swiper-slide{ .swiper-backface-hidden .swiper-slide{
padding-inline: 10px; // padding-inline: 10px;
min-width: 50px !important; min-width: 50px !important;
} }
> span{ > span{
@ -110,7 +110,8 @@
.product_multi_image{ .product_multi_image{
width: 60px !important; width: 60px !important;
height: 50px; height: 50px;
object-fit: contain; object-fit: cover;
aspect-ratio: 1;
cursor: pointer; cursor: pointer;
} }
} }

View File

@ -97,6 +97,13 @@
border: 1px solid var(--primary); border: 1px solid var(--primary);
font-size: 14px; font-size: 14px;
padding:6px 6px; padding:6px 6px;
&:hover{
background: var(--primary);
color: var(--white);
svg{
color: var(--white);
}
}
} }
svg { svg {
color: var(--primary); color: var(--primary);

View File

@ -18,5 +18,5 @@
.swiper-slide{ .swiper-slide{
min-width: 220px; min-width: 220px;
margin-inline: auto; // margin-inline: auto;
} }

View File

@ -7,3 +7,13 @@ const KEY = "product";
export const useGetProduct = (params?: any) => export const useGetProduct = (params?: any) =>
useGetQuery(KEY, API.GET, params); useGetQuery(KEY, API.GET, params);
const API2 = {
GETSimilar: `product`,
};
const KEY2 = "product_similar";
export const useGetProductSimilar = (params?: any) =>
useGetQuery(KEY2, API2.GETSimilar, params);

View File

@ -400,6 +400,6 @@
"Additional Info":"معلومات إضافية", "Additional Info":"معلومات إضافية",
"Product info is empty":"معلومات المنتج فارغة", "Product info is empty":"معلومات المنتج فارغة",
"We are DM company, which has been working for two decades. We are active in the United Arab Emirates in the field of stock laptops, computer parts, RAM, hard drives, etc. We are currently working with Europe, Africa and the Middle East.We provide you the best services with the shortest time and the highest quality":"نحن شركة DM، التي تعمل منذ عقدين من الزمن. نحن نشطون في دولة الإمارات العربية المتحدة في مجال أجهزة الكمبيوتر المحمولة، وقطع الكمبيوتر، وذاكرة الوصول العشوائي، والأقراص الصلبة، وما إلى ذلك. ونعمل حاليًا مع أوروبا وأفريقيا والشرق الأوسط. نقدم لك أفضل الخدمات في أقصر وقت وبأقل تكلفة. اعلى جودة", "We are DM company, which has been working for two decades. We are active in the United Arab Emirates in the field of stock laptops, computer parts, RAM, hard drives, etc. We are currently working with Europe, Africa and the Middle East.We provide you the best services with the shortest time and the highest quality":"نحن شركة DM، التي تعمل منذ عقدين من الزمن. نحن نشطون في دولة الإمارات العربية المتحدة في مجال أجهزة الكمبيوتر المحمولة، وقطع الكمبيوتر، وذاكرة الوصول العشوائي، والأقراص الصلبة، وما إلى ذلك. ونعمل حاليًا مع أوروبا وأفريقيا والشرق الأوسط. نقدم لك أفضل الخدمات في أقصر وقت وبأقل تكلفة. اعلى جودة",
"":"" "What do you like":"ماذا تريد"
} }

View File

@ -385,5 +385,5 @@
"Info":"信息", "Info":"信息",
"Additional Info":"附加信息", "Additional Info":"附加信息",
"Product info is empty":"产品信息为空", "Product info is empty":"产品信息为空",
"":"" "What do you like":"你喜欢什么"
} }

View File

@ -6,26 +6,23 @@ interface ImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {
} }
const CustomImage: React.FC<ImageProps> = ({ src, ...props }) => { const CustomImage: React.FC<ImageProps> = ({ src, ...props }) => {
const addBaseUrlToSrc = (src: string) => {
return ImageBaseURL + src?.replace("public", "/storage");
};
const [imgSrc, setImgSrc] = useState(addBaseUrlToSrc(src)); const [imgSrc, setImgSrc] = useState<any>(src);
useEffect(() => { useEffect(() => {
setImgSrc(addBaseUrlToSrc(src)); setImgSrc(src);
}, [src]); }, [src,props]);
const newImage = ImageBaseURL + (imgSrc?.replace("public", "/storage"))
const handleError = () => {
setImgSrc("/Home/p1.png");
};
return ( return (
<img <img
src={imgSrc} src={newImage}
onError={handleError}
{...props} {...props}
alt={props.alt || "image"} alt="there is no image"
/> />
); );
}; };