feat: listings for sale, and move detail property url

This commit is contained in:
RizqiSyahrendra 2025-04-23 17:45:24 +07:00
parent f5c5f3fd78
commit 73de3fd07d
4 changed files with 98 additions and 3 deletions

View File

@ -0,0 +1,95 @@
import HeroImage from "@/components/HeroImage";
import Pagination from "@/components/Pagination";
import CardProperty from "@/components/properties/CardProperty";
import FilterProperty from "@/components/properties/FilterProperty";
import { FetchPropertyParams } from "@/schema/services/property";
import { fetchProperty } from "@/services/payload/property";
import { getDefaultMetadata } from "@/utils/metadata";
import { sanitizeNumber, sanitizePageNumber } from "@/utils/sanitize";
import { Metadata } from "next";
const metaDesc = "Explore the latest properties on the Dynamic Realty.";
export async function generateMetadata(): Promise<Metadata> {
const metadata = await getDefaultMetadata();
metadata.title = `Listings For Sale - ${metadata.openGraph?.siteName}`;
metadata.description = metaDesc;
return metadata;
}
export default async function ListingsForRent(props: {
searchParams?: Promise<{ [P in keyof FetchPropertyParams]: string }>;
}) {
const searchParams = await props?.searchParams;
const page = sanitizePageNumber(searchParams?.page);
const minPrice = sanitizeNumber(searchParams?.min_price);
const maxPrice = sanitizeNumber(searchParams?.max_price);
const minArea = sanitizeNumber(searchParams?.min_area);
const maxArea = sanitizeNumber(searchParams?.max_area);
const propertiesData = await fetchProperty({
property_type: "sell",
page,
name: searchParams?.name,
min_price: minPrice,
max_price: maxPrice,
min_area: minArea,
max_area: maxArea,
location: searchParams?.location,
});
const isEmpty = propertiesData.formattedData.length <= 0;
return (
<>
<HeroImage title="Listings For Sale" />
<section className="section section-md bg-gray-12">
<div className="container">
<div className="row row-50">
<div className="col-lg-7 col-xl-8">
<div className="row row-30">
<div className="col-12">
{isEmpty && (
<div className="text-center mt-40">
<h3 className="text-spacing-20">No Properties Found</h3>
<p className="heading-5 mt-3">Looks like we couldnt find any listings that match your search.</p>
</div>
)}
{!isEmpty && (
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{propertiesData.formattedData.map((p, idx) => (
<CardProperty key={idx} data={p} />
))}
</div>
)}
</div>
{/* Pagination */}
{propertiesData.totalPages > 1 && (
<div className="col-12">
<Pagination
page={propertiesData.page ?? 1}
hasNextPage={propertiesData.hasNextPage}
hasPreviousPage={propertiesData.hasPrevPage}
totalPages={propertiesData.totalPages}
/>
</div>
)}
{/* End Pagination */}
</div>
</div>
<div className="col-lg-5 col-xl-4">
<div className="row row-50">
<div className="col-md-6 col-lg-12">
<FilterProperty propertyType="rent" searchParams={searchParams} />
</div>
</div>
</div>
</div>
</div>
</section>
</>
);
}

View File

@ -61,7 +61,7 @@ export async function generateMetadata(props: { params: Promise<{ slug: string }
return metadata; return metadata;
} }
export default async function ListingsForRentDetail({ params }: { params: Promise<{ slug: string }> }) { export default async function PropertyDetail({ params }: { params: Promise<{ slug: string }> }) {
const slug = (await params).slug; const slug = (await params).slug;
const propertyDetail = await fetchPropertyDetail({ slug }); const propertyDetail = await fetchPropertyDetail({ slug });
if (!propertyDetail) return notFound(); if (!propertyDetail) return notFound();

View File

@ -113,7 +113,7 @@ export default function Header() {
</a> </a>
</li> </li>
<li className="rd-nav-item"> <li className="rd-nav-item">
<a className="rd-nav-link rd-nav-link-custom" href="/"> <a className="rd-nav-link rd-nav-link-custom" href="/listings-for-sale">
LISTINGS FOR SALE LISTINGS FOR SALE
</a> </a>
</li> </li>

View File

@ -8,7 +8,7 @@ type CardPropertyProps = {
}; };
export default function CardProperty({ data }: CardPropertyProps) { export default function CardProperty({ data }: CardPropertyProps) {
const href = data?.propertyType === "rent" ? `/listings-for-rent/${data.slug}` : `/listings-for-sell/${data.slug}`; const href = data?.propertyType === "rent" ? `/property/${data.slug}` : `/property/${data.slug}`;
return ( return (
<div> <div>
<article className="product-classic"> <article className="product-classic">