Files
SkinbaseNova/resources/js/components/leaderboard/LeaderboardItem.jsx
2026-03-20 21:17:26 +01:00

70 lines
3.0 KiB
JavaScript

import React from 'react'
import LevelBadge from '../xp/LevelBadge'
const PODIUM_STYLES = {
1: 'border-yellow-300/40 bg-[linear-gradient(180deg,rgba(250,204,21,0.18),rgba(15,23,42,0.84))]',
2: 'border-slate-300/30 bg-[linear-gradient(180deg,rgba(226,232,240,0.16),rgba(15,23,42,0.84))]',
3: 'border-amber-700/40 bg-[linear-gradient(180deg,rgba(180,83,9,0.22),rgba(15,23,42,0.84))]',
}
function cx(...parts) {
return parts.filter(Boolean).join(' ')
}
function formatScore(score) {
return new Intl.NumberFormat().format(Math.round(Number(score || 0)))
}
export default function LeaderboardItem({ item, type, highlight = false }) {
const entity = item?.entity || {}
const rank = Number(item?.rank || 0)
const tone = highlight ? PODIUM_STYLES[rank] || PODIUM_STYLES[3] : 'border-white/10 bg-white/[0.03]'
const image = entity.avatar || entity.image || null
return (
<article className={cx('rounded-3xl border p-4 shadow-lg transition', tone)}>
<div className="flex items-start gap-4">
<div className={cx('flex shrink-0 items-center justify-center rounded-2xl border font-black', highlight ? 'h-14 w-14 text-xl' : 'h-11 w-11 text-base', 'border-white/10 bg-slate-950/70 text-white')}>
#{rank}
</div>
<div className="min-w-0 flex-1">
<div className="flex items-start justify-between gap-3">
<div className="min-w-0">
<a href={entity.url || '#'} className="block text-lg font-semibold text-white hover:text-sky-300 transition">
{entity.name || 'Unknown'}
</a>
{entity.creator_name ? (
<a href={entity.creator_url || '#'} className="mt-1 block text-sm text-slate-400 hover:text-sky-300 transition">
by {entity.creator_name}
</a>
) : null}
{entity.username ? <p className="mt-1 text-sm text-slate-500">@{entity.username}</p> : null}
</div>
<div className="text-right">
<p className="text-[11px] uppercase tracking-[0.24em] text-slate-500">Score</p>
<p className="mt-1 text-2xl font-black text-white">{formatScore(item?.score)}</p>
</div>
</div>
<div className="mt-4 flex flex-wrap items-center gap-3">
{type === 'creator' ? <LevelBadge level={entity.level} rank={entity.rank} compact /> : null}
{type !== 'creator' && entity.creator_name ? (
<span className="rounded-full border border-white/10 bg-white/5 px-3 py-1 text-[11px] uppercase tracking-[0.14em] text-slate-300">
{type}
</span>
) : null}
</div>
</div>
{image ? (
<a href={entity.url || '#'} className={cx('block shrink-0 overflow-hidden rounded-2xl border border-white/10 bg-slate-900', type === 'creator' ? 'h-16 w-16' : 'h-20 w-24')}>
<img src={image} alt={entity.name || 'Leaderboard item'} className="h-full w-full object-cover" loading="lazy" />
</a>
) : null}
</div>
</article>
)
}