Achievement Card
trophy/achievement-cardFreeComponent
React achievement card with totals, featured badges, and scrollable lists for profile and progress surfaces. Fits achievement UI examples in SaaS, consumer and community products. Open source, built on shadcn/ui + Tailwind.
Live preview
live · rendered by the registry
Rendered by trophy on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.trophy.so/r/achievement-card.jsonSource
1"use client"23import * as React from "react"45import { cn } from "@/lib/utils"6import { AchievementBadge } from "@/components/ui/achievement-badge"7import { AchievementList } from "@/components/ui/achievement-list"8import { Button } from "@/components/ui/button"910interface Achievement {11 id: string12 name: string13 description?: string | null14 trigger: "metric" | "api" | "streak"15 badgeUrl?: string | null16 progress?: number17 rarity?: number18}1920interface UserAchievement extends Achievement {21 achievedAt: string | null22}2324interface AchievementCardProps extends React.HTMLAttributes<HTMLDivElement> {25 achievements: UserAchievement[]26 highlightedAchievements: UserAchievement[]27 badgeSize?: "sm" | "default" | "lg"28 lockedStyle?: "grayscale" | "silhouette" | "hidden"29 onAchievementClick?: (achievement: UserAchievement) => void30}3132const AchievementCard = React.forwardRef<HTMLDivElement, AchievementCardProps>(33 (34 {35 className,36 achievements,37 highlightedAchievements,38 badgeSize = "default",39 lockedStyle = "grayscale",40 onAchievementClick,41 ...props42 },43 ref44 ) => {45 const unlockedCount = achievements.filter(46 (a) => a.achievedAt !== null47 ).length4849 return (50 <div51 ref={ref}52 className={cn("bg-card rounded-2xl border p-6 shadow-sm", className)}53 {...props}54 >55 <div className="text-center">56 <p className="text-7xl font-bold tracking-tight sm:text-8xl">57 {unlockedCount}58 </p>59 <p className="text-muted-foreground mt-1 text-sm font-medium">60 Badges Unlocked61 </p>62 </div>6364 <div className="mt-10 flex items-end justify-center gap-4">65 {highlightedAchievements.slice(0, 3).map((achievement, index) => (66 <AchievementBadge67 key={achievement.id}68 achievement={achievement}69 badgeSize="sm"70 onAchievementClick={onAchievementClick}71 className={cn(72 "w-28 border-0 bg-transparent p-0 shadow-none hover:shadow-none",73 index === 1 ? "-translate-y-2" : "translate-y-1"74 )}75 />76 ))}77 </div>7879 <div className="mt-10">80 <div className="mb-3 flex items-center justify-between">81 <h3 className="text-primary text-sm font-medium">82 All Achievements83 </h3>84// … truncated
What it pulls in
Other registry items
Files it writes
More from trophy
All 18 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Achievement Badgeachievement-badge | trophy | Components | Free | 1 dep | |
| Achievement Gridachievement-grid | trophy | Components | Free | 2 deps | |
| Achievement Listachievement-list | trophy | Components | Free | 2 deps | |
| Achievement Unlockedachievement-unlocked | trophy | Components | Free | 1 dep | |
| Leaderboard Cardleaderboard-card | trophy | Components | Free | no deps | |
| Leaderboard Podiumleaderboard-podium | trophy | Components | Free | 2 deps | |
| Leaderboard Rankingsleaderboard-rankings | trophy | Components | Free | 2 deps | |
| Points Awardspoints-awards | trophy | Components | Free | 2 deps |
