feat: 초기 프로젝트 설정 및 룰.md 파일 추가
This commit is contained in:
187
web-ui/js/load-sections.js
Normal file
187
web-ui/js/load-sections.js
Normal file
@@ -0,0 +1,187 @@
|
||||
// ✅ /js/load-sections.js - 확장 가능한 구조 (개선됨)
|
||||
import { API, getAuthHeaders } from '/js/api-config.js';
|
||||
|
||||
// 역할별 섹션 매핑 (쉽게 추가/수정 가능)
|
||||
const SECTION_MAP = {
|
||||
'admin': '/components/sections/admin-sections.html',
|
||||
'system': '/components/sections/admin-sections.html',
|
||||
'leader': '/components/sections/leader-sections.html',
|
||||
'group_leader': '/components/sections/leader-sections.html',
|
||||
'support': '/components/sections/support-sections.html',
|
||||
'support_team': '/components/sections/support-sections.html',
|
||||
'user': '/components/sections/user-sections.html',
|
||||
'worker': '/components/sections/user-sections.html'
|
||||
};
|
||||
|
||||
// 공통 섹션 (모든 사용자에게 표시)
|
||||
const COMMON_SECTIONS = '/components/sections/common-sections.html';
|
||||
|
||||
async function loadSections() {
|
||||
try {
|
||||
console.log('🔄 섹션 로딩 시작');
|
||||
|
||||
// 사용자 정보 확인
|
||||
const token = localStorage.getItem('token');
|
||||
if (!token) {
|
||||
console.log('❌ 토큰 없음, 로그인 페이지로 이동');
|
||||
window.location.href = '/index.html';
|
||||
return;
|
||||
}
|
||||
|
||||
let userInfo = { role: 'user', access_level: 'worker' };
|
||||
try {
|
||||
const payload = JSON.parse(atob(token.split('.')[1]));
|
||||
userInfo = {
|
||||
role: payload.role || 'user',
|
||||
access_level: payload.access_level || 'worker'
|
||||
};
|
||||
console.log('👤 사용자 정보:', userInfo);
|
||||
} catch (err) {
|
||||
console.warn('⚠️ JWT 파싱 실패:', err);
|
||||
}
|
||||
|
||||
// ✅ 컨테이너 찾기 - 더 안전한 방식
|
||||
const possibleContainers = [
|
||||
'#sections-container',
|
||||
'#admin-sections',
|
||||
'#user-sections',
|
||||
'main[id$="-sections"]',
|
||||
'#content-container main'
|
||||
];
|
||||
|
||||
let container = null;
|
||||
for (const selector of possibleContainers) {
|
||||
container = document.querySelector(selector);
|
||||
if (container) {
|
||||
console.log(`✅ 컨테이너 발견: ${selector}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!container) {
|
||||
console.error('❌ 섹션 컨테이너를 찾을 수 없습니다');
|
||||
return;
|
||||
}
|
||||
|
||||
container.innerHTML = '<div class="loading">콘텐츠를 불러오는 중...</div>';
|
||||
|
||||
// 역할별 섹션 파일 결정 (수정된 버전)
|
||||
console.log('🔍 사용자 정보 디버깅:');
|
||||
console.log('- userInfo.role:', userInfo.role);
|
||||
console.log('- userInfo.access_level:', userInfo.access_level);
|
||||
|
||||
// role이 없으므로 access_level을 우선 사용
|
||||
const effectiveRole = userInfo.access_level || userInfo.role || 'user';
|
||||
const sectionFile = SECTION_MAP[effectiveRole] || SECTION_MAP['user'];
|
||||
|
||||
console.log(`📄 실제 사용될 역할: ${effectiveRole}`);
|
||||
console.log(`📄 로딩할 섹션 파일: ${sectionFile}`);
|
||||
|
||||
try {
|
||||
// 1. 공통 섹션 로드 (있을 경우)
|
||||
let commonHtml = '';
|
||||
try {
|
||||
console.log('📄 공통 섹션 로딩 시도');
|
||||
const commonRes = await fetch(COMMON_SECTIONS);
|
||||
if (commonRes.ok) {
|
||||
commonHtml = await commonRes.text();
|
||||
console.log('✅ 공통 섹션 로딩 성공');
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('ℹ️ 공통 섹션 없음 (정상)');
|
||||
}
|
||||
|
||||
// 2. 역할별 섹션 로드
|
||||
console.log('📄 역할별 섹션 로딩 시도');
|
||||
const res = await fetch(sectionFile);
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP ${res.status}: 섹션 파일을 찾을 수 없습니다 (${sectionFile})`);
|
||||
}
|
||||
|
||||
const roleHtml = await res.text();
|
||||
console.log('✅ 역할별 섹션 로딩 성공');
|
||||
|
||||
// 3. 조합하여 표시
|
||||
container.innerHTML = commonHtml + roleHtml;
|
||||
console.log('✅ 섹션 HTML 렌더링 완료');
|
||||
|
||||
// 4. 추가 데이터 로드 (필요시)
|
||||
await loadDynamicData(userInfo);
|
||||
console.log('✅ 섹션 로딩 완료');
|
||||
|
||||
} catch (err) {
|
||||
console.error('❌ 섹션 로드 실패:', err);
|
||||
container.innerHTML = `
|
||||
<div class="error-state">
|
||||
<h3>❌ 콘텐츠를 불러올 수 없습니다</h3>
|
||||
<p>오류: ${err.message}</p>
|
||||
<p>잠시 후 다시 시도해주세요.</p>
|
||||
<button onclick="location.reload()" class="btn btn-primary">🔄 새로고침</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.error('🔴 섹션 로딩 실패:', err);
|
||||
}
|
||||
}
|
||||
|
||||
// 동적 데이터 로드 (예: 대시보드 통계)
|
||||
async function loadDynamicData(userInfo) {
|
||||
console.log('📊 동적 데이터 로딩 시작');
|
||||
|
||||
// 오늘의 작업 현황
|
||||
const todayStats = document.getElementById('today-stats');
|
||||
if (todayStats) {
|
||||
try {
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
const res = await fetch(`${API}/workreports?start=${today}&end=${today}`, {
|
||||
headers: getAuthHeaders()
|
||||
});
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
todayStats.innerHTML = `
|
||||
<p>📝 오늘 등록된 작업: ${data.length}건</p>
|
||||
<p>👥 참여 작업자: ${new Set(data.map(d => d.worker_id)).size}명</p>
|
||||
`;
|
||||
console.log('✅ 오늘 통계 로딩 완료');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('❌ 통계 로드 실패:', e);
|
||||
if (todayStats) {
|
||||
todayStats.innerHTML = '<p>⚠️ 통계를 불러올 수 없습니다</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 빠른 링크 활성화
|
||||
initializeQuickLinks(userInfo);
|
||||
}
|
||||
|
||||
// 권한별 빠른 링크 표시/숨김
|
||||
function initializeQuickLinks(userInfo) {
|
||||
console.log('🔗 빠른 링크 초기화');
|
||||
|
||||
// 권한에 따라 특정 링크 숨기기
|
||||
if (userInfo.role !== 'admin' && userInfo.access_level !== 'admin') {
|
||||
document.querySelectorAll('.admin-only').forEach(el => {
|
||||
el.style.display = 'none';
|
||||
console.log('🔒 관리자 전용 링크 숨김');
|
||||
});
|
||||
}
|
||||
|
||||
if (userInfo.access_level !== 'group_leader') {
|
||||
document.querySelectorAll('.leader-only').forEach(el => {
|
||||
el.style.display = 'none';
|
||||
console.log('🔒 그룹장 전용 링크 숨김');
|
||||
});
|
||||
}
|
||||
|
||||
console.log('✅ 빠른 링크 초기화 완료');
|
||||
}
|
||||
|
||||
// 페이지 로드 시 실행
|
||||
document.addEventListener('DOMContentLoaded', loadSections);
|
||||
|
||||
// 수동 새로고침 함수 (다른 곳에서 호출 가능)
|
||||
window.refreshSections = loadSections;
|
||||
Reference in New Issue
Block a user