파일 업로드 구조 개선
This commit is contained in:
@@ -26,80 +26,108 @@ import {
|
||||
// 위젯 동적 임포트
|
||||
const WeatherWidget = dynamic(() => import("@/components/dashboard/widgets/WeatherWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
const ExchangeWidget = dynamic(() => import("@/components/dashboard/widgets/ExchangeWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
const CalculatorWidget = dynamic(() => import("@/components/dashboard/widgets/CalculatorWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
const VehicleStatusWidget = dynamic(() => import("@/components/dashboard/widgets/VehicleStatusWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
const VehicleListWidget = dynamic(() => import("@/components/dashboard/widgets/VehicleListWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
const VehicleMapOnlyWidget = dynamic(() => import("@/components/dashboard/widgets/VehicleMapOnlyWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
// 범용 지도 위젯 (차량, 창고, 고객 등 모든 위치 위젯 통합)
|
||||
const MapSummaryWidget = dynamic(() => import("@/components/dashboard/widgets/MapSummaryWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</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-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</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-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
// 🧪 테스트용 차트 위젯 (다중 데이터 소스)
|
||||
const ChartTestWidget = dynamic(() => import("@/components/dashboard/widgets/ChartTestWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</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-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
const CustomMetricTestWidget = dynamic(() => import("@/components/dashboard/widgets/CustomMetricTestWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
const RiskAlertTestWidget = dynamic(() => import("@/components/dashboard/widgets/RiskAlertTestWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
// 범용 상태 요약 위젯 (차량, 배송 등 모든 상태 위젯 통합)
|
||||
const StatusSummaryWidget = dynamic(() => import("@/components/dashboard/widgets/StatusSummaryWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
// 범용 목록 위젯 (차량, 기사, 제품 등 모든 목록 위젯 통합) - 다른 분 작업 중, 임시 주석
|
||||
@@ -128,22 +156,30 @@ const StatusSummaryWidget = dynamic(() => import("@/components/dashboard/widgets
|
||||
|
||||
const RiskAlertWidget = dynamic(() => import("@/components/dashboard/widgets/RiskAlertWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
const TaskWidget = dynamic(() => import("@/components/dashboard/widgets/TaskWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
const BookingAlertWidget = dynamic(() => import("@/components/dashboard/widgets/BookingAlertWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
const DocumentWidget = dynamic(() => import("@/components/dashboard/widgets/DocumentWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
// 시계 위젯 임포트
|
||||
@@ -160,25 +196,33 @@ 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-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
// 작업 이력 위젯
|
||||
const WorkHistoryWidget = dynamic(() => import("@/components/dashboard/widgets/WorkHistoryWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
// 커스텀 통계 카드 위젯
|
||||
const CustomStatsWidget = dynamic(() => import("@/components/dashboard/widgets/CustomStatsWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
// 사용자 커스텀 카드 위젯
|
||||
const CustomMetricWidget = dynamic(() => import("@/components/dashboard/widgets/CustomMetricWidget"), {
|
||||
ssr: false,
|
||||
loading: () => <div className="flex h-full items-center justify-center text-sm text-muted-foreground">로딩 중...</div>,
|
||||
loading: () => (
|
||||
<div className="text-muted-foreground flex h-full items-center justify-center text-sm">로딩 중...</div>
|
||||
),
|
||||
});
|
||||
|
||||
interface CanvasElementProps {
|
||||
@@ -758,7 +802,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-background shadow-lg ${isSelected ? "border-primary ring-2 ring-primary/20" : "border-border"} ${isDragging || isResizing ? "transition-none" : "transition-all duration-150"} `}
|
||||
className={`bg-background absolute min-h-[120px] min-w-[120px] cursor-move overflow-hidden rounded-lg border-2 shadow-lg ${isSelected ? "border-primary ring-primary/20 ring-2" : "border-border"} ${isDragging || isResizing ? "transition-none" : "transition-all duration-150"} `}
|
||||
style={{
|
||||
left: displayPosition.x,
|
||||
top: displayPosition.y,
|
||||
@@ -809,7 +853,7 @@ export function CanvasElement({
|
||||
)}
|
||||
{/* 제목 */}
|
||||
{!element.type || element.type !== "chart" ? (
|
||||
<span className="text-xs font-bold text-foreground">{element.customTitle || element.title}</span>
|
||||
<span className="text-foreground text-xs font-bold">{element.customTitle || element.title}</span>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="flex gap-1">
|
||||
@@ -817,7 +861,7 @@ export function CanvasElement({
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="element-close hover:bg-destructive h-5 w-5 text-muted-foreground hover:text-white"
|
||||
className="element-close hover:bg-destructive text-muted-foreground h-5 w-5 hover:text-white"
|
||||
onClick={handleRemove}
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
title="삭제"
|
||||
@@ -831,9 +875,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-background">
|
||||
<div className="bg-background h-full w-full">
|
||||
{isLoadingData ? (
|
||||
<div className="flex h-full w-full items-center justify-center text-muted-foreground">
|
||||
<div className="text-muted-foreground flex h-full w-full items-center justify-center">
|
||||
<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>
|
||||
@@ -921,7 +965,12 @@ 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-background to-primary/10" />
|
||||
<StatusSummaryWidget
|
||||
element={element}
|
||||
title="상태 요약"
|
||||
icon="📊"
|
||||
bgGradient="from-background to-primary/10"
|
||||
/>
|
||||
</div>
|
||||
) : /* element.type === "widget" && element.subtype === "list-summary" ? (
|
||||
// 커스텀 목록 카드 - 범용 위젯 (다른 분 작업 중 - 임시 주석)
|
||||
@@ -1106,7 +1155,7 @@ function ResizeHandle({ position, onMouseDown }: ResizeHandleProps) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`resize-handle absolute h-3 w-3 border border-white bg-success ${getPositionClass()} `}
|
||||
className={`resize-handle bg-success absolute h-3 w-3 border border-white ${getPositionClass()} `}
|
||||
onMouseDown={(e) => onMouseDown(e, position)}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user