fix(purchase): 모바일 네비 수정 + 권한 자동허용 + 장바구니 다중 품목 신청

- sideNav: TBM 패턴(hidden lg:flex + mobile-open) 적용, 회색 오버레이 버그 수정
- 권한: NAV_MENU 기반 publicPageKeys 추출, admin이 아닌 페이지는 비관리자 자동 접근 허용
- 장바구니: 검색→품목 추가→계속 검색→추가, 동일 품목 수량 합산, 품목별 메모
- bulk API: POST /purchase-requests/bulk (트랜잭션, is_new 품목 마스터 등록 포함)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-04-01 10:21:16 +09:00
parent 41bb755181
commit 5832755475
7 changed files with 323 additions and 208 deletions

View File

@@ -6,8 +6,8 @@
<title>소모품 신청 - TK 공장관리</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/static/css/tkfb.css?v=2026040102">
<link rel="stylesheet" href="/css/purchase-mobile.css?v=2026040102">
<link rel="stylesheet" href="/static/css/tkfb.css?v=2026040103">
<link rel="stylesheet" href="/css/purchase-mobile.css?v=2026040103">
<script src="https://cdn.jsdelivr.net/npm/heic2any@0.0.4/dist/heic2any.min.js"></script>
</head>
<body class="bg-gray-50">
@@ -24,9 +24,9 @@
</div>
</header>
<!-- 사이드 네비 -->
<nav id="sideNav" class="fixed inset-y-0 left-0 w-64 bg-white shadow-xl z-40 transform -translate-x-full transition-transform duration-200" style="top:48px"></nav>
<div id="mobileOverlay" class="fixed inset-0 bg-black/40 z-30 hidden" onclick="toggleMobileMenu()"></div>
<!-- 사이드 네비 (TBM 패턴) -->
<div id="mobileOverlay" class="hidden fixed inset-0 bg-black/50 z-30 lg:hidden"></div>
<nav id="sideNav" class="hidden lg:flex flex-col gap-1 w-52 flex-shrink-0 pt-2 fixed lg:static z-40 bg-white lg:bg-transparent p-4 lg:p-0 rounded-lg lg:rounded-none shadow-lg lg:shadow-none top-12 left-0 bottom-0 overflow-y-auto"></nav>
<div class="pm-content">
<!-- 상태 탭 -->
@@ -62,61 +62,18 @@
</div>
<div class="pm-search-results" id="searchResults"></div>
<!-- 선택된 품목 표시 -->
<div id="selectedItemWrap" class="hidden mb-3">
<div class="flex items-center gap-2 p-3 bg-orange-50 rounded-lg">
<div class="flex-1">
<div id="selectedItemName" class="font-medium text-sm text-gray-800"></div>
<div id="selectedItemMeta" class="text-xs text-gray-500 mt-1"></div>
</div>
<button onclick="clearSelectedItem()" class="text-gray-400 hover:text-red-500"><i class="fas fa-times-circle"></i></button>
</div>
</div>
<input type="hidden" id="selectedItemId">
<input type="hidden" id="selectedCustomName">
<!-- 신규 품목 등록 영역 (Phase 4에서 활성화) -->
<div id="newItemForm" class="hidden">
<div class="p-3 bg-yellow-50 border border-yellow-200 rounded-lg mb-3">
<div class="text-sm font-medium text-yellow-800 mb-2"><i class="fas fa-plus-circle mr-1"></i>새 품목 등록</div>
<div class="pm-field">
<label class="pm-label">품목명 *</label>
<input type="text" id="newItemName" class="pm-input" readonly>
</div>
<div class="grid grid-cols-2 gap-2">
<div class="pm-field">
<label class="pm-label">규격</label>
<input type="text" id="newItemSpec" class="pm-input" placeholder="예: 300mm">
</div>
<div class="pm-field">
<label class="pm-label">제조사</label>
<input type="text" id="newItemMaker" class="pm-input" placeholder="예: 3M">
</div>
</div>
<div class="pm-field">
<label class="pm-label">분류 (선택)</label>
<select id="newItemCategory" class="pm-select">
<option value="">나중에 분류</option>
<option value="consumable">소모품</option>
<option value="safety">안전용품</option>
<option value="repair">수선비</option>
<option value="equipment">설비</option>
</select>
</div>
<!-- 장바구니 -->
<div id="cartWrap" class="hidden mb-3">
<div class="pm-cart-header">
<span class="pm-cart-title"><i class="fas fa-shopping-cart mr-1"></i>신청 목록</span>
<span class="pm-cart-count" id="cartCount">0건</span>
</div>
<div id="cartList"></div>
</div>
<!-- 수량/메모/사진 -->
<!-- 사진 (공통) -->
<div class="pm-field">
<label class="pm-label">수량 *</label>
<input type="number" id="reqQuantity" class="pm-input" value="1" min="1" inputmode="numeric">
</div>
<div class="pm-field">
<label class="pm-label">메모</label>
<input type="text" id="reqNotes" class="pm-input" placeholder="요청 사항">
</div>
<div class="pm-field">
<label class="pm-label">사진 첨부</label>
<label class="pm-label">참고 사진</label>
<label class="pm-photo-btn">
<i class="fas fa-camera"></i>
<span id="photoLabel">사진 촬영/선택</span>
@@ -125,7 +82,7 @@
<img id="reqPhotoPreview" class="pm-photo-preview hidden">
</div>
<button id="submitBtn" class="pm-submit" onclick="submitRequest()">신청하기</button>
<button id="submitBtn" class="pm-submit" onclick="submitRequest()" disabled>신청하기</button>
</div>
</div>
@@ -140,8 +97,8 @@
<div class="pm-sheet-body" id="detailContent"></div>
</div>
<script src="/static/js/tkfb-core.js?v=2026040102"></script>
<script src="/static/js/purchase-request-mobile.js?v=2026040102"></script>
<script src="/static/js/shared-bottom-nav.js?v=2026040102"></script>
<script src="/static/js/tkfb-core.js?v=2026040103"></script>
<script src="/static/js/purchase-request-mobile.js?v=2026040103"></script>
<script src="/static/js/shared-bottom-nav.js?v=2026040103"></script>
</body>
</html>