+ {/* ===== Header ===== */}
+
+
+
+
+
+ 입고 장바구니
+
+ {supplierName && (
+
{supplierName}
+ )}
+
+
+
+ {/* Confirm button (header) */}
+
+
+
+ {/* ===== Info banner ===== */}
+
+
+ {supplierName && (
+
+ {supplierName}
+
+ )}
+
+ {inboundDate}
+
+ {selectedWarehouseName && (
+
+ | {selectedWarehouseName}
+
+ )}
+ {inboundNumber && (
+
+ {inboundNumber}
+
+ )}
+
+
+ {/* Info fields: 3 columns */}
+
+ {/* Inbound date */}
+
+
+ setInboundDate(e.target.value)}
+ className="w-full px-3 py-2.5 border border-gray-200 rounded-lg text-sm outline-none focus:border-blue-400 focus:ring-1 focus:ring-blue-100 bg-white"
+ />
+
+
+ {/* Warehouse selector - card-style touch button */}
+
+
+
+
+
+ {/* Inbound number (readonly) */}
+
+
+
+ {inboundNumber || "자동 채번"}
+
+
+
+
+
+ {/* ===== Select all bar ===== */}
+ {items.length > 0 && (
+
+
+
+
+ 담은 품목{" "}
+ {items.length}
+
+
+
+
+
+ )}
+
+ {/* ===== Items list ===== */}
+ {loading ? (
+
+ ) : items.length === 0 ? (
+
+
+
+ 담은 품목이 없습니다
+
+
+ 구매입고 화면에서 품목을 담아주세요
+
+
+
+ ) : (
+
+ {items.map((item) => (
+
+ {/* Top row: checkbox + item info + delete */}
+
+ {/* Checkbox */}
+
+
+ {/* Product image placeholder */}
+
+ {"\uD83D\uDCE6"}
+
+
+
+
+
+ {item.item_code}
+
+
+
+ {item.item_name}
+
+ {(item.spec || item.material) && (
+
+ {[item.spec, item.material].filter(Boolean).join(" | ")}
+
+ )}
+ {item.purchase_no && (
+
+ {item.purchase_no}
+ {item.order_date ? ` | ${item.order_date}` : ""}
+
+ )}
+
+
+ {/* Delete button */}
+
+
+
+ {/* Qty row: remain info + qty edit button */}
+
+
+
+ 미입고{" "}
+
+ {item.remain_qty.toLocaleString()}
+
+
+ {item.unit_price > 0 && (
+
+ | @{item.unit_price.toLocaleString()}원
+
+ )}
+
+
+ {/* Qty button (opens numpad) */}
+
+
+
+ {/* Package info */}
+ {item.packages && item.packages.length > 0 && (
+
+
+
+ 포장완료
+
+
+ {"\uD83D\uDCE6"}{" "}
+ {item.packages
+ .map(
+ (p) =>
+ `${p.count}${p.unit.label} x ${p.qtyPerUnit.toLocaleString()} = ${(
+ p.count * p.qtyPerUnit
+ ).toLocaleString()}EA`
+ )
+ .join(", ")}
+
+
+
+ )}
+
+ {/* Inspection row */}
+ {(item.inspection_type === "self" ||
+ item.inspection_type === "request") && (
+
+
+
+
+ {/* Pass button for non-required */}
+ {!item.inspection_required &&
+ !item.inspectionResult?.completed && (
+
+ )}
+
+
+ )}
+
+ ))}
+
+ )}
+
+ {/* ===== Footer summary + confirm ===== */}
+ {items.length > 0 && (
+
+ {/* Result message */}
+ {resultMsg && (
+
+ {resultMsg}
+
+ )}
+
+ {/* Required inspection warning */}
+ {hasUnfinishedRequiredInspection && (
+
+ 필수 검사를 완료해주세요. 검사 미완료 품목이 있어 확정할 수 없습니다.
+
+ )}
+
+ {/* Summary */}
+
+
+ 선택{" "}
+
+ {selectedItemsList.length}
+
+ /{items.length}건
+
+
+ 합계 수량:{" "}
+
+ {totalQty.toLocaleString()}
+ {" "}
+ EA
+
+
+
+ {/* Confirm button (footer) */}
+
+
+ )}
+
+ {/* ===== Warehouse picker modal ===== */}
+ {warehousePickerOpen && (
+
+
setWarehousePickerOpen(false)}
+ />
+
+ {/* Header */}
+
+
창고 선택
+
+
+
+ {/* Warehouse list */}
+
+ {warehouses.length === 0 ? (
+
+ 등록된 창고가 없습니다
+
+ ) : (
+
+ {warehouses.map((wh) => (
+
+ ))}
+
+ )}
+
+
+
+ )}
+
+ {/* ===== Inspection Modal ===== */}
+ {inspectionTarget && (
+
{
+ setInspectionModalOpen(false);
+ setInspectionTarget(null);
+ }}
+ onComplete={handleInspectionComplete}
+ itemCode={inspectionTarget.item_code}
+ itemName={inspectionTarget.item_name}
+ totalQty={inspectionTarget.inbound_qty}
+ initialResult={inspectionTarget.inspectionResult}
+ />
+ )}
+
+ {/* ===== NumberPad Modal (qty edit) ===== */}
+ {numpadTarget && (
+ {
+ setNumpadOpen(false);
+ setNumpadTarget(null);
+ }}
+ onConfirm={handleNumpadConfirm}
+ maxQty={numpadTarget.remain_qty}
+ itemName={numpadTarget.item_name}
+ initialQty={numpadTarget.inbound_qty}
+ initialPackages={numpadTarget.packages}
+ />
+ )}
+
+ );
+}
diff --git a/frontend/components/pop/hardcoded/inbound/PurchaseInbound.tsx b/frontend/components/pop/hardcoded/inbound/PurchaseInbound.tsx
index 6cf00c13..ec39f9cd 100644
--- a/frontend/components/pop/hardcoded/inbound/PurchaseInbound.tsx
+++ b/frontend/components/pop/hardcoded/inbound/PurchaseInbound.tsx
@@ -4,7 +4,7 @@ import React, { useState, useCallback, useEffect, useMemo, useRef } from "react"
import { useRouter } from "next/navigation";
import { apiClient } from "@/lib/api/client";
import { SupplierModal, type Supplier, matchChosung } from "./SupplierModal";
-import { InboundCart, type CartItem } from "./InboundCart";
+import type { CartItem } from "./InboundCart";
import { NumberPadModal, type PackageEntry } from "./NumberPadModal";
import { BarcodeScanModal } from "../common/BarcodeScanModal";
@@ -86,19 +86,14 @@ const DUMMY_ORDERS: PurchaseOrder[] = [
interface PurchaseInboundProps {
onCartCountChange?: (count: number) => void;
- externalCartOpen?: boolean;
- onExternalCartClose?: () => void;
}
-export function PurchaseInbound({ onCartCountChange, externalCartOpen, onExternalCartClose }: PurchaseInboundProps = {}) {
+export function PurchaseInbound({ onCartCountChange }: PurchaseInboundProps = {}) {
const router = useRouter();
/* State */
const [selectedSupplier, setSelectedSupplier] = useState
(null);
const [supplierModalOpen, setSupplierModalOpen] = useState(false);
- const [_cartOpen, _setCartOpen] = useState(false);
- const cartOpen = externalCartOpen || _cartOpen;
- const setCartOpen = (v: boolean) => { _setCartOpen(v); if (!v && onExternalCartClose) onExternalCartClose(); };
const [cartItems, _setCartItems] = useState([]);
const setCartItems: typeof _setCartItems = (val) => {
_setCartItems(val);
@@ -300,14 +295,13 @@ export function PurchaseInbound({ onCartCountChange, externalCartOpen, onExterna
/* Remove from cart (cancel) */
const handleRemoveFromCart = (id: string) => {
setCartItems((prev) => prev.filter((c) => c.id !== id));
- };
-
- /* Cart operations */
- const handleUpdateCartQty = (id: string, qty: number) => {
- setCartItems((prev) => prev.map((c) => c.id === id ? { ...c, inbound_qty: qty } : c));
- };
- const handleClearCart = () => {
- setCartItems([]);
+ // Delete from cart_items DB (background)
+ apiClient.post("/pop/execute-action", {
+ tasks: [{ type: "cart-save" }],
+ cartChanges: {
+ toDelete: [id],
+ },
+ }).catch(() => {});
};
/* Search */
@@ -617,17 +611,6 @@ export function PurchaseInbound({ onCartCountChange, externalCartOpen, onExterna
onSelect={(s) => setSelectedSupplier(s)}
/>
- setCartOpen(false)}
- items={cartItems}
- onUpdateQty={handleUpdateCartQty}
- onRemove={handleRemoveFromCart}
- onClear={handleClearCart}
- supplierName={selectedSupplier?.customer_name}
- onUpdateItems={setCartItems}
- />
-
{ setNumpadOpen(false); setNumpadTarget(null); }}
diff --git a/frontend/components/pop/hardcoded/inbound/index.ts b/frontend/components/pop/hardcoded/inbound/index.ts
index 88b57e34..b4272e78 100644
--- a/frontend/components/pop/hardcoded/inbound/index.ts
+++ b/frontend/components/pop/hardcoded/inbound/index.ts
@@ -5,3 +5,4 @@ export { InboundCart } from "./InboundCart";
export { NumberPadModal } from "./NumberPadModal";
export { PackagingModal } from "./PackagingModal";
export { InspectionModal } from "./InspectionModal";
+export { InboundCartPage } from "./InboundCartPage";