Add src/app/properties/page.tsx

This commit is contained in:
2026-03-12 10:28:28 +00:00
parent 78b6c83719
commit 51a8e04ced

292
src/app/properties/page.tsx Normal file
View File

@@ -0,0 +1,292 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleFullscreen from "@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen";
import FooterSimple from "@/components/sections/footer/FooterSimple";
import ProductCardTwo from "@/components/sections/product/ProductCardTwo";
import { useState } from "react";
import { ChevronDown } from "lucide-react";
interface Property {
id: string;
brand: string;
name: string;
price: string;
rating: number;
reviewCount: string;
imageSrc: string;
imageAlt: string;
category: string;
beds?: number;
baths?: number;
sqft?: number;
}
const PROPERTIES: Property[] = [
{
id: "1", brand: "Luxury Living", name: "Modern Downtown Penthouse", price: "$2,450,000", rating: 5,
reviewCount: "124", imageSrc: "http://img.b2bpic.net/free-photo/modern-building-in-city-with-glass-walls_23-2150515621.jpg", imageAlt: "Modern Downtown Penthouse", category: "luxury", beds: 3,
baths: 2,
sqft: 2500
},
{
id: "2", brand: "Urban Estates", name: "Spacious Family Home", price: "$890,000", rating: 4,
reviewCount: "87", imageSrc: "http://img.b2bpic.net/free-photo/beautiful-white-house-with-beautiful-landscaping_23-2149315331.jpg", imageAlt: "Spacious Family Home", category: "residential", beds: 4,
baths: 3,
sqft: 3200
},
{
id: "3", brand: "Prime Properties", name: "Waterfront Villa", price: "$3,750,000", rating: 5,
reviewCount: "256", imageSrc: "http://img.b2bpic.net/free-photo/beachfront-house-with-pool-deck-modern-architecture_23-2148515621.jpg", imageAlt: "Waterfront Villa", category: "luxury", beds: 5,
baths: 4,
sqft: 5000
},
{
id: "4", brand: "Smart Investments", name: "Studio Apartment", price: "$425,000", rating: 4,
reviewCount: "45", imageSrc: "http://img.b2bpic.net/free-photo/contemporary-apartment-with-modern-minimalist-design_23-2149315621.jpg", imageAlt: "Studio Apartment", category: "apartment", beds: 1,
baths: 1,
sqft: 650
},
{
id: "5", brand: "Luxury Living", name: "Executive Condo", price: "$1,250,000", rating: 5,
reviewCount: "98", imageSrc: "http://img.b2bpic.net/free-photo/luxury-apartment-interior-with-elegant-furnishings_23-2150515721.jpg", imageAlt: "Executive Condo", category: "condo", beds: 2,
baths: 2,
sqft: 1800
},
{
id: "6", brand: "Dream Homes", name: "Countryside Estate", price: "$1,950,000", rating: 4,
reviewCount: "112", imageSrc: "http://img.b2bpic.net/free-photo/traditional-house-surrounded-by-greenery_23-2148515821.jpg", imageAlt: "Countryside Estate", category: "residential", beds: 4,
baths: 3,
sqft: 3800
},
{
id: "7", brand: "Urban Estates", name: "Two-Bedroom Loft", price: "$725,000", rating: 4,
reviewCount: "67", imageSrc: "http://img.b2bpic.net/free-photo/modern-loft-apartment-with-industrial-design_23-2150615621.jpg", imageAlt: "Two-Bedroom Loft", category: "apartment", beds: 2,
baths: 1,
sqft: 1200
},
{
id: "8", brand: "Prime Properties", name: "Beachfront Bungalow", price: "$2,100,000", rating: 5,
reviewCount: "178", imageSrc: "http://img.b2bpic.net/free-photo/beautiful-beach-house-with-ocean-view_23-2148615921.jpg", imageAlt: "Beachfront Bungalow", category: "luxury", beds: 3,
baths: 2,
sqft: 2200
}
];
const CATEGORIES = [
{ id: "all", label: "All Properties" },
{ id: "luxury", label: "Luxury" },
{ id: "residential", label: "Residential" },
{ id: "apartment", label: "Apartments" },
{ id: "condo", label: "Condos" }
];
const PRICE_RANGES = [
{ id: "all", label: "All Prices" },
{ id: "under-500k", label: "Under $500K", min: 0, max: 500000 },
{ id: "500k-1m", label: "$500K - $1M", min: 500000, max: 1000000 },
{ id: "1m-2m", label: "$1M - $2M", min: 1000000, max: 2000000 },
{ id: "above-2m", label: "Above $2M", min: 2000000, max: Infinity }
];
export default function PropertiesPage() {
const [selectedCategory, setSelectedCategory] = useState("all");
const [selectedPriceRange, setSelectedPriceRange] = useState("all");
const [sortBy, setSortBy] = useState("featured");
const filteredProperties = PROPERTIES.filter(property => {
const categoryMatch = selectedCategory === "all" || property.category === selectedCategory;
let priceMatch = true;
if (selectedPriceRange !== "all") {
const priceRange = PRICE_RANGES.find(pr => pr.id === selectedPriceRange);
if (priceRange) {
const propertyPrice = parseInt(property.price.replace(/[^0-9]/g, ""));
priceMatch = propertyPrice >= priceRange.min && propertyPrice <= priceRange.max;
}
}
return categoryMatch && priceMatch;
});
const sortedProperties = [...filteredProperties].sort((a, b) => {
if (sortBy === "price-low") {
const priceA = parseInt(a.price.replace(/[^0-9]/g, ""));
const priceB = parseInt(b.price.replace(/[^0-9]/g, ""));
return priceA - priceB;
}
if (sortBy === "price-high") {
const priceA = parseInt(a.price.replace(/[^0-9]/g, ""));
const priceB = parseInt(b.price.replace(/[^0-9]/g, ""));
return priceB - priceA;
}
if (sortBy === "rating") {
return b.rating - a.rating;
}
return 0;
});
return (
<ThemeProvider
defaultButtonVariant="expand-hover"
defaultTextAnimation="reveal-blur"
borderRadius="pill"
contentWidth="medium"
sizing="medium"
background="noiseDiagonalGradient"
cardStyle="glass-elevated"
primaryButtonStyle="diagonal-gradient"
secondaryButtonStyle="layered"
headingFontWeight="bold"
>
<div id="nav" data-section="nav">
<NavbarStyleFullscreen
navItems={[
{ name: "Home", id: "/" },
{ name: "About", id: "about" },
{ name: "Services", id: "services" },
{ name: "Properties", id: "/properties" },
{ name: "Contact", id: "contact" }
]}
brandName="Premium Studio"
bottomLeftText="Global Presence"
bottomRightText="hello@premiumstudio.com"
/>
</div>
<div id="properties" data-section="properties" className="min-h-screen pt-32 pb-20">
<div className="container mx-auto px-4">
{/* Header */}
<div className="mb-12 text-center">
<h1 className="text-4xl md:text-5xl font-bold mb-4">Property Listings</h1>
<p className="text-lg text-foreground/70">Discover your perfect property from our curated collection</p>
</div>
{/* Filters */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-12">
{/* Category Filter */}
<div className="flex flex-col gap-3">
<label className="text-sm font-semibold">Property Type</label>
<div className="flex flex-wrap gap-2">
{CATEGORIES.map(category => (
<button
key={category.id}
onClick={() => setSelectedCategory(category.id)}
className={`px-4 py-2 rounded-full text-sm font-medium transition-all ${
selectedCategory === category.id
? "bg-primary-cta text-white"
: "bg-card text-foreground hover:bg-accent/20"
}`}
>
{category.label}
</button>
))}
</div>
</div>
{/* Price Range Filter */}
<div className="flex flex-col gap-3">
<label className="text-sm font-semibold">Price Range</label>
<div className="flex flex-wrap gap-2">
{PRICE_RANGES.map(range => (
<button
key={range.id}
onClick={() => setSelectedPriceRange(range.id)}
className={`px-4 py-2 rounded-full text-sm font-medium transition-all ${
selectedPriceRange === range.id
? "bg-primary-cta text-white"
: "bg-card text-foreground hover:bg-accent/20"
}`}
>
{range.label}
</button>
))}
</div>
</div>
{/* Sort */}
<div className="flex flex-col gap-3">
<label className="text-sm font-semibold">Sort By</label>
<div className="relative">
<select
value={sortBy}
onChange={(e) => setSortBy(e.target.value)}
className="w-full px-4 py-2 rounded-full bg-card text-foreground border border-accent/20 appearance-none cursor-pointer transition-all hover:border-accent/40"
>
<option value="featured">Featured</option>
<option value="price-low">Price: Low to High</option>
<option value="price-high">Price: High to Low</option>
<option value="rating">Highest Rated</option>
</select>
<ChevronDown className="absolute right-3 top-1/2 transform -translate-y-1/2 text-foreground/50 pointer-events-none" size={20} />
</div>
</div>
</div>
{/* Results Count */}
<div className="mb-6">
<p className="text-foreground/70">Showing {sortedProperties.length} of {PROPERTIES.length} properties</p>
</div>
{/* Property Cards Grid */}
{sortedProperties.length > 0 ? (
<ProductCardTwo
products={sortedProperties}
title=""
description=""
textboxLayout="default"
animationType="slide-up"
useInvertedBackground={false}
gridVariant="three-columns-all-equal-width"
/>
) : (
<div className="text-center py-20">
<p className="text-xl text-foreground/60">No properties found matching your criteria. Try adjusting your filters.</p>
</div>
)}
</div>
</div>
<div id="footer" data-section="footer">
<FooterSimple
columns={[
{
title: "Company", items: [
{ label: "About", href: "about" },
{ label: "Services", href: "services" },
{ label: "Careers", href: "#" },
{ label: "Blog", href: "#" }
]
},
{
title: "Properties", items: [
{ label: "All Listings", href: "/properties" },
{ label: "Luxury", href: "/properties" },
{ label: "Residential", href: "/properties" },
{ label: "Commercial", href: "#" }
]
},
{
title: "Resources", items: [
{ label: "Buying Guide", href: "#" },
{ label: "Market Insights", href: "#" },
{ label: "FAQ", href: "#faq" },
{ label: "Support", href: "contact" }
]
},
{
title: "Legal", items: [
{ label: "Privacy Policy", href: "#" },
{ label: "Terms of Service", href: "#" },
{ label: "Cookie Policy", href: "#" },
{ label: "Contact", href: "contact" }
]
}
]}
bottomLeftText="© 2025 Premium Studio. All rights reserved."
bottomRightText="Designed with excellence"
/>
</div>
</ThemeProvider>
);
}