import { ListOrdered } from "lucide-react";
import { Link } from "react-router";
import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader } from "~/components/ui/card";
import { GradientIcon } from "~/components/ui/GradientIcon";
import { TeamAvatar } from "~/components/TeamAvatar";
// ─── Stat helpers (mirrors LeagueRow) ────────────────────────────────────────
function StatColumn({
label,
children,
}: {
label: string;
children: React.ReactNode;
}) {
return (
);
}
function StatDivider() {
return ;
}
function RankChangeIndicator({ change }: { change: number }) {
if (change === 0) return null;
if (change > 0) {
return (
▲{change}
);
}
return (
▼{Math.abs(change)}
);
}
function PointChangeIndicator({ change }: { change: number }) {
if (change >= 0) {
return ▲{Math.round(change)};
}
return (
▼{Math.abs(Math.round(change))}
);
}
// ─── Row styles ───────────────────────────────────────────────────────────────
const ROW_RANK_CLASSES: Record = {
1: "bg-yellow-500/10 hover:bg-yellow-500/15",
2: "bg-white/[0.14] hover:bg-white/[0.18]",
3: "bg-orange-600/[0.08] hover:bg-orange-600/[0.12]",
};
function rowClasses(currentRank: number | undefined, hasHref: boolean): string {
const podium = currentRank !== undefined ? ROW_RANK_CLASSES[currentRank] : undefined;
const base = podium ?? `bg-white/[0.04] ${hasHref ? "hover:bg-white/[0.07]" : ""}`;
return `flex flex-col sm:flex-row sm:items-center gap-0 rounded-lg px-3 py-3 sm:px-5 sm:py-4 transition-colors ${base}`;
}
// ─── Row content ──────────────────────────────────────────────────────────────
function RowContent({ entry }: { entry: StandingsPreviewEntry }) {
return (
<>
{/* Left: avatar + name */}
{entry.teamName}
{entry.ownerName && (
{entry.ownerName}
)}
{/* Right: stats — second row on mobile */}
{entry.displayRank}
{entry.rankChange !== undefined && entry.rankChange !== 0 && (
)}
{Math.round(entry.points).toLocaleString("en-US")}
{entry.pointChange !== undefined && entry.pointChange !== 0 && (
)}
>
);
}
// ─── Public API ───────────────────────────────────────────────────────────────
export interface StandingsPreviewEntry {
teamId: string;
teamName: string;
ownerName?: string | null;
/** Pre-computed display rank, e.g. 1, "T2", "T5". Use getDisplayRank(). */
displayRank: string | number;
/** Numeric rank used to select the gold/silver/bronze row tint (1–3 only). */
currentRank?: number;
points: number;
href?: string;
/** Positive = moved up, negative = moved down. From TeamStanding.rankChange. */
rankChange?: number;
/** 7-day point delta. From TeamStanding.sevenDayPointChange. */
pointChange?: number;
}
export interface StandingsPreviewProps {
entries: StandingsPreviewEntry[];
description?: string;
fullStandingsHref?: string;
}
export function StandingsPreview({ entries, description, fullStandingsHref }: StandingsPreviewProps) {
return (
Standings
{description && (
{description}
)}
{fullStandingsHref && (
)}
{entries.map((entry) =>
entry.href ? (
) : (
)
)}
);
}