Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 1x 4x 4x 4x 1x 4x 1x 1x 4x | import React from 'react';
import { FC, MouseEvent } from 'react';
import { Property } from '../../types/property';
import { useNavigate } from 'react-router-dom';
import { ROUTES } from '../../config/routes';
import { FaBed, FaBath, FaRulerCombined, FaHome } from 'react-icons/fa';
import { getFullImageUrl } from '../../config/api';
import { useAuth } from '../../context/AuthContext';
interface PropertyCardProps {
property: Property;
}
const PropertyCard: FC<PropertyCardProps> = ({ property }) => {
const navigate = useNavigate();
const { isAdmin } = useAuth();
const handleViewDetails = () => {
navigate(ROUTES.PROPERTIES.DETAILS(property.id!));
};
const handleEdit = (e: MouseEvent) => {
e.stopPropagation();
navigate(ROUTES.PROPERTIES.EDIT(property.id!));
};
return (
<div
onClick={handleViewDetails}
data-testid="property-card"
className="bg-white rounded-xl overflow-hidden shadow-none border-2 border-[#e5e5e5] hover:border-[#00deb6] transition-colors duration-300 cursor-pointer flex flex-col h-[500px]"
>
{/* Image Section */}
<div className="relative h-48 bg-gray-200 flex-shrink-0">
{property.images && property.images.length > 0 ? (
<img
src={getFullImageUrl(property.images[0].url)}
alt={property.address}
className="w-full h-full object-cover rounded-t-xl"
/>
) : (
<div data-testid="property-placeholder" className="flex items-center justify-center h-full bg-gray-200 rounded-t-xl">
<FaHome className="text-4xl text-gray-400" />
</div>
)}
{isAdmin && (
<div className="absolute top-4 right-4">
<button
onClick={handleEdit}
className="bg-white text-[#262637] px-4 py-2 rounded-full text-sm font-medium border-2 border-[#e5e5e5] hover:border-[#00deb6] transition-colors duration-200"
>
Edit
</button>
</div>
)}
</div>
{/* Content Section */}
<div className="p-4 flex flex-col flex-grow">
<div className="mb-2">
<h3 className="text-xl font-bold text-[#262637] mb-2 line-clamp-1">{property.address}</h3>
<p className="text-2xl font-bold text-[#00deb6]">
£{property.price.toLocaleString()}
</p>
</div>
{/* Property Features */}
<div className="grid grid-cols-3 gap-4 py-4 border-t border-gray-100">
<div className="text-center">
{property.bedrooms && (
<div className="flex items-center justify-center text-[#666666]">
<FaBed className="mr-1" />
<span>{property.bedrooms}</span>
</div>
)}
</div>
<div className="text-center">
{property.bathrooms && (
<div className="flex items-center justify-center text-[#666666]">
<FaBath className="mr-1" />
<span>{property.bathrooms}</span>
</div>
)}
</div>
<div className="text-center">
{property.squareFootage && (
<div className="flex items-center justify-center text-[#666666]">
<FaRulerCombined className="mr-1" />
<span>{property.squareFootage.toLocaleString()}</span>
</div>
)}
</div>
</div>
{/* Description Preview */}
{property.description && (
<div className="mt-4 border-t border-gray-100 pt-4 flex-grow">
<p className="text-[#666666] text-sm line-clamp-2">
{property.description}
</p>
</div>
)}
{/* View Details Button */}
<div className="mt-auto pt-4">
<button
onClick={handleViewDetails}
className="w-full bg-[#00deb6] text-white px-4 py-2 rounded-xl hover:bg-[#00c5a0] transition-colors duration-200"
>
View Details
</button>
</div>
</div>
</div>
);
};
export default PropertyCard; |