248 lines
7.5 KiB
TypeScript
248 lines
7.5 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import { DragData, ElementType, ElementSubtype } from "./types";
|
|
|
|
/**
|
|
* 대시보드 사이드바 컴포넌트
|
|
* - 드래그 가능한 차트/위젯 목록
|
|
* - 카테고리별 구분
|
|
*/
|
|
export function DashboardSidebar() {
|
|
// 드래그 시작 처리
|
|
const handleDragStart = (e: React.DragEvent, type: ElementType, subtype: ElementSubtype) => {
|
|
const dragData: DragData = { type, subtype };
|
|
e.dataTransfer.setData("application/json", JSON.stringify(dragData));
|
|
e.dataTransfer.effectAllowed = "copy";
|
|
};
|
|
|
|
return (
|
|
<div className="w-[370px] overflow-y-auto border-l border-gray-200 bg-white p-6">
|
|
{/* 차트 섹션 */}
|
|
<div className="mb-8">
|
|
<h3 className="mb-4 border-b-2 border-green-500 pb-3 text-lg font-semibold text-gray-800">📊 차트 종류</h3>
|
|
|
|
<div className="space-y-3">
|
|
<DraggableItem
|
|
icon="📊"
|
|
title="바 차트"
|
|
type="chart"
|
|
subtype="bar"
|
|
onDragStart={handleDragStart}
|
|
className="border-primary border-l-4"
|
|
/>
|
|
<DraggableItem
|
|
icon="📊"
|
|
title="수평 바 차트"
|
|
type="chart"
|
|
subtype="horizontal-bar"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-blue-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="📚"
|
|
title="누적 바 차트"
|
|
type="chart"
|
|
subtype="stacked-bar"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-blue-600"
|
|
/>
|
|
<DraggableItem
|
|
icon="📈"
|
|
title="꺾은선 차트"
|
|
type="chart"
|
|
subtype="line"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-green-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="📉"
|
|
title="영역 차트"
|
|
type="chart"
|
|
subtype="area"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-green-600"
|
|
/>
|
|
<DraggableItem
|
|
icon="🥧"
|
|
title="원형 차트"
|
|
type="chart"
|
|
subtype="pie"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-purple-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="🍩"
|
|
title="도넛 차트"
|
|
type="chart"
|
|
subtype="donut"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-purple-600"
|
|
/>
|
|
<DraggableItem
|
|
icon="📊📈"
|
|
title="콤보 차트"
|
|
type="chart"
|
|
subtype="combo"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-indigo-500"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 위젯 섹션 */}
|
|
<div className="mb-8">
|
|
<h3 className="mb-4 border-b-2 border-green-500 pb-3 text-lg font-semibold text-gray-800">🔧 위젯 종류</h3>
|
|
|
|
<div className="space-y-3">
|
|
<DraggableItem
|
|
icon="💱"
|
|
title="환율 위젯"
|
|
type="widget"
|
|
subtype="exchange"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-orange-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="☁️"
|
|
title="날씨 위젯"
|
|
type="widget"
|
|
subtype="weather"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-cyan-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="🧮"
|
|
title="계산기 위젯"
|
|
type="widget"
|
|
subtype="calculator"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-green-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="⏰"
|
|
title="시계 위젯"
|
|
type="widget"
|
|
subtype="clock"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-teal-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="🚚"
|
|
title="차량 위치 지도"
|
|
type="widget"
|
|
subtype="vehicle-map"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-red-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="📦"
|
|
title="배송/화물 현황"
|
|
type="widget"
|
|
subtype="delivery-status"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-amber-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="⚠️"
|
|
title="리스크/알림 위젯"
|
|
type="widget"
|
|
subtype="risk-alert"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-rose-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="📅"
|
|
title="달력 위젯"
|
|
type="widget"
|
|
subtype="calendar"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-indigo-500"
|
|
/>
|
|
<DraggableItem
|
|
icon="🚗"
|
|
title="기사 관리 위젯"
|
|
type="widget"
|
|
subtype="driver-management"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-blue-500"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 운영/작업 지원 섹션 */}
|
|
<div className="mb-8">
|
|
<h3 className="mb-4 border-b-2 border-green-500 pb-3 text-lg font-semibold text-gray-800">📋 운영/작업 지원</h3>
|
|
|
|
<div className="space-y-3">
|
|
<DraggableItem
|
|
icon="✅"
|
|
title="To-Do / 긴급 지시"
|
|
type="widget"
|
|
subtype="todo"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-blue-600"
|
|
/>
|
|
<DraggableItem
|
|
icon="🔔"
|
|
title="예약 요청 알림"
|
|
type="widget"
|
|
subtype="booking-alert"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-rose-600"
|
|
/>
|
|
<DraggableItem
|
|
icon="🔧"
|
|
title="정비 일정 관리"
|
|
type="widget"
|
|
subtype="maintenance"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-teal-600"
|
|
/>
|
|
<DraggableItem
|
|
icon="📂"
|
|
title="문서 다운로드"
|
|
type="widget"
|
|
subtype="document"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-purple-600"
|
|
/>
|
|
<DraggableItem
|
|
icon="📋"
|
|
title="리스트 위젯"
|
|
type="widget"
|
|
subtype="list"
|
|
onDragStart={handleDragStart}
|
|
className="border-l-4 border-blue-600"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface DraggableItemProps {
|
|
icon: string;
|
|
title: string;
|
|
type: ElementType;
|
|
subtype: ElementSubtype;
|
|
className?: string;
|
|
onDragStart: (e: React.DragEvent, type: ElementType, subtype: ElementSubtype) => void;
|
|
}
|
|
|
|
/**
|
|
* 드래그 가능한 아이템 컴포넌트
|
|
*/
|
|
function DraggableItem({ icon, title, type, subtype, className = "", onDragStart }: DraggableItemProps) {
|
|
return (
|
|
<div
|
|
draggable
|
|
className={`cursor-move rounded-lg border-2 border-gray-200 bg-white p-4 text-center text-sm font-medium transition-all duration-200 hover:translate-x-1 hover:border-green-500 hover:bg-gray-50 ${className} `}
|
|
onDragStart={(e) => onDragStart(e, type, subtype)}
|
|
>
|
|
<span className="mr-2 text-lg">{icon}</span>
|
|
{title}
|
|
</div>
|
|
);
|
|
}
|