Files
vexplor_dev/frontend/components/pop/hardcoded/MenuIcons.tsx
SeongHyun Kim 9f00988110 feat: POP 전면 개선 — 신규 화면 5개 + 버그 수정 9건 + UI 개선
[신규 화면]
- 설비허브 + 설비관리 + 설비점검
- 재고조정 + 재고이동

[버그 수정]
- 창고 NULL status 누락
- 작업지시 sync detail fallback
- InspectionModal API 경로
- 검사결과 DB 저장
- seq_no 비순차 대응
- 출고 재고 부족 검증
- 자동 창고 매칭
- 내 접수 목록 필터

[UI 개선]
- 사이드바 카드형
- 자재투입 컴팩트
- 커스텀 모달
- 불필요 버튼 제거
2026-04-10 10:28:39 +09:00

220 lines
6.4 KiB
TypeScript

"use client";
import { useRouter } from "next/navigation";
import type React from "react";
interface MenuIconItem {
id: string;
title: string;
gradient: string;
shadowColor: string;
icon: React.ReactNode;
href: string;
}
const MENU_ITEMS: MenuIconItem[] = [
{
id: "incoming",
title: "입고",
gradient: "linear-gradient(135deg,#3b82f6,#1d4ed8)",
shadowColor: "rgba(59,130,246,.3)",
icon: (
<svg
className="w-7 h-7 sm:w-8 sm:h-8 text-white"
fill="none"
stroke="currentColor"
strokeWidth={1.5}
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"
/>
</svg>
),
href: "/pop/inbound",
},
{
id: "outgoing",
title: "출고",
gradient: "linear-gradient(135deg,#22c55e,#15803d)",
shadowColor: "rgba(34,197,94,.3)",
icon: (
<svg
className="w-7 h-7 sm:w-8 sm:h-8 text-white"
fill="none"
stroke="currentColor"
strokeWidth={1.5}
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M8.25 18.75a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h6m-9 0H3.375a1.125 1.125 0 01-1.125-1.125V14.25m17.25 4.5a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0H6.75m11.25 0h2.625c.621 0 1.125-.504 1.125-1.125v-4.875c0-.621-.504-1.125-1.125-1.125H17.25m-13.5-.375V6.375c0-.621.504-1.125 1.125-1.125h7.5c.621 0 1.125.504 1.125 1.125v7.125"
/>
</svg>
),
href: "/pop/outbound",
},
{
id: "production",
title: "생산",
gradient: "linear-gradient(135deg,#f59e0b,#d97706)",
shadowColor: "rgba(245,158,11,.3)",
icon: (
<svg
className="w-7 h-7 sm:w-8 sm:h-8 text-white"
fill="none"
stroke="currentColor"
strokeWidth={1.5}
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z"
/>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
/>
</svg>
),
href: "/pop/production",
},
{
id: "quality",
title: "품질",
gradient: "linear-gradient(135deg,#ef4444,#b91c1c)",
shadowColor: "rgba(239,68,68,.3)",
icon: (
<svg
className="w-7 h-7 sm:w-8 sm:h-8 text-white"
fill="none"
stroke="currentColor"
strokeWidth={1.5}
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
),
href: "/pop/quality",
},
{
id: "equipment",
title: "설비",
gradient: "linear-gradient(135deg,#8b5cf6,#6d28d9)",
shadowColor: "rgba(139,92,246,.3)",
icon: (
<svg
className="w-7 h-7 sm:w-8 sm:h-8 text-white"
fill="none"
stroke="currentColor"
strokeWidth={1.5}
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
),
href: "/pop/equipment",
},
{
id: "inventory",
title: "재고",
gradient: "linear-gradient(135deg,#06b6d4,#0e7490)",
shadowColor: "rgba(6,182,212,.3)",
icon: (
<svg
className="w-7 h-7 sm:w-8 sm:h-8 text-white"
fill="none"
stroke="currentColor"
strokeWidth={1.5}
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z"
/>
</svg>
),
href: "/pop/inventory",
},
// 작업지시, 생산실적은 생산관리(/pop/production) 메뉴 안으로 이동
{
id: "safety",
title: "안전관리",
gradient: "linear-gradient(135deg,#f97316,#c2410c)",
shadowColor: "rgba(249,115,22,.3)",
icon: (
<svg
className="w-7 h-7 sm:w-8 sm:h-8 text-white"
fill="none"
stroke="currentColor"
strokeWidth={1.5}
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M12 9v3.75m0-10.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.75c0 5.592 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.57-.598-3.75h-.152c-3.196 0-6.1-1.249-8.25-3.286zm0 13.036h.008v.008H12v-.008z"
/>
</svg>
),
href: "/pop/screens/safety",
},
];
export function MenuIcons() {
const router = useRouter();
const handleClick = (item: MenuIconItem) => {
if (item.href === "#") {
alert(`${item.title} 화면은 준비 중입니다.`);
} else {
router.push(item.href);
}
};
return (
<section>
<h2 className="text-xl sm:text-[22px] font-bold text-gray-900 tracking-tight mb-4">
</h2>
<div className="flex flex-wrap justify-center gap-x-6 gap-y-5 sm:gap-x-8 sm:gap-y-6 lg:gap-x-10">
{MENU_ITEMS.map((item) => (
<div
key={item.id}
className="flex flex-col items-center gap-2 w-16 sm:w-20 cursor-pointer group"
style={{ WebkitTapHighlightColor: "transparent" }}
onClick={() => handleClick(item)}
>
<div
className="w-14 h-14 sm:w-16 sm:h-16 rounded-2xl flex items-center justify-center transition-transform duration-150 group-hover:scale-110 group-active:scale-[0.93]"
style={{
background: item.gradient,
boxShadow: `0 4px 12px ${item.shadowColor}`,
}}
>
{item.icon}
</div>
<span className="text-xs sm:text-sm font-semibold text-gray-700">
{item.title}
</span>
</div>
))}
</div>
</section>
);
}