86 lines
2.8 KiB
TypeScript
86 lines
2.8 KiB
TypeScript
// pages/page.tsx
|
|
"use client";
|
|
import React, { useEffect, useState } from 'react';
|
|
import { motion } from 'framer-motion';
|
|
import Link from 'next/link';
|
|
import Header from '@/components/Header';
|
|
import Footer from '@/components/Footer';
|
|
|
|
interface User {
|
|
username: string;
|
|
total_gains: string;
|
|
img_url: string;
|
|
}
|
|
|
|
const Page: React.FC = () => {
|
|
const [userData, setUserData] = useState<User[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
const fetchData = async () => {
|
|
try {
|
|
const response = await fetch("https://api.callfi.io/get_user_list.php");
|
|
if (!response.ok) {
|
|
throw new Error("Network response was not ok");
|
|
}
|
|
const data = await response.json();
|
|
setUserData(data);
|
|
} catch (error: any) {
|
|
setError(error.message);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
// Conditionally execute useEffect on the client side only
|
|
if (typeof window !== 'undefined') {
|
|
fetchData();
|
|
}
|
|
}, []);
|
|
|
|
// Sort userData by total_gains before rendering
|
|
const sortedUserData = [...userData].sort((a, b) => parseFloat(b.total_gains) - parseFloat(a.total_gains));
|
|
|
|
return (
|
|
<>
|
|
<main className="flex flex-col min-h-screen items-center justify-between text-white">
|
|
<Header />
|
|
<section className="w-full p-4 flex flex-col items-center justify-center">
|
|
<h1 className="text-2xl font-bold mb-4">User Rankings</h1>
|
|
{loading ? (
|
|
<p>Loading...</p>
|
|
) : error ? (
|
|
<p>Error: {error}</p>
|
|
) : (
|
|
<ul className="w-full max-w-4xl">
|
|
{sortedUserData.map((user) => (
|
|
<motion.div key={user.username} whileHover={{ scale: 1.05, transition: { duration: 0.15 } }}>
|
|
<Link href={`/users/${user.username}`}>
|
|
<li className="leaderboard-card glassmorphism mx-auto mb-4 p-4 rounded-lg flex items-center">
|
|
<div className="flex items-center">
|
|
<img
|
|
src={user.img_url}
|
|
alt={`${user.username}'s profile`}
|
|
className="w-12 h-12 rounded-full mr-4"
|
|
/>
|
|
<div className="flex flex-col items-center justify-center flex-1">
|
|
<span className="text-center font-bold">{user.username}</span>
|
|
<span className="text-center">Points: {(parseFloat(user.total_gains) * 100).toFixed(2)}</span>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</Link>
|
|
</motion.div>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</section>
|
|
<Footer />
|
|
</main>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Page;
|