Files
MemeStudio/components/levels/level-card.tsx
richarjiang 4854f1cefc feat: initial project setup for Meme Studio
Next.js 14 App Router application for managing homophone pun game levels:

- Better Auth with Prisma adapter for authentication
- MySQL database with Prisma ORM
- Level CRUD operations with drag-and-drop reordering
- Tencent COS integration for image uploads
- shadcn/ui components with Tailwind CSS
- TanStack Query for server state management
2026-03-15 15:01:47 +08:00

79 lines
2.6 KiB
TypeScript

'use client'
import { Level } from '@/types'
import { Card, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { GripVertical, Pencil, Trash2 } from 'lucide-react'
import Image from 'next/image'
interface LevelCardProps {
level: Level
onEdit: (level: Level) => void
onDelete: (id: string) => void
isDragging?: boolean
}
export function LevelCard({ level, onEdit, onDelete, isDragging }: LevelCardProps) {
return (
<Card
className={`cursor-grab transition-shadow ${
isDragging ? 'shadow-lg opacity-90' : 'hover:shadow-md'
}`}
>
<CardContent className="p-4">
<div className="flex items-start gap-4">
<div className="flex items-center justify-center w-8 h-8 rounded bg-gray-100 text-gray-500 cursor-grab">
<GripVertical className="h-4 w-4" />
</div>
<div className="relative w-20 h-20 rounded-md overflow-hidden bg-gray-100 flex-shrink-0">
{level.imageUrl ? (
<Image
src={level.imageUrl}
alt="关卡图片"
fill
className="object-cover"
sizes="80px"
/>
) : (
<div className="w-full h-full flex items-center justify-center text-gray-400 text-xs">
</div>
)}
</div>
<div className="flex-1 min-w-0">
<p className="font-medium text-lg truncate">{level.answer}</p>
<div className="mt-1 space-y-0.5">
{level.hint1 && (
<p className="text-sm text-gray-500 truncate">1: {level.hint1}</p>
)}
{level.hint2 && (
<p className="text-sm text-gray-500 truncate">2: {level.hint2}</p>
)}
{level.hint3 && (
<p className="text-sm text-gray-500 truncate">3: {level.hint3}</p>
)}
</div>
</div>
<div className="flex items-center gap-2">
<Button
variant="outline"
size="icon"
onClick={() => onEdit(level)}
>
<Pencil className="h-4 w-4" />
</Button>
<Button
variant="outline"
size="icon"
onClick={() => onDelete(level.id)}
className="text-red-600 hover:text-red-700 hover:bg-red-50"
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
</div>
</CardContent>
</Card>
)
}