feat : fixed menu
This commit is contained in:
6
package-lock.json
generated
6
package-lock.json
generated
@@ -20,6 +20,7 @@
|
|||||||
"country-flag-icons": "^1.5.11",
|
"country-flag-icons": "^1.5.11",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"framer-motion": "^11.2.9",
|
"framer-motion": "^11.2.9",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
@@ -4008,6 +4009,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.debounce": {
|
||||||
|
"version": "4.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||||
|
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
||||||
|
},
|
||||||
"node_modules/lodash.merge": {
|
"node_modules/lodash.merge": {
|
||||||
"version": "4.6.2",
|
"version": "4.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"country-flag-icons": "^1.5.11",
|
"country-flag-icons": "^1.5.11",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"framer-motion": "^11.2.9",
|
"framer-motion": "^11.2.9",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export default function MuiModal({
|
|||||||
nameService,
|
nameService,
|
||||||
submitText,
|
submitText,
|
||||||
submitOnClick,
|
submitOnClick,
|
||||||
|
disabled,
|
||||||
children,
|
children,
|
||||||
}: MuiModalProps) {
|
}: MuiModalProps) {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
@@ -33,19 +34,19 @@ export default function MuiModal({
|
|||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
aria-labelledby="modal-modal-title"
|
aria-labelledby="modal-modal-title"
|
||||||
aria-describedby="modal-modal-description"
|
aria-describedby="modal-modal-description"
|
||||||
className="relative w-full h-full flex justify-center items-center border-none outline-none"
|
className="relative w-full h-full flex justify-center items-center !border-none !outline-none !ring-0"
|
||||||
>
|
>
|
||||||
<motion.div
|
<motion.div
|
||||||
className="max-md:w-72 md:w-80 lg:w-96 min-h-80 shadow-xl shadow-[rgb(20,20,20)] bg-[rgb(20,20,20,0.99)] rounded-lg p-4 relative flex flex-col justify-between items-center gap-4"
|
className="max-md:w-72 md:w-80 lg:w-96 min-h-80 shadow-xl shadow-[rgb(20,20,20)] bg-[rgb(20,20,20,0.99)] rounded-lg p-4 relative flex flex-col justify-between items-center gap-4"
|
||||||
initial={{ opacity: 0 }}
|
initial={{ y: "-100vw", opacity: 0 }}
|
||||||
animate={{ opacity: 1 }}
|
animate={{ y: 0, opacity: 1 }}
|
||||||
transition={{duration:0.7}}
|
transition={{ duration: 0.5 }}
|
||||||
>
|
>
|
||||||
<motion.div className="w-full h-full flex gap-2 justify-between">
|
<motion.div className="w-full h-full flex gap-2 justify-between">
|
||||||
<h1 className="text-lg md:text-xl font-bold">
|
<h1 className="text-lg md:text-xl font-bold">
|
||||||
{title && title}
|
{title && title}
|
||||||
{nameService && (
|
{nameService && (
|
||||||
<span className="text-green-600"> {nameService} </span>
|
<span className="text-secondTheme"> {nameService} </span>
|
||||||
)}
|
)}
|
||||||
</h1>
|
</h1>
|
||||||
<button onClick={handleClose}>
|
<button onClick={handleClose}>
|
||||||
@@ -55,10 +56,14 @@ export default function MuiModal({
|
|||||||
<motion.div className="w-full h-full flex flex-col justify-between text-center items-center">
|
<motion.div className="w-full h-full flex flex-col justify-between text-center items-center">
|
||||||
{children}
|
{children}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<motion.div className={`w-full h-full flex ${submitText ? 'justify-end' : 'justify-center' } items-center gap-2 md:gap-3 text-lg md:text-xl`}>
|
<motion.div
|
||||||
|
className={`w-full h-full flex ${
|
||||||
|
submitText ? "justify-end" : "justify-center"
|
||||||
|
} items-center gap-2 md:gap-3 text-lg md:text-xl`}
|
||||||
|
>
|
||||||
<Button onClick={() => handleClose()}> بستن </Button>
|
<Button onClick={() => handleClose()}> بستن </Button>
|
||||||
{submitText && (
|
{submitText && (
|
||||||
<Button onClick={submitOnClick}> {submitText} </Button>
|
<Button onClick={submitOnClick} disabled={disabled}> {submitText} </Button>
|
||||||
)}
|
)}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AlertProps, MessageType } from "../../types/props";
|
import { AlertProps, MessageType } from "../../types/props";
|
||||||
|
|
||||||
const Alert = ({ children, type = "info", message }: AlertProps) => {
|
const Alert = ({ children, type = "info", message , extra }: AlertProps) => {
|
||||||
const types: Record<
|
const types: Record<
|
||||||
MessageType,
|
MessageType,
|
||||||
{
|
{
|
||||||
@@ -57,7 +57,7 @@ const Alert = ({ children, type = "info", message }: AlertProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`w-full h-full flex items-center p-4 mb-4 text-xs md:text-sm ${text} rounded-lg ${bg} ${darkText} ${darkBg}`}
|
className={`w-full h-full flex items-center p-4 mb-4 text-xs md:text-sm ${text} rounded-lg ${bg} ${darkText} ${darkBg} ${extra}`}
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -71,7 +71,7 @@ const Alert = ({ children, type = "info", message }: AlertProps) => {
|
|||||||
</svg>
|
</svg>
|
||||||
<span className="sr-only">{children}</span>
|
<span className="sr-only">{children}</span>
|
||||||
<div>
|
<div>
|
||||||
<span className="font-medium">{children}</span> {message && message}
|
{message && message} <span className="font-medium">{children}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { Route } from "../../../../types/props";
|
import { Route } from "../../../../types/props";
|
||||||
import { isAuthenticated } from "../../../../utils/auth";
|
import { isAuthenticated } from "../../../../utils/auth";
|
||||||
|
|
||||||
const Navbar = () => {
|
const Navbar = ({extra}:{extra?:string}) => {
|
||||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||||
const auth = isAuthenticated();
|
const auth = isAuthenticated();
|
||||||
const [routes] = useState<Route[]>(router);
|
const [routes] = useState<Route[]>(router);
|
||||||
@@ -29,7 +29,7 @@ const Navbar = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<nav className="glass text-white p-4 flex justify-between items-center">
|
<nav className={`glass text-white p-4 flex justify-between items-center ${extra}`}>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<h1 className="text-xl font-bold">پرشین پینگ</h1>
|
<h1 className="text-xl font-bold">پرشین پینگ</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,26 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
import Navbar from "./components/navbar/Navbar";
|
import Navbar from "./components/navbar/Navbar";
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
|
const [isFixed, setIsFixed] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleScroll = () => {
|
||||||
|
if (window.scrollY > 50) {
|
||||||
|
setIsFixed(true);
|
||||||
|
} else {
|
||||||
|
setIsFixed(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("scroll", handleScroll);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("scroll", handleScroll);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative w-full p-5 h-[7rem]">
|
<div className="w-full p-5 h-[7rem]">
|
||||||
<header>
|
<header className={`w-full transition-all duration-300 ease-in-out ${isFixed ? "fixed max-w-[1400px] h-[6rem] mx-auto z-[1000] inset-0 p-2" : ""}`}>
|
||||||
<Navbar />
|
<Navbar extra={`${isFixed && '!bg-gray-800/90'}`}/>
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,7 +7,14 @@ import { PersistGate } from "redux-persist/integration/react";
|
|||||||
import store, { persistor } from "./redux/store";
|
import store, { persistor } from "./redux/store";
|
||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
|
|
||||||
export const queryClient = new QueryClient();
|
export const queryClient = new QueryClient({
|
||||||
|
defaultOptions: {
|
||||||
|
queries: {
|
||||||
|
retry: false,
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
|||||||
Reference in New Issue
Block a user