- 실시간 작업장 현황을 지도로 시각화 - 작업장 관리 페이지에서 정의한 구역 정보 활용 - TBM 작업자 및 방문자 현황 표시 주요 변경사항: - dashboard.html: 작업장 현황 섹션 추가 (기존 작업 현황 테이블 제거) - workplace-status.js: 지도 렌더링 및 데이터 통합 로직 구현 - modern-dashboard.js: 삭제된 DOM 요소 조건부 체크 추가 시각화 방식: - 인원 없음: 회색 테두리 + 작업장 이름 - 내부 작업자: 파란색 영역 + 인원 수 - 외부 방문자: 보라색 영역 + 인원 수 - 둘 다: 초록색 영역 + 총 인원 수 기술 구현: - Canvas API 기반 사각형 영역 렌더링 - map-regions API를 통한 데이터 일관성 보장 - 클릭 이벤트로 상세 정보 모달 표시 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
253 lines
12 KiB
HTML
253 lines
12 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?v=2">
|
||
<link rel="icon" type="image/png" href="/img/favicon.png">
|
||
|
||
<!-- 스크립트 (순서 중요: api-config.js가 먼저 로드되어야 함) -->
|
||
<script type="module" src="/js/api-config.js"></script>
|
||
<script type="module" src="/js/auth-check.js" defer></script>
|
||
<script type="module" src="/js/load-navbar.js"></script>
|
||
<script type="module" src="/js/modern-dashboard.js?v=10" defer></script>
|
||
<script type="module" src="/js/group-leader-dashboard.js?v=1" defer></script>
|
||
<script src="/js/workplace-status.js" defer></script>
|
||
</head>
|
||
|
||
<body>
|
||
<!-- 메인 컨테이너 -->
|
||
<div class="dashboard-container">
|
||
|
||
<!-- 네비게이션 헤더 -->
|
||
<div id="navbar-container"></div>
|
||
|
||
<!-- 메인 콘텐츠 -->
|
||
<main class="dashboard-main">
|
||
|
||
<!-- 빠른 작업 섹션 -->
|
||
<section class="quick-actions-section">
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h2 class="card-title">빠른 작업</h2>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="quick-actions-grid-full">
|
||
<!-- TBM 관리 (페이지 권한 체크) -->
|
||
<a href="/pages/work/tbm.html" class="quick-action-card" id="tbmQuickAction" style="display: none; background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); color: white;">
|
||
<div class="action-content">
|
||
<h3 style="color: white;">🛠️ TBM 관리</h3>
|
||
<p style="color: rgba(255, 255, 255, 0.9);">아침 안전 회의 및 팀 구성을 관리합니다</p>
|
||
</div>
|
||
<div class="action-arrow" style="color: white;">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/work/visit-request.html" class="quick-action-card" style="background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%); color: white;">
|
||
<div class="action-content">
|
||
<h3 style="color: white;">🚪 출입 신청</h3>
|
||
<p style="color: rgba(255, 255, 255, 0.9);">작업장 출입 및 안전교육을 신청합니다</p>
|
||
</div>
|
||
<div class="action-arrow" style="color: white;">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/admin/safety-management.html" class="quick-action-card admin-only" style="background: linear-gradient(135deg, #ec4899 0%, #db2777 100%); color: white;">
|
||
<div class="action-content">
|
||
<h3 style="color: white;">🛡️ 안전관리</h3>
|
||
<p style="color: rgba(255, 255, 255, 0.9);">출입 신청 승인 및 안전교육 관리</p>
|
||
</div>
|
||
<div class="action-arrow" style="color: white;">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/work/report-create.html" class="quick-action-card">
|
||
<div class="action-content">
|
||
<h3>작업 보고서 작성</h3>
|
||
<p>오늘의 작업 내용을 입력하고 관리합니다</p>
|
||
</div>
|
||
<div class="action-arrow">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/work/report-view.html" class="quick-action-card">
|
||
<div class="action-content">
|
||
<h3>작업 현황 확인</h3>
|
||
<p>팀원들의 작업 현황을 실시간으로 조회합니다</p>
|
||
</div>
|
||
<div class="action-arrow">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/work/analysis.html" class="quick-action-card admin-only">
|
||
<div class="action-content">
|
||
<h3>작업 분석</h3>
|
||
<p>작업 효율성 및 통계를 분석합니다</p>
|
||
</div>
|
||
<div class="action-arrow">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/admin/projects.html" class="quick-action-card admin-only">
|
||
<div class="action-content">
|
||
<h3>기본 정보 관리</h3>
|
||
<p>프로젝트, 작업자, 코드를 관리합니다</p>
|
||
</div>
|
||
<div class="action-arrow">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/common/daily-attendance.html" class="quick-action-card" style="background: linear-gradient(135deg, #06b6d4 0%, #0891b2 100%); color: white;">
|
||
<div class="action-content">
|
||
<h3 style="color: white;">📅 일일 출퇴근 입력</h3>
|
||
<p style="color: rgba(255, 255, 255, 0.9);">오늘의 출퇴근 기록을 입력합니다</p>
|
||
</div>
|
||
<div class="action-arrow" style="color: white;">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/common/monthly-attendance.html" class="quick-action-card">
|
||
<div class="action-content">
|
||
<h3>📆 월별 출퇴근 현황</h3>
|
||
<p>이번 달 출퇴근 현황을 조회합니다</p>
|
||
</div>
|
||
<div class="action-arrow">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/common/vacation-request.html" class="quick-action-card">
|
||
<div class="action-content">
|
||
<h3>📝 휴가 신청</h3>
|
||
<p>휴가를 신청하고 신청 내역을 확인합니다</p>
|
||
</div>
|
||
<div class="action-arrow">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/common/vacation-management.html" class="quick-action-card admin-only">
|
||
<div class="action-content">
|
||
<h3>🏖️ 휴가 관리</h3>
|
||
<p>휴가 승인, 직접 입력, 전체 내역을 관리합니다</p>
|
||
</div>
|
||
<div class="action-arrow">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/common/annual-vacation-overview.html" class="quick-action-card admin-only">
|
||
<div class="action-content">
|
||
<h3>📊 연간 연차 현황</h3>
|
||
<p>모든 작업자의 연간 휴가 현황을 차트로 확인합니다</p>
|
||
</div>
|
||
<div class="action-arrow">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/common/vacation-allocation.html" class="quick-action-card admin-only">
|
||
<div class="action-content">
|
||
<h3>➕ 휴가 발생 입력</h3>
|
||
<p>작업자별 휴가를 입력하고 특별 휴가를 관리합니다</p>
|
||
</div>
|
||
<div class="action-arrow">→</div>
|
||
</a>
|
||
|
||
<a href="/pages/admin/attendance-report-comparison.html" class="quick-action-card admin-only">
|
||
<div class="action-content">
|
||
<h3>🔍 출퇴근-작업보고서 대조</h3>
|
||
<p>출퇴근 기록과 작업보고서를 비교 분석합니다</p>
|
||
</div>
|
||
<div class="action-arrow">→</div>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 작업장 현황 -->
|
||
<section class="workplace-status-section">
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<div class="flex justify-between items-center">
|
||
<h2 class="card-title">작업장 현황</h2>
|
||
<div class="flex items-center" style="gap: 12px;">
|
||
<select id="categorySelect" class="form-select" style="width: 200px;">
|
||
<option value="">공장을 선택하세요</option>
|
||
</select>
|
||
<button class="btn btn-primary btn-sm" id="refreshMapBtn">
|
||
새로고침
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<!-- 지도 영역 -->
|
||
<div id="workplaceMapContainer" style="position: relative; min-height: 500px; display: none;">
|
||
<canvas id="workplaceMapCanvas" style="width: 100%; max-width: 100%; cursor: pointer; border: 2px solid var(--gray-300); border-radius: var(--radius-md);"></canvas>
|
||
<div id="mapLegend" style="position: absolute; top: 16px; right: 16px; background: white; padding: 16px; border-radius: var(--radius-md); box-shadow: var(--shadow-md);">
|
||
<h4 style="font-size: var(--text-sm); font-weight: 700; margin-bottom: 12px;">범례</h4>
|
||
<div style="display: flex; flex-direction: column; gap: 8px;">
|
||
<div style="display: flex; align-items: center; gap: 8px;">
|
||
<div style="width: 16px; height: 16px; background: rgba(59, 130, 246, 0.3); border: 2px solid rgb(59, 130, 246); border-radius: 4px;"></div>
|
||
<span style="font-size: var(--text-sm);">작업 중 (내부 작업자)</span>
|
||
</div>
|
||
<div style="display: flex; align-items: center; gap: 8px;">
|
||
<div style="width: 16px; height: 16px; background: rgba(168, 85, 247, 0.3); border: 2px solid rgb(168, 85, 247); border-radius: 4px;"></div>
|
||
<span style="font-size: var(--text-sm);">방문 예정 (외부 인원)</span>
|
||
</div>
|
||
<div style="display: flex; align-items: center; gap: 8px;">
|
||
<div style="width: 16px; height: 16px; background: rgba(34, 197, 94, 0.3); border: 2px solid rgb(34, 197, 94); border-radius: 4px;"></div>
|
||
<span style="font-size: var(--text-sm);">작업 + 방문</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 안내 메시지 -->
|
||
<div id="mapPlaceholder" style="display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 400px; color: var(--gray-500);">
|
||
<div style="font-size: 48px; margin-bottom: 16px;">🏭</div>
|
||
<h3 style="margin-bottom: 8px;">공장을 선택하세요</h3>
|
||
<p style="font-size: var(--text-sm);">위에서 공장을 선택하면 작업장 현황을 확인할 수 있습니다.</p>
|
||
</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>
|
||
|
||
<!-- 작업장 상세 정보 모달 -->
|
||
<div id="workplaceDetailModal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 1000; align-items: center; justify-content: center;">
|
||
<div style="background: white; border-radius: var(--radius-lg); padding: 32px; max-width: 800px; width: 90%; max-height: 80vh; overflow-y: auto; box-shadow: var(--shadow-2xl);">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px;">
|
||
<h2 id="modalWorkplaceName" style="margin: 0; font-size: var(--text-2xl); font-weight: 700;"></h2>
|
||
<button class="btn btn-secondary btn-sm" onclick="closeWorkplaceModal()">닫기</button>
|
||
</div>
|
||
|
||
<!-- 내부 작업자 -->
|
||
<div id="internalWorkersSection" style="margin-bottom: 24px;">
|
||
<h3 style="font-size: var(--text-lg); font-weight: 600; margin-bottom: 16px; color: var(--primary-600);">👷 내부 작업자</h3>
|
||
<div id="internalWorkersList"></div>
|
||
</div>
|
||
|
||
<!-- 외부 방문자 -->
|
||
<div id="externalVisitorsSection">
|
||
<h3 style="font-size: var(--text-lg); font-weight: 600; margin-bottom: 16px; color: var(--purple-600);">🚪 외부 방문자</h3>
|
||
<div id="externalVisitorsList"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</body>
|
||
|
||
</html> |