feat : add footer , header , base css, progressBar , main and page components
This commit is contained in:
70
src/components/alert/Alert.tsx
Normal file
70
src/components/alert/Alert.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
const Alert = ({ children, type, message }) => {
|
||||
const types = {
|
||||
info: {
|
||||
text: "text-blue-800",
|
||||
bg: "bg-blue-50",
|
||||
darkText: "dark:text-blue-400",
|
||||
darkBg: "dark:bg-gray-800",
|
||||
iconPath:
|
||||
"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z",
|
||||
},
|
||||
danger: {
|
||||
text: "text-red-800",
|
||||
bg: "bg-red-50",
|
||||
darkText: "dark:text-red-400",
|
||||
darkBg: "dark:bg-gray-800",
|
||||
iconPath:
|
||||
"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z",
|
||||
},
|
||||
success: {
|
||||
text: "text-green-800",
|
||||
bg: "bg-green-50",
|
||||
darkText: "dark:text-green-400",
|
||||
darkBg: "dark:bg-gray-800",
|
||||
iconPath:
|
||||
"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z",
|
||||
},
|
||||
warning: {
|
||||
text: "text-yellow-800",
|
||||
bg: "bg-yellow-50",
|
||||
darkText: "dark:text-yellow-300",
|
||||
darkBg: "dark:bg-gray-800",
|
||||
iconPath:
|
||||
"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z",
|
||||
},
|
||||
dark: {
|
||||
text: "text-gray-800",
|
||||
bg: "bg-gray-50",
|
||||
darkText: "dark:text-gray-300",
|
||||
darkBg: "dark:bg-gray-800",
|
||||
iconPath:
|
||||
"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z",
|
||||
},
|
||||
};
|
||||
|
||||
const { text, bg, darkText, darkBg, iconPath, title } =
|
||||
types[type] || types.info;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center p-4 mb-4 text-sm ${text} rounded-lg ${bg} ${darkText} ${darkBg}`}
|
||||
role="alert"
|
||||
>
|
||||
<svg
|
||||
className="flex-shrink-0 inline w-4 h-4 me-3"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path d={iconPath} />
|
||||
</svg>
|
||||
<span className="sr-only">Info</span>
|
||||
<div>
|
||||
<span className="font-medium">{children}</span> {message}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Alert;
|
||||
12
src/components/footer/components/CopyRight.tsx
Normal file
12
src/components/footer/components/CopyRight.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
const CopyRight = () => {
|
||||
return (
|
||||
<div className="relative w-full h-full p-3">
|
||||
<p className="text-center text-sm md:text-lg">
|
||||
تمام حقوق این سایت مطعلق به پرشین پینگ است . ساخته شده با عشق توسط سهیل
|
||||
خالدابادی
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CopyRight;
|
||||
13
src/components/footer/components/SocialMedia.tsx
Normal file
13
src/components/footer/components/SocialMedia.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import { FaInstagram, FaTelegram, FaTwitter } from "react-icons/fa6";
|
||||
|
||||
const SocialMedia = () => {
|
||||
return (
|
||||
<div className="w-full h-full flex pt-2 gap-5 justify-center items-center">
|
||||
<FaInstagram />
|
||||
<FaTwitter />
|
||||
<FaTelegram />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SocialMedia;
|
||||
16
src/components/footer/index.tsx
Normal file
16
src/components/footer/index.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import CopyRight from "./components/CopyRight";
|
||||
import SocialMedia from "./components/SocialMedia";
|
||||
|
||||
const Footer = () => {
|
||||
return (
|
||||
<div className="relative w-full p-5 h-[10rem]">
|
||||
<footer className="glass w-full flex flex-col justify-center items-center gap-2 h-full">
|
||||
<SocialMedia />
|
||||
<hr className="w-3/4 border-gray-700" />
|
||||
<CopyRight />
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
50
src/components/header/components/navbar/MobileMenu.tsx
Normal file
50
src/components/header/components/navbar/MobileMenu.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
// src/components/Header/Navbar/MobileMenu.tsx
|
||||
import NavbarLink from "./NavbarLink";
|
||||
const MobileMenu = ({ isOpen, toggleMenu, routes }) => {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={`fixed inset-y-0 right-0 w-1/2 glass transform ${
|
||||
isOpen ? "translate-x-0" : "translate-x-full"
|
||||
} transition-transform duration-300 ease-in-out z-50 md:hidden`}
|
||||
>
|
||||
<div className="absolute top-0 left-0 p-4">
|
||||
<button onClick={toggleMenu} className="text-white">
|
||||
<svg
|
||||
className="h-6 w-6"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-8 mt-4 ">
|
||||
{routes?.map((i) => {
|
||||
return (
|
||||
<NavbarLink key={i.id} to={i.path} onClick={toggleMenu}>
|
||||
{i.name}
|
||||
</NavbarLink>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
{isOpen && (
|
||||
<div
|
||||
className="fixed inset-0 bg-black bg-opacity-50 backdrop-filter backdrop-blur-sm z-40 md:hidden"
|
||||
onClick={toggleMenu}
|
||||
></div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default MobileMenu;
|
||||
46
src/components/header/components/navbar/MobileMenuButton.tsx
Normal file
46
src/components/header/components/navbar/MobileMenuButton.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
const MobileMenuButton = ({ isOpen, onClick }) => {
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
type="button"
|
||||
className="p-2 rounded-md scale-110 text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none"
|
||||
>
|
||||
<span className="sr-only">{"باز کردن منو"}</span>
|
||||
{!isOpen ? (
|
||||
<svg
|
||||
className="block h-6 w-6"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M4 6h16M4 12h16M4 18h16"
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
<svg
|
||||
className="block h-6 w-6"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default MobileMenuButton;
|
||||
56
src/components/header/components/navbar/Navbar.tsx
Normal file
56
src/components/header/components/navbar/Navbar.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
// src/components/Header/Navbar/Navbar.tsx
|
||||
import React, { useState, useEffect } from "react";
|
||||
import MobileMenuButton from "./MobileMenuButton";
|
||||
import MobileMenu from "./MobileMenu";
|
||||
import NavbarLink from "./NavbarLink";
|
||||
import router from "../../../../routes/routes";
|
||||
import Button from "../../../../assets/button";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const Navbar = () => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const [routes, setRoutes] = useState(router);
|
||||
|
||||
const toggleMenu = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
document.body.style.overflow = "hidden";
|
||||
} else {
|
||||
document.body.style.overflow = "auto";
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<nav className="glass text-white p-4 flex justify-between items-center">
|
||||
<div className="flex items-center">
|
||||
<h1 className="text-xl font-bold">پرشین پینگ</h1>
|
||||
</div>
|
||||
<div className="flex gap-3 md:space-x-4">
|
||||
<div className="hidden md:flex space-x-4">
|
||||
{routes?.map((i) => {
|
||||
return (
|
||||
<NavbarLink key={i.id} to={i.path}>
|
||||
{i.name}
|
||||
</NavbarLink>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<Button>
|
||||
<Link to="login"> ورود </Link>
|
||||
</Button>
|
||||
<div className="md:hidden">
|
||||
<MobileMenuButton isOpen={isOpen} onClick={toggleMenu} />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<MobileMenu isOpen={isOpen} toggleMenu={toggleMenu} routes={routes} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navbar;
|
||||
19
src/components/header/components/navbar/NavbarLink.tsx
Normal file
19
src/components/header/components/navbar/NavbarLink.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { NavLink } from "react-router-dom";
|
||||
|
||||
const NavbarLink = ({ to, children, onClick }) => {
|
||||
return (
|
||||
<NavLink
|
||||
to={to}
|
||||
className={(navData) =>
|
||||
navData.isActive
|
||||
? "block px-2 mx-3 py-2 text-base font-medium text-yellow-600 border-b-2 border-yellow-600"
|
||||
: "block px-2 mx-3 py-2 rounded-md text-base font-medium text-white"
|
||||
}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</NavLink>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavbarLink;
|
||||
13
src/components/header/index.tsx
Normal file
13
src/components/header/index.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import Navbar from "./components/navbar/Navbar";
|
||||
|
||||
const Header = () => {
|
||||
return (
|
||||
<div className="relative w-full p-5 h-[7rem]">
|
||||
<header>
|
||||
<Navbar />
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
Reference in New Issue
Block a user