'use client'
import { useState, useCallback } from 'react'
import { Level } from '@/types'
import {
DndContext,
closestCenter,
KeyboardSensor,
PointerSensor,
useSensor,
useSensors,
DragEndEvent,
} from '@dnd-kit/core'
import {
arrayMove,
SortableContext,
sortableKeyboardCoordinates,
verticalListSortingStrategy,
useSortable,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { LevelCard } from './level-card'
interface SortableLevelCardProps {
level: Level
onEdit: (level: Level) => void
onDelete: (id: string) => void
}
function SortableLevelCard({ level, onEdit, onDelete }: SortableLevelCardProps) {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
isDragging,
} = useSortable({ id: level.id })
const style = {
transform: CSS.Transform.toString(transform),
transition,
}
return (
)
}
interface LevelListProps {
levels: Level[]
onReorder: (orders: { id: string; sortOrder: number }[]) => void
onEdit: (level: Level) => void
onDelete: (id: string) => void
}
export function LevelList({ levels, onReorder, onEdit, onDelete }: LevelListProps) {
const [items, setItems] = useState(levels)
// Update items when levels prop changes
if (JSON.stringify(items.map(i => i.id)) !== JSON.stringify(levels.map(l => l.id))) {
setItems(levels)
}
const sensors = useSensors(
useSensor(PointerSensor, {
activationConstraint: {
distance: 8,
},
}),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
)
const handleDragEnd = useCallback(
(event: DragEndEvent) => {
const { active, over } = event
if (over && active.id !== over.id) {
const oldIndex = items.findIndex((item) => item.id === active.id)
const newIndex = items.findIndex((item) => item.id === over.id)
const newItems = arrayMove(items, oldIndex, newIndex)
setItems(newItems)
// Notify parent of new order
const orders = newItems.map((item, index) => ({
id: item.id,
sortOrder: index,
}))
onReorder(orders)
}
},
[items, onReorder]
)
if (items.length === 0) {
return (
暂无关卡数据
点击上方“添加关卡”按钮创建第一个关卡
)
}
return (
{items.map((level) => (
))}
)
}