feat: 입고 장바구니 독립 페이지 (/pop/inbound/cart)
- InboundCartPage: cart_items DB 영속 저장, 탭 이동해도 유지 - 상단: 입고일자(날짜피커) + 창고(터치선택) + 입고번호(자동채번) - 품목: 체크박스, 수량수정(키패드), 삭제, 포장정보 - 검사: 필수→완료필수, 비필수→패스버튼, 미완료시 확정차단 - 전량 입고 원칙: 불량 포함 전체 입고 (팀장 규칙) - PurchaseInbound: 장바구니 아이콘→독립페이지 이동 (모달 제거)
This commit is contained in:
12
frontend/app/(pop)/pop/inbound/cart/page.tsx
Normal file
12
frontend/app/(pop)/pop/inbound/cart/page.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { PopShell } from "@/components/pop/hardcoded";
|
||||
import { InboundCartPage } from "@/components/pop/hardcoded/inbound/InboundCartPage";
|
||||
|
||||
export default function InboundCartRoute() {
|
||||
return (
|
||||
<PopShell showBanner={false} title="입고 장바구니">
|
||||
<InboundCartPage />
|
||||
</PopShell>
|
||||
);
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { PopShell } from "@/components/pop/hardcoded";
|
||||
import { PurchaseInbound } from "@/components/pop/hardcoded/inbound";
|
||||
|
||||
export default function PurchaseInboundPage() {
|
||||
const router = useRouter();
|
||||
const [cartCount, setCartCount] = useState(0);
|
||||
const [openCart, setOpenCart] = useState(false);
|
||||
|
||||
return (
|
||||
<PopShell
|
||||
@@ -14,7 +15,7 @@ export default function PurchaseInboundPage() {
|
||||
title="구매입고"
|
||||
headerRight={
|
||||
<button
|
||||
onClick={() => setOpenCart(true)}
|
||||
onClick={() => router.push("/pop/inbound/cart")}
|
||||
className="relative w-11 h-11 rounded-xl bg-white/10 flex items-center justify-center text-white hover:bg-white/20 active:scale-95 transition-all"
|
||||
>
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
|
||||
@@ -30,8 +31,6 @@ export default function PurchaseInboundPage() {
|
||||
>
|
||||
<PurchaseInbound
|
||||
onCartCountChange={setCartCount}
|
||||
externalCartOpen={openCart}
|
||||
onExternalCartClose={() => setOpenCart(false)}
|
||||
/>
|
||||
</PopShell>
|
||||
);
|
||||
|
||||
1156
frontend/components/pop/hardcoded/inbound/InboundCartPage.tsx
Normal file
1156
frontend/components/pop/hardcoded/inbound/InboundCartPage.tsx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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<Supplier | null>(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<CartItem[]>([]);
|
||||
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)}
|
||||
/>
|
||||
|
||||
<InboundCart
|
||||
open={cartOpen}
|
||||
onClose={() => setCartOpen(false)}
|
||||
items={cartItems}
|
||||
onUpdateQty={handleUpdateCartQty}
|
||||
onRemove={handleRemoveFromCart}
|
||||
onClear={handleClearCart}
|
||||
supplierName={selectedSupplier?.customer_name}
|
||||
onUpdateItems={setCartItems}
|
||||
/>
|
||||
|
||||
<NumberPadModal
|
||||
open={numpadOpen}
|
||||
onClose={() => { setNumpadOpen(false); setNumpadTarget(null); }}
|
||||
|
||||
@@ -5,3 +5,4 @@ export { InboundCart } from "./InboundCart";
|
||||
export { NumberPadModal } from "./NumberPadModal";
|
||||
export { PackagingModal } from "./PackagingModal";
|
||||
export { InspectionModal } from "./InspectionModal";
|
||||
export { InboundCartPage } from "./InboundCartPage";
|
||||
|
||||
Reference in New Issue
Block a user