89 lines
3.6 KiB
TypeScript
89 lines
3.6 KiB
TypeScript
import { Badge } from '@/components/ui/badge';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Card } from '@/components/ui/card';
|
|
import { KeywordBadge } from '@/components/ui/keyword-badge';
|
|
import { Link } from '@inertiajs/react';
|
|
import { Edit } from 'lucide-react';
|
|
import { route } from 'ziggy-js';
|
|
|
|
interface MemeMedia {
|
|
ids: string;
|
|
name: string;
|
|
description: string;
|
|
keywords: string[];
|
|
action_keywords: string[];
|
|
emotion_keywords: string[];
|
|
misc_keywords: string[];
|
|
mov_url: string;
|
|
webm_url: string;
|
|
gif_url: string;
|
|
webp_url: string;
|
|
slug: string;
|
|
}
|
|
|
|
interface MemeCardProps {
|
|
meme: MemeMedia;
|
|
showButton?: boolean;
|
|
showKeywords?: boolean;
|
|
className?: string;
|
|
}
|
|
|
|
export function MemeCard({ meme, showButton = true, showKeywords = true, className = '' }: MemeCardProps) {
|
|
return (
|
|
<Card className={`group flex flex-col overflow-hidden p-0 transition-shadow hover:shadow-lg ${className}`}>
|
|
<div
|
|
className="relative aspect-[9/16] overflow-hidden"
|
|
style={{
|
|
backgroundColor: '#ffffff',
|
|
backgroundImage: `
|
|
linear-gradient(45deg, #cccccc 25%, transparent 25%),
|
|
linear-gradient(-45deg, #cccccc 25%, transparent 25%),
|
|
linear-gradient(45deg, transparent 75%, #cccccc 75%),
|
|
linear-gradient(-45deg, transparent 75%, #cccccc 75%)
|
|
`,
|
|
backgroundSize: '20px 20px',
|
|
backgroundPosition: '0 0, 0 10px, 10px -10px, -10px 0px'
|
|
}}
|
|
>
|
|
<img
|
|
src={meme.webp_url}
|
|
alt={meme.name}
|
|
className="h-full w-full object-cover transition-transform group-hover:scale-105"
|
|
/>
|
|
<Link
|
|
href={route('memes.show', meme.slug)}
|
|
className="bg-opacity-0 absolute inset-0 flex items-center justify-center transition-all group-hover:opacity-40 hover:bg-black"
|
|
>
|
|
<Edit className="h-8 w-8 text-white opacity-0 transition-opacity group-hover:opacity-100" />
|
|
</Link>
|
|
</div>
|
|
<div className="flex flex-grow flex-col px-4 pt-0 pb-4">
|
|
<h3 className="text-foreground mb-2 line-clamp-2 text-sm font-semibold">{meme.name}</h3>
|
|
{showKeywords && (
|
|
<div className="mb-3 flex flex-wrap gap-1">
|
|
{meme.keywords?.slice(0, 6).map((keyword, index) => (
|
|
<KeywordBadge key={index} keyword={keyword} />
|
|
))}
|
|
{meme.keywords && meme.keywords.length > 6 && (
|
|
<Badge variant="secondary" className="text-xs">
|
|
+{meme.keywords.length - 6} more
|
|
</Badge>
|
|
)}
|
|
</div>
|
|
)}
|
|
{showButton && (
|
|
<div className="mt-auto">
|
|
<Link href={route('memes.show', meme.slug)}>
|
|
<Button
|
|
size="sm"
|
|
className="w-full bg-gradient-to-r from-purple-600 to-pink-600 text-white hover:from-purple-700 hover:to-pink-700"
|
|
>
|
|
Use meme
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</Card>
|
|
);
|
|
} |