TBM 시스템: - 4단계 워크플로우 (draft→세부편집→완료→작업보고) - 모바일 전용 TBM 페이지 (tbm-mobile.html) + 3단계 생성 위자드 - 작업자 작업 분할 (work_hours + split_seq) - 작업자 이동 보내기/빼오기 (tbm_transfers 테이블) - 생성 시 중복 배정 방지 (당일 배정 현황 조회) - 데스크탑 TBM 페이지 세부편집 기능 추가 작업보고서: - 모바일 전용 작업보고서 페이지 (report-create-mobile.html) - TBM에서 사전 등록된 work_hours 자동 반영 권한 시스템: - tkuser user_page_permissions 테이블과 system1 페이지 접근 연동 - pageAccessRoutes를 userRoutes보다 먼저 등록 (라우트 우선순위 수정) - TKUSER_DEFAULT_ACCESS 폴백 추가 (개인→부서→기본값 3단계) - 권한 캐시키 갱신 (userPageAccess_v2) 기타: - app-init.js 캐시 버스팅 (v=5) - iOS Safari touch-action: manipulation 적용 - KST 타임존 날짜 버그 수정 (toISOString UTC 이슈) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
148 lines
4.1 KiB
HTML
148 lines
4.1 KiB
HTML
<!-- components/mobile-nav.html -->
|
|
<!-- 모바일 하단 네비게이션 (4개 핵심 기능) -->
|
|
<nav class="mobile-bottom-nav" id="mobileBottomNav">
|
|
<a href="/pages/dashboard.html" class="mobile-nav-item" data-page="dashboard">
|
|
<svg class="mobile-nav-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
|
|
<polyline points="9 22 9 12 15 12 15 22"/>
|
|
</svg>
|
|
<span class="mobile-nav-label">홈</span>
|
|
</a>
|
|
<a href="/pages/work/tbm-mobile.html" class="mobile-nav-item" data-page="tbm">
|
|
<svg class="mobile-nav-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M9 11l3 3L22 4"/>
|
|
<path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/>
|
|
</svg>
|
|
<span class="mobile-nav-label">TBM</span>
|
|
</a>
|
|
<a href="/pages/work/report-create-mobile.html" class="mobile-nav-item" data-page="report">
|
|
<svg class="mobile-nav-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
<polyline points="14 2 14 8 20 8"/>
|
|
<line x1="16" y1="13" x2="8" y2="13"/>
|
|
<line x1="16" y1="17" x2="8" y2="17"/>
|
|
<polyline points="10 9 9 9 8 9"/>
|
|
</svg>
|
|
<span class="mobile-nav-label">작업보고</span>
|
|
</a>
|
|
<a href="/pages/attendance/checkin.html" class="mobile-nav-item" data-page="checkin">
|
|
<svg class="mobile-nav-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<circle cx="12" cy="12" r="10"/>
|
|
<polyline points="12 6 12 12 16 14"/>
|
|
</svg>
|
|
<span class="mobile-nav-label">출근</span>
|
|
</a>
|
|
</nav>
|
|
|
|
<style>
|
|
/* 모바일 하단 네비게이션 */
|
|
.mobile-bottom-nav {
|
|
display: none;
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 68px;
|
|
background: #ffffff;
|
|
border-top: 1px solid #e5e7eb;
|
|
box-shadow: 0 -2px 12px rgba(0,0,0,0.08);
|
|
z-index: 1000;
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.mobile-bottom-nav {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-around;
|
|
}
|
|
|
|
body {
|
|
padding-bottom: calc(68px + env(safe-area-inset-bottom)) !important;
|
|
}
|
|
}
|
|
|
|
.mobile-nav-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex: 1;
|
|
height: 100%;
|
|
text-decoration: none;
|
|
color: #9ca3af;
|
|
background: none;
|
|
border: none;
|
|
font-family: inherit;
|
|
cursor: pointer;
|
|
padding: 0.5rem 0.25rem;
|
|
-webkit-tap-highlight-color: transparent;
|
|
touch-action: manipulation;
|
|
position: relative;
|
|
transition: color 0.15s;
|
|
}
|
|
|
|
.mobile-nav-item:active {
|
|
color: #6b7280;
|
|
}
|
|
|
|
/* SVG 아이콘 */
|
|
.mobile-nav-svg {
|
|
width: 26px;
|
|
height: 26px;
|
|
margin-bottom: 4px;
|
|
transition: transform 0.15s;
|
|
}
|
|
|
|
.mobile-nav-label {
|
|
font-size: 0.6875rem;
|
|
font-weight: 500;
|
|
line-height: 1;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
/* 활성 상태 */
|
|
.mobile-nav-item.active {
|
|
color: #2563eb;
|
|
}
|
|
|
|
.mobile-nav-item.active .mobile-nav-svg {
|
|
transform: scale(1.08);
|
|
stroke-width: 2.5;
|
|
}
|
|
|
|
.mobile-nav-item.active .mobile-nav-label {
|
|
font-weight: 700;
|
|
}
|
|
|
|
/* 활성 인디케이터 점 */
|
|
.mobile-nav-item.active::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 4px;
|
|
width: 4px;
|
|
height: 4px;
|
|
border-radius: 50%;
|
|
background: #2563eb;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
(function() {
|
|
var currentPath = window.location.pathname;
|
|
var navItems = document.querySelectorAll('.mobile-nav-item[data-page]');
|
|
|
|
navItems.forEach(function(item) {
|
|
var href = item.getAttribute('href');
|
|
if (href && currentPath.includes(href.replace('/pages/', '').replace('.html', ''))) {
|
|
item.classList.add('active');
|
|
}
|
|
});
|
|
|
|
if (currentPath.includes('dashboard')) {
|
|
var dashItem = document.querySelector('[data-page="dashboard"]');
|
|
if (dashItem) dashItem.classList.add('active');
|
|
}
|
|
})();
|
|
</script>
|