75 lines
2.6 KiB
TypeScript
75 lines
2.6 KiB
TypeScript
"use client";
|
|
|
|
import { useDrag } from "react-dnd";
|
|
import {
|
|
Type, CreditCard, Minus, Tag,
|
|
ImageIcon, Hash, Calendar, Link2, Circle, Space, FileText,
|
|
} from "lucide-react";
|
|
import type { CardElementType } from "@/types/report";
|
|
|
|
interface CardElementItem {
|
|
type: CardElementType;
|
|
label: string;
|
|
icon: React.ReactNode;
|
|
}
|
|
|
|
const CARD_ELEMENTS: CardElementItem[] = [
|
|
{ type: "header", label: "헤더", icon: <Type className="h-4 w-4" /> },
|
|
{ type: "dataCell", label: "데이터 셀", icon: <CreditCard className="h-4 w-4" /> },
|
|
{ type: "divider", label: "구분선", icon: <Minus className="h-4 w-4" /> },
|
|
{ type: "badge", label: "뱃지", icon: <Tag className="h-4 w-4" /> },
|
|
{ type: "image", label: "이미지", icon: <ImageIcon className="h-4 w-4" /> },
|
|
{ type: "number", label: "숫자/금액", icon: <Hash className="h-4 w-4" /> },
|
|
{ type: "date", label: "날짜", icon: <Calendar className="h-4 w-4" /> },
|
|
{ type: "link", label: "링크", icon: <Link2 className="h-4 w-4" /> },
|
|
{ type: "status", label: "상태", icon: <Circle className="h-4 w-4" /> },
|
|
{ type: "spacer", label: "빈 공간", icon: <Space className="h-4 w-4" /> },
|
|
{ type: "staticText", label: "고정 텍스트", icon: <FileText className="h-4 w-4" /> },
|
|
];
|
|
|
|
export const CARD_ELEMENT_DND_TYPE = "card-element";
|
|
|
|
interface DraggableElementProps {
|
|
type: CardElementType;
|
|
label: string;
|
|
icon: React.ReactNode;
|
|
}
|
|
|
|
function DraggableElement({ type, label, icon }: DraggableElementProps) {
|
|
const [{ isDragging }, drag] = useDrag(() => ({
|
|
type: CARD_ELEMENT_DND_TYPE,
|
|
item: { elementType: type },
|
|
collect: (monitor) => ({
|
|
isDragging: monitor.isDragging(),
|
|
}),
|
|
}));
|
|
|
|
return (
|
|
<div
|
|
ref={drag}
|
|
className={`flex cursor-move flex-col items-center justify-center gap-1 rounded-lg border border-gray-200 bg-gray-50 px-3 py-2 transition-colors hover:border-blue-400 hover:bg-blue-50 ${
|
|
isDragging ? "opacity-50" : ""
|
|
}`}
|
|
>
|
|
<div className="text-gray-600">{icon}</div>
|
|
<span className="text-xs font-medium text-gray-700">{label}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function CardElementPalette() {
|
|
return (
|
|
<div className="bg-white border border-border rounded-xl p-4">
|
|
<div className="text-sm font-bold text-gray-800 mb-3">
|
|
요소 팔레트
|
|
<span className="ml-2 text-xs font-normal text-muted-foreground">드래그하여 추가</span>
|
|
</div>
|
|
<div className="grid grid-cols-4 gap-2">
|
|
{CARD_ELEMENTS.map((item) => (
|
|
<DraggableElement key={item.type} {...item} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|