// === Shared UI helpers === const { useState, useEffect, useMemo, useRef, useCallback } = React; const formatKRW = (n) => "₩" + Math.round(n).toLocaleString("ko-KR"); const formatNum = (n) => Math.round(n).toLocaleString("ko-KR"); const formatDate = (s) => s.split(" ")[0].replace(/-/g, "."); // Toast manager let toastSetter; function ToastHost() { const [toasts, setToasts] = useState([]); toastSetter = setToasts; useEffect(() => { if (toasts.length === 0) return; const t = setTimeout(() => setToasts(arr => arr.slice(1)), 2800); return () => clearTimeout(t); }, [toasts]); return (
{toasts.map((t, i) => (
{t}
))}
); } function toast(msg) { toastSetter && toastSetter(arr => [...arr, msg]); } window.toast = toast; // Image placeholder using gradient — pseudo product photo function ProductThumb({ tone = 0, name = "", size = 36, radius = 6 }) { const [a, b] = window.MOCK.TONES[tone % window.MOCK.TONES.length]; const initial = name.replace(/[^가-힣A-Za-z]/g, "").slice(0, 2); return (
{initial}
); } window.ProductThumb = ProductThumb; // Modal function Modal({ open, onClose, title, children, footer, size = "" }) { if (!open) return null; return (
e.stopPropagation()}>
{title}
{children}
{footer &&
{footer}
}
); } window.Modal = Modal; // Status badge for products function StatusBadge({ status }) { const map = { active: { label: "판매중", cls: "badge-success" }, outofstock: { label: "품절", cls: "badge-warn" }, paused: { label: "판매중지", cls: "" }, paid: { label: "결제완료", cls: "badge-info" }, shipped: { label: "배송중", cls: "badge-warn" }, delivered: { label: "배송완료", cls: "badge-success" }, }; const c = map[status] || { label: status, cls: "" }; return {c.label}; } window.StatusBadge = StatusBadge; // MiniSpark — sparkline chart function MiniSpark({ data, height = 40, color = "var(--accent)" }) { const max = Math.max(...data); const min = Math.min(...data); const w = 100; const pts = data.map((v, i) => { const x = (i / (data.length - 1)) * w; const y = height - ((v - min) / (max - min || 1)) * (height - 4) - 2; return `${x},${y}`; }).join(" "); const areaPts = `0,${height} ${pts} ${w},${height}`; return ( ); } window.MiniSpark = MiniSpark;