Add src/app/properties/page.tsx
This commit is contained in:
292
src/app/properties/page.tsx
Normal file
292
src/app/properties/page.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user