// === Dashboard screen ===
function Dashboard({ goto }) {
const { PRODUCTS, ORDERS, SALES_TREND } = window.MOCK;
const totalRevenue = SALES_TREND.reduce((s, d) => s + d.revenue, 0);
const totalOrders = SALES_TREND.reduce((s, d) => s + d.orders, 0);
const todayRevenue = SALES_TREND[SALES_TREND.length - 1].revenue;
const yesterdayRevenue = SALES_TREND[SALES_TREND.length - 2].revenue;
const revenueChange = ((todayRevenue - yesterdayRevenue) / yesterdayRevenue) * 100;
const newOrders = ORDERS.filter(o => o.status === "paid").length;
const outOfStock = PRODUCTS.filter(p => p.status === "outofstock").length;
const topProducts = [...PRODUCTS].sort((a, b) => b.sales30d - a.sales30d).slice(0, 5);
const recentOrders = ORDERS.slice(0, 5);
// chart bars
const chartMax = Math.max(...SALES_TREND.map(d => d.revenue));
const todayD = "05/10";
return (
대시보드
2026년 5월 10일 일요일 · 스마트스토어 판매 현황
}
spark={SALES_TREND.map(d => d.revenue)}
/>
}
/>
p.status === "active").length}개`}
deltaText={`품절 ${outOfStock}개`}
deltaPositive={false}
icon={}
/>
}
/>
{/* Sales chart */}
{SALES_TREND.map((d, i) => {
const h = (d.revenue / chartMax) * 178;
const isToday = d.d === todayD;
return (
{isToday && (
{Math.round(d.revenue / 10000)}만
)}
{d.d}
);
})}
{/* Quick actions */}
} label="상품 가격 수정" desc="개별 또는 일괄 수정" onClick={() => goto("products")} />
} label="일괄 가격 변경" desc="키워드/카테고리 필터로 일괄" onClick={() => goto("bulk")} accent />
} label="로젠 송장 출력" desc={`${ORDERS.filter(o => o.status === "paid").length}건 발송 대기`} onClick={() => goto("shipping")} />
} label="ISVM 상품 등록" desc="공급사 카탈로그 → 스토어 연동" onClick={() => goto("isvm")} />
{/* Top products */}
베스트 상품 TOP 5
{topProducts.map((p, i) => (
{i + 1}
{p.name}
{formatKRW(p.price)} · 재고 {p.stock}
))}
{/* Recent orders */}
최근 주문
{recentOrders.map((o, i) => {
const totalPrice = o.items.reduce((s, it) => {
const p = window.MOCK.PRODUCTS.find(x => x.id === it.pid);
return s + (p ? p.price * it.qty : 0);
}, 0);
const firstItem = window.MOCK.PRODUCTS.find(x => x.id === o.items[0].pid);
return (
{o.buyer} · {o.items.length === 1 ? firstItem?.name : `${firstItem?.name} 외 ${o.items.length - 1}건`}
{o.date.split(" ")[1]} · {o.id.slice(-5)}
);
})}
);
}
function StatTile({ label, value, delta, deltaText, deltaPositive, icon, spark }) {
const showDelta = delta !== undefined;
const isUp = showDelta ? delta >= 0 : deltaPositive;
return (
{icon} {label}
{value}
{showDelta ? (
{isUp ? : }
{Math.abs(delta).toFixed(1)}% (전일 대비)
) : (
{deltaText}
)}
{spark &&
}
);
}
function QuickAction({ icon, label, desc, onClick, accent }) {
return (
);
}
window.Dashboard = Dashboard;