-
-
- setSafetyLeadTime(Number(e.target.value))} className="h-8 w-[100px] text-xs" min={0} max={10} />
-
setDisplayWeeks(Number(e.target.value))} className="h-8 w-[100px] text-xs" min={1} max={12} />
diff --git a/frontend/app/(main)/sales/claim/page.tsx b/frontend/app/(main)/sales/claim/page.tsx
index 12d37472..333e8fc6 100644
--- a/frontend/app/(main)/sales/claim/page.tsx
+++ b/frontend/app/(main)/sales/claim/page.tsx
@@ -62,9 +62,11 @@ import {
Check,
ChevronsUpDown,
Loader2,
+ FileSpreadsheet,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
+import { ExcelUploadModal } from "@/components/common/ExcelUploadModal";
// --- Types ---
type ClaimType = "불량" | "교환" | "반품" | "배송지연" | "기타";
@@ -94,57 +96,7 @@ interface SalesOrderOption {
status: string;
}
-// --- Sample Data ---
-const initialData: Claim[] = [
- {
- claimNo: "CLM-2025-004",
- claimDate: "2025-11-09",
- claimType: "불량",
- claimStatus: "접수",
- customerCode: "CUST-0001",
- customerName: "주식회사 코아스포트",
- managerName: "김철수",
- orderNo: "SO-2025-0102",
- claimContent: "제품 표면에 스크래치가 발견되었습니다.",
- processContent: "",
- },
- {
- claimNo: "CLM-2025-001",
- claimDate: "2025-01-05",
- claimType: "불량",
- claimStatus: "접수",
- customerCode: "CUST-0002",
- customerName: "(주)현상산업",
- managerName: "김철수",
- orderNo: "SO-2025-0102",
- claimContent: "제품 불량",
- processContent: "",
- },
- {
- claimNo: "CLM-2025-002",
- claimDate: "2025-01-04",
- claimType: "교환",
- claimStatus: "처리중",
- customerCode: "CUST-0003",
- customerName: "대한전섬",
- managerName: "이영희",
- orderNo: "SO-2025-0095",
- claimContent: "규격 불일치",
- processContent: "교환 진행 중",
- },
- {
- claimNo: "CLM-2025-003",
- claimDate: "2025-01-03",
- claimType: "반품",
- claimStatus: "완료",
- customerCode: "CUST-0004",
- customerName: "삼성전자",
- managerName: "박민수",
- orderNo: "SO-2024-1285",
- claimContent: "수량 초과 납품",
- processContent: "반품 완료",
- },
-];
+const initialData: Claim[] = [];
const getClaimTypeStyle = (type: ClaimType) => {
switch (type) {
@@ -193,6 +145,9 @@ export default function ClaimManagementPage() {
const [searchCustomer, setSearchCustomer] = useState("");
const [searchClaimNo, setSearchClaimNo] = useState("");
+ // 엑셀 업로드
+ const [excelUploadOpen, setExcelUploadOpen] = useState(false);
+
// 모달 상태
const [isModalOpen, setIsModalOpen] = useState(false);
const [isEditMode, setIsEditMode] = useState(false);
@@ -563,9 +518,14 @@ export default function ClaimManagementPage() {
{filteredData.length}건
-
+
+
+
+
@@ -1122,6 +1082,16 @@ export default function ClaimManagementPage() {
+
+ {/* 엑셀 업로드 모달 */}
+ {
+ // TODO: 클레임 테이블 API 연동 후 데이터 새로고침
+ }}
+ />
);
}
diff --git a/frontend/app/(main)/sales/shipping-order/page.tsx b/frontend/app/(main)/sales/shipping-order/page.tsx
index ff05ffac..8b2c0dea 100644
--- a/frontend/app/(main)/sales/shipping-order/page.tsx
+++ b/frontend/app/(main)/sales/shipping-order/page.tsx
@@ -12,7 +12,7 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogD
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";
-import { Plus, Trash2, RotateCcw, Save, X, ChevronDown, ChevronRight, ChevronLeft, Truck, Search, Loader2 } from "lucide-react";
+import { Plus, Trash2, RotateCcw, Save, X, ChevronDown, ChevronRight, ChevronLeft, Truck, Search, Loader2, FileSpreadsheet } from "lucide-react";
import { cn } from "@/lib/utils";
import { FormDatePicker } from "@/components/screen/filters/FormDatePicker";
import {
@@ -24,6 +24,7 @@ import {
getSalesOrderSource,
getItemSource,
} from "@/lib/api/shipping";
+import { ExcelUploadModal } from "@/components/common/ExcelUploadModal";
type DataSourceType = "shipmentPlan" | "salesOrder" | "itemInfo";
@@ -84,6 +85,9 @@ export default function ShippingOrderPage() {
const [searchDateFrom, setSearchDateFrom] = useState("");
const [searchDateTo, setSearchDateTo] = useState("");
+ // 엑셀 업로드
+ const [excelUploadOpen, setExcelUploadOpen] = useState(false);
+
// 모달
const [isModalOpen, setIsModalOpen] = useState(false);
const [isEditMode, setIsEditMode] = useState(false);
@@ -467,6 +471,9 @@ export default function ShippingOrderPage() {
{orders.length}건
);
}
diff --git a/frontend/app/(main)/screens/[screenId]/page.tsx b/frontend/app/(main)/screens/[screenId]/page.tsx
index efcef2a4..706703da 100644
--- a/frontend/app/(main)/screens/[screenId]/page.tsx
+++ b/frontend/app/(main)/screens/[screenId]/page.tsx
@@ -26,6 +26,9 @@ import { useScheduleGenerator, ScheduleConfirmDialog } from "@/lib/v2-core/servi
import { ResponsiveGridRenderer } from "@/components/screen/ResponsiveGridRenderer";
import { useTabId } from "@/contexts/TabIdContext";
import { useTabStore } from "@/stores/tabStore";
+import { FileSpreadsheet, Loader2 as ExcelLoader } from "lucide-react";
+import { MultiTableExcelUploadModal } from "@/components/common/MultiTableExcelUploadModal";
+import { autoDetectMultiTableConfig, TableChainConfig } from "@/lib/api/multiTableExcel";
export interface ScreenViewPageProps {
screenIdProp?: number;
@@ -96,6 +99,11 @@ function ScreenViewPage({ screenIdProp, menuObjidProp }: ScreenViewPageProps = {
// 데이터 전달에 의해 강제 활성화된 레이어 ID 목록
const [forceActivatedLayerIds, setForceActivatedLayerIds] = useState