Files
distribution_erp/src/components/momo/sidebar.tsx
T
chpark 04d51eb792
Deploy momo-erp / deploy (push) Successful in 46s
feat(menu): 사용자 → 대메뉴 → 소메뉴 2단 트리로 재구성, 모모 자체 회원/권한/메뉴 제거
DB:
- [사용자] 그룹 아래에 5개 대메뉴 신규 (거래처 주문/마스터 관리/매입·입고/출고·정산/통계)
- 각 대메뉴 아래에 모모 페이지 소메뉴로 배치 (URL 직접 연결)
- 기존 [DASHBOARD] 대메뉴 활용 — 자식 [대시보드 → /m/dashboard] 추가, 기존 dashboard.do 비활성화

코드:
- /m/admin/users, /m/admin/roles, /m/admin/menus 페이지 삭제
- /api/m/users, /api/m/roles, /api/m/menus 삭제
- 모모 사이드바 [시스템] 그룹 제거 (기존 admin-panel 사용자/권한/메뉴 관리 활용)

→ plm_admin 로그인 후 [사용자] 그룹 펼치면 깔끔한 2단 트리 표시,
   각 소메뉴 클릭 시 /m/* 페이지로 정상 이동
2026-04-26 00:04:16 +09:00

98 lines
4.3 KiB
TypeScript

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import {
LayoutDashboard, Package, ShoppingCart, Warehouse, TrendingUp,
Building2, ClipboardList, Truck, Receipt, PackagePlus, Wallet,
} from "lucide-react";
interface MenuLink {
href: string;
label: string;
icon: React.ComponentType<{ size?: number }>;
roles: ("USER" | "ADMIN")[];
group?: string;
}
const MENU: MenuLink[] = [
{ href: "/m/dashboard", label: "대시보드", icon: LayoutDashboard, roles: ["USER", "ADMIN"] },
{ href: "/m/items", label: "품목 검색", icon: Package, roles: ["USER"], group: "주문" },
{ href: "/m/orders/new", label: "출고 요청", icon: ShoppingCart, roles: ["USER"], group: "주문" },
{ href: "/m/orders", label: "내 출고 이력", icon: ClipboardList, roles: ["USER"], group: "주문" },
{ href: "/m/admin/items", label: "품목 관리", icon: Package, roles: ["ADMIN"], group: "마스터" },
{ href: "/m/admin/vendors", label: "매입처 관리", icon: Building2, roles: ["ADMIN"], group: "마스터" },
{ href: "/m/admin/warehouses", label: "창고 관리", icon: Warehouse, roles: ["ADMIN"], group: "마스터" },
{ href: "/m/admin/procurements", label: "매입 발주", icon: Truck, roles: ["ADMIN"], group: "매입" },
{ href: "/m/admin/inbounds", label: "입고 처리", icon: PackagePlus, roles: ["ADMIN"], group: "매입" },
{ href: "/m/admin/inventory", label: "재고 관리", icon: Warehouse, roles: ["ADMIN"], group: "매입" },
{ href: "/m/admin/orders", label: "출고 관리", icon: ClipboardList, roles: ["ADMIN"], group: "출고/정산" },
{ href: "/m/admin/payments", label: "입금 관리", icon: Wallet, roles: ["ADMIN"], group: "출고/정산" },
{ href: "/m/admin/invoices", label: "계산서 발행", icon: Receipt, roles: ["ADMIN"], group: "출고/정산" },
{ href: "/m/admin/statistics", label: "월간 매출", icon: TrendingUp, roles: ["ADMIN"], group: "통계" },
{ href: "/m/admin/statistics/daily", label: "일자별", icon: TrendingUp, roles: ["ADMIN"], group: "통계" },
{ href: "/m/admin/statistics/margin", label: "원가/마진", icon: TrendingUp, roles: ["ADMIN"], group: "통계" },
];
export function MomoSidebar({ role }: { role: "USER" | "ADMIN" }) {
const pathname = usePathname();
const items = MENU.filter((m) => m.roles.includes(role));
const grouped: Record<string, MenuLink[]> = {};
for (const m of items) {
const g = m.group || "_top";
(grouped[g] ||= []).push(m);
}
return (
<aside className="w-60 shrink-0 bg-gradient-to-b from-[#0d3b24] to-[#1b5e3a] text-white flex flex-col">
<Link href="/m/dashboard" className="px-6 h-16 flex items-center gap-2.5 border-b border-white/10 hover:bg-white/5 transition">
<img src="/momo-icon.svg" alt="" className="w-8 h-8" />
<div>
<div className="text-[11px] tracking-widest text-emerald-200/80 leading-none">MOMO</div>
<div className="text-sm font-bold leading-tight"></div>
</div>
</Link>
<nav className="flex-1 py-4 px-2 space-y-2 overflow-y-auto">
{Object.entries(grouped).map(([group, list]) => (
<div key={group}>
{group !== "_top" && (
<div className="px-3 py-1.5 text-[10px] font-bold tracking-widest text-emerald-300/60 uppercase">
{group}
</div>
)}
<div className="space-y-0.5">
{list.map((it) => {
const Icon = it.icon;
const active = pathname === it.href || pathname.startsWith(it.href + "/");
return (
<Link
key={it.href}
href={it.href}
className={
"flex items-center gap-3 px-4 h-9 rounded-lg text-sm transition " +
(active
? "bg-white/15 text-white font-semibold"
: "text-emerald-100/80 hover:bg-white/10 hover:text-white")
}
>
<Icon size={15} />
{it.label}
</Link>
);
})}
</div>
</div>
))}
</nav>
<div className="p-4 border-t border-white/10 text-[11px] text-emerald-200/60">© 2026 MOMO Distribution</div>
</aside>
);
}