feat: new header styyling

This commit is contained in:
RizqiSyahrendra 2025-04-27 11:01:54 +07:00
parent 0344b6a6fc
commit 0cef18f696
9 changed files with 379 additions and 139 deletions

View File

@ -18,6 +18,7 @@
"@payloadcms/plugin-form-builder": "^3.35.1",
"@payloadcms/richtext-lexical": "^3.35.1",
"@payloadcms/storage-s3": "^3.35.1",
"clsx": "^2.1.1",
"country-state-city": "^3.2.1",
"dayjs": "^1.11.13",
"graphql": "^16.8.1",
@ -29,7 +30,8 @@
"react-hook-form": "^7.56.1",
"react-select": "^5.10.1",
"react-toastify": "^11.0.5",
"swiper": "^11.2.6"
"swiper": "^11.2.6",
"tailwind-merge": "^3.2.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3",

View File

@ -3744,13 +3744,13 @@ html .page .divider-secondary::after {
}
.button-primary, .button-primary:focus {
color: #ffffff;
background-color: #bc986b;
border-color: #bc986b;
color: var(--color-colorBtnPrimaryText);
background-color: var(--color-colorBtnPrimary);
border-color: var(--color-colorBtnPrimary);
}
.button-primary:hover, .button-primary:active {
color: #151515;
color: var(--color-colorBtnPrimaryText);
opacity: 0.8;
}
@ -3759,15 +3759,14 @@ html .page .divider-secondary::after {
}
.button-secondary, .button-secondary:focus {
color: #151515;
background-color: #fdde52;
border-color: #fdde52;
color: var(--color-colorBtnSecondaryText);
background-color: var(--color-colorBtnSecondary);
border-color: var(--color-colorBtnSecondary);
}
.button-secondary:hover, .button-secondary:active {
color: #ffffff;
background-color: #bc986b;
border-color: #bc986b;
color: var(--color-colorBtnSecondaryText);
opacity: 0.8;
}
.button-secondary.button-ujarak::before {
@ -11699,7 +11698,7 @@ html.tablet .ui-to-top {
}
.rd-navbar-static .rd-menu {
z-index: 15;
z-index: 30;
position: absolute;
display: block;
visibility: hidden;

View File

@ -35,6 +35,10 @@
--color-colorText2: var(--color-colorExt20);
--color-colorLoaderBackground: var(--color-colorExt20);
--color-colorPriceTag: var(--color-colorExt30);
--color-colorBtnPrimary: var(--color-colorext40);
--color-colorBtnPrimaryText: var(--color-colorExt20);
--color-colorBtnSecondary: var(--color-colorExt50);
--color-colorBtnSecondaryText: var(--color-colorExt20);
}
@layer components {

View File

@ -1,4 +1,6 @@
import { headers } from "next/headers";
import HeaderFeaturedHomes from "./HeaderFeaturedHomes";
import { HeaderDropdown, HeaderDropdownGroup, HeaderDropdownMenu } from "./HeaderDropdown";
export default async function Header() {
const headerList = await headers();
@ -103,46 +105,134 @@ export default async function Header() {
srcSet="images/logo2.png 2x"
/>
</a>
{/* <h3 className="text-colorHeaderText! font-montserrat! font-semibold! hidden lg:inline">
Dynamic Realty
</h3> */}
</div>
</div>
<div className="rd-navbar-nav-wrap">
<ul className="rd-navbar-nav">
<li className="rd-nav-item">
<a className={`rd-nav-link rd-nav-link-custom ${headerActive("")}`} href="/">
HOME
<a className="rd-nav-link rd-nav-link-custom" href="#">
Buying / Selling
</a>
</li>
<li className="rd-nav-item">
<a
className="rd-nav-link rd-nav-link-custom"
href="https://dynamicrealtyinc.managebuilding.com/Resident/public/rentals"
target="_blank"
>
RENTAL PORTAL
<a className="rd-nav-link rd-nav-link-custom" href="#">
Leasing
</a>
<HeaderDropdown>
<HeaderDropdownGroup>
<div>
<form>
<div className="form-wrap">
<input type="text" id="search" className="form-input" />
<label className="form-label" htmlFor="search">
Search
</label>
</div>
</form>
</div>
<div className="mt-2">
<HeaderFeaturedHomes />
</div>
</HeaderDropdownGroup>
<HeaderDropdownGroup title="Future Residents">
<HeaderDropdownMenu
list={[
{
title: "Our Rentals",
href: "/#",
},
{
title: "Application Process",
child: [
{
title: "Before You Apply",
href: "/#",
},
{
title: "Rental Criteria",
href: "/#",
},
{
title: "Before You Apply",
href: "/#",
},
],
},
]}
/>
</HeaderDropdownGroup>
<HeaderDropdownGroup title="Current Residents">
<HeaderDropdownMenu
list={[
{
title: "Moving In",
child: [
{
title: "What To Be Done Prior",
href: "/#",
},
{
title: "Next Steps (keys, utilities, etc)",
href: "/#",
},
{
title: "Common Questions",
href: "/#",
},
],
},
{
title: "Welcome home",
child: [
{
title: "Payment",
href: "#",
},
{
title: "Utilities",
href: "#",
},
{
title: "Maintenance",
href: "#",
},
],
},
{
title: "Moving Out",
child: [
{
title: "What To Be Done Prior",
href: "/#",
},
{
title: "Next Steps (keys, utilities, etc)",
href: "/#",
},
{
title: "Common Questions",
href: "/#",
},
],
},
]}
/>
</HeaderDropdownGroup>
<HeaderDropdownGroup className="flex! pr-4!">
<div className="flex flex-col self-end!">
<a className="button button-secondary" href="/">
FAQ
</a>
<a className="button button-primary mt-2!" href="/">
APPLY NOW
</a>
</div>
</HeaderDropdownGroup>
</HeaderDropdown>
</li>
<li className="rd-nav-item">
<a
className={`rd-nav-link rd-nav-link-custom ${headerActive("listings-for-sale")}`}
href="/listings-for-sale"
>
LISTINGS FOR SALE
</a>
</li>
<li className="rd-nav-item">
<a
className={`rd-nav-link rd-nav-link-custom ${headerActive("listings-for-rent")}`}
href="/listings-for-rent"
>
LISTINGS FOR RENT
</a>
</li>
<li className="rd-nav-item">
<a className={`rd-nav-link rd-nav-link-custom ${headerActive("blog")}`} href="/blog">
BLOGS
<a className={`rd-nav-link rd-nav-link-custom`} href="/blog">
Resources
</a>
</li>
<li className="rd-nav-item block lg:hidden!">
@ -205,99 +295,117 @@ export default async function Header() {
<a className="rd-nav-link" href="#">
Pages
</a>
<ul className="rd-menu rd-navbar-megamenu">
<li className="rd-megamenu-item">
<h6 className="rd-megamenu-title">Pages 1</h6>
<ul className="rd-megamenu-list">
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="agents.html">
Agents
<HeaderDropdown>
<HeaderDropdownGroup>
<div>
<form>
<div className="form-wrap">
<input type="text" id="search" className="form-input" />
<label className="form-label" htmlFor="search">
Search
</label>
</div>
</form>
</div>
<div className="mt-2">
<HeaderFeaturedHomes />
</div>
</HeaderDropdownGroup>
<HeaderDropdownGroup title="Future Residents">
<HeaderDropdownMenu
list={[
{
title: "Our Rentals",
href: "/#",
},
{
title: "Application Process",
child: [
{
title: "Before You Apply",
href: "/#",
},
{
title: "Rental Criteria",
href: "/#",
},
{
title: "Before You Apply",
href: "/#",
},
],
},
]}
/>
</HeaderDropdownGroup>
<HeaderDropdownGroup title="Current Residents">
<HeaderDropdownMenu
list={[
{
title: "Moving In",
child: [
{
title: "What To Be Done Prior",
href: "/#",
},
{
title: "Next Steps (keys, utilities, etc)",
href: "/#",
},
{
title: "Common Questions",
href: "/#",
},
],
},
{
title: "Welcome home",
child: [
{
title: "Payment",
href: "#",
},
{
title: "Utilities",
href: "#",
},
{
title: "Maintenance",
href: "#",
},
],
},
{
title: "Moving Out",
child: [
{
title: "What To Be Done Prior",
href: "/#",
},
{
title: "Next Steps (keys, utilities, etc)",
href: "/#",
},
{
title: "Common Questions",
href: "/#",
},
],
},
]}
/>
</HeaderDropdownGroup>
<HeaderDropdownGroup className="flex! pr-4!">
<div className="flex flex-col self-end!">
<a className="button button-secondary" href="/">
FAQ
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="agent-single-page.html">
Agent Single Page
<a className="button button-primary mt-2!" href="/">
APPLY NOW
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="careers.html">
Careers
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="gallery.html">
Gallery
</a>
</li>
</ul>
</li>
<li className="rd-megamenu-item">
<h6 className="rd-megamenu-title">Pages 2</h6>
<ul className="rd-megamenu-list">
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="search-results.html">
Search results
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="coming-soon.html">
Coming Soon
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="404.html">
404
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="privacy-policy.html">
Privacy Policy
</a>
</li>
</ul>
</li>
<li className="rd-megamenu-item">
<h6 className="rd-megamenu-title">Elements</h6>
<ul className="rd-megamenu-list">
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="typography.html">
Typography
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="buttons.html">
Buttons
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="forms.html">
Forms
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="tabs-and-accordions.html">
Tabs and accordions
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="progress-bars.html">
Progress bars
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="tables.html">
Tables
</a>
</li>
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href="grid-system.html">
Grid System
</a>
</li>
</ul>
</li>
</ul>
</div>
</HeaderDropdownGroup>
</HeaderDropdown>
</li>
<li className="rd-nav-item">
<a className="rd-nav-link" href="contact-us.html">
@ -305,11 +413,6 @@ export default async function Header() {
</a>
</li> */}
</ul>
<div className="rd-navbar-main-item context-dark">
<a className="button button-sm button-primary-outline" href="#">
BOOK APPOINTMENT
</a>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,76 @@
import { createSlug } from "@/utils/general";
import { cn } from "@/utils/style";
import { FC, Fragment, PropsWithChildren } from "react";
export const HeaderDropdown: FC<PropsWithChildren> = ({ children }) => {
return <ul className="rd-menu rd-navbar-megamenu">{children}</ul>;
};
type HeaderDropdownGroupProps = {
title?: string;
className?: string;
};
export const HeaderDropdownGroup: FC<PropsWithChildren<HeaderDropdownGroupProps>> = ({
children,
title,
className,
}) => {
return (
<li className={cn("rd-megamenu-item", className)}>
{!!title && <h6 className="rd-megamenu-title">{title}</h6>}
{children}
</li>
);
};
type HeaderDropdownMenuItem = { title: string; href: string };
type HeaderDropdownMenuItemWithChild = { title: string; child: HeaderDropdownMenuItem[] };
type HeaderDropdownMenuProps = {
list?: (HeaderDropdownMenuItem | HeaderDropdownMenuItemWithChild)[];
};
export const HeaderDropdownMenu: FC<HeaderDropdownMenuProps> = ({ list = [] }) => {
return (
<ul className="rd-megamenu-list">
{list.map((item, idx) => {
const collapseId = createSlug(`collapse-${item.title}-${idx}`);
const hasChild = "child" in item;
return (
<Fragment key={idx}>
{hasChild && (
<li className="rd-megamenu-list-item">
<a
className="rd-megamenu-list-link cursor-pointer"
data-toggle="collapse"
data-target={`#${collapseId}`}
aria-controls={collapseId}
aria-expanded="false"
>
{item.title}
</a>
<div className="pl-3 mt-2 space-y-2 collapse visible!" id={collapseId}>
{item.child.map((itemChild, itemChildIdx) => (
<a key={itemChildIdx} className="rd-megamenu-list-link" href={itemChild.href}>
- {itemChild.title}
</a>
))}
</div>
</li>
)}
{!hasChild && (
<li className="rd-megamenu-list-item">
<a className="rd-megamenu-list-link" href={item.href}>
{item.title}
</a>
</li>
)}
</Fragment>
);
})}
</ul>
);
};

View File

@ -0,0 +1,34 @@
"use client";
import Image from "next/image";
export default function HeaderFeaturedHomes() {
const images = [
"/images/featured-properties-17-480x287.jpg",
"/images/featured-properties-17-480x287.jpg",
"/images/featured-properties-17-480x287.jpg",
"/images/featured-properties-17-480x287.jpg",
"/images/featured-properties-17-480x287.jpg",
"/images/featured-properties-17-480x287.jpg",
];
return (
<div className="p-2">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-1">
{images.map((src, index) => (
<div
key={index}
className="overflow-hidden rounded-lg shadow hover:shadow-lg transition-shadow duration-300 relative h-16"
>
<Image
src={src}
alt={`Gallery image ${index + 1}`}
className="object-cover transform transition-transform duration-300 hover:scale-105 cursor-pointer"
fill
/>
</div>
))}
</div>
</div>
);
}

View File

@ -24,3 +24,10 @@ export function formatCurrency(num: number): string {
//maximumFractionDigits: 0, // Causes 2500.99 to be printed as $2,501
}).format(num);
}
export function createSlug(val: string) {
return val
.replace(/ /g, "-")
.replace(/[^\w-/]+/g, "")
.toLowerCase();
}

6
src/utils/style.ts Normal file
View File

@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

View File

@ -5044,6 +5044,7 @@ __metadata:
"@types/node": "npm:^20"
"@types/react": "npm:^19"
"@types/react-dom": "npm:^19"
clsx: "npm:^2.1.1"
country-state-city: "npm:^3.2.1"
dayjs: "npm:^1.11.13"
eslint: "npm:^9"
@ -5061,6 +5062,7 @@ __metadata:
react-select: "npm:^5.10.1"
react-toastify: "npm:^11.0.5"
swiper: "npm:^11.2.6"
tailwind-merge: "npm:^3.2.0"
tailwindcss: "npm:^4"
typescript: "npm:^5"
languageName: unknown
@ -9759,6 +9761,13 @@ __metadata:
languageName: node
linkType: hard
"tailwind-merge@npm:^3.2.0":
version: 3.2.0
resolution: "tailwind-merge@npm:3.2.0"
checksum: 10c0/294f6c2db0df74405bff126107107426c3126a70a1717d78e8d6811db65546c9bb3d61282bdb8d9fbded23f6bc8ec3e8e61031a4f53265f90b7f3dba558f88f4
languageName: node
linkType: hard
"tailwindcss@npm:4.1.4, tailwindcss@npm:^4":
version: 4.1.4
resolution: "tailwindcss@npm:4.1.4"