trackerdeq/src/app/components/Ranked.tsx

104 lines
2.7 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
interface Match
{
matchId: string;
championImg: string;
win: boolean;
kills: number;
deaths: number;
assists: number;
isOld?: boolean;
}
interface SummonerData
{
tier: string;
division?: string;
lp: number;
wins: number;
losses: number;
winrate: number;
matches: Match[];
}
export default function Ranked ( { name, tag }: { name: string; tag: string } )
{
const [ data, setData ] = useState<SummonerData | null>( null );
useEffect( () =>
{
const fetchData = async () =>
{
try
{
const res = await fetch( `/api/ranked/${ name }/${ tag }` );
if ( !res.ok ) throw new Error( "API error" );
const json = await res.json();
setData( json );
} catch ( err )
{
console.error( "Failed to fetch ranked data:", err );
}
};
fetchData();
const interval = setInterval( fetchData, 2 * 60 * 1000 );
return () => clearInterval( interval );
}, [ name, tag ] );
if ( !data ) return null;
return (
<div className="font-sans">
<div className="text flex flex-row font-bold tracking-wide">
<div className="elo basis-2/3 pr-4 mb-3 text-white">
{ [ "MASTER", "GRANDMASTER", "CHALLENGER" ].includes( data.tier ) ? (
<div className="league basis-1/2 text-4xl text-shadow-xl">
{ data.tier } { data.lp } LP
</div>
) : (
<div className="points basis-1/2 text-3xl text-shadow-xl">
{ data.tier } { data.division } { data.lp } LP
</div>
) }
</div>
<div className="stats basis-1/3 flex flex-row justify-end text-3xl tracking-tighter">
<div className="wins px-2 text-sky-600 text-shadow-xl">{ data.wins }W</div>
<div className="losses px-2 text-red-600 text-shadow-xl">{ data.losses }L</div>
<div className="winrate pl-3 text-white text-shadow-xl">
{ data.winrate }%
</div>
</div>
</div>
<div className="games flex flex-row">
{ data.matches.map( ( match, index ) => (
<div
key={ match.matchId || index }
className={ `game basis-1/6 px-1.5 ${ match.isOld ? "old" : "" }` }
>
<div
className={ `background ring-4 rounded-full ${ match.win ? "win ring-sky-600" : "loss ring-red-600"
}` }
>
<div
className={ `champion bg-center aspect-square scale-90 rounded-full drop-shadow-lg bg-no-repeat bg-[length:110%] ${ match.win ? "" : "lose"
}` }
style={ { backgroundImage: `url('${ match.championImg }')` } }
/>
</div>
<div className="kda text-center text-xl font-semilight text-gray-200 tracking-tight text-shadow-xl">
{ match.kills }/{ match.deaths }/{ match.assists }
</div>
</div>
) ) }
</div>
</div>
);
}