feat : add section (productList , bestQuality) in shop page

This commit is contained in:
Ali Josheghani
2024-05-28 00:21:10 +03:30
parent 8dc97f4ec1
commit 278bfca3c8
11 changed files with 258 additions and 10 deletions

View File

@@ -0,0 +1,5 @@
const Modal = () => {
return <div>index</div>;
};
export default Modal;

View File

@@ -1,9 +1,13 @@
import { ButtonProps } from "../../types/props";
function Button({ children, onClick, extra }: ButtonProps) {
function Button({ children, onClick, extra, active }: ButtonProps) {
return (
<button
className={`px-4 py-1 md:px-5 md:py-2 rounded-md transition duration-300 ease-in-out transform bg-white text-[#333] hover:bg-gray-600 hover:text-white ${extra}`}
className={`px-4 py-1 md:px-5 md:py-2 rounded-md transition duration-300 ease-in-out transform bg-white text-[#333] hover:bg-gray-600 hover:text-white ${
active
? "bg-yellow-600 shadow-yellow-600 hover:shadow-gray-600 shadow-lg text-white"
: ""
} ${extra}`}
onClick={onClick}
>
{children}

View File

@@ -0,0 +1,50 @@
import { AM, EC, GA, US, GD, GB } from "country-flag-icons/react/1x1";
import { ProductBoxProps } from "../../types/props";
import Button from "../button";
const ProductBox = ({
title,
space,
users,
price,
btnText,
variant,
}: ProductBoxProps) => {
return (
<div
className={`p-4 w-full h-full flex flex-col gap-3 justify-center items-center rounded-lg shadow-inner ${
variant === 1
? "shadow-purple-800 bg-purple-600"
: variant === 2
? "shadow-orange-800 bg-orange-600"
: variant === 3 && "shadow-indigo-800 bg-indigo-600"
} bg-cover bg-center bg-banner`}
>
<h1 className="max-md:text-xl md:text-2xl font-bold">{title}</h1>
<div className="w-full h-full p-2 flex gap-2 justify-between items-center">
<div className="w-full h-full flex flex-col gap-2">
<h2 className="max-md:text-lg md:text-xl text-center">{space} گیگ</h2>
<p className="max-md:text-sm md:text-lg text-center">
{users} کاربره
</p>
</div>
<div className="w-full h-full gap-4 grid grid-cols-3">
<GA className="w-5 lg:w-7 rounded-md" />
<US className="w-5 lg:w-7 rounded-md" />
<EC className="w-5 lg:w-7 rounded-md" />
<AM className="w-5 lg:w-7 rounded-md" />
<GB className="w-5 lg:w-7 rounded-md" />
<GD className="w-5 lg:w-7 rounded-md" />
</div>
</div>
<div className="w-full h-full bg-purple-950 text-center rounded-lg md:text-xl font-bold shadow-inner shadow-purple-600 px-4 py-2">
{price} تومان
</div>
<div className="w-full h-full grid grid-cols-1">
<Button extra="shadow-inner shadow-gray-400">{btnText}</Button>
</div>
</div>
);
};
export default ProductBox;

View File

@@ -2,11 +2,11 @@ import { FC } from "react";
const PulsatingCircle: FC = () => {
return (
<div className="relative flex justify-center items-center w-52 h-52">
<div className="absolute flex justify-center items-center w-24 h-24 border-4 border-yellow-400 rounded-full z-10">
<span className="text-4xl text-yellow-400">1</span>
<div className="relative flex justify-center items-center w-full h-full">
<div className="relative flex justify-center items-center max-md:w-32 max-md:h-32 w-52 h-52 max-md:border-[10px] border-[15px] border-yellow-600 rounded-full z-10">
<span className="text-6xl md:text-8xl text-white">1</span>
</div>
<div className="absolute w-24 h-24 border-4 border-yellow-400 rounded-full animate-pulse delay-75"></div>
<div className="absolute max-md:w-32 max-md:h-32 w-52 h-52 border-4 border-yellow-600 rounded-full animate-pulse"></div>
</div>
);
};

View File

@@ -1,6 +1,8 @@
import BestQuality from "./section/bestQuality/BestQuality";
import FastSell from "./section/fastSell/FastSell";
import Intro from "./section/intro/Intro";
import NowSell from "./section/nowSell/NowSell";
import ProductList from "./section/productList/ProductList";
const Shop = () => {
return (
@@ -9,6 +11,8 @@ const Shop = () => {
<Intro />
<FastSell />
<NowSell />
<ProductList />
<BestQuality />
</div>
</div>
);

View File

@@ -0,0 +1,25 @@
import PulsatingCircle from "../../../../components/pulsatingCircle";
const BestQuality = () => {
return (
<div className="w-full h-full mt-4 md:mt-10 mb-10 flex gap-10 flex-col justify-center items-center">
<div className="w-full h-full flex justify-center items-center">
<PulsatingCircle />
</div>
<div className="w-full h-full flex flex-col gap-2 md:gap-4 justify-center items-center">
<h1 className="max-md:text-xl md:text-4xl font-bold">
به عنوان{" "}
<span className="max-md:text-xl md:text-5xl text-yellow-600 font-bold">
اولین و بهترین
</span>{" "}
ارائه دهنده{" "}
</h1>
<h1 className="relative max-md:right-10 max-lg:right-20 lg:right-40 max-md:text-xl md:text-4xl font-bold">
مفتخریم که در خدمت شما باشیم
</h1>
</div>
</div>
);
};
export default BestQuality;

View File

@@ -1,5 +1,7 @@
import Button from "../../../../components/button";
import Rocket3D from "../../../../assets/ui/Rocket.png";
const Intro = () => {
return (
<div className="relative w-full h-full md:pt-40 mb-16 md:mb-32 gap-6 grid grid-cols-1 py-8 md:grid-cols-2">
@@ -18,9 +20,9 @@ const Intro = () => {
</div>
<div className="w-full h-full flex justify-center py-4 mx-auto items-center">
<img
src="https://persain-game.com/front_end/img/Iphone%2015.png"
src={Rocket3D}
alt="intro"
className="w-60 md:w-72 lg:w-80"
className="w-60 md:w-72 lg:w-[25rem] animate-bounce"
/>
</div>
</div>

View File

@@ -1,5 +1,30 @@
import { useState } from "react";
import ButtonList from "./components/ButtonList";
import ListAllProduct from "./components/ListAllProduct";
const ProductList = () => {
return <div className="relative w-full h-full"></div>;
const [activeId, setActiveId] = useState(1);
const ProductsList = [
{ id: 1, title: "سرویس اشتراکی" },
{ id: 2, title: "سرویس گیمینگ" },
{ id: 3, title: "سرویس مولتی" },
];
return (
<div className="relative w-full h-full max-md:mt-4 md:mt-8 ">
<div className="w-full h-full gap-4 md:gap-6 flex flex-col p-5 justify-center items-center">
<h1 className="max-md:text-lg text-center text-2xl font-bold">
برای انتخاب پلن مورد نظر کلیک کنید تا پلن و سرویس ها براتون نمایش داده
شود
</h1>
<ButtonList
ProductsList={ProductsList}
activeId={activeId}
setActiveId={setActiveId}
/>
<ListAllProduct activeId={activeId} />
</div>
</div>
);
};
export default ProductList;

View File

@@ -0,0 +1,27 @@
import Button from "../../../../../components/button";
import { ButtonListProps } from "../../../../../types/props";
const ButtonList = ({
ProductsList,
activeId,
setActiveId,
}: ButtonListProps) => {
return (
<div className="w-full h-full gap-4 grid max-sm:grid-cols-1 max-md:grid-cols-2 md:grid-cols-4 ">
{ProductsList?.map((i) => {
return (
<Button
key={i.id}
active={i.id === activeId}
extra="py-4 text-lg"
onClick={() => setActiveId(i.id)}
>
{i.title}
</Button>
);
})}
</div>
);
};
export default ButtonList;

View File

@@ -0,0 +1,90 @@
import { Fragment, useEffect, useState } from "react";
import ProductBox from "../../../../../components/productBox";
const ListAllProduct = ({ activeId }: { activeId: number }) => {
const Product = [
{
id: 1,
data: [
{ id: 1, title: "مولتی سرور ۱", users: 2, price: "100/000", space: 40 },
{ id: 2, title: "مولتی سرور ۲", users: 2, price: "200/000", space: 60 },
{
id: 3,
title: "مولتی سرور ۳",
users: 1,
price: "300/000",
space: 100,
},
{ id: 4, title: "مولتی سرور ۴", users: 3, price: "400/000", space: 50 },
],
},
{
id: 2,
data: [
{
id: 1,
title: " کاهش پینگ ۱",
users: 2,
price: "1/000/000",
space: 40,
},
{ id: 2, title: "کاهش پینگ ۲", users: 2, price: "500/000", space: 60 },
{
id: 3,
title: "کاهش پینگ ۳",
users: 1,
price: "800/000",
space: 100,
},
{ id: 4, title: "کاهش پینگ ۴", users: 3, price: "200/000", space: 50 },
],
},
{
id: 3,
data: [
{ id: 1, title: " سرور بازی ۱", users: 2, price: "50/000", space: 40 },
{ id: 2, title: "سرور بازی ۲", users: 2, price: "100/000", space: 60 },
{
id: 3,
title: "سرور بازی ۳",
users: 1,
price: "700/000",
space: 100,
},
{ id: 4, title: "سرور بازی ۴", users: 3, price: "350/000", space: 50 },
],
},
];
const [dataProduct, setDataProduct] = useState(
Product?.filter((i) => i.id === activeId)
);
useEffect(() => {
setDataProduct(Product?.filter((i) => i.id === activeId));
}, [activeId]);
return (
<div className="w-full h-full border-4 gap-5 border-spacing-1 border-solid border-yellow-600 rounded-lg p-3 grid max-sm:grid-cols-1 max-md:grid-cols-2 max-lg:grid-cols-3 lg:grid-cols-4">
{dataProduct?.map((item) => {
return (
<Fragment key={item.id}>
{item.data?.map((i) => {
return (
<ProductBox
key={i.id}
variant={item.id}
btnText="خرید"
price={i.price}
space={i.space}
title={i.title}
users={i.users}
/>
);
})}
</Fragment>
);
})}
</div>
);
};
export default ListAllProduct;

18
src/types/props.d.ts vendored
View File

@@ -12,6 +12,7 @@ export interface ButtonProps {
children: React.ReactNode;
onClick?: () => void;
extra?: string;
active?: boolean;
}
// begin Route
@@ -49,7 +50,7 @@ export interface NavData {
}
// begin ListTutorial.tsx
import { SetStateAction } from "react";
import { Component, SetStateAction } from "react";
export type TutorialList = { id: number; name: string }[];
@@ -69,3 +70,18 @@ interface TypewriterProps {
text: string;
speed?: number; // سرعت تایپ در میلی‌ثانیه
}
interface ButtonListProps {
ProductsList: { id: number; title: string }[];
activeId: number;
setActiveId: SetStateAction;
}
interface ProductBoxProps {
title: string;
space: number;
users: number;
price: string;
btnText: string;
variant: number;
}