website refactor

This commit is contained in:
2026-01-18 21:31:08 +01:00
parent 502d4aa092
commit b43a23a48c
96 changed files with 3461 additions and 4067 deletions

View File

@@ -1,70 +1,80 @@
import { Trophy } from 'lucide-react';
import { ReactNode } from 'react';
import React, { ReactNode } from 'react';
import { Box } from './primitives/Box';
import { Heading } from './Heading';
import { Icon } from './Icon';
import { Stack } from './primitives/Stack';
import { Text } from './Text';
import { Avatar } from './Avatar';
import { Trophy } from 'lucide-react';
import { Icon } from './Icon';
import { Heading } from './Heading';
interface PodiumProps {
title: string;
children: ReactNode;
export interface PodiumEntry {
name: string;
avatar?: string;
value: string | number;
position: 1 | 2 | 3;
}
export function Podium({ title, children }: PodiumProps) {
return (
<Box bg="bg-iron-gray/50" rounded="2xl" border style={{ borderColor: 'rgba(38, 38, 38, 0.8)' }} p={8} mb={10}>
<Box display="flex" justifyContent="center" mb={8}>
<Stack direction="row" align="center" gap={2}>
<Icon icon={Trophy} size={6} color="var(--warning-amber)" />
<Heading level={2}>{title}</Heading>
</Stack>
</Box>
export interface PodiumProps {
entries?: PodiumEntry[];
title?: string;
children?: ReactNode;
}
<Stack direction="row" align="end" justify="center" gap={8}>
{children}
</Stack>
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>
);
}
};
interface PodiumItemProps {
position: number;
height: string;
cardContent: ReactNode;
bgColor: string;
positionColor: string;
}
export function PodiumItem({
position,
height,
cardContent,
bgColor,
positionColor,
}: PodiumItemProps) {
return (
<Stack align="center">
{cardContent}
{/* Podium stand */}
<Box
bg={bgColor}
h={height}
border
style={{ borderColor: 'rgba(38, 38, 38, 0.8)', borderTopLeftRadius: '0.5rem', borderTopRightRadius: '0.5rem' }}
w="28"
display="flex"
p={3}
>
<Box display="flex" center fullWidth>
<Text size="3xl" weight="bold" color={positionColor}>
{position}
</Text>
</Box>
</Box>
</Stack>
);
}
export const PodiumItem = ({ children }: { children: ReactNode }) => <>{children}</>;