122 lines
4.6 KiB
TypeScript
122 lines
4.6 KiB
TypeScript
import { Link, useLocation, useNavigate } from "react-router";
|
|
import { AnimatePresence, motion } from "motion/react";
|
|
import clsx from "clsx";
|
|
import Button from "../ui/Button";
|
|
import NavItem from "./NavItem";
|
|
import ProjectBrochuresList from "./ProjectBrochuresList";
|
|
import { projects } from "../../data/projects";
|
|
import { projectBrochures } from "../../data/brochures";
|
|
import useModalStore from "../../stores/useModalStore";
|
|
import PrivacyPolicyModal from "../modals/PrivacyPolicyModal";
|
|
|
|
interface MobileMenuProps {
|
|
opened: boolean;
|
|
onClose: () => void;
|
|
menuRef: React.RefObject<HTMLDivElement>;
|
|
}
|
|
|
|
export default function MobileMenu({
|
|
opened,
|
|
onClose,
|
|
menuRef,
|
|
}: MobileMenuProps) {
|
|
const navigate = useNavigate();
|
|
const { pathname } = useLocation();
|
|
const { setModal } = useModalStore();
|
|
|
|
return (
|
|
<AnimatePresence mode="wait">
|
|
{opened && (
|
|
<>
|
|
<motion.div
|
|
ref={menuRef}
|
|
initial={{ opacity: 0, y: "-100%" }}
|
|
animate={{ opacity: 1, y: "0%" }}
|
|
exit={{ opacity: 0, y: "-100%" }}
|
|
transition={{ duration: 0.3 }}
|
|
className="2xl:hidden fixed z-[1] left-0 md:top-16 top-14 md:p-4 p-3 w-full md:rounded-b-2xl flex flex-col gap-10 bg-white overflow-y-auto max-h-[calc(100dvh-56px)] pointer-events-auto ring-[0.069vw] ring-[#E2E2DC]"
|
|
>
|
|
<div className="space-y-4">
|
|
<p className="font-medium text-h3">Projects</p>
|
|
<div className="flex flex-wrap gap-2 items-start max-md:flex-col">
|
|
{projects.map(({ img, title, slug }, index) => {
|
|
return (
|
|
<Link
|
|
key={index}
|
|
to={`/complex/${slug}`}
|
|
className={clsx(
|
|
"p-1 pr-5 flex gap-2 items-center flex-nowrap rounded-full transition-[box-shadow,opacity,color] text-s md:ring-[0.069vw] ring-1",
|
|
pathname.endsWith(slug)
|
|
? "ring-[#00BED7] text-[#00BED7]"
|
|
: "ring-[#E2E2DC] text-[#0D1922]/70"
|
|
)}
|
|
>
|
|
<img src={img} alt={title} className="size-10" />
|
|
<span className="text-s">{title}</span>
|
|
</Link>
|
|
);
|
|
})}
|
|
<button
|
|
className={clsx(
|
|
"px-5 py-3.5 rounded-full text-s md:ring-[0.069vw] ring-1",
|
|
pathname === "/"
|
|
? "ring-[#00BED7] text-[#00BED7]"
|
|
: "ring-[#E2E2DC] text-[#0D1922]/70"
|
|
)}
|
|
onClick={() => {
|
|
onClose();
|
|
navigate("/");
|
|
}}
|
|
>
|
|
Show on Map
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<nav className="grid gap-2 md:grid-cols-2 md:gap-4">
|
|
<NavItem href={"/unit-types"} title={"Unit Types"} />
|
|
<NavItem href={"/about"} title={"About IRTH"} />
|
|
<NavItem href={"/favorites"} title={"Favorites"} />
|
|
<NavItem href={"/search"} title={"Search"} />
|
|
</nav>
|
|
<hr className="border-[#E2E2DC]" />
|
|
<div className="space-y-6">
|
|
<p className="font-medium text-h3">Brochures</p>
|
|
<div className="p-[0.278vw] flex md:gap-[1.111vw] gap-6 justify-stretch items-stretch max-md:flex-col">
|
|
{projectBrochures.map((project, index) => (
|
|
<ProjectBrochuresList
|
|
key={index}
|
|
projectTitle={project.projectTitle}
|
|
brochures={project.brochures}
|
|
variant="mobile"
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
<div className="flex bottom-0 left-0 justify-between items-end p-4 pt-6 w-full bg-white">
|
|
<p className="opacity-40 text-s w-fit">
|
|
For more information, visit our
|
|
<br />
|
|
website:{" "}
|
|
<Link
|
|
to="https://www.irth.ae"
|
|
className="underline text-[#00BED7]"
|
|
>
|
|
www.irth.ae
|
|
</Link>
|
|
</p>
|
|
<Button
|
|
variant="tertiary"
|
|
size="small"
|
|
onClick={() => setModal(<PrivacyPolicyModal />)}
|
|
>
|
|
<span className="text-btn-s">Privacy Policy</span>
|
|
</Button>
|
|
</div>
|
|
</motion.div>
|
|
<div className="fixed inset-0" />
|
|
</>
|
|
)}
|
|
</AnimatePresence>
|
|
);
|
|
}
|