🐛 해결된 문제: - auth-check.js의 ES6 import 문법 오류 - window.apiCall is not a function 오류 - 스크립트 로딩 순서로 인한 의존성 문제 🔧 수정 내용: 1. auth-check.js: - ES6 import 제거 → 함수 직접 구현 - isLoggedIn, getUser, clearAuthData 내장 - 모듈 의존성 완전 제거 2. 스크립트 로딩 순서 최적화: - api-config.js: defer 제거 (즉시 로드) - auth-check.js: defer 유지 - modern-dashboard.js: defer 유지 3. modern-dashboard.js: - API 함수 로드 대기 로직 추가 - 최대 5초 대기 후 오류 처리 - 안전한 초기화 보장 ✅ 개선 효과: - 모든 JavaScript 오류 해결 - 안정적인 스크립트 로딩 순서 - API 함수 의존성 문제 해결 - 대시보드 정상 초기화 보장 테스트: http://localhost:20000/pages/dashboard/group-leader.html
284 lines
10 KiB
HTML
284 lines
10 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/modern-dashboard.css">
|
|
<link rel="icon" type="image/png" href="/img/favicon.png">
|
|
|
|
<!-- 스크립트 (순서 중요: api-config.js가 먼저 로드되어야 함) -->
|
|
<script src="/js/api-config.js"></script>
|
|
<script src="/js/auth-check.js" defer></script>
|
|
<script src="/js/modern-dashboard.js" defer></script>
|
|
</head>
|
|
<body>
|
|
<!-- 메인 컨테이너 -->
|
|
<div class="dashboard-container">
|
|
|
|
<!-- 헤더 -->
|
|
<header class="dashboard-header">
|
|
<div class="header-content">
|
|
<div class="header-left">
|
|
<div class="brand">
|
|
<img src="/img/logo.png" alt="테크니컬코리아" class="brand-logo">
|
|
<div class="brand-text">
|
|
<h1 class="brand-title">테크니컬코리아</h1>
|
|
<p class="brand-subtitle">작업 현황판</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="header-center">
|
|
<div class="current-time" id="currentTime">
|
|
<span class="time-label">현재 시각</span>
|
|
<span class="time-value" id="timeValue">--:--:--</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="header-right">
|
|
<div class="user-profile" id="userProfile">
|
|
<div class="user-avatar">
|
|
<span class="avatar-text" id="userInitial">사</span>
|
|
</div>
|
|
<div class="user-info">
|
|
<span class="user-name" id="userName">사용자</span>
|
|
<span class="user-role" id="userRole">작업자</span>
|
|
</div>
|
|
<div class="profile-menu" id="profileMenu">
|
|
<a href="/pages/profile/my-profile.html" class="menu-item">
|
|
<span class="menu-icon">👤</span>
|
|
내 프로필
|
|
</a>
|
|
<a href="/pages/profile/change-password.html" class="menu-item">
|
|
<span class="menu-icon">🔐</span>
|
|
비밀번호 변경
|
|
</a>
|
|
<button class="menu-item logout-btn" id="logoutBtn">
|
|
<span class="menu-icon">🚪</span>
|
|
로그아웃
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- 메인 콘텐츠 -->
|
|
<main class="dashboard-main">
|
|
|
|
<!-- 상태 요약 카드 -->
|
|
<section class="summary-section">
|
|
<div class="grid grid-cols-4">
|
|
|
|
<!-- 오늘 작업자 수 -->
|
|
<div class="card summary-card fade-in">
|
|
<div class="card-body">
|
|
<div class="summary-icon success">
|
|
<span>👥</span>
|
|
</div>
|
|
<div class="summary-content">
|
|
<h3 class="summary-title">오늘 작업자</h3>
|
|
<div class="summary-value" id="todayWorkers">
|
|
<span class="value-number">-</span>
|
|
<span class="value-unit">명</span>
|
|
</div>
|
|
<p class="summary-change positive" id="workersChange">
|
|
<span class="change-icon">↗</span>
|
|
전일 대비 +2명
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 총 작업 시간 -->
|
|
<div class="card summary-card fade-in">
|
|
<div class="card-body">
|
|
<div class="summary-icon primary">
|
|
<span>⏰</span>
|
|
</div>
|
|
<div class="summary-content">
|
|
<h3 class="summary-title">총 작업 시간</h3>
|
|
<div class="summary-value" id="totalHours">
|
|
<span class="value-number">-</span>
|
|
<span class="value-unit">시간</span>
|
|
</div>
|
|
<p class="summary-change positive" id="hoursChange">
|
|
<span class="change-icon">↗</span>
|
|
전일 대비 +4시간
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 진행 중인 프로젝트 -->
|
|
<div class="card summary-card fade-in">
|
|
<div class="card-body">
|
|
<div class="summary-icon warning">
|
|
<span>📁</span>
|
|
</div>
|
|
<div class="summary-content">
|
|
<h3 class="summary-title">진행 프로젝트</h3>
|
|
<div class="summary-value" id="activeProjects">
|
|
<span class="value-number">-</span>
|
|
<span class="value-unit">개</span>
|
|
</div>
|
|
<p class="summary-change neutral" id="projectsChange">
|
|
<span class="change-icon">→</span>
|
|
변동 없음
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 오류 발생 건수 -->
|
|
<div class="card summary-card fade-in">
|
|
<div class="card-body">
|
|
<div class="summary-icon error">
|
|
<span>⚠️</span>
|
|
</div>
|
|
<div class="summary-content">
|
|
<h3 class="summary-title">오류 발생</h3>
|
|
<div class="summary-value" id="errorCount">
|
|
<span class="value-number">-</span>
|
|
<span class="value-unit">건</span>
|
|
</div>
|
|
<p class="summary-change negative" id="errorsChange">
|
|
<span class="change-icon">↘</span>
|
|
전일 대비 -1건
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
<!-- 메인 콘텐츠 그리드 -->
|
|
<section class="content-section">
|
|
<div class="grid grid-cols-3 gap-6">
|
|
|
|
<!-- 오늘의 작업 현황 -->
|
|
<div class="card content-card col-span-2">
|
|
<div class="card-header">
|
|
<div class="flex justify-between items-center">
|
|
<h2 class="card-title">📊 오늘의 작업 현황</h2>
|
|
<div class="date-selector">
|
|
<input type="date" id="selectedDate" class="date-input">
|
|
<button class="btn btn-primary btn-sm" id="refreshBtn">
|
|
<span>🔄</span>
|
|
새로고침
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="work-status-container" id="workStatusContainer">
|
|
<div class="loading-state">
|
|
<div class="spinner"></div>
|
|
<p>작업 현황을 불러오는 중...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 빠른 작업 -->
|
|
<div class="card content-card">
|
|
<div class="card-header">
|
|
<h2 class="card-title">⚡ 빠른 작업</h2>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="quick-actions">
|
|
<a href="/pages/common/daily-work-report.html" class="quick-action-btn">
|
|
<div class="action-icon">📝</div>
|
|
<div class="action-content">
|
|
<h3>작업 보고서 작성</h3>
|
|
<p>오늘의 작업 내용 입력</p>
|
|
</div>
|
|
</a>
|
|
|
|
<a href="/pages/common/daily-work-report-viewer.html" class="quick-action-btn">
|
|
<div class="action-icon">📋</div>
|
|
<div class="action-content">
|
|
<h3>작업 현황 확인</h3>
|
|
<p>팀원들의 작업 현황 조회</p>
|
|
</div>
|
|
</a>
|
|
|
|
<a href="/pages/analysis/daily_work_analysis.html" class="quick-action-btn">
|
|
<div class="action-icon">📈</div>
|
|
<div class="action-content">
|
|
<h3>작업 분석</h3>
|
|
<p>작업 효율성 및 통계 확인</p>
|
|
</div>
|
|
</a>
|
|
|
|
<a href="/pages/admin/manage-daily-work.html" class="quick-action-btn admin-only">
|
|
<div class="action-icon">⚙️</div>
|
|
<div class="action-content">
|
|
<h3>작업 관리</h3>
|
|
<p>작업자 및 프로젝트 관리</p>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
<!-- 작업자별 현황 -->
|
|
<section class="workers-section">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="flex justify-between items-center">
|
|
<h2 class="card-title">👥 작업자별 현황</h2>
|
|
<div class="view-controls">
|
|
<button class="btn btn-secondary btn-sm" id="listViewBtn">
|
|
<span>📋</span>
|
|
목록형
|
|
</button>
|
|
<button class="btn btn-secondary btn-sm" id="cardViewBtn">
|
|
<span>🎴</span>
|
|
카드형
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="workers-container" id="workersContainer">
|
|
<div class="loading-state">
|
|
<div class="spinner"></div>
|
|
<p>작업자 정보를 불러오는 중...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
</main>
|
|
|
|
<!-- 푸터 -->
|
|
<footer class="dashboard-footer">
|
|
<div class="footer-content">
|
|
<p class="footer-text">
|
|
© 2025 (주)테크니컬코리아. 모든 권리 보유.
|
|
</p>
|
|
<div class="footer-links">
|
|
<a href="#" class="footer-link">도움말</a>
|
|
<a href="#" class="footer-link">문의하기</a>
|
|
<a href="#" class="footer-link">개인정보처리방침</a>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
</div>
|
|
|
|
<!-- 알림 토스트 -->
|
|
<div class="toast-container" id="toastContainer"></div>
|
|
|
|
</body>
|
|
</html> |