project-standalo-todo-super/app/components/BadgeCard.tsx

79 lines
3.0 KiB
TypeScript

"use client";
interface BadgeCardProps {
badge: {
id: string;
name: string;
description: string;
icon: string;
earnedDate?: string;
progress?: number;
requirement?: number;
};
earned: boolean;
}
export default function BadgeCard({ badge, earned }: BadgeCardProps) {
const progressPercent = badge.progress && badge.requirement
? (badge.progress / badge.requirement) * 100
: 0;
return (
<div className={`bg-gray-800 border-2 rounded-xl p-6 transition ${
earned
? "border-yellow-500 shadow-lg shadow-yellow-500/20"
: "border-gray-700 opacity-75"
}`}>
<div className="flex flex-col items-center text-center">
<div className={`w-24 h-24 rounded-full flex items-center justify-center mb-4 transition ${
earned
? "bg-gradient-to-br from-yellow-400 to-orange-500 shadow-xl shadow-yellow-500/50 animate-pulse"
: "bg-gray-700"
}`}>
<span className="text-4xl">{badge.icon}</span>
</div>
<h3 className={`text-xl font-bold mb-2 ${earned ? "text-white" : "text-gray-400"}`}>
{badge.name}
</h3>
<p className="text-gray-400 text-sm mb-4">{badge.description}</p>
{earned && badge.earnedDate ? (
<div className="flex items-center gap-2 bg-yellow-500/20 border border-yellow-500/30 rounded-full px-4 py-2">
<svg className="w-4 h-4 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
</svg>
<span className="text-yellow-400 text-sm font-medium">
Earned {new Date(badge.earnedDate).toLocaleDateString()}
</span>
</div>
) : badge.progress !== undefined && badge.requirement !== undefined ? (
<div className="w-full">
<div className="flex justify-between text-xs text-gray-400 mb-2">
<span>Progress</span>
<span>{badge.progress} / {badge.requirement}</span>
</div>
<div className="w-full bg-gray-700 rounded-full h-2 overflow-hidden">
<div
className="bg-gradient-to-r from-yellow-500 to-orange-500 h-full rounded-full transition-all duration-500"
style={{ width: `${progressPercent}%` }}
></div>
</div>
<p className="text-xs text-gray-500 mt-2">
{Math.round(progressPercent)}% complete
</p>
</div>
) : (
<div className="flex items-center gap-2 text-gray-500 text-sm">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clipRule="evenodd" />
</svg>
<span>Not earned yet</span>
</div>
)}
</div>
</div>
);
}