// === Orders / Sales history === function OrdersScreen({ orders, setOrders, goto, ordersSource, ordersLoading, ordersError, ordersProgress, ordersDays, reloadOrders }) { const { PRODUCTS } = window.MOCK; const isLive = ordersSource === "live"; const [statusFilter, setStatusFilter] = useState("all"); const [search, setSearch] = useState(""); const [selected, setSelected] = useState(new Set()); const [expanded, setExpanded] = useState(new Set()); // 인라인 확장된 주문 id const toggleExpand = (id) => { setExpanded(prev => { const next = new Set(prev); if (next.has(id)) next.delete(id); else next.add(id); return next; }); }; const buildShippingText = (o) => { const lines = []; if (o.buyer) lines.push(o.buyer); if (o.phone) lines.push(o.phone); if (o.zipcode || o.address) lines.push((o.zipcode ? "[" + o.zipcode + "] " : "") + (o.address || "")); const itemSummary = (o.items || []).map(it => { const namePart = (it.name || it.pid) + (it.option ? " [" + it.option + "]" : ""); return namePart + " " + it.qty + "개"; }).join(", "); if (itemSummary) lines.push("[" + itemSummary + "]"); if (o.memo) lines.push("메모: " + o.memo); return lines.join("\n"); }; const copyShipping = async (o) => { const text = buildShippingText(o); try { await navigator.clipboard.writeText(text); window.toast("배송정보가 클립보드에 복사되었습니다"); } catch (e) { window.toast("복사 실패: " + e.message); } }; const copyField = async (label, value) => { try { await navigator.clipboard.writeText(value); window.toast(label + " 복사됨: " + value); } catch (e) { window.toast("복사 실패: " + e.message); } }; // 마운트 시 자격증명 있고 아직 mock이면 자동 로드 useEffect(() => { if (window.API.naverConfigured() && ordersSource === "mock" && reloadOrders) { reloadOrders({ days: ordersDays || 7 }); } }, []); const filtered = useMemo(() => { return orders.filter(o => { if (statusFilter !== "all" && o.status !== statusFilter) return false; if (search) { const q = search.toLowerCase(); if (!o.buyer.toLowerCase().includes(q) && !o.id.toLowerCase().includes(q) && !(o.phone || "").includes(q)) return false; } return true; }); }, [orders, statusFilter, search]); const toggleAll = () => { if (selected.size === filtered.length) setSelected(new Set()); else setSelected(new Set(filtered.map(o => o.id))); }; const toggleOne = (id) => { const s = new Set(selected); if (s.has(id)) s.delete(id); else s.add(id); setSelected(s); }; // 결제금액 — 라이브는 totalPaymentAmount, mock은 PRODUCTS lookup const orderTotal = (o) => { if (o.totalPaymentAmount) return o.totalPaymentAmount; return o.items.reduce((s, it) => { if (it.price) return s + it.price * it.qty; const p = PRODUCTS.find(x => x.id === it.pid); return s + (p ? p.price * it.qty : 0); }, 0); }; const counts = { paid: orders.filter(o => o.status === "paid").length, shipped: orders.filter(o => o.status === "shipped").length, delivered: orders.filter(o => o.status === "delivered").length, canceled: orders.filter(o => o.status === "canceled").length, }; return (

주문/판매 내역

{isLive ? `네이버 라이브 · 최근 ${ordersDays || 7}일 · 전체 ${orders.length}건` : `전체 ${orders.length}건 · 결제완료 ${counts.paid}건 · 배송중 ${counts.shipped}건`} {isLive && counts.paid > 0 && ` · 결제완료 ${counts.paid}`} {isLive && counts.canceled > 0 && ` · 취소 ${counts.canceled}`}

{isLive && reloadOrders && ( <>
{[7, 14, 30].map(d => ( ))}
)}
{ordersLoading && ordersProgress && (
네이버에서 {ordersProgress.total}일 데이터 수집 중... ({ordersProgress.done}/{ordersProgress.total})
)} {ordersError && (
주문 조회 실패: {ordersError}
)}
setSearch(e.target.value)} />
{[["all", "전체"], ["paid", `결제완료 ${counts.paid}`], ["shipped", `배송중 ${counts.shipped}`], ["delivered", `배송완료 ${counts.delivered}`], ["canceled", `취소 ${counts.canceled}`]].map(([k, l]) => ( ))}
{selected.size > 0 && (
{selected.size}건 선택됨
)}
{filtered.map(o => { const firstItem = isLive ? null : PRODUCTS.find(x => x.id === o.items[0].pid); const productName = isLive ? (o.items[0]?.name || "") : (firstItem?.name || ""); const isExpanded = expanded.has(o.id); return ( {isExpanded && ( )} ); })}
0 && selected.size === filtered.length} onChange={toggleAll} /> 주문번호 구매자 상품 결제금액 상태 주문일시
toggleOne(o.id)} />
{o.buyer}
{o.phone}
{!isLive && }
{productName}{o.items.length > 1 ? ` 외 ${o.items.length - 1}건` : ""}
총 {o.items.reduce((s, it) => s + it.qty, 0)}개
{formatKRW(orderTotal(o))} {o.date}
{/* 줄 1: 받는분 + 전화번호 + 우편번호 */}
{o.buyer} {o.phone && {o.phone}} {o.zipcode && [{o.zipcode}]}
{/* 줄 2: 주소 */}
{o.address || "-"}
{/* 줄 3: 상품 (옵션 포함) */}
{(o.items || []).map((it, i) => ( {i > 0 && · } {it.name || it.pid} {it.option && [{it.option}]} {it.optionPrice > 0 && (+{formatNum(it.optionPrice)}원)} × {it.qty}개 ))}
{/* 줄 4: 메모 (있을 때만) */} {o.memo &&
메모: {o.memo}
}
{filtered.length === 0 && !ordersLoading && (
{isLive ? `최근 ${ordersDays || 7}일 동안 ${statusFilter !== "all" ? "해당 상태의 " : ""}주문이 없습니다` : "검색 결과가 없습니다"}
{isLive && (
기간을 늘려보세요 (14일 / 30일)
)}
)}
); } window.OrdersScreen = OrdersScreen;