샤드시옌으로 쫙 수정

This commit is contained in:
leeheejin
2025-10-29 17:53:03 +09:00
parent 2517261db9
commit 437e0c331c
87 changed files with 1493 additions and 1491 deletions

View File

@@ -26,124 +26,124 @@ import {
// 위젯 동적 임포트
const WeatherWidget = dynamic(() => import("@/components/dashboard/widgets/WeatherWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
const ExchangeWidget = dynamic(() => import("@/components/dashboard/widgets/ExchangeWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
const CalculatorWidget = dynamic(() => import("@/components/dashboard/widgets/CalculatorWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
const VehicleStatusWidget = dynamic(() => import("@/components/dashboard/widgets/VehicleStatusWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
const VehicleListWidget = dynamic(() => import("@/components/dashboard/widgets/VehicleListWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
const VehicleMapOnlyWidget = dynamic(() => import("@/components/dashboard/widgets/VehicleMapOnlyWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
// 범용 지도 위젯 (차량, 창고, 고객 등 모든 위치 위젯 통합)
const MapSummaryWidget = dynamic(() => import("@/components/dashboard/widgets/MapSummaryWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
// 🧪 테스트용 지도 위젯 (REST API 지원)
const MapTestWidget = dynamic(() => import("@/components/dashboard/widgets/MapTestWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
// 🧪 테스트용 지도 위젯 V2 (다중 데이터 소스)
const MapTestWidgetV2 = dynamic(() => import("@/components/dashboard/widgets/MapTestWidgetV2"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
// 🧪 테스트용 차트 위젯 (다중 데이터 소스)
const ChartTestWidget = dynamic(() => import("@/components/dashboard/widgets/ChartTestWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
const ListTestWidget = dynamic(
() => import("@/components/dashboard/widgets/ListTestWidget").then((mod) => ({ default: mod.ListTestWidget })),
{
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
},
);
const CustomMetricTestWidget = dynamic(() => import("@/components/dashboard/widgets/CustomMetricTestWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
const RiskAlertTestWidget = dynamic(() => import("@/components/dashboard/widgets/RiskAlertTestWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
// 범용 상태 요약 위젯 (차량, 배송 등 모든 상태 위젯 통합)
const StatusSummaryWidget = dynamic(() => import("@/components/dashboard/widgets/StatusSummaryWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
// 범용 목록 위젯 (차량, 기사, 제품 등 모든 목록 위젯 통합) - 다른 분 작업 중, 임시 주석
/* const ListSummaryWidget = dynamic(() => import("@/components/dashboard/widgets/ListSummaryWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500">로딩 중...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
}); */
// 개별 위젯들 (주석 처리 - StatusSummaryWidget으로 통합됨)
// const DeliveryStatusSummaryWidget = dynamic(() => import("@/components/dashboard/widgets/DeliveryStatusSummaryWidget"), {
// ssr: false,
// loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500">로딩 중...</div>,
// loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
// });
// const DeliveryTodayStatsWidget = dynamic(() => import("@/components/dashboard/widgets/DeliveryTodayStatsWidget"), {
// ssr: false,
// loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500">로딩 중...</div>,
// loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
// });
// const CargoListWidget = dynamic(() => import("@/components/dashboard/widgets/CargoListWidget"), {
// ssr: false,
// loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500">로딩 중...</div>,
// loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
// });
// const CustomerIssuesWidget = dynamic(() => import("@/components/dashboard/widgets/CustomerIssuesWidget"), {
// ssr: false,
// loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500">로딩 중...</div>,
// loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
// });
const RiskAlertWidget = dynamic(() => import("@/components/dashboard/widgets/RiskAlertWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
const TaskWidget = dynamic(() => import("@/components/dashboard/widgets/TaskWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
const BookingAlertWidget = dynamic(() => import("@/components/dashboard/widgets/BookingAlertWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
const DocumentWidget = dynamic(() => import("@/components/dashboard/widgets/DocumentWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
// 시계 위젯 임포트
@@ -160,25 +160,25 @@ import { Button } from "@/components/ui/button";
// 야드 관리 3D 위젯
const YardManagement3DWidget = dynamic(() => import("./widgets/YardManagement3DWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
// 작업 이력 위젯
const WorkHistoryWidget = dynamic(() => import("@/components/dashboard/widgets/WorkHistoryWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
// 커스텀 통계 카드 위젯
const CustomStatsWidget = dynamic(() => import("@/components/dashboard/widgets/CustomStatsWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
// 사용자 커스텀 카드 위젯
const CustomMetricWidget = dynamic(() => import("@/components/dashboard/widgets/CustomMetricWidget"), {
ssr: false,
loading: () => <div className="flex h-full items-center justify-center text-sm text-gray-500"> ...</div>,
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> ...</div>,
});
interface CanvasElementProps {
@@ -712,33 +712,33 @@ export function CanvasElement({
if (element.type === "chart") {
switch (element.subtype) {
case "bar":
return "bg-gradient-to-br from-indigo-400 to-purple-600";
return "bg-gradient-to-br from-primary to-purple-500";
case "pie":
return "bg-gradient-to-br from-pink-400 to-red-500";
return "bg-gradient-to-br from-destructive to-destructive/80";
case "line":
return "bg-gradient-to-br from-blue-400 to-cyan-400";
return "bg-gradient-to-br from-primary to-primary/80";
default:
return "bg-gray-200";
return "bg-muted";
}
} else if (element.type === "widget") {
switch (element.subtype) {
case "exchange":
return "bg-gradient-to-br from-pink-400 to-yellow-400";
return "bg-gradient-to-br from-warning to-warning/80";
case "weather":
return "bg-gradient-to-br from-cyan-400 to-indigo-800";
return "bg-gradient-to-br from-primary to-primary/80";
case "clock":
return "bg-gradient-to-br from-teal-400 to-cyan-600";
return "bg-gradient-to-br from-primary to-primary/80";
case "calendar":
return "bg-gradient-to-br from-indigo-400 to-purple-600";
return "bg-gradient-to-br from-primary to-purple-500";
case "driver-management":
return "bg-gradient-to-br from-blue-400 to-indigo-600";
return "bg-gradient-to-br from-primary to-primary";
case "list":
return "bg-gradient-to-br from-cyan-400 to-blue-600";
return "bg-gradient-to-br from-primary to-primary/80";
default:
return "bg-gray-200";
return "bg-muted";
}
}
return "bg-gray-200";
return "bg-muted";
};
// 드래그/리사이즈 중일 때는 임시 위치/크기 사용, 아니면 실제 값 사용
@@ -758,7 +758,7 @@ export function CanvasElement({
<div
ref={elementRef}
data-element-id={element.id}
className={`absolute min-h-[120px] min-w-[120px] cursor-move overflow-hidden rounded-lg border-2 bg-white shadow-lg ${isSelected ? "border-blue-500 shadow-blue-200" : "border-gray-400"} ${isDragging || isResizing ? "transition-none" : "transition-all duration-150"} `}
className={`absolute min-h-[120px] min-w-[120px] cursor-move overflow-hidden rounded-lg border-2 bg-background shadow-lg ${isSelected ? "border-primary ring-2 ring-primary/20" : "border-border"} ${isDragging || isResizing ? "transition-none" : "transition-all duration-150"} `}
style={{
left: displayPosition.x,
top: displayPosition.y,
@@ -809,7 +809,7 @@ export function CanvasElement({
)}
{/* 제목 */}
{!element.type || element.type !== "chart" ? (
<span className="text-xs font-bold text-gray-800">{element.customTitle || element.title}</span>
<span className="text-xs font-bold text-foreground">{element.customTitle || element.title}</span>
) : null}
</div>
<div className="flex gap-1">
@@ -817,7 +817,7 @@ export function CanvasElement({
<Button
variant="ghost"
size="icon"
className="element-close hover:bg-destructive h-5 w-5 text-gray-400 hover:text-white"
className="element-close hover:bg-destructive h-5 w-5 text-muted-foreground hover:text-white"
onClick={handleRemove}
onMouseDown={(e) => e.stopPropagation()}
title="삭제"
@@ -831,9 +831,9 @@ export function CanvasElement({
<div className="relative h-[calc(100%-32px)] px-2 pb-2">
{element.type === "chart" ? (
// 차트 렌더링
<div className="h-full w-full bg-white">
<div className="h-full w-full bg-background">
{isLoadingData ? (
<div className="flex h-full w-full items-center justify-center text-gray-500">
<div className="flex h-full w-full items-center justify-center text-muted-foreground">
<div className="text-center">
<div className="border-primary mx-auto mb-2 h-6 w-6 animate-spin rounded-full border-2 border-t-transparent" />
<div className="text-sm"> ...</div>
@@ -926,7 +926,7 @@ export function CanvasElement({
) : element.type === "widget" && element.subtype === "status-summary" ? (
// 커스텀 상태 카드 - 범용 위젯
<div className="widget-interactive-area h-full w-full">
<StatusSummaryWidget element={element} title="상태 요약" icon="📊" bgGradient="from-slate-50 to-blue-50" />
<StatusSummaryWidget element={element} title="상태 요약" icon="📊" bgGradient="from-background to-primary/10" />
</div>
) : /* element.type === "widget" && element.subtype === "list-summary" ? (
// 커스텀 목록 카드 - 범용 위젯 (다른 분 작업 중 - 임시 주석)
@@ -940,7 +940,7 @@ export function CanvasElement({
element={element}
title="배송/화물 현황"
icon="📦"
bgGradient="from-slate-50 to-blue-50"
bgGradient="from-background to-primary/10"
/>
</div>
) : element.type === "widget" && element.subtype === "delivery-status-summary" ? (
@@ -950,7 +950,7 @@ export function CanvasElement({
element={element}
title="배송 상태 요약"
icon="📊"
bgGradient="from-slate-50 to-blue-50"
bgGradient="from-background to-primary/10"
statusConfig={{
: { label: "배송중", color: "blue" },
: { label: "완료", color: "green" },
@@ -966,7 +966,7 @@ export function CanvasElement({
element={element}
title="오늘 처리 현황"
icon="📈"
bgGradient="from-slate-50 to-green-50"
bgGradient="from-background to-success/10"
/>
</div>
) : element.type === "widget" && element.subtype === "cargo-list" ? (
@@ -976,7 +976,7 @@ export function CanvasElement({
element={element}
title="화물 목록"
icon="📦"
bgGradient="from-slate-50 to-orange-50"
bgGradient="from-background to-warning/10"
/>
</div>
) : element.type === "widget" && element.subtype === "customer-issues" ? (
@@ -986,7 +986,7 @@ export function CanvasElement({
element={element}
title="고객 클레임/이슈"
icon="⚠️"
bgGradient="from-slate-50 to-red-50"
bgGradient="from-background to-destructive/10"
/>
</div>
) : element.type === "widget" && element.subtype === "risk-alert" ? (
@@ -1111,7 +1111,7 @@ function ResizeHandle({ position, onMouseDown }: ResizeHandleProps) {
return (
<div
className={`resize-handle absolute h-3 w-3 border border-white bg-green-500 ${getPositionClass()} `}
className={`resize-handle absolute h-3 w-3 border border-white bg-success ${getPositionClass()} `}
onMouseDown={(e) => onMouseDown(e, position)}
/>
);