Integrate FavoriteProperty API: add/remove/get favorites with real backend
All checks were successful
Build frontend / build (push) Successful in 42s

This commit is contained in:
Claw AI
2026-03-30 17:54:42 +00:00
parent 1f40c6a4fd
commit 3b9831a513
5 changed files with 152 additions and 33 deletions

View File

@ -1,6 +1,8 @@
'use client';
import { createContext, useContext, useState, useEffect } from 'react';
import { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { getUserFavoriteProperties, addFavoriteProperty, removeFavoriteProperty } from '../utils/api';
import AuthService from '../services/AuthService';
const FavoritesContext = createContext();
@ -12,42 +14,106 @@ export const useFavorites = () => {
return context;
};
function mapApiFavorite(item) {
const info = item.propertyInformation || {};
let details = {};
try { details = JSON.parse(info.detailsJSON || '{}'); } catch {}
const price = item.monthlyRent || item.dailyRent || 0;
const priceUnit = item.monthlyRent ? 'monthly' : 'daily';
const buildingType = info.buildingType ?? 0;
const type = { 0: 'apartment', 1: 'villa', 2: 'house' }[buildingType] || 'apartment';
const typeLabel = { 0: 'شقة', 1: 'فيلا', 2: 'بيت' }[buildingType] || 'عقار';
const address = info.address || '';
const addressParts = address.split(',').map(s => s.trim()).filter(Boolean);
const images = info.images || [];
const resolvedImages = images.map(img => {
if (!img) return '';
if (img.startsWith('http')) return img;
return `http://45.93.137.91${img.startsWith('/') ? '' : '/'}${img}`;
});
return {
id: info.id || item.propertyInformationId,
faveId: item.id, // needed to remove from favorites
title: `${typeLabel} في ${addressParts[0] || address}`,
type,
typeLabel,
price,
priceUnit,
bedrooms: info.numberOfBedRooms || 0,
bathrooms: info.numberOfBathRooms || 0,
area: info.space || 0,
location: {
city: addressParts[addressParts.length - 1] || '',
district: addressParts[0] || '',
},
images: resolvedImages,
rating: item.rating || 0,
deposit: item.deposit || 0,
};
}
export const FavoritesProvider = ({ children }) => {
const [favorites, setFavorites] = useState([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const stored = localStorage.getItem('favorites');
if (stored) {
try {
setFavorites(JSON.parse(stored));
} catch (e) {
console.error('Failed to parse favorites', e);
}
const fetchFavorites = useCallback(async () => {
if (!AuthService.isAuthenticated()) {
setFavorites([]);
return;
}
setIsLoading(true);
try {
const data = await getUserFavoriteProperties();
const items = Array.isArray(data) ? data : [];
setFavorites(items.map(mapApiFavorite));
} catch (err) {
console.error('[Favorites] Failed to fetch:', err);
setFavorites([]);
} finally {
setIsLoading(false);
}
}, []);
useEffect(() => {
localStorage.setItem('favorites', JSON.stringify(favorites));
}, [favorites]);
fetchFavorites();
}, [fetchFavorites]);
const addFavorite = (property) => {
setFavorites(prev => {
if (prev.some(p => p.id === property.id)) return prev;
return [...prev, property];
});
const addFavorite = async (propId) => {
if (!AuthService.isAuthenticated()) return false;
try {
await addFavoriteProperty(propId);
await fetchFavorites(); // refresh list
return true;
} catch (err) {
console.error('[Favorites] Add failed:', err);
return false;
}
};
const removeFavorite = (propertyId) => {
setFavorites(prev => prev.filter(p => p.id !== propertyId));
const removeFavorite = async (propId) => {
if (!AuthService.isAuthenticated()) return false;
// Find the faveId for this property
const fav = favorites.find(f => f.id === propId);
if (!fav) return false;
try {
await removeFavoriteProperty(fav.faveId);
setFavorites(prev => prev.filter(f => f.id !== propId));
return true;
} catch (err) {
console.error('[Favorites] Remove failed:', err);
return false;
}
};
const isFavorite = (propertyId) => {
return favorites.some(p => p.id === propertyId);
const isFavorite = (propId) => {
return favorites.some(f => f.id === propId);
};
return (
<FavoritesContext.Provider value={{ favorites, addFavorite, removeFavorite, isFavorite }}>
<FavoritesContext.Provider value={{ favorites, isLoading, addFavorite, removeFavorite, isFavorite, refreshFavorites: fetchFavorites }}>
{children}
</FavoritesContext.Provider>
);
};
};