Files
gridpilot.gg/apps/website/ui/Podium.tsx
2026-01-18 23:24:30 +01:00

81 lines
2.7 KiB
TypeScript

import { Trophy } from 'lucide-react';
import { ReactNode } from 'react';
import { Avatar } from './Avatar';
import { Box } from './Box';
import { Heading } from './Heading';
import { Icon } from './Icon';
import { Text } from './Text';
export interface PodiumEntry {
name: string;
avatar?: string;
value: string | number;
position: 1 | 2 | 3;
}
export interface PodiumProps {
entries?: PodiumEntry[];
title?: string;
children?: ReactNode;
}
export const Podium = ({ entries = [], title, children }: PodiumProps) => {
const sortedEntries = [...entries].sort((a, b) => {
const order = { 2: 0, 1: 1, 3: 2 };
return order[a.position] - order[b.position];
});
const getPositionColor = (pos: number) => {
if (pos === 1) return 'var(--ui-color-intent-warning)';
if (pos === 2) return '#A1A1AA';
if (pos === 3) return '#CD7F32';
return 'var(--ui-color-text-low)';
};
return (
<Box paddingY={8}>
{title && <Heading level={2} align="center" marginBottom={8}>{title}</Heading>}
<Box display="flex" alignItems="end" justifyContent="center" gap={4}>
{sortedEntries.map((entry) => {
const height = entry.position === 1 ? '12rem' : entry.position === 2 ? '10rem' : '8rem';
const color = getPositionColor(entry.position);
return (
<Box key={entry.position} display="flex" flexDirection="col" alignItems="center" gap={4}>
<Box display="flex" flexDirection="col" alignItems="center" gap={2}>
{entry.position === 1 && <Icon icon={Trophy} size={6} intent="warning" />}
<Avatar src={entry.avatar} alt={entry.name} size={entry.position === 1 ? 'lg' : 'md'} />
<Text weight="bold" variant="high" size={entry.position === 1 ? 'md' : 'sm'}>{entry.name}</Text>
<Text size="xs" variant="low">{entry.value}</Text>
</Box>
<Box
width="6rem"
height={height}
bg="var(--ui-color-bg-surface-muted)"
display="flex"
alignItems="center"
justifyContent="center"
style={{
borderTopLeftRadius: 'var(--ui-radius-lg)',
borderTopRightRadius: 'var(--ui-radius-lg)',
border: `1px solid ${color}`,
borderBottom: 'none'
}}
>
<Text size="3xl" weight="bold" style={{ color }}>
{entry.position}
</Text>
</Box>
</Box>
);
})}
</Box>
{children}
</Box>
);
};
export const PodiumItem = ({ children }: { children: ReactNode }) => <>{children}</>;