first commit
This commit is contained in:
132
components/BusinessCard.tsx
Normal file
132
components/BusinessCard.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { CheckCircle, MapPin, Star, Phone, Share2, Facebook, Linkedin, Instagram, Twitter } from 'lucide-react';
|
||||
import { Business } from '../types';
|
||||
|
||||
const BusinessCard: React.FC<{ business: Business }> = ({ business }) => {
|
||||
const [isShareOpen, setIsShareOpen] = useState(false);
|
||||
|
||||
const toggleShare = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsShareOpen(!isShareOpen);
|
||||
};
|
||||
|
||||
const handleShare = (platform: string) => {
|
||||
const url = encodeURIComponent(`${window.location.origin}/#/directory/${business.id}`);
|
||||
const text = encodeURIComponent(`Découvrez ${business.name} sur Afropreunariat`);
|
||||
|
||||
let shareLink = '';
|
||||
switch(platform) {
|
||||
case 'facebook':
|
||||
shareLink = `https://www.facebook.com/sharer/sharer.php?u=${url}`;
|
||||
break;
|
||||
case 'twitter':
|
||||
shareLink = `https://twitter.com/intent/tweet?url=${url}&text=${text}`;
|
||||
break;
|
||||
case 'linkedin':
|
||||
shareLink = `https://www.linkedin.com/sharing/share-offsite/?url=${url}`;
|
||||
break;
|
||||
case 'instagram':
|
||||
// Instagram web share is limited, alerting user
|
||||
alert("Pour partager sur Instagram, copiez le lien ou faites une capture d'écran.");
|
||||
setIsShareOpen(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shareLink) {
|
||||
window.open(shareLink, '_blank', 'width=600,height=400');
|
||||
}
|
||||
setIsShareOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-xl shadow-sm hover:shadow-md transition-shadow duration-200 border border-gray-100 overflow-hidden flex flex-col h-full group relative">
|
||||
{/* Header with Image and Actions */}
|
||||
<div className="relative h-40 bg-gray-200">
|
||||
<img
|
||||
src={`https://picsum.photos/seed/${business.id}/500/300`}
|
||||
alt="Couverture"
|
||||
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent"></div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className="absolute top-2 right-2 flex gap-2 z-20">
|
||||
{business.contactPhone && (
|
||||
<a
|
||||
href={`tel:${business.contactPhone}`}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="p-2 bg-white/20 backdrop-blur-md border border-white/20 rounded-full text-white hover:bg-white hover:text-brand-600 transition-all shadow-sm"
|
||||
title="Appeler"
|
||||
>
|
||||
<Phone className="w-4 h-4" />
|
||||
</a>
|
||||
)}
|
||||
<div className="relative">
|
||||
<button
|
||||
onClick={toggleShare}
|
||||
className="p-2 bg-white/20 backdrop-blur-md border border-white/20 rounded-full text-white hover:bg-white hover:text-brand-600 transition-all shadow-sm"
|
||||
title="Partager"
|
||||
>
|
||||
<Share2 className="w-4 h-4" />
|
||||
</button>
|
||||
|
||||
{isShareOpen && (
|
||||
<div className="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-xl py-2 border border-gray-100 z-30 animate-in fade-in zoom-in duration-200" onMouseLeave={() => setIsShareOpen(false)}>
|
||||
<div className="px-4 py-2 text-xs font-semibold text-gray-400 uppercase tracking-wider">Partager</div>
|
||||
<button onClick={(e) => { e.preventDefault(); e.stopPropagation(); handleShare('facebook'); }} className="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 flex items-center hover:text-blue-600">
|
||||
<Facebook className="w-4 h-4 mr-3" /> Facebook
|
||||
</button>
|
||||
<button onClick={(e) => { e.preventDefault(); e.stopPropagation(); handleShare('twitter'); }} className="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 flex items-center hover:text-black">
|
||||
<Twitter className="w-4 h-4 mr-3" /> X (Twitter)
|
||||
</button>
|
||||
<button onClick={(e) => { e.preventDefault(); e.stopPropagation(); handleShare('linkedin'); }} className="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 flex items-center hover:text-blue-700">
|
||||
<Linkedin className="w-4 h-4 mr-3" /> LinkedIn
|
||||
</button>
|
||||
<button onClick={(e) => { e.preventDefault(); e.stopPropagation(); handleShare('instagram'); }} className="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 flex items-center hover:text-pink-600">
|
||||
<Instagram className="w-4 h-4 mr-3" /> Instagram
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Logo */}
|
||||
<div className="absolute -bottom-6 left-4 z-10 w-16 h-16 bg-white rounded-lg p-1 shadow-md">
|
||||
<img src={business.logoUrl} alt={business.name} className="w-full h-full object-cover rounded-md bg-gray-50" />
|
||||
</div>
|
||||
|
||||
<Link to={`/directory/${business.id}`} className="absolute inset-0 z-0" aria-label={`Voir ${business.name}`} />
|
||||
</div>
|
||||
|
||||
{/* Body */}
|
||||
<div className="pt-8 px-4 pb-4 flex-1 flex flex-col">
|
||||
<div className="flex justify-between items-start">
|
||||
<Link to={`/directory/${business.id}`} className="font-bold text-lg text-gray-900 truncate hover:text-brand-600 transition-colors">
|
||||
{business.name}
|
||||
</Link>
|
||||
{business.verified && <CheckCircle className="w-5 h-5 text-blue-500 flex-shrink-0 ml-1" />}
|
||||
</div>
|
||||
<p className="text-xs text-brand-600 font-semibold mb-2 uppercase tracking-wide">{business.category}</p>
|
||||
<div className="flex items-center text-sm text-gray-500 mb-3">
|
||||
<MapPin className="w-4 h-4 mr-1" />
|
||||
{business.location}
|
||||
</div>
|
||||
<p className="text-sm text-gray-600 line-clamp-2 mb-4 flex-1">{business.description}</p>
|
||||
|
||||
<div className="mt-auto flex items-center justify-between pt-4 border-t border-gray-50">
|
||||
<div className="flex items-center">
|
||||
<Star className="w-4 h-4 text-yellow-400 fill-current" />
|
||||
<span className="text-sm font-bold ml-1 text-gray-700">{business.rating}</span>
|
||||
<span className="text-xs text-gray-400 ml-1">({business.viewCount} vues)</span>
|
||||
</div>
|
||||
<Link to={`/directory/${business.id}`} className="text-brand-600 text-sm font-medium hover:underline">Voir la fiche</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BusinessCard;
|
||||
Reference in New Issue
Block a user