81 lines
2.7 KiB
TypeScript
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}</>;
|