favorites compare completed

This commit is contained in:
2025-05-16 19:02:18 +05:00
parent 501ed130be
commit bde2ab91fe
11 changed files with 422 additions and 288 deletions
+86 -14
View File
@@ -5,8 +5,25 @@ import FacebookIcon from "./icons/FacebookIcon";
import LinkedInIcon from "./icons/LinkedInIcon";
import TwitterIcon from "./icons/TwitterIcon";
import ChevronDownIcon from "./icons/ChevronDownIcon";
import { useFavoritesUnitsStore } from "../stores/useFavoritesUnitsStore";
import { AnimatePresence, motion } from "motion/react";
import { useState } from "react";
import { BrochureButton } from "./Header";
import clsx from "clsx";
import { useClickAway } from "@uidotdev/usehooks";
import Button from "./ui/Button";
import useModalStore from "../stores/useModalStore";
import PrivacyPolicyModal from "./modals/PrivacyPolicyModal";
function Footer() {
const { favoriteUnits } = useFavoritesUnitsStore();
const [opened, setOpened] = useState(false);
const ref = useClickAway<HTMLDivElement>(() => setOpened(false));
const { setModal } = useModalStore();
return (
<footer className="z-1 2xl:px-[2.222vw] 2xl:pb-[2.222vw] 2xl:pt-[2.778vw] md:max-2xl:p-6 px-4 py-6 grid 2xl:grid-cols-6 md:max-2xl:grid-cols-4 grid-cols-2 2xl:grid-rows-2 2xl:gap-x-[1.667vw] 2xl:gap-y-[1.111vw] max-2xl:gap-y-6 2xl:rounded-t-[1.667vw] rounded-t-3xl outline outline-[#E2E2DC] bg-white">
<img
@@ -61,19 +78,19 @@ function Footer() {
<div className="2xl:border-l-[0.069vw] border-l border-[#E2E2DC] 2xl:pl-[1.111vw] pl-4 flex flex-col items-start 2xl:col-start-4 2xl:row-start-1 2xl:row-span-2 md:max-2xl:col-start-3 col-start-1">
<Link
to={"/"}
className="text-btn-l flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
className="md:text-btn-l text-btn-m flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
>
Map
</Link>
<Link
to={"/unit-types"}
className="text-btn-l flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
className="md:text-btn-l text-btn-m flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
>
Unit Types
</Link>
<Link
to={"/about-irth"}
className="text-btn-l flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
className="md:text-btn-l text-btn-m flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
>
About IRTH
</Link>
@@ -82,31 +99,86 @@ function Footer() {
<div className="2xl:border-l-[0.069vw] border-l border-[#E2E2DC] 2xl:pl-[1.111vw] md:max-2xl:pl-6 pl-3.5 flex flex-col items-start 2xl:col-start-5 2xl:row-start-1 2xl:row-span-2">
<Link
to={"/favorites"}
className="text-btn-l flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
className="md:text-btn-l text-btn-m flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70 relative"
>
Favorites
{!!favoriteUnits.length && (
<div className="absolute top-0 right-0 translate-x-full max-2xl:-translate-y-full rounded-full w-5 flex items-center justify-center aspect-square bg-[#00BED7] text-white text-caption-s">
{favoriteUnits.length}
</div>
)}
</Link>
<Link
to={"/search"}
className="text-btn-l flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
className="md:text-btn-l text-btn-m flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
>
Search
</Link>
<button className="text-btn-l flex-1 content-center md:my-3 my-[13px] text-[#0D1922]/70 flex items-center gap-2">
<span>Brochures</span>
<div className="2xl:w-[1.667vw] 2xl:h-[1.667vw] md:max-2xl:w-6 md:max-2xl:h-6 w-5 h-5">
<ChevronDownIcon />
</div>
</button>
<div ref={ref}>
<Button
variant="tertiary"
size="large"
className="2xl:!py-[17px] !py-[13px]"
onClick={() => setOpened((prev) => !prev)}
>
<span className="md:text-btn-l text-btn-m text-[#0D1922]/70">
Brochures
</span>
<span
className={clsx(
"2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 transition-transform duration-300 text-[#0D1922]/70",
opened && "rotate-180"
)}
>
<ChevronDownIcon />
</span>
</Button>
<AnimatePresence>
{opened && (
<motion.div
initial={{ opacity: 0, x: "100%" }}
animate={{ opacity: 1, x: "0%" }}
exit={{ opacity: 0, x: "100%" }}
transition={{ bounce: 0, duration: 0.3 }}
className="max-2xl:hidden p-[1.667vw] flex gap-[1.111vw] justify-stretch items-stretch fixed top-[calc(3.889vw+20px)] left-[57.083vw] w-[32.222vw] rounded-[1.111vw] bg-white shadow-[0_2px_8px_rgba(0,0,0,0.15)]"
>
<div className="flex-1 space-y-4">
<p className="text-s font-medium">Rove Home Marasi Drive</p>
<div className="flex flex-col gap-[0.556vw]">
{[
"Rove Main Brochure",
"Rove Amenties Brochure",
"Rove Technical Brochure",
].map((title) => (
<BrochureButton title={title} key={title} />
))}
</div>
</div>
<div className="flex-1 space-y-4">
<p className="text-s font-medium">Rove Home Downtown</p>
<div className="flex flex-col gap-[0.556vw]">
{[
"Rove Main Brochure",
"Rove Amenties Brochure",
"Rove Technical Brochure",
].map((title) => (
<BrochureButton title={title} key={title} />
))}
</div>
</div>
</motion.div>
)}
</AnimatePresence>
</div>
</div>
<div className="content-end 2xl:text-right 2xl:col-start-6 2xl:row-start-1 2xl:row-span-2 md:max-2xl:col-start-1 md:max-2xl:row-start-3 max-md:col-span-3 max-md:pt-3 max-md:border-t border-[#E2E2DC]">
<Link
to={"/"}
<button
className="md:text-caption-m text-caption-s max-2xl:text-[#73787C] text-[#0D1922]/70"
onClick={() => setModal(<PrivacyPolicyModal />)}
>
Privacy Policy
</Link>
</button>
</div>
</footer>
);
+15 -3
View File
@@ -12,6 +12,7 @@ import { projects } from "../data/projects";
import useModalStore from "../stores/useModalStore";
import PrivacyPolicyModal from "./modals/PrivacyPolicyModal";
import ChevronDownIcon from "./icons/ChevronDownIcon";
import { useFavoritesUnitsStore } from "../stores/useFavoritesUnitsStore";
function Header() {
function handleLogoClick() {
@@ -35,7 +36,7 @@ function Header() {
return (
<>
<header className="sticky top-0 left-0 z-2 w-full h-14 md:max-2xl:h-16 2xl:h-[4.444vw] flex items-center justify-center bg-white ring ring-[#E2E2DC]">
<header className="sticky top-0 left-0 z-4 w-full h-14 md:max-2xl:h-16 2xl:h-[4.444vw] flex items-center justify-center bg-white ring ring-[#E2E2DC]">
<div className="flex 2xl:gap-[1.111vw] gap-4 flex-1">
<div
className="2xl:px-[2.222vw] 2xl:py-[1.111vw] md:max-2xl:px-6 max-md:px-4 py-4 cursor-pointer"
@@ -92,7 +93,7 @@ function Header() {
animate={{ opacity: 1, y: "0%" }}
exit={{ opacity: 0, y: "-100%" }}
transition={{ duration: 0.3 }}
className="2xl:hidden fixed left-0 md:top-16 top-14 md:p-4 p-3 z-1 w-full md:rounded-b-2xl flex flex-col gap-10 bg-white overflow-y-auto max-h-[calc(100dvh-56px)] pointer-events-auto"
className="2xl:hidden fixed left-0 md:top-16 top-14 md:p-4 p-3 z-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 ring-[#E2E2DC]"
>
<div className="space-y-4">
<p className="text-h3 font-medium">Projects</p>
@@ -191,17 +192,28 @@ function Header() {
export default Header;
function NavItem({ href, title }: { href: string; title: string }) {
const { favoriteUnits } = useFavoritesUnitsStore();
return (
<NavLink
to={href}
className={({ isActive }) =>
clsx(
"text-btn-m 2xl:px-[1.25vw] 2xl:py-[0.903vw] p-4 2xl:rounded-[0.833vw] rounded-xl transition-colors duration-300 !leading-none max-2xl:text-center max-2xl:bg-[#F3F3F2]",
"text-btn-m 2xl:px-[1.25vw] 2xl:py-[0.903vw] p-4 2xl:rounded-[0.833vw] rounded-xl transition-colors duration-300 !leading-none max-2xl:text-center max-2xl:bg-[#F3F3F2] relative",
isActive && "!bg-[#00BED7] text-[#FFFFFF]"
)
}
>
{title}
{title === "Favorites" && !!favoriteUnits.length && (
<div
className={clsx(
"absolute 2xl:top-0 2xl:right-0 top-0.5 right-0.5 rounded-full w-5 flex items-center justify-center aspect-square bg-[#00BED7] text-white text-caption-s"
)}
>
{favoriteUnits.length}
</div>
)}
</NavLink>
);
}
+4 -4
View File
@@ -44,14 +44,14 @@ function ModalContainer() {
{modal && (
<motion.div
ref={rootRef}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
// initial={{ opacity: 0 }}
// animate={{ opacity: 1 }}
// exit={{ opacity: 0 }}
className="h-full"
>
<div
ref={popoverRef}
className="bg-black/70 fixed inset-0 max-md:top-14 flex flex-col items-center justify-center max-md:justify-start overflow-y-auto z-10"
className="bg-black/70 fixed inset-0 max-md:top-14 flex flex-col items-center justify-center max-md:justify-start overflow-y-auto z-5"
>
<div className="max-h-full">
<div ref={divRef} className="md:p-[1.08vw]">
+4 -1
View File
@@ -5,6 +5,7 @@ import HeartIcon from "./icons/HeartIcon";
import Button from "./ui/Button";
import "react-loading-skeleton/dist/skeleton.css";
import Skeleton from "react-loading-skeleton";
import { unitTypesFormatted } from "../data/unitTypes";
function UnitCard({ unit }: { unit: IUnit }) {
const { favoriteUnits, setFavoriteUnits } = useFavoritesUnitsStore();
@@ -52,7 +53,9 @@ function UnitCard({ unit }: { unit: IUnit }) {
</div>
<div className="2xl:space-y-[0.278vw] space-y-1">
<p className="text-s">
{`${unit.unitType}, ${unit.squareFt.toLocaleString(undefined, {
{`${unitTypesFormatted.get(
unit.unitType
)}, ${unit.squareFt.toLocaleString(undefined, {
maximumFractionDigits: 2,
})} Sqft`}
</p>
+2 -1
View File
@@ -1,6 +1,7 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useState } from "react";
import clsx from "clsx";
import { unitTypesFormatted } from "../data/unitTypes";
function UnitTypesSelect({
unitTypes,
@@ -37,7 +38,7 @@ function UnitTypesSelect({
: "ring-[#E2E2DC] text-[#0D1922]/70"
)}
>
{unitType}
{unitTypesFormatted.get(unitType)}
</p>
))}
</div>