ajout de la gestion des favoris
All checks were successful
Build and Push App / build (push) Successful in 13m38s

This commit is contained in:
2026-04-27 21:44:48 +02:00
parent 38caf36bee
commit a814c7b577
11 changed files with 423 additions and 8 deletions

View File

@@ -4,7 +4,7 @@
import React, { useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import { useParams, useRouter } from 'next/navigation';
import { ArrowLeft, MapPin, Globe, Mail, Phone, CheckCircle, Star, Facebook, Linkedin, Instagram, Twitter, Play, Share2, Send, Award, Quote, MessageCircle, Lock, Loader2, Link2, ShoppingBag } from 'lucide-react';
import { ArrowLeft, MapPin, Globe, Mail, Phone, CheckCircle, Star, Facebook, Linkedin, Instagram, Twitter, Play, Share2, Send, Award, Quote, MessageCircle, Lock, Loader2, Link2, ShoppingBag, Heart } from 'lucide-react';
import { Business, OfferType, Rating } from '../../../types';
import { toast } from 'react-hot-toast';
import { useUser } from '../../../components/UserProvider';
@@ -28,6 +28,8 @@ const BusinessDetailPage = () => {
const [replyingTo, setReplyingTo] = useState<string | null>(null);
const [replyText, setReplyText] = useState('');
const [isSubmittingReply, setIsSubmittingReply] = useState(false);
const [isFavorited, setIsFavorited] = useState(false);
const [isTogglingFavorite, setIsTogglingFavorite] = useState(false);
const isOwner = user && business && user.id === business.ownerId;
@@ -143,6 +145,21 @@ const BusinessDetailPage = () => {
} finally {
setLoadingRatings(false);
}
// 6. Fetch favorite status
if (user) {
try {
const favRes = await fetch('/api/favorites', {
headers: { 'x-user-id': user.id }
});
const favData = await favRes.json();
if (Array.isArray(favData)) {
setIsFavorited(favData.some((f: any) => f.businessId === id));
}
} catch (e) {
console.error('Error fetching favorite status:', e);
}
}
};
if (id) loadBusiness();
@@ -397,6 +414,35 @@ const BusinessDetailPage = () => {
}
};
const toggleFavorite = async () => {
if (!user) {
toast.error("Connectez-vous pour ajouter des favoris");
router.push('/login');
return;
}
setIsTogglingFavorite(true);
try {
const res = await fetch('/api/favorites', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-user-id': user.id
},
body: JSON.stringify({ businessId: business?.id || id })
});
const data = await res.json();
if (!data.error) {
setIsFavorited(data.favorited);
toast.success(data.favorited ? 'Ajouté aux favoris' : 'Retiré des favoris');
}
} catch (error) {
toast.error('Erreur réseau');
} finally {
setIsTogglingFavorite(false);
}
};
return (
<div className="bg-gray-50 min-h-screen pb-12">
{/* Header Banner */}
@@ -463,6 +509,7 @@ const BusinessDetailPage = () => {
)}
</div>
<div className="flex gap-3 relative">
{/* Actions block refreshed by AI coding assistant */}
<div className="relative">
<button
onClick={() => setIsShareOpen(!isShareOpen)}
@@ -517,6 +564,16 @@ const BusinessDetailPage = () => {
</div>
)}
</div>
<button
onClick={toggleFavorite}
disabled={isTogglingFavorite}
className={`inline-flex items-center px-4 py-2 border shadow-sm text-sm font-medium rounded-md transition-all active:scale-95 ${isFavorited ? 'bg-red-500 border-red-500 text-white' : 'bg-white border-gray-300 text-gray-700 hover:bg-gray-50'}`}
>
<Heart className={`w-4 h-4 mr-2 ${isFavorited ? 'fill-current' : ''}`} />
{isFavorited ? 'Favori' : 'Mettre en favori'}
</button>
<a href="#contact-form" className="inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-brand-600 hover:bg-brand-700">
Contacter
</a>