mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-24 12:51:14 -05:00
Add types, hook, UI components, and integration for leaderboard showing top users with badges
174 lines
5.0 KiB
TypeScript
174 lines
5.0 KiB
TypeScript
import { Badge } from '@/components/ui/badge';
|
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
|
import {
|
|
Award,
|
|
Camera,
|
|
Edit,
|
|
MapPin,
|
|
MessageSquare,
|
|
Sparkles,
|
|
Trophy,
|
|
Crown,
|
|
Shield
|
|
} from 'lucide-react';
|
|
import type { AchievementLevel, SpecialBadge } from '@/types/contributor';
|
|
|
|
interface AchievementBadgeProps {
|
|
level: AchievementLevel;
|
|
size?: 'sm' | 'md' | 'lg';
|
|
}
|
|
|
|
interface SpecialBadgeProps {
|
|
badge: SpecialBadge;
|
|
size?: 'sm' | 'md';
|
|
}
|
|
|
|
const achievementConfig: Record<AchievementLevel, {
|
|
label: string;
|
|
color: string;
|
|
icon: React.ReactNode;
|
|
description: string;
|
|
}> = {
|
|
legend: {
|
|
label: 'Legend',
|
|
color: 'bg-gradient-to-r from-purple-500 to-pink-500 text-white border-0',
|
|
icon: <Crown className="w-3 h-3" />,
|
|
description: '5000+ contribution points - An absolute legend!',
|
|
},
|
|
platinum: {
|
|
label: 'Platinum',
|
|
color: 'bg-gradient-to-r from-slate-300 to-slate-400 text-slate-900 border-0',
|
|
icon: <Trophy className="w-3 h-3" />,
|
|
description: '1000+ contribution points - Elite contributor',
|
|
},
|
|
gold: {
|
|
label: 'Gold',
|
|
color: 'bg-gradient-to-r from-yellow-400 to-yellow-500 text-yellow-900 border-0',
|
|
icon: <Award className="w-3 h-3" />,
|
|
description: '500+ contribution points - Outstanding work!',
|
|
},
|
|
silver: {
|
|
label: 'Silver',
|
|
color: 'bg-gradient-to-r from-gray-300 to-gray-400 text-gray-800 border-0',
|
|
icon: <Award className="w-3 h-3" />,
|
|
description: '100+ contribution points - Great contributor',
|
|
},
|
|
bronze: {
|
|
label: 'Bronze',
|
|
color: 'bg-gradient-to-r from-orange-400 to-orange-500 text-orange-900 border-0',
|
|
icon: <Award className="w-3 h-3" />,
|
|
description: '10+ contribution points - Getting started!',
|
|
},
|
|
newcomer: {
|
|
label: 'Newcomer',
|
|
color: 'bg-muted text-muted-foreground',
|
|
icon: <Sparkles className="w-3 h-3" />,
|
|
description: 'Just getting started',
|
|
},
|
|
};
|
|
|
|
const specialBadgeConfig: Record<SpecialBadge, {
|
|
label: string;
|
|
icon: React.ReactNode;
|
|
description: string;
|
|
color: string;
|
|
}> = {
|
|
park_explorer: {
|
|
label: 'Park Explorer',
|
|
icon: <MapPin className="w-3 h-3" />,
|
|
description: 'Added 100+ parks to the database',
|
|
color: 'bg-green-500/10 text-green-700 dark:text-green-400 border-green-500/20',
|
|
},
|
|
ride_master: {
|
|
label: 'Ride Master',
|
|
icon: <Sparkles className="w-3 h-3" />,
|
|
description: 'Added 200+ rides to the database',
|
|
color: 'bg-blue-500/10 text-blue-700 dark:text-blue-400 border-blue-500/20',
|
|
},
|
|
photographer: {
|
|
label: 'Photographer',
|
|
icon: <Camera className="w-3 h-3" />,
|
|
description: 'Uploaded 500+ photos',
|
|
color: 'bg-purple-500/10 text-purple-700 dark:text-purple-400 border-purple-500/20',
|
|
},
|
|
critic: {
|
|
label: 'Critic',
|
|
icon: <MessageSquare className="w-3 h-3" />,
|
|
description: 'Wrote 100+ reviews',
|
|
color: 'bg-orange-500/10 text-orange-700 dark:text-orange-400 border-orange-500/20',
|
|
},
|
|
editor: {
|
|
label: 'Editor',
|
|
icon: <Edit className="w-3 h-3" />,
|
|
description: 'Made 500+ edits to existing entries',
|
|
color: 'bg-cyan-500/10 text-cyan-700 dark:text-cyan-400 border-cyan-500/20',
|
|
},
|
|
completionist: {
|
|
label: 'Completionist',
|
|
icon: <Shield className="w-3 h-3" />,
|
|
description: 'Contributed across all content types',
|
|
color: 'bg-indigo-500/10 text-indigo-700 dark:text-indigo-400 border-indigo-500/20',
|
|
},
|
|
veteran: {
|
|
label: 'Veteran',
|
|
icon: <Award className="w-3 h-3" />,
|
|
description: 'Member for over 1 year',
|
|
color: 'bg-amber-500/10 text-amber-700 dark:text-amber-400 border-amber-500/20',
|
|
},
|
|
top_contributor: {
|
|
label: 'Top Contributor',
|
|
icon: <Crown className="w-3 h-3" />,
|
|
description: 'Ranked #1 contributor',
|
|
color: 'bg-pink-500/10 text-pink-700 dark:text-pink-400 border-pink-500/20',
|
|
},
|
|
};
|
|
|
|
export function AchievementBadge({ level, size = 'md' }: AchievementBadgeProps) {
|
|
const config = achievementConfig[level];
|
|
const sizeClasses = {
|
|
sm: 'text-xs px-2 py-0.5',
|
|
md: 'text-sm px-2.5 py-0.5',
|
|
lg: 'text-base px-3 py-1',
|
|
};
|
|
|
|
return (
|
|
<TooltipProvider>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Badge className={`${config.color} ${sizeClasses[size]} gap-1`}>
|
|
{config.icon}
|
|
{config.label}
|
|
</Badge>
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
<p>{config.description}</p>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
</TooltipProvider>
|
|
);
|
|
}
|
|
|
|
export function SpecialBadge({ badge, size = 'sm' }: SpecialBadgeProps) {
|
|
const config = specialBadgeConfig[badge];
|
|
const sizeClasses = {
|
|
sm: 'text-xs px-2 py-0.5',
|
|
md: 'text-sm px-2.5 py-0.5',
|
|
};
|
|
|
|
return (
|
|
<TooltipProvider>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Badge variant="outline" className={`${config.color} ${sizeClasses[size]} gap-1`}>
|
|
{config.icon}
|
|
{config.label}
|
|
</Badge>
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
<p>{config.description}</p>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
</TooltipProvider>
|
|
);
|
|
}
|