Spaces:
Sleeping
Sleeping
| import { useState, useEffect } from 'react'; | |
| import { Trophy, Star, Loader2 } from 'lucide-react'; | |
| import api from '../api/api'; | |
| const Leaderboard = ({ limit = 5 }) => { | |
| const [photographers, setPhotographers] = useState([ | |
| { | |
| _id: '1', | |
| firstName: 'Rohit', | |
| lastName: 'Sharma', | |
| profilePicture: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=300&q=80', | |
| rating: 4.9, | |
| reviewCount: 142, | |
| bookingCount: 345, | |
| }, | |
| { | |
| _id: '2', | |
| firstName: 'Sapna', | |
| lastName: 'Gupta', | |
| profilePicture: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?auto=format&fit=crop&w=300&q=80', | |
| rating: 4.8, | |
| reviewCount: 128, | |
| bookingCount: 312, | |
| }, | |
| { | |
| _id: '3', | |
| firstName: 'Mohan', | |
| lastName: 'Khan', | |
| profilePicture: 'https://images.unsplash.com/photo-1503104834685-c826cabba2e6?auto=format&fit=crop&w=300&q=80', | |
| rating: 4.7, | |
| reviewCount: 95, | |
| bookingCount: 287, | |
| }, | |
| { | |
| _id: '4', | |
| firstName: 'Divya', | |
| lastName: 'Singh', | |
| profilePicture: 'https://images.unsplash.com/photo-1507289147ce569074b61281aa07d0a93?auto=format&fit=crop&w=300&q=80', | |
| rating: 4.6, | |
| reviewCount: 87, | |
| bookingCount: 245, | |
| }, | |
| { | |
| _id: '5', | |
| firstName: 'Ahmed', | |
| lastName: 'Malik', | |
| profilePicture: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?auto=format&fit=crop&w=300&q=80', | |
| rating: 4.5, | |
| reviewCount: 76, | |
| bookingCount: 198, | |
| }, | |
| ]); | |
| const getMedalEmoji = (index) => { | |
| if (index === 0) return '🥇'; | |
| if (index === 1) return '🥈'; | |
| if (index === 2) return '🥉'; | |
| return ''; | |
| }; | |
| return ( | |
| <div> | |
| <div className="flex items-center justify-between mb-6"> | |
| <h2 className="text-2xl font-bold flex items-center gap-2"> | |
| <Trophy className="text-amber-500" size={28} /> | |
| Top Photographers | |
| </h2> | |
| <a href="/leaderboard" className="text-blue-600 hover:text-blue-700 font-medium"> | |
| View All → | |
| </a> | |
| </div> | |
| <div className="space-y-2"> | |
| {photographers.slice(0, limit).map((photographer, index) => ( | |
| <div | |
| key={photographer._id} | |
| className="bg-white border border-gray-200 rounded-lg p-4 hover:shadow-md transition-shadow flex items-center gap-4" | |
| > | |
| {/* Rank */} | |
| <div className="text-2xl font-bold text-gray-400 w-8 text-center"> | |
| {getMedalEmoji(index) || `#${index + 1}`} | |
| </div> | |
| {/* Profile Picture */} | |
| <img | |
| src={photographer.profilePicture} | |
| alt={photographer.firstName} | |
| className="w-12 h-12 rounded-full object-cover flex-shrink-0" | |
| /> | |
| {/* Info */} | |
| <div className="flex-1 min-w-0"> | |
| <h3 className="font-bold text-gray-900"> | |
| {photographer.firstName} {photographer.lastName} | |
| </h3> | |
| <div className="flex items-center gap-4 mt-1"> | |
| <div className="flex items-center gap-1"> | |
| <Star className="w-4 h-4 fill-yellow-400 text-yellow-400" /> | |
| <span className="text-sm font-semibold text-gray-700"> | |
| {photographer.rating.toFixed(1)} | |
| </span> | |
| <span className="text-xs text-gray-500">({photographer.reviewCount} reviews)</span> | |
| </div> | |
| <div className="text-xs text-gray-600"> | |
| <span className="font-semibold">{photographer.bookingCount}</span> bookings | |
| </div> | |
| </div> | |
| </div> | |
| {/* CTA */} | |
| <a | |
| href={`/photographer/${photographer._id}`} | |
| className="px-4 py-2 bg-blue-50 hover:bg-blue-100 text-blue-600 font-medium rounded-lg transition whitespace-nowrap flex-shrink-0" | |
| > | |
| View Profile | |
| </a> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default Leaderboard; | |