diff --git a/src/features/badges/components/badge-showcase.tsx b/src/features/badges/components/badge-showcase.tsx index fefc745..f49264c 100644 --- a/src/features/badges/components/badge-showcase.tsx +++ b/src/features/badges/components/badge-showcase.tsx @@ -1,8 +1,9 @@ -import { Box, Text, Popover, Card } from "@mantine/core"; +import { Box, Text, Popover, Progress } from "@mantine/core"; import { usePlayerBadges, useAllBadges } from "../queries"; import { useAuth } from "@/contexts/auth-context"; import { Badge, BadgeProgress } from "../types"; import { useMemo } from "react"; +import { MedalIcon, LockKeyIcon } from "@phosphor-icons/react"; interface BadgeShowcaseProps { playerId: string; @@ -86,87 +87,189 @@ const BadgeShowcase = ({ playerId }: BadgeShowcaseProps) => { } return ( - - + + + Badges + + + + - - Badges - - - - - {badgesToDisplay.map((display) => ( - - - ({ - opacity: display.earned ? 1 : 0.35, - cursor: "pointer", - transition: 'all 0.2s ease', - minHeight: 70, - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - borderStyle: display.earned ? 'solid' : 'dashed', - ':hover': { - transform: display.earned ? 'translateY(-2px)' : 'none', - boxShadow: display.earned ? theme.shadows.sm : undefined, - }, - })} - > - { + const isStackableBadge = display.badge.criteria?.tournament_wins !== undefined || + display.badge.criteria?.placement !== undefined; + const stackCount = display.earned && isStackableBadge + ? Math.floor((display.progress?.progress || 0) / getTargetProgress(display.badge)) + : 1; + const showStack = stackCount > 1; + + return ( + + + - {display.badge.name} - - - + {showStack && ( + <> + {[...Array(Math.min(stackCount - 1, 2))].map((_, i) => ( + ({ + aspectRatio: '1', + borderRadius: '12px', + background: `linear-gradient(135deg, ${theme.colors[theme.primaryColor][5]} 0%, ${theme.colors[theme.primaryColor][7]} 100%)`, + border: `2px solid ${theme.colors[theme.primaryColor][6]}`, + position: 'absolute', + top: `${(i + 1) * 3}px`, + left: `${(i + 1) * 3}px`, + right: `-${(i + 1) * 3}px`, + bottom: `-${(i + 1) * 3}px`, + opacity: 0.6 - (i * 0.2), + zIndex: -(i + 1), + })} + /> + ))} + + )} + + ({ + aspectRatio: '1', + borderRadius: '12px', + background: display.earned + ? `linear-gradient(135deg, ${theme.colors[theme.primaryColor][5]} 0%, ${theme.colors[theme.primaryColor][7]} 100%)` + : 'light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-6))', + border: `2px solid ${display.earned ? theme.colors[theme.primaryColor][6] : 'light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4))'}`, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flexDirection: 'column', + gap: '4px', + padding: 'var(--mantine-spacing-xs)', + position: 'relative', + boxShadow: display.earned + ? `0 2px 8px ${theme.colors[theme.primaryColor][6]}30` + : '0 1px 3px rgba(0, 0, 0, 0.1)', + opacity: display.earned ? 1 : 0.5, + zIndex: 1, + ':hover': { + transform: 'translateY(-2px)', + boxShadow: display.earned + ? `0 4px 12px ${theme.colors[theme.primaryColor][6]}40` + : '0 2px 6px rgba(0, 0, 0, 0.15)', + }, + })} + > + {display.earned ? ( + + ) : ( + + )} + + {showStack && ( + ({ + position: 'absolute', + top: '4px', + right: '4px', + background: theme.colors[theme.primaryColor][8], + color: 'white', + borderRadius: '50%', + width: '20px', + height: '20px', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + fontSize: '10px', + fontWeight: 700, + border: '2px solid white', + boxShadow: '0 1px 3px rgba(0, 0, 0, 0.3)', + })} + > + {stackCount} + + )} + + + {display.badge.name} + + + + - + {display.badge.name} - + {display.badge.description} {isCurrentUser && ( - - Progress: {display.progressText} - + + + + Progress + + + {display.progressText} + + + + )} - ))} + ); + })} - + ); };