Showcase your properties elegantly with Tailwind CSS property cards. These cards combine images, titles, prices, and brief details into visually appealing layouts, making navigation intuitive and engaging. They are perfect for real estate websites and marketplaces aiming for modern, organized, and conversion-friendly screens.
"use client";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger
} from "@/components/ui/dropdown-menu";
import { Eye, Heart, BedDouble, Copy, Pencil, Trash2, ChevronDown } from "lucide-react";
import Image from "next/image";
interface PropertyCardProps {
id: string;
name: string;
address: string;
type: string;
price: string;
views: number;
likes: number;
bedrooms: number;
status: "Active" | "Pending" | "Sold";
imageUrl: string;
dateAdded: string;
}
export function PropertyCard({
id,
name,
address,
type,
price,
views,
likes,
bedrooms,
status,
imageUrl,
dateAdded
}: PropertyCardProps) {
const statusColors = {
Active: "bg-primary/10 text-primary hover:bg-primary/20",
Pending: "bg-amber-500/10 text-amber-600 hover:bg-amber-500/20",
Sold: "bg-emerald-500/10 text-emerald-600 hover:bg-emerald-500/20"
};
return (
<div className="bg-card overflow-hidden rounded-lg border pb-0 shadow-none">
{/* Main Content */}
<div className="flex flex-col gap-4 p-4 md:flex-row">
{/* Property Image */}
<div className="bg-muted relative h-40 w-full flex-shrink-0 overflow-hidden rounded-lg md:w-48">
<Image src={imageUrl || "/placeholder.svg"} alt={name} fill className="object-cover" />
</div>
{/* Property Details */}
<div className="flex min-w-0 flex-1 flex-col justify-between">
<div>
<div className="mb-2 flex items-start justify-between gap-4">
<div className="min-w-0 flex-1">
<h3 className="text-foreground mb-1 truncate text-lg font-semibold">{name}</h3>
<p className="text-muted-foreground mb-1 line-clamp-1 text-sm">{address}</p>
<p className="text-muted-foreground text-sm">{type}</p>
</div>
<div className="flex flex-shrink-0 items-center gap-2">
<p className="text-foreground text-xl font-bold whitespace-nowrap">{price}</p>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm" className={statusColors[status]}>
{status}
<ChevronDown className="ml-1 h-3 w-3" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Active</DropdownMenuItem>
<DropdownMenuItem>Pending</DropdownMenuItem>
<DropdownMenuItem>Sold</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
{/* Stats */}
<div className="text-muted-foreground flex items-center gap-4 text-sm">
<div className="flex items-center gap-1.5">
<Eye className="h-4 w-4" />
<span>{views}</span>
</div>
<div className="flex items-center gap-1.5">
<Heart className="h-4 w-4" />
<span>{likes}</span>
</div>
<div className="flex items-center gap-1.5">
<BedDouble className="h-4 w-4" />
<span>{bedrooms}</span>
</div>
</div>
</div>
</div>
</div>
{/* Footer */}
<div className="border-border bg-muted/30 flex flex-col items-start justify-between gap-3 border-t px-4 py-3 sm:flex-row sm:items-center">
<div className="text-muted-foreground flex items-center gap-3 text-sm">
<div className="flex items-center gap-2">
<span className="font-medium">ID: {id}</span>
<Button variant="ghost" size="icon" className="h-6 w-6">
<Copy className="h-3 w-3" />
</Button>
</div>
<span className="hidden sm:inline">|</span>
<span>Added {dateAdded}</span>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm" className="text-foreground hover:text-foreground">
<Pencil />
Edit
</Button>
<Button variant="ghost" size="sm" className="text-foreground hover:text-foreground">
<Eye />
Preview
</Button>
<Button
variant="ghost"
size="sm"
className="text-destructive hover:text-destructive hover:bg-destructive/10">
<Trash2 />
Delete
</Button>
</div>
</div>
</div>
);
}
npx shadcn@latest add @bundui/property-cards-01import { PropertyCards01 } from "@/components/property-cards-01"<PropertyCards01 />