generated from dwd/boilarplate-remix-tailwind-antd
101 lines
4.3 KiB
TypeScript
101 lines
4.3 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
|
|
interface Performer {
|
|
id: number;
|
|
name: string;
|
|
rank: number;
|
|
avatar: string;
|
|
score: number;
|
|
program: string;
|
|
points: number;
|
|
}
|
|
|
|
export default function TopPerformers() {
|
|
const [data, setData] = useState<Performer[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<Error | null>(null);
|
|
|
|
useEffect(() => {
|
|
fetch('https://iimtt-api.s38.siliconpin.com/api/top-performers')
|
|
.then(res => {
|
|
if (!res.ok) {
|
|
throw new Error('Network response was not ok');
|
|
}
|
|
return res.json();
|
|
})
|
|
.then(data => {
|
|
// console.log(data)
|
|
const sortedData: Performer[] = data.sort((a: Performer, b: Performer) => a.rank - b.rank);
|
|
setData(sortedData);
|
|
setLoading(false);
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching data:', error);
|
|
setError(error);
|
|
setLoading(false);
|
|
});
|
|
}, []);
|
|
|
|
if (loading) {
|
|
return <div>Loading...</div>;
|
|
}
|
|
|
|
if (error) {
|
|
return <div>Error: {error.message}</div>;
|
|
}
|
|
|
|
const [highestRank, secondHighestRank, thirdHighestRank, ...sortedData] = data;
|
|
|
|
return (
|
|
<div className=''>
|
|
<h2 className='text-[20px] font-[700] inline-flex px-4 pt-4'>
|
|
Top Performers <img src="/assets/right-arrow.svg" alt="" />
|
|
</h2>
|
|
<p className='text-[16px] font-[700] text-[#6E6E6E] px-4 pb-4 mb-28'>Knowledge Quest</p>
|
|
<div className='flex flex-row justify-between place-items-center space-x-2 border-b-[1px] border-[#CFCFCF]'>
|
|
<div className='w-full mx-auto h-[88px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
|
|
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
|
|
<img className='mx-auto h-[52px] w-[60px]' src={secondHighestRank.avatar} alt="" />
|
|
<img className='absolute mt-12' src="/assets/bacth2.svg" alt="" />
|
|
</div>
|
|
<p className='text-[12px] font-[700] text-center mt-4'>{secondHighestRank.name}</p>
|
|
<p className='text-[12px] font-[700] text-center'>{secondHighestRank.score} / 50</p>
|
|
</div>
|
|
<div className='w-full mx-auto h-[130px] -mt-[42px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
|
|
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
|
|
<img className='-mt-10' src="/assets/crown.png" alt="" />
|
|
<img className='mx-auto h-[52px] w-[60px]' src={highestRank.avatar} alt="" />
|
|
<img className='absolute mt-9' src="/assets/bacth1.svg" alt="" />
|
|
</div>
|
|
<p className='text-[12px] font-[700] text-center mt-4'>{highestRank.name}</p>
|
|
<p className='text-[12px] font-[700] text-center'>{highestRank.score} / 50</p>
|
|
</div>
|
|
<div className='w-full mx-auto h-[88px] border-x-[1px] border-t-[1px] border-[#CFCFCF] rounded-t-[10px] justify-center place-items-center mx-auto py-4'>
|
|
<div className='-mt-10 relative flex flex-col justify-center place-items-center'>
|
|
<img className='mx-auto h-[52px] w-[60px]' src={thirdHighestRank.avatar} alt="" />
|
|
<img className='absolute mt-12' src="/assets/bacth3.svg" alt="" />
|
|
</div>
|
|
<p className='text-[12px] font-[700] text-center mt-4'>{thirdHighestRank.name}</p>
|
|
<p className='text-[12px] font-[700] text-center'>{thirdHighestRank.score} / 50</p>
|
|
</div>
|
|
</div>
|
|
<div className='flex flex-col'>
|
|
{sortedData.map(data => (
|
|
<div key={data.id} className='flex flex-row justify-between place-items-center border-b-[1px] border-[#CFCFCF] p-2'>
|
|
<p className='text-[11px] font-[700]'># {data.rank}</p>
|
|
<img className='w-[35px] h-[35px]' src={data.avatar} alt="" />
|
|
<div>
|
|
<p className='text-[14px] font-[700]'>{data.name}</p>
|
|
<p className='text-[10px] font-[700] text-[#6E6E6E]'>{data.program}</p>
|
|
</div>
|
|
<div className='flex flex-col justify-center place-items-center'>
|
|
<img src="/assets/points-icon.svg" alt="" />
|
|
<p className='text-[10px] font-[700]'>{data.points} Points</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|