niki-frontend/src/app/gamification/page.tsx

92 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { useState } from 'react';
import PageHeader from '@/components/PageHeader';
const mockLeaderboard = [
{ rank: 1, name: 'Ali Mohammadi', points: 2500, badges: 5, level: 'Gold' },
{ rank: 2, name: 'Sara Ahmadi', points: 1800, badges: 3, level: 'Silver' },
{ rank: 3, name: 'Reza Hosseini', points: 1200, badges: 2, level: 'Silver' },
{ rank: 4, name: 'Mehdi Rezaei', points: 800, badges: 1, level: 'Bronze' },
{ rank: 5, name: 'Narges Karimi', points: 500, badges: 1, level: 'Bronze' },
];
const levelColors: Record<string, string> = {
Gold: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400',
Silver: 'bg-gray-100 text-gray-800 dark:bg-gray-900/30 dark:text-gray-400',
Bronze: 'bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-400',
};
const badges = [
{ name: 'First Donation', icon: '🎖️', description: 'Made your first donation' },
{ name: 'Helping Hand', icon: '🤲', description: 'Helped 10 benefactors' },
{ name: 'Consistent Giver', icon: '📅', description: 'Active for 30 days' },
{ name: 'Top Donor', icon: '👑', description: 'Top 10 donor this month' },
{ name: 'Community Star', icon: '⭐', description: 'Referral master' },
];
export default function GamificationPage() {
const [tab, setTab] = useState<'leaderboard' | 'badges'>('leaderboard');
return (
<div className="space-y-6">
<PageHeader title="Gamification" description="Leaderboards and achievements" />
<div className="flex gap-1 p-1 rounded-lg bg-gray-100 dark:bg-gray-800 w-fit">
<button onClick={() => setTab('leaderboard')} className={`px-4 py-2 rounded-md text-sm font-medium transition-all ${tab === 'leaderboard' ? 'bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 shadow-sm' : 'text-gray-500 hover:text-gray-700'}`}>🏆 Leaderboard</button>
<button onClick={() => setTab('badges')} className={`px-4 py-2 rounded-md text-sm font-medium transition-all ${tab === 'badges' ? 'bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 shadow-sm' : 'text-gray-500 hover:text-gray-700'}`}>🎖 Badges</button>
</div>
{tab === 'leaderboard' && (
<div className="table-container">
<table>
<thead>
<tr>
<th>Rank</th>
<th>Name</th>
<th>Points</th>
<th>Badges</th>
<th>Level</th>
</tr>
</thead>
<tbody>
{mockLeaderboard.map((p) => (
<tr key={p.rank}>
<td>
<span className={`inline-flex items-center justify-center w-7 h-7 rounded-full text-sm font-bold ${
p.rank === 1 ? 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400' :
p.rank === 2 ? 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300' :
p.rank === 3 ? 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400' :
'text-gray-500'
}`}>{p.rank}</span>
</td>
<td className="font-medium text-gray-900 dark:text-gray-100">{p.name}</td>
<td className="font-bold">{p.points.toLocaleString()}</td>
<td>{p.badges}</td>
<td><span className={`badge ${levelColors[p.level]}`}>{p.level}</span></td>
</tr>
))}
</tbody>
</table>
</div>
)}
{tab === 'badges' && (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{badges.map((b) => (
<div key={b.name} className="card hover:shadow-lg transition-all">
<div className="card-body flex items-center gap-4">
<span className="text-3xl">{b.icon}</span>
<div>
<h3 className="font-semibold text-gray-900 dark:text-gray-100">{b.name}</h3>
<p className="text-sm text-gray-500 dark:text-gray-400">{b.description}</p>
</div>
</div>
</div>
))}
</div>
)}
</div>
);
}