// Reusable UI chunks: avatar, badge pill, bottom nav, player card
const { useState } = React;
function Avatar({ player, size = 68, showTag = true }) {
const s = size;
return (
{player.nick}
{showTag && s >= 60 && PHOTO}
);
}
// darken/lighten hex
function shade(hex, pct) {
const h = hex.replace('#','');
const n = parseInt(h, 16);
let r = (n >> 16) + Math.round(255 * pct/100);
let g = ((n >> 8) & 0xff) + Math.round(255 * pct/100);
let b = (n & 0xff) + Math.round(255 * pct/100);
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
return '#' + ((r<<16) | (g<<8) | b).toString(16).padStart(6,'0');
}
function MiniAvatar({ player, size = 26 }) {
return (
{player.nick}
);
}
function BadgePill({ badge }) {
return (
{badge.icon}
{badge.label}
);
}
function BottomNav({ page, onNav }) {
const items = [
{ id: "leaderboard", label: "الأبطال", ico: "♛" },
{ id: "history", label: "المباريات", ico: "♦" },
{ id: "profile", label: "البروفايل", ico: "♥" },
{ id: "admin", label: "إدارة", ico: "♠" },
];
return (
);
}
function PlayerCard({ player, rank, onClick, dealIndex = 0 }) {
const tiltClass = `tilt-${(rank % 4) + 1}`;
const isTop = rank === 0;
const crown = rank === 0 ? "المتصدّر" : rank === 1 ? "الثاني" : rank === 2 ? "الثالث" : null;
const total = player.wins + player.losses;
const wr = total ? Math.round((player.wins / total) * 100) : 0;
const myBadges = badgesFor(player.id);
return (
{rank + 1}
{crown &&
{crown}}
{player.name}
{player.wins}فوز
{player.losses}خسارة
{wr}٪نسبة
{myBadges.length > 0 && (
{myBadges.slice(0,2).map(b => (
{b.icon}
{b.label}
))}
)}
{rank + 1}
RANK
);
}
Object.assign(window, { Avatar, MiniAvatar, BadgePill, BottomNav, PlayerCard, shade });