feat: 모든 페이지에 공통 헤더 적용 및 모바일 최적화
- 모든 HTML 페이지에 권한 기반 공통 헤더 적용 - 부적합 등록 페이지 모바일 최적화 (사진 업로드 UI 개선) - 부적합 조회 페이지에 모바일 캘린더 날짜 필터 적용 - 사용자별 권한에 따른 동적 페이지 제목 및 메시지 표시 Page Updates: - index.html: 모바일 친화적 사진 업로드 UI, 공통 헤더 적용 - issue-view.html: 터치/스와이프 캘린더 필터, 권한별 조회 제한 - daily-work.html: 공통 헤더 적용, 프로젝트 로딩 로직 개선 - project-management.html: 공통 헤더 적용, 권한 체크 강화 - admin.html: 페이지 권한 관리 UI 추가, 공통 헤더 적용 Mobile Optimizations: - 터치 타겟 최소 44px 보장 - 스와이프 제스처 지원 - 반응형 레이아웃 - 모바일 전용 UI 컴포넌트
This commit is contained in:
@@ -93,51 +93,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="min-h-screen bg-gray-50">
|
||||
<!-- 헤더 -->
|
||||
<header class="bg-white shadow-sm sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-3">
|
||||
<div class="flex justify-between items-center">
|
||||
<h1 class="text-xl font-bold text-gray-800">
|
||||
<i class="fas fa-clipboard-check text-blue-500 mr-2"></i>작업보고서
|
||||
</h1>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="text-sm text-gray-600" id="userDisplay"></span>
|
||||
<button onclick="logout()" class="text-gray-500 hover:text-gray-700">
|
||||
<i class="fas fa-sign-out-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 네비게이션 -->
|
||||
<nav class="bg-white border-b">
|
||||
<div class="container mx-auto px-4">
|
||||
<div id="navContainer" class="flex gap-2 py-2 overflow-x-auto">
|
||||
<a href="daily-work.html" class="nav-link active">
|
||||
<i class="fas fa-calendar-check mr-2"></i>일일 공수
|
||||
</a>
|
||||
<a href="index.html" class="nav-link">
|
||||
<i class="fas fa-camera-retro mr-2"></i>부적합 등록
|
||||
</a>
|
||||
<a href="issue-view.html" class="nav-link">
|
||||
<i class="fas fa-search mr-2"></i>부적합 조회
|
||||
</a>
|
||||
<a href="index.html#list" class="nav-link" style="display:none;" id="listBtn">
|
||||
<i class="fas fa-list mr-2"></i>목록 관리
|
||||
</a>
|
||||
<a href="index.html#summary" class="nav-link" style="display:none;" id="summaryBtn">
|
||||
<i class="fas fa-chart-bar mr-2"></i>보고서
|
||||
</a>
|
||||
<a href="project-management.html" class="nav-link" style="display:none;" id="projectBtn">
|
||||
<i class="fas fa-folder-open mr-2"></i>프로젝트 관리
|
||||
</a>
|
||||
<a href="admin.html" class="nav-link" style="display:none;" id="adminBtn">
|
||||
<i class="fas fa-users-cog mr-2"></i>관리
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- 공통 헤더가 여기에 자동으로 삽입됩니다 -->
|
||||
|
||||
<!-- 메인 컨텐츠 -->
|
||||
<main class="container mx-auto px-4 py-6 max-w-2xl">
|
||||
@@ -230,6 +186,9 @@
|
||||
document.head.appendChild(script);
|
||||
</script>
|
||||
<script src="/static/js/date-utils.js?v=20250917"></script>
|
||||
<script src="/static/js/core/permissions.js?v=20251025"></script>
|
||||
<script src="/static/js/components/common-header.js?v=20251025"></script>
|
||||
<script src="/static/js/core/page-manager.js?v=20251025"></script>
|
||||
<script>
|
||||
let currentUser = null;
|
||||
let projects = [];
|
||||
@@ -248,6 +207,19 @@
|
||||
const user = await AuthAPI.getCurrentUser();
|
||||
currentUser = user;
|
||||
localStorage.setItem('currentUser', JSON.stringify(user));
|
||||
|
||||
// 공통 헤더 초기화
|
||||
await window.commonHeader.init(user, 'daily_work');
|
||||
|
||||
// 페이지 접근 권한 체크 (일일 공수 페이지)
|
||||
setTimeout(() => {
|
||||
if (!canAccessPage('daily_work')) {
|
||||
alert('일일 공수 페이지에 접근할 권한이 없습니다.');
|
||||
window.location.href = '/index.html';
|
||||
return;
|
||||
}
|
||||
}, 500);
|
||||
|
||||
} catch (error) {
|
||||
console.error('인증 실패:', error);
|
||||
localStorage.removeItem('access_token');
|
||||
@@ -256,14 +228,12 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// 사용자 표시
|
||||
document.getElementById('userDisplay').textContent = user.full_name || user.username;
|
||||
// 사용자 정보는 공통 헤더에서 표시됨
|
||||
|
||||
// 네비게이션 권한 체크
|
||||
updateNavigation();
|
||||
// 네비게이션은 공통 헤더에서 처리됨
|
||||
|
||||
// 프로젝트 및 일일 공수 데이터 로드
|
||||
loadProjects();
|
||||
await loadProjects();
|
||||
loadDailyWorkData();
|
||||
|
||||
// 오늘 날짜로 초기화
|
||||
@@ -281,35 +251,43 @@
|
||||
console.log('📄 DOM 로드 완료 - API 스크립트 로딩 대기 중...');
|
||||
});
|
||||
|
||||
// 네비게이션 권한 업데이트
|
||||
function updateNavigation() {
|
||||
const listBtn = document.getElementById('listBtn');
|
||||
const summaryBtn = document.getElementById('summaryBtn');
|
||||
const adminBtn = document.getElementById('adminBtn');
|
||||
const projectBtn = document.getElementById('projectBtn');
|
||||
|
||||
if (currentUser.role === 'admin') {
|
||||
// 관리자는 모든 메뉴 표시
|
||||
listBtn.style.display = '';
|
||||
summaryBtn.style.display = '';
|
||||
projectBtn.style.display = '';
|
||||
adminBtn.style.display = '';
|
||||
adminBtn.innerHTML = '<i class="fas fa-users-cog mr-2"></i>사용자 관리';
|
||||
} else {
|
||||
// 일반 사용자는 제한된 메뉴만 표시
|
||||
listBtn.style.display = 'none';
|
||||
summaryBtn.style.display = 'none';
|
||||
projectBtn.style.display = 'none';
|
||||
adminBtn.style.display = '';
|
||||
adminBtn.innerHTML = '<i class="fas fa-key mr-2"></i>비밀번호 변경';
|
||||
}
|
||||
}
|
||||
// 네비게이션은 공통 헤더에서 처리됨
|
||||
|
||||
// 프로젝트 데이터 로드
|
||||
function loadProjects() {
|
||||
const saved = localStorage.getItem('work-report-projects');
|
||||
if (saved) {
|
||||
projects = JSON.parse(saved);
|
||||
async function loadProjects() {
|
||||
try {
|
||||
// API에서 최신 프로젝트 데이터 가져오기
|
||||
const response = await fetch('/api/projects/', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('access_token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
projects = await response.json();
|
||||
console.log('프로젝트 로드 완료:', projects.length, '개');
|
||||
console.log('활성 프로젝트:', projects.filter(p => p.is_active).length, '개');
|
||||
|
||||
// localStorage에도 캐시 저장
|
||||
localStorage.setItem('work-report-projects', JSON.stringify(projects));
|
||||
} else {
|
||||
console.error('프로젝트 로드 실패:', response.status);
|
||||
// 실패 시 localStorage에서 로드
|
||||
const saved = localStorage.getItem('work-report-projects');
|
||||
if (saved) {
|
||||
projects = JSON.parse(saved);
|
||||
console.log('캐시에서 프로젝트 로드:', projects.length, '개');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('프로젝트 로드 오류:', error);
|
||||
// 오류 시 localStorage에서 로드
|
||||
const saved = localStorage.getItem('work-report-projects');
|
||||
if (saved) {
|
||||
projects = JSON.parse(saved);
|
||||
console.log('캐시에서 프로젝트 로드:', projects.length, '개');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +306,7 @@
|
||||
|
||||
// 활성 프로젝트만 필터링
|
||||
function getActiveProjects() {
|
||||
return projects.filter(p => p.isActive);
|
||||
return projects.filter(p => p.is_active);
|
||||
}
|
||||
|
||||
// 프로젝트 입력 항목 추가
|
||||
|
||||
Reference in New Issue
Block a user