Integrate FavoriteProperty API: add/remove/get favorites with real backend
All checks were successful
Build frontend / build (push) Successful in 42s
All checks were successful
Build frontend / build (push) Successful in 42s
This commit is contained in:
@ -32,6 +32,9 @@ import {
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { getRentProperties, getSaleProperties } from '../utils/api';
|
||||
import { useFavorites } from '@/app/contexts/FavoritesContext';
|
||||
import AuthService from '@/app/services/AuthService';
|
||||
import toast, { Toaster } from 'react-hot-toast';
|
||||
|
||||
// Map API data to UI format
|
||||
function mapApiProperty(item, index) {
|
||||
@ -95,9 +98,25 @@ function extractCity(address) {
|
||||
// API-only — no fallback data
|
||||
|
||||
const PropertyCard = ({ property, viewMode = 'grid' }) => {
|
||||
const [isFavorite, setIsFavorite] = useState(false);
|
||||
const { isFavorite: checkFavorite, addFavorite, removeFavorite } = useFavorites();
|
||||
const [favLoading, setFavLoading] = useState(false);
|
||||
const [currentImage, setCurrentImage] = useState(0);
|
||||
|
||||
const isFav = checkFavorite(property.id);
|
||||
|
||||
const toggleFavorite = async (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (!AuthService.isAuthenticated()) { toast.error('سجل الدخول أولاً'); return; }
|
||||
setFavLoading(true);
|
||||
if (isFav) {
|
||||
await removeFavorite(property.id);
|
||||
} else {
|
||||
await addFavorite(property.id);
|
||||
}
|
||||
setFavLoading(false);
|
||||
};
|
||||
|
||||
const formatCurrency = (amount) => {
|
||||
return amount?.toLocaleString() + ' ل.س';
|
||||
};
|
||||
@ -150,10 +169,11 @@ const PropertyCard = ({ property, viewMode = 'grid' }) => {
|
||||
)}
|
||||
<div className="absolute top-2 right-2 flex gap-2">
|
||||
<button
|
||||
onClick={() => setIsFavorite(!isFavorite)}
|
||||
onClick={toggleFavorite}
|
||||
disabled={favLoading}
|
||||
className="w-8 h-8 bg-white/90 backdrop-blur-sm rounded-full flex items-center justify-center hover:bg-white transition-colors shadow-sm"
|
||||
>
|
||||
<Heart className={`w-4 h-4 ${isFavorite ? 'fill-red-500 text-red-500' : 'text-gray-600'}`} />
|
||||
<Heart className={`w-4 h-4 ${isFav ? 'fill-red-500 text-red-500' : 'text-gray-600'}`} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -231,10 +251,11 @@ const PropertyCard = ({ property, viewMode = 'grid' }) => {
|
||||
/>
|
||||
<div className="absolute top-2 right-2 flex gap-2">
|
||||
<button
|
||||
onClick={() => setIsFavorite(!isFavorite)}
|
||||
onClick={toggleFavorite}
|
||||
disabled={favLoading}
|
||||
className="w-8 h-8 bg-white/90 backdrop-blur-sm rounded-full flex items-center justify-center hover:bg-white transition-colors shadow-sm"
|
||||
>
|
||||
<Heart className={`w-4 h-4 ${isFavorite ? 'fill-red-500 text-red-500' : 'text-gray-600'}`} />
|
||||
<Heart className={`w-4 h-4 ${isFav ? 'fill-red-500 text-red-500' : 'text-gray-600'}`} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -622,6 +643,7 @@ export default function PropertiesPage() {
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
<Toaster position="top-center" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user