Files
tk-factory-services/system1-factory/web/pages/admin/equipments.html
Hyungi Ahn d36303101e feat: 모바일 UX 대폭 개선 + PWA 구현 + 로그인 루프 수정
- 모바일 하단 네비: 메뉴 제거, 4개 핵심 기능(홈/TBM/작업보고/출근) SVG 아이콘
- 모바일 사이드바 스킵: 768px 이하에서 사이드바 미로드, 레이아웃 오프셋 해결
- 모바일 헤더: 햄버거 메뉴 숨김, 본문 margin/overflow 정리
- TBM 모바일: 풀스크린 모달, 저장 버튼 하단 고정, 터치 UX 개선
- PWA: manifest.json, sw.js(network-first), 앱 아이콘, iOS 메타태그, 킬스위치
- 로그인 무한루프 수정: 토큰 만료 검증, 쿠키 정리, loginPage 경로 수정
- 신고 메뉴 tkreport 리다이렉트: navbar + sidebar cross-system-link 적용
- TBM API: 작업장별 안전점검 체크리스트 조회 엔드포인트 추가
- 안전점검 체크리스트 관리 UI 개선
- tkuser: 이슈유형 관리 기능 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 08:20:50 +09:00

221 lines
8.9 KiB
HTML

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>설비 관리 | (주)테크니컬코리아</title>
<link rel="stylesheet" href="/css/design-system.css">
<link rel="stylesheet" href="/css/admin-pages.css?v=8">
<link rel="stylesheet" href="/css/equipment-management.css?v=1">
<link rel="icon" type="image/png" href="/img/favicon.png">
<script src="/js/api-base.js"></script>
<script src="/js/app-init.js?v=3" defer></script>
</head>
<body>
<!-- 네비게이션 바 -->
<div id="navbar-container"></div>
<!-- 메인 레이아웃 -->
<div class="page-container">
<!-- 메인 콘텐츠 -->
<main class="main-content">
<div class="dashboard-main">
<div class="page-header">
<div class="page-title-section">
<h1 class="page-title">설비 관리</h1>
<p class="page-description">작업장별 설비 정보를 등록하고 관리합니다</p>
</div>
<div class="page-actions">
<button class="btn btn-primary" onclick="openEquipmentModal()">
<span>+ 설비 추가</span>
</button>
</div>
</div>
<!-- 통계 요약 -->
<div id="statsSection" class="eq-stats-section">
<!-- JS에서 동적으로 렌더링 -->
</div>
<!-- 필터 영역 -->
<div class="eq-filter-section">
<div class="eq-filter-group">
<label for="filterWorkplace">작업장</label>
<select id="filterWorkplace" class="form-control" onchange="filterEquipments()">
<option value="">전체</option>
</select>
</div>
<div class="eq-filter-group">
<label for="filterType">설비 유형</label>
<select id="filterType" class="form-control" onchange="filterEquipments()">
<option value="">전체</option>
</select>
</div>
<div class="eq-filter-group">
<label for="filterStatus">상태</label>
<select id="filterStatus" class="form-control" onchange="filterEquipments()">
<option value="">전체</option>
<option value="active">활성</option>
<option value="maintenance">정비중</option>
<option value="inactive">비활성</option>
</select>
</div>
<div class="eq-filter-group eq-search-group">
<label for="searchInput">검색</label>
<input type="text" id="searchInput" class="form-control" placeholder="설비명, 코드, 제조사 검색..." oninput="filterEquipments()">
</div>
</div>
<!-- 설비 목록 -->
<div id="equipmentList" class="eq-table-container">
<!-- 설비 목록이 여기에 동적으로 렌더링됩니다 -->
</div>
</div>
</main>
</div>
<!-- 설비 추가/수정 모달 -->
<div id="equipmentModal" class="modal-overlay" style="display: none;">
<div class="modal-container" style="max-width: 720px;">
<div class="modal-header">
<h2 id="modalTitle">설비 추가</h2>
<button class="btn-close" onclick="closeEquipmentModal()">&times;</button>
</div>
<div class="modal-body eq-modal-body">
<form id="equipmentForm">
<input type="hidden" id="equipmentId">
<!-- 기본 정보 -->
<div class="eq-form-section">
<div class="eq-form-section-title">기본 정보</div>
<div class="eq-form-row">
<div class="form-group">
<label for="equipmentCode">관리번호 *</label>
<input type="text" id="equipmentCode" class="form-control" placeholder="예: TKP-001" required>
</div>
<div class="form-group">
<label for="equipmentName">설비명 *</label>
<input type="text" id="equipmentName" class="form-control" placeholder="예: TIG용접기" required>
</div>
</div>
<div class="eq-form-row">
<div class="form-group">
<label for="modelName">모델명</label>
<input type="text" id="modelName" class="form-control" placeholder="예: Perfect-500PT">
</div>
<div class="form-group">
<label for="specifications">규격</label>
<input type="text" id="specifications" class="form-control" placeholder="예: 500A/DC">
</div>
</div>
</div>
<!-- 제조사 및 구입 정보 -->
<div class="eq-form-section">
<div class="eq-form-section-title">제조사 및 구입 정보</div>
<div class="eq-form-row">
<div class="form-group">
<label for="manufacturer">제조사 (메이커)</label>
<input type="text" id="manufacturer" class="form-control" placeholder="예: 퍼펙트대대">
</div>
<div class="form-group">
<label for="supplier">구입처</label>
<input type="text" id="supplier" class="form-control" placeholder="예: 현대용접기">
</div>
</div>
<div class="eq-form-row">
<div class="form-group">
<label for="purchasePrice">구입가격 (원)</label>
<input type="number" id="purchasePrice" class="form-control" placeholder="예: 1600000">
</div>
<div class="form-group">
<label for="installationDate">구입일자</label>
<input type="date" id="installationDate" class="form-control">
</div>
</div>
</div>
<!-- 상세 정보 -->
<div class="eq-form-section">
<div class="eq-form-section-title">상세 정보</div>
<div class="eq-form-row">
<div class="form-group">
<label for="serialNumber">시리얼 번호 (S/N)</label>
<input type="text" id="serialNumber" class="form-control">
</div>
<div class="form-group">
<label for="equipmentStatus">상태</label>
<select id="equipmentStatus" class="form-control">
<option value="active">활성</option>
<option value="maintenance">정비중</option>
<option value="inactive">비활성</option>
</select>
</div>
</div>
<div class="eq-form-row">
<div class="form-group">
<label for="equipmentType">설비 유형</label>
<input type="text" id="equipmentType" class="form-control" placeholder="예: 용접기, 크레인 등">
</div>
<div class="form-group">
<label for="workplaceId">작업장</label>
<select id="workplaceId" class="form-control">
<option value="">선택 안함</option>
</select>
</div>
</div>
<div class="form-group">
<label for="notes">비고</label>
<textarea id="notes" class="form-control" rows="2" placeholder="기타 메모사항"></textarea>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="closeEquipmentModal()">취소</button>
<button type="button" class="btn btn-primary" onclick="saveEquipment()">저장</button>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script type="module">
import '/js/api-config.js?v=3';
</script>
<script>
(function() {
const checkApiConfig = setInterval(() => {
if (window.API_BASE_URL) {
clearInterval(checkApiConfig);
axios.defaults.baseURL = window.API_BASE_URL;
const token = localStorage.getItem('sso_token');
if (token) {
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
}
axios.interceptors.request.use(
config => {
const token = localStorage.getItem('sso_token');
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
},
error => Promise.reject(error)
);
axios.interceptors.response.use(
response => response,
error => {
if (error.response?.status === 401) {
alert('세션이 만료되었습니다. 다시 로그인해주세요.');
window.location.href = '/pages/login.html';
}
return Promise.reject(error);
}
);
}
}, 50);
})();
</script>
<script src="/js/equipment-management.js?v=8"></script>
</body>
</html>