website refactor

This commit is contained in:
2026-01-18 17:55:04 +01:00
parent 489deb2991
commit 9ffe47da37
75 changed files with 1596 additions and 1259 deletions

View File

@@ -1,93 +1,100 @@
import React from 'react';
import { Box } from './primitives/Box';
import { Text } from './Text';
import { ImagePlaceholder } from './ImagePlaceholder';
import { Image } from './Image';
import { Surface } from './primitives/Surface';
import { Text } from './Text';
import { Play, Image as ImageIcon } from 'lucide-react';
import { Icon } from './Icon';
export interface MediaPreviewCardProps {
src?: string;
alt?: string;
interface MediaPreviewCardProps {
type: 'image' | 'video';
src: string;
alt: string;
title?: string;
subtitle?: string;
onClick?: () => void;
aspectRatio?: string;
isLoading?: boolean;
error?: string;
onClick?: () => void;
className?: string;
actions?: React.ReactNode;
}
export function MediaPreviewCard({
type,
src,
alt = 'Media preview',
alt,
title,
subtitle,
aspectRatio = '16/9',
isLoading,
error,
onClick,
aspectRatio = '16/9',
isLoading = false,
className = '',
actions,
}: MediaPreviewCardProps) {
return (
<Box
display="flex"
flexDirection="col"
bg="bg-charcoal-outline/10"
<Surface
variant="muted"
rounded="xl"
border
borderColor="border-charcoal-outline/50"
rounded="lg"
overflow="hidden"
transition
hoverScale={!!onClick}
cursor={onClick ? 'pointer' : 'default'}
cursor="pointer"
onClick={onClick}
className={`group ${className}`}
group
className={className}
>
<Box position="relative" width="full" style={{ aspectRatio }}>
<Box position="relative" w="full" aspectRatio={aspectRatio}>
{isLoading ? (
<ImagePlaceholder variant="loading" aspectRatio={aspectRatio} rounded="none" />
) : error ? (
<ImagePlaceholder variant="error" message={error} aspectRatio={aspectRatio} rounded="none" />
) : src ? (
<Box fullWidth fullHeight bg="bg-white/5" className="animate-pulse" />
) : (
<Image
src={src}
alt={alt}
className="w-full h-full object-cover"
fullWidth
fullHeight
className="object-cover"
/>
) : (
<ImagePlaceholder aspectRatio={aspectRatio} rounded="none" />
)}
{actions && (
{/* Overlay */}
<Box
position="absolute"
inset={0}
bg="bg-black/40"
display="flex"
center
opacity={0}
groupHoverOpacity={1}
transition="all 0.2s"
>
<Box
w="12"
h="12"
rounded="full"
bg="bg-white/20"
display="flex"
center
className="backdrop-blur-md"
>
<Icon
icon={type === 'video' ? Play : ImageIcon}
size={6}
color="white"
/>
</Box>
</Box>
{title && (
<Box
position="absolute"
top={2}
right={2}
display="flex"
gap={2}
opacity={0}
className="group-hover:opacity-100 transition-opacity"
bottom={0}
left={0}
right={0}
p={3}
bg="bg-gradient-to-t from-black/80 to-transparent"
>
{actions}
<Text size="xs" weight="medium" color="text-white" truncate>
{title}
</Text>
</Box>
)}
</Box>
{(title || subtitle) && (
<Box p={3} borderTop borderColor="border-charcoal-outline/30">
{title && (
<Text block size="sm" weight="semibold" truncate>
{title}
</Text>
)}
{subtitle && (
<Text block size="xs" color="text-gray-500" truncate mt={0.5}>
{subtitle}
</Text>
)}
</Box>
)}
</Box>
</Surface>
);
}