Skip to content

Commit 2a400c9

Browse files
María Paz Arrieta LandazuriMaría Paz Arrieta Landazuri
authored andcommitted
feat: add Leaderboard component and integrate it into Prices dropdown menu
1 parent c3e17a3 commit 2a400c9

File tree

3 files changed

+179
-1
lines changed

3 files changed

+179
-1
lines changed

frontend/src/app/components/Header.tsx

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Link from 'next/link';
33

44
const Header = () => {
55
const [isAprendeOpen, setIsAprendeOpen] = useState(false);
6+
const [isPreciosOpen, setIsPreciosOpen] = useState(false);
67

78
return (
89
<header className="w-full bg-white shadow-sm">
@@ -15,7 +16,41 @@ const Header = () => {
1516
{/* Secciones */}
1617
<div className="flex space-x-8 items-center">
1718
<a href="#acerca" className="text-gray-700 hover:text-orange-400 font-medium transition-colors">Acerca de</a>
18-
<a href="#precios" className="text-gray-700 hover:text-orange-400 font-medium transition-colors">Precios</a>
19+
20+
{/* Precios Dropdown */}
21+
<div className="relative">
22+
<button
23+
onClick={() => setIsPreciosOpen(!isPreciosOpen)}
24+
className="text-gray-700 hover:text-orange-400 font-medium transition-colors flex items-center"
25+
>
26+
Precios
27+
<svg
28+
className={`ml-1 w-4 h-4 transition-transform ${isPreciosOpen ? 'rotate-180' : ''}`}
29+
fill="none"
30+
stroke="currentColor"
31+
viewBox="0 0 24 24"
32+
>
33+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
34+
</svg>
35+
</button>
36+
37+
{isPreciosOpen && (
38+
<div className="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg py-2 z-50 border border-gray-100">
39+
<a
40+
href="#precios"
41+
className="block px-4 py-2 text-gray-700 hover:bg-orange-50 hover:text-orange-400 transition-colors"
42+
>
43+
Planes y Precios
44+
</a>
45+
<Link
46+
href="/leaderboard"
47+
className="block px-4 py-2 text-gray-700 hover:bg-orange-50 hover:text-orange-400 transition-colors"
48+
>
49+
Leaderboard
50+
</Link>
51+
</div>
52+
)}
53+
</div>
1954

2055
{/* Aprende Dropdown */}
2156
<div className="relative">
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import React from 'react';
2+
3+
interface LeaderboardUser {
4+
username: string;
5+
afpBalance: number;
6+
afpFund: string;
7+
profit: number;
8+
}
9+
10+
interface LeaderboardProps {
11+
users: LeaderboardUser[];
12+
}
13+
14+
const Leaderboard: React.FC<LeaderboardProps> = ({ users }) => {
15+
// Sort users by profit in descending order
16+
const sortedUsers = [...users].sort((a, b) => b.profit - a.profit);
17+
18+
const formatCurrency = (amount: number) => {
19+
return new Intl.NumberFormat('es-CL', {
20+
style: 'currency',
21+
currency: 'CLP',
22+
minimumFractionDigits: 0,
23+
maximumFractionDigits: 0,
24+
}).format(amount);
25+
};
26+
27+
return (
28+
<div className="bg-white rounded-2xl p-8 shadow-xl">
29+
<h2 className="text-3xl font-bold text-gray-900 mb-6">Leaderboard</h2>
30+
<div className="overflow-x-auto">
31+
<table className="w-full">
32+
<thead>
33+
<tr className="border-b-2 border-gray-200">
34+
<th className="text-left py-4 px-4 text-gray-600 font-semibold">Usuario</th>
35+
<th className="text-right py-4 px-4 text-gray-600 font-semibold">Saldo AFP</th>
36+
<th className="text-center py-4 px-4 text-gray-600 font-semibold">Fondo AFP</th>
37+
<th className="text-right py-4 px-4 text-gray-600 font-semibold">Ganancia</th>
38+
</tr>
39+
</thead>
40+
<tbody>
41+
{sortedUsers.map((user, index) => (
42+
<tr
43+
key={user.username}
44+
className={`border-b border-gray-100 hover:bg-gray-50 transition-colors ${
45+
index === 0 ? 'bg-yellow-50' :
46+
index === 1 ? 'bg-gray-100' :
47+
index === 2 ? 'bg-amber-50' : ''
48+
}`}
49+
>
50+
<td className="py-4 px-4">
51+
<div className="flex items-center">
52+
{index < 3 && (
53+
<span className="mr-2 text-lg">
54+
{index === 0 ? '🥇' : index === 1 ? '🥈' : '🥉'}
55+
</span>
56+
)}
57+
<span className="font-medium text-gray-900">{user.username}</span>
58+
</div>
59+
</td>
60+
<td className="text-right py-4 px-4 text-gray-900">
61+
{formatCurrency(user.afpBalance)}
62+
</td>
63+
<td className="text-center py-4 px-4">
64+
<span className="px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800">
65+
{user.afpFund}
66+
</span>
67+
</td>
68+
<td className="text-right py-4 px-4">
69+
<span className={`font-medium ${
70+
user.profit >= 0 ? 'text-green-600' : 'text-red-600'
71+
}`}>
72+
{formatCurrency(user.profit)}
73+
</span>
74+
</td>
75+
</tr>
76+
))}
77+
</tbody>
78+
</table>
79+
</div>
80+
</div>
81+
);
82+
};
83+
84+
export default Leaderboard;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use client';
2+
3+
import React from 'react';
4+
import Leaderboard from '../components/Leaderboard';
5+
6+
// Sample data - In a real application, this would come from an API
7+
const sampleUsers = [
8+
{
9+
username: "Juan Pérez",
10+
afpBalance: 45000000,
11+
afpFund: "Capital",
12+
profit: 2500000
13+
},
14+
{
15+
username: "María González",
16+
afpBalance: 38000000,
17+
afpFund: "Habitat",
18+
profit: 1800000
19+
},
20+
{
21+
username: "Carlos Rodríguez",
22+
afpBalance: 42000000,
23+
afpFund: "Cuprum",
24+
profit: 2100000
25+
},
26+
{
27+
username: "Ana Martínez",
28+
afpBalance: 35000000,
29+
afpFund: "ProVida",
30+
profit: 1500000
31+
},
32+
{
33+
username: "Pedro Sánchez",
34+
afpBalance: 40000000,
35+
afpFund: "PlanVital",
36+
profit: 1900000
37+
}
38+
];
39+
40+
export default function LeaderboardPage() {
41+
return (
42+
<div className="min-h-screen w-full bg-cover bg-center flex flex-col items-center justify-center" style={{ backgroundImage: 'url(/bg-hero.png)' }}>
43+
<div className="mt-8 bg-white rounded-3xl shadow-2xl px-8 py-10 max-w-4xl w-full flex flex-col items-center border-2 border-gray-200">
44+
<h1 className="text-4xl md:text-5xl font-bold text-center text-gray-900 mb-8">
45+
<span className="text-orange-400">Leaderboard</span>
46+
</h1>
47+
48+
<div className="w-full">
49+
<Leaderboard users={sampleUsers} />
50+
</div>
51+
52+
<div className="mt-8 text-gray-600 text-sm text-center">
53+
<p>* Los datos mostrados son actualizados diariamente</p>
54+
<p>* Las ganancias son calculadas en base al rendimiento anual</p>
55+
</div>
56+
</div>
57+
</div>
58+
);
59+
}

0 commit comments

Comments
 (0)