website refactor
This commit is contained in:
@@ -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}</>;
|
||||
|
||||
Reference in New Issue
Block a user