Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 1x 4x 3x 3x 1x 2x 4x | // src/components/AchievementsList.tsx
import React from 'react';
import { Achievement, UserAchievement } from '../types';
/**
* A simple component to render an icon based on its name.
* In a real app, this would map to an icon library like Feather or FontAwesome.
*/
const Icon: React.FC<{ name: string | null | undefined }> = ({ name }) => {
if (!name) return <span className="icon-placeholder">🏆</span>;
// For now, just return the name as text or a default emoji.
// Example: if name is 'chef-hat', you could return a chef hat icon.
const iconMap: { [key: string]: string } = {
'chef-hat': '🧑🍳',
'share-2': '🤝',
list: '📋',
heart: '❤️',
'git-fork': '🍴',
'piggy-bank': '🐷',
};
return <span className="text-2xl">{iconMap[name] || '🏆'}</span>;
};
interface AchievementsListProps {
achievements: (UserAchievement & Achievement)[];
}
export const AchievementsList: React.FC<AchievementsListProps> = ({ achievements }) => {
return (
<div>
<h2 className="text-2xl font-semibold mb-4 border-b pb-2">Achievements</h2>
{achievements.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{achievements.map((ach) => (
<div
key={ach.achievement_id}
className="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md flex items-start space-x-4"
>
<div className="shrink-0">
<Icon name={ach.icon} />
</div>
<div>
<h3 className="font-bold">{ach.name}</h3>
<p className="text-sm text-gray-600 dark:text-gray-300">{ach.description}</p>
<p className="text-xs text-yellow-500 font-semibold mt-1">
+{ach.points_value} Points
</p>
</div>
</div>
))}
</div>
) : (
<p className="text-gray-500">No achievements earned yet. Keep exploring to unlock them!</p>
)}
</div>
);
};
|