refactor: 전체 페이지 이모지 제거 및 사이드바 레이아웃 수정
- 모든 페이지에서 이모지 제거 (CODING_GUIDE 준수) - admin/ (9개), safety/ (7개), work/ (4개) - attendance/ (8개), profile/ (2개) - 사이드바 CSS에 누락된 컨테이너 클래스 추가 - work-report-container, analysis-container, dashboard-main - 사이드바 토글 시 메인 콘텐츠 정상 반응하도록 수정 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
<link rel="icon" type="image/png" href="/img/favicon.png">
|
||||
<script src="/js/auth-check.js?v=1" defer></script>
|
||||
<script type="module" src="/js/api-config.js?v=3"></script>
|
||||
<script type="module" src="/js/load-navbar.js"></script>
|
||||
<script type="module" src="/js/load-sidebar.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
@@ -26,20 +28,17 @@
|
||||
|
||||
<!-- 페이지 헤더 -->
|
||||
<header class="page-header fade-in">
|
||||
<h1 class="page-title">
|
||||
<span class="icon">📊</span>
|
||||
작업 분석
|
||||
</h1>
|
||||
<h1 class="page-title">작업 분석</h1>
|
||||
<p class="page-subtitle">기간별/프로젝트별 작업 현황을 분석하고 통계를 확인합니다</p>
|
||||
</header>
|
||||
|
||||
<!-- 분석 모드 탭 -->
|
||||
<nav class="analysis-tabs fade-in">
|
||||
<button class="tab-button active" data-mode="period" onclick="switchAnalysisMode('period')">
|
||||
📅 기간별 분석
|
||||
기간별 분석
|
||||
</button>
|
||||
<button class="tab-button" data-mode="project" onclick="switchAnalysisMode('project')">
|
||||
🏗️ 프로젝트별 분석
|
||||
프로젝트별 분석
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
@@ -48,33 +47,23 @@
|
||||
<div class="controls-grid">
|
||||
<!-- 기간 설정 -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="startDate">
|
||||
<span class="icon">📅</span>
|
||||
시작일
|
||||
</label>
|
||||
<label class="form-label" for="startDate">시작일</label>
|
||||
<input type="date" id="startDate" class="form-input" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="endDate">
|
||||
<span class="icon">📅</span>
|
||||
종료일
|
||||
</label>
|
||||
<label class="form-label" for="endDate">종료일</label>
|
||||
<input type="date" id="endDate" class="form-input" required>
|
||||
</div>
|
||||
|
||||
<!-- 기간 확정 버튼 -->
|
||||
<div class="form-group">
|
||||
<button class="confirm-period-button" onclick="confirmPeriod()">
|
||||
<span class="icon">✅</span>
|
||||
기간 확정
|
||||
</button>
|
||||
<button class="confirm-period-button" onclick="confirmPeriod()">기간 확정</button>
|
||||
</div>
|
||||
|
||||
<!-- 기간 상태 표시 -->
|
||||
<div class="form-group" id="periodStatusGroup" style="display: none;">
|
||||
<div class="period-status">
|
||||
<span class="icon">✅</span>
|
||||
<div>
|
||||
<div style="font-size: 0.8rem; opacity: 0.8; margin-bottom: 2px;">분석 기간</div>
|
||||
<div id="periodText">기간이 설정되지 않았습니다</div>
|
||||
@@ -96,19 +85,15 @@
|
||||
<div id="analysisTabNavigation" class="tab-navigation" style="display: none;">
|
||||
<div class="tab-buttons">
|
||||
<button class="tab-button active" data-tab="work-status">
|
||||
<span class="icon">📈</span>
|
||||
기간별 작업 현황
|
||||
</button>
|
||||
<button class="tab-button" data-tab="project-distribution">
|
||||
<span class="icon">🥧</span>
|
||||
프로젝트별 분포
|
||||
</button>
|
||||
<button class="tab-button" data-tab="worker-performance">
|
||||
<span class="icon">👤</span>
|
||||
작업자별 성과
|
||||
</button>
|
||||
<button class="tab-button" data-tab="error-analysis">
|
||||
<span class="icon">⚠️</span>
|
||||
오류 분석
|
||||
</button>
|
||||
</div>
|
||||
@@ -125,14 +110,8 @@
|
||||
<div id="work-status-tab" class="tab-content active">
|
||||
<div class="chart-container table-type">
|
||||
<div class="chart-header">
|
||||
<h3 class="chart-title">
|
||||
<span class="icon">📈</span>
|
||||
기간별 작업 현황
|
||||
</h3>
|
||||
<button class="chart-analyze-btn" onclick="analyzeWorkStatus()" disabled>
|
||||
<span class="icon">🔍</span>
|
||||
분석 실행
|
||||
</button>
|
||||
<h3 class="chart-title">기간별 작업 현황</h3>
|
||||
<button class="chart-analyze-btn" onclick="analyzeWorkStatus()" disabled>분석 실행</button>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<table class="work-report-table" id="workReportTable">
|
||||
@@ -172,14 +151,8 @@
|
||||
<div id="project-distribution-tab" class="tab-content">
|
||||
<div class="chart-container table-type">
|
||||
<div class="chart-header">
|
||||
<h3 class="chart-title">
|
||||
<span class="icon">📋</span>
|
||||
프로젝트별 작업 분포
|
||||
</h3>
|
||||
<button class="chart-analyze-btn" onclick="analyzeProjectDistribution()" disabled>
|
||||
<span class="icon">🔍</span>
|
||||
분석 실행
|
||||
</button>
|
||||
<h3 class="chart-title">프로젝트별 작업 분포</h3>
|
||||
<button class="chart-analyze-btn" onclick="analyzeProjectDistribution()" disabled>분석 실행</button>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<table class="production-report-table" id="projectDistributionTable">
|
||||
@@ -216,14 +189,8 @@
|
||||
<div id="worker-performance-tab" class="tab-content">
|
||||
<div class="chart-container chart-type">
|
||||
<div class="chart-header">
|
||||
<h3 class="chart-title">
|
||||
<span class="icon">👤</span>
|
||||
작업자별 성과
|
||||
</h3>
|
||||
<button class="chart-analyze-btn" onclick="analyzeWorkerPerformance()" disabled>
|
||||
<span class="icon">🔍</span>
|
||||
분석 실행
|
||||
</button>
|
||||
<h3 class="chart-title">작업자별 성과</h3>
|
||||
<button class="chart-analyze-btn" onclick="analyzeWorkerPerformance()" disabled>분석 실행</button>
|
||||
</div>
|
||||
<canvas id="workerPerformanceChart" class="chart-canvas"></canvas>
|
||||
</div>
|
||||
@@ -233,14 +200,8 @@
|
||||
<div id="error-analysis-tab" class="tab-content">
|
||||
<div class="chart-container table-type">
|
||||
<div class="chart-header">
|
||||
<h3 class="chart-title">
|
||||
<span class="icon">⚠️</span>
|
||||
오류 분석
|
||||
</h3>
|
||||
<button class="chart-analyze-btn" onclick="analyzeErrorAnalysis()" disabled>
|
||||
<span class="icon">🔍</span>
|
||||
분석 실행
|
||||
</button>
|
||||
<h3 class="chart-title">오류 분석</h3>
|
||||
<button class="chart-analyze-btn" onclick="analyzeErrorAnalysis()" disabled>분석 실행</button>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<table class="error-analysis-table" id="errorAnalysisTable">
|
||||
@@ -279,10 +240,7 @@
|
||||
<!-- 상세 데이터 테이블 -->
|
||||
<div id="dataTableContainer" class="data-table-container" style="display: none;">
|
||||
<div class="table-header">
|
||||
<h3 class="table-title">
|
||||
<span class="icon">📋</span>
|
||||
상세 작업 데이터
|
||||
</h3>
|
||||
<h3 class="table-title">상세 작업 데이터</h3>
|
||||
</div>
|
||||
<div style="overflow-x: auto;">
|
||||
<table class="data-table" id="detailDataTable">
|
||||
@@ -330,13 +288,13 @@
|
||||
if (useCache && this.cache.has(cacheKey)) {
|
||||
const cached = this.cache.get(cacheKey);
|
||||
if (Date.now() - cached.timestamp < this.CACHE_DURATION) {
|
||||
console.log('📦 캐시에서 데이터 반환:', endpoint);
|
||||
console.log('[Cache] 캐시에서 데이터 반환:', endpoint);
|
||||
return cached.data;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('🌐 API 호출:', endpoint);
|
||||
console.log('[API] 호출:', endpoint);
|
||||
const response = await window.apiCall(endpoint, method, data);
|
||||
|
||||
// 성공 시 캐시 저장
|
||||
@@ -349,34 +307,34 @@
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error('❌ API 호출 실패:', endpoint, error);
|
||||
console.error('[Error] API 호출 실패:', endpoint, error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
// 배치 API 호출 (병렬 처리)
|
||||
async batchCall(requests) {
|
||||
console.log('🔄 배치 API 호출 시작:', requests.length, '개');
|
||||
console.log('[Batch] API 호출 시작:', requests.length, '개');
|
||||
|
||||
const promises = requests.map(async (req) => {
|
||||
try {
|
||||
const result = await this.call(req.endpoint, req.method, req.data, req.useCache);
|
||||
return { name: req.name, success: true, data: result };
|
||||
} catch (error) {
|
||||
console.warn(`⚠️ ${req.name} API 실패:`, error);
|
||||
console.warn(`[Warning] ${req.name} API 실패:`, error);
|
||||
return { name: req.name, success: false, error: error.message, data: null };
|
||||
}
|
||||
});
|
||||
|
||||
const results = await Promise.all(promises);
|
||||
console.log('✅ 배치 API 호출 완료');
|
||||
console.log('[Complete] 배치 API 호출 완료');
|
||||
return results;
|
||||
},
|
||||
|
||||
// 캐시 초기화
|
||||
clearCache() {
|
||||
this.cache.clear();
|
||||
console.log('🗑️ API 캐시 초기화');
|
||||
console.log('[Clear] API 캐시 초기화');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -453,7 +411,7 @@
|
||||
toast.className = `error-toast toast-${type}`;
|
||||
toast.innerHTML = `
|
||||
<div class="toast-content">
|
||||
<span class="toast-icon">${type === 'error' ? '⚠️' : type === 'success' ? '✅' : 'ℹ️'}</span>
|
||||
<span class="toast-icon">${type === 'error' ? '[!]' : type === 'success' ? '[v]' : '[i]'}</span>
|
||||
<span class="toast-message">${message}</span>
|
||||
<button class="toast-close" onclick="this.parentElement.parentElement.remove()">×</button>
|
||||
</div>
|
||||
@@ -491,7 +449,7 @@
|
||||
const userMessage = this.UserMessages[errorType];
|
||||
|
||||
// 콘솔에 상세 로그
|
||||
console.error(`❌ [${context}] ${errorType.toUpperCase()} 오류:`, error);
|
||||
console.error(`[Error] [${context}] ${errorType.toUpperCase()} 오류:`, error);
|
||||
|
||||
// 사용자에게 친화적 메시지 표시
|
||||
if (showUserMessage) {
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
<link rel="stylesheet" href="/css/daily-work-report.css?v=11">
|
||||
<link rel="icon" type="image/png" href="/img/favicon.png">
|
||||
<script src="/js/auth-check.js" defer></script>
|
||||
<script type="module" src="/js/api-config.js"></script>
|
||||
<script type="module" src="/js/load-navbar.js"></script>
|
||||
<script type="module" src="/js/load-sidebar.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="work-report-container">
|
||||
@@ -77,17 +80,13 @@
|
||||
<div id="workplaceModal" class="modal-overlay" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 1002; align-items: center; justify-content: center; overflow-y: auto; padding: 2rem 0;">
|
||||
<div class="modal-container" style="background: white; border-radius: 8px; max-width: 1000px; width: 90%; max-height: none; margin: auto; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); display: flex; flex-direction: column;">
|
||||
<div class="modal-header" style="padding: 1.5rem; border-bottom: 1px solid #e5e7eb; display: flex; justify-content: space-between; align-items: center;">
|
||||
<h2 style="font-size: 1.25rem; font-weight: 600; color: #111827; margin: 0;">
|
||||
<span style="margin-right: 0.5rem;">🗺️</span>작업장소 선택
|
||||
</h2>
|
||||
<h2 style="font-size: 1.25rem; font-weight: 600; color: #111827; margin: 0;">작업장소 선택</h2>
|
||||
<button class="modal-close" onclick="closeWorkplaceModal()" style="background: none; border: none; font-size: 1.5rem; cursor: pointer; color: #6b7280; padding: 0; width: 2rem; height: 2rem; display: flex; align-items: center; justify-content: center; border-radius: 4px;">×</button>
|
||||
</div>
|
||||
<div class="modal-body" style="padding: 1.5rem; flex: 1; overflow-y: visible;">
|
||||
<!-- 1단계: 카테고리 선택 -->
|
||||
<div id="categorySelectionArea">
|
||||
<h3 style="font-size: 1rem; font-weight: 600; margin-bottom: 0.75rem; color: #374151;">
|
||||
<span style="margin-right: 0.5rem;">🏭</span>공장 선택
|
||||
</h3>
|
||||
<h3 style="font-size: 1rem; font-weight: 600; margin-bottom: 0.75rem; color: #374151;">공장 선택</h3>
|
||||
<div id="workplaceCategoryList" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 0.75rem;">
|
||||
<!-- 카테고리 버튼들 -->
|
||||
</div>
|
||||
@@ -96,14 +95,12 @@
|
||||
<!-- 2단계: 작업장 선택 (지도 + 리스트) -->
|
||||
<div id="workplaceSelectionArea" style="display: none; margin-top: 1.5rem;">
|
||||
<h3 style="font-size: 1rem; font-weight: 600; margin-bottom: 0.75rem; color: #374151;">
|
||||
<span style="margin-right: 0.5rem;">📍</span>
|
||||
<span id="selectedCategoryTitle">작업장 선택</span>
|
||||
</h3>
|
||||
|
||||
<!-- 지도 기반 선택 영역 -->
|
||||
<div id="layoutMapArea" style="display: none; margin-bottom: 1.5rem; padding: 1rem; background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 0.5rem;">
|
||||
<div style="font-size: 0.875rem; color: #6b7280; margin-bottom: 0.75rem;">
|
||||
<span style="margin-right: 0.25rem;">🗺️</span>
|
||||
지도에서 작업장을 클릭하여 선택하세요
|
||||
</div>
|
||||
<div style="text-align: center; position: relative; display: inline-block; max-width: 100%;">
|
||||
@@ -114,10 +111,7 @@
|
||||
<!-- 리스트 선택 영역 -->
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.5rem;">
|
||||
<span style="font-size: 0.875rem; color: #6b7280;">
|
||||
<span style="margin-right: 0.25rem;">📋</span>
|
||||
리스트에서 선택
|
||||
</span>
|
||||
<span style="font-size: 0.875rem; color: #6b7280;">리스트에서 선택</span>
|
||||
</div>
|
||||
<div id="workplaceListArea" style="display: flex; flex-direction: column; gap: 0.5rem; max-height: 200px; overflow-y: auto; padding: 0.75rem; border: 1px solid #e5e7eb; border-radius: 0.5rem; background: white;">
|
||||
<!-- 작업장소 목록 -->
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
<link rel="stylesheet" href="/css/common.css?v=13">
|
||||
<link rel="stylesheet" href="/css/modern-dashboard.css?v=14">
|
||||
<link rel="stylesheet" href="/css/work-report-calendar.css?v=29">
|
||||
<script src="/js/auth-check.js" defer></script>
|
||||
<script type="module" src="/js/api-config.js"></script>
|
||||
<script type="module" src="/js/load-navbar.js"></script>
|
||||
<script type="module" src="/js/load-sidebar.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 네비게이션 헤더 -->
|
||||
@@ -18,7 +22,7 @@
|
||||
<div class="calendar-page-container">
|
||||
<!-- 페이지 제목 -->
|
||||
<div class="page-title-section">
|
||||
<h2 class="page-title">📅 작업 현황 확인</h2>
|
||||
<h2 class="page-title">작업 현황 확인</h2>
|
||||
<p class="page-subtitle">월별 작업자 현황을 한눈에 확인하세요</p>
|
||||
</div>
|
||||
|
||||
@@ -101,28 +105,28 @@
|
||||
<!-- 요약 정보 -->
|
||||
<div class="daily-summary">
|
||||
<div class="summary-card">
|
||||
<div class="summary-icon success">👥</div>
|
||||
<div class="summary-icon success"></div>
|
||||
<div class="summary-content">
|
||||
<div class="summary-label">총 작업자</div>
|
||||
<div class="summary-value" id="modalTotalWorkers">0명</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-icon primary">⏰</div>
|
||||
<div class="summary-icon primary"></div>
|
||||
<div class="summary-content">
|
||||
<div class="summary-label">총 작업시간</div>
|
||||
<div class="summary-value" id="modalTotalHours">0.0h</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-icon warning">📝</div>
|
||||
<div class="summary-icon warning"></div>
|
||||
<div class="summary-content">
|
||||
<div class="summary-label">작업 건수</div>
|
||||
<div class="summary-value" id="modalTotalTasks">0건</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-icon error">⚠️</div>
|
||||
<div class="summary-icon error"></div>
|
||||
<div class="summary-content">
|
||||
<div class="summary-label">오류 건수</div>
|
||||
<div class="summary-value" id="modalErrorCount">0건</div>
|
||||
@@ -151,7 +155,7 @@
|
||||
</div>
|
||||
|
||||
<div id="modalNoData" class="empty-state" style="display: none;">
|
||||
<div class="empty-icon">📭</div>
|
||||
<div class="empty-icon"></div>
|
||||
<h3>해당 날짜의 작업 보고서가 없습니다</h3>
|
||||
<p>다른 날짜를 선택해 주세요.</p>
|
||||
</div>
|
||||
@@ -172,10 +176,10 @@
|
||||
<!-- 탭 네비게이션 -->
|
||||
<div class="modal-tabs">
|
||||
<button class="tab-btn active" data-tab="existing" onclick="switchTab('existing')">
|
||||
📋 기존 작업 (0건)
|
||||
기존 작업 (0건)
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="new" onclick="switchTab('new')">
|
||||
➕ 새 작업 추가
|
||||
새 작업 추가
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -193,7 +197,7 @@
|
||||
</div>
|
||||
|
||||
<div id="noExistingWork" class="empty-state" style="display: none;">
|
||||
<div class="empty-icon">📝</div>
|
||||
<div class="empty-icon"></div>
|
||||
<h3>등록된 작업이 없습니다</h3>
|
||||
<p>"새 작업 추가" 탭에서 작업을 등록해보세요.</p>
|
||||
</div>
|
||||
@@ -271,12 +275,8 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeWorkEntryModal()">취소</button>
|
||||
<div class="footer-actions">
|
||||
<button type="button" class="btn btn-danger" id="deleteWorkBtn" onclick="deleteWork()" style="display: none;">
|
||||
🗑️ 삭제
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" id="saveWorkBtn" onclick="saveWorkEntry()">
|
||||
💾 저장
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger" id="deleteWorkBtn" onclick="deleteWork()" style="display: none;">삭제</button>
|
||||
<button type="button" class="btn btn-primary" id="saveWorkBtn" onclick="saveWorkEntry()">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
<link rel="icon" type="image/png" href="/img/favicon.png">
|
||||
<script src="/js/auth-check.js?v=1" defer></script>
|
||||
<script type="module" src="/js/api-config.js?v=3"></script>
|
||||
<script type="module" src="/js/load-navbar.js"></script>
|
||||
<script type="module" src="/js/load-sidebar.js"></script>
|
||||
<style>
|
||||
.date-group {
|
||||
margin-bottom: 2rem;
|
||||
@@ -67,10 +69,7 @@
|
||||
<div class="dashboard-main">
|
||||
<div class="page-header">
|
||||
<div class="page-title-section">
|
||||
<h1 class="page-title">
|
||||
<span class="title-icon">🛠️</span>
|
||||
TBM (Tool Box Meeting)
|
||||
</h1>
|
||||
<h1 class="page-title">TBM (Tool Box Meeting)</h1>
|
||||
<p class="page-description">아침 안전 회의 및 팀 구성 관리</p>
|
||||
</div>
|
||||
|
||||
@@ -82,11 +81,9 @@
|
||||
<!-- TBM 탭 -->
|
||||
<div class="code-tabs">
|
||||
<button class="tab-btn active" data-tab="tbm-input" onclick="switchTbmTab('tbm-input')">
|
||||
<span class="tab-icon">➕</span>
|
||||
TBM 입력
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="tbm-manage" onclick="switchTbmTab('tbm-manage')">
|
||||
<span class="tab-icon">📋</span>
|
||||
TBM 관리
|
||||
</button>
|
||||
</div>
|
||||
@@ -95,29 +92,20 @@
|
||||
<div id="tbm-input-tab" class="code-tab-content active">
|
||||
<div class="code-section">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">
|
||||
<span class="section-icon">🌅</span>
|
||||
오늘의 TBM
|
||||
</h2>
|
||||
<h2 class="section-title">오늘의 TBM</h2>
|
||||
<div class="section-actions">
|
||||
<button class="btn btn-primary" onclick="openNewTbmModal()">
|
||||
<span class="btn-icon">➕</span>
|
||||
새 TBM 시작
|
||||
</button>
|
||||
<button class="btn btn-primary" onclick="openNewTbmModal()">새 TBM 시작</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="code-stats">
|
||||
<span class="stat-item">
|
||||
<span class="stat-icon">📋</span>
|
||||
오늘 등록 <span id="todayTotalSessions">0</span>개
|
||||
</span>
|
||||
<span class="stat-item">
|
||||
<span class="stat-icon">✅</span>
|
||||
완료 <span id="todayCompletedSessions">0</span>개
|
||||
</span>
|
||||
<span class="stat-item">
|
||||
<span class="stat-icon">⏳</span>
|
||||
진행중 <span id="todayActiveSessions">0</span>개
|
||||
</span>
|
||||
</div>
|
||||
@@ -128,11 +116,11 @@
|
||||
|
||||
<!-- Empty State -->
|
||||
<div class="empty-state" id="todayEmptyState" style="display: none;">
|
||||
<div class="empty-icon">🛠️</div>
|
||||
<div class="empty-icon"></div>
|
||||
<h3>오늘 등록된 TBM이 없습니다</h3>
|
||||
<p>"새 TBM 시작" 버튼을 눌러 오늘의 TBM을 시작해보세요.</p>
|
||||
<button class="btn btn-primary" onclick="openNewTbmModal()">
|
||||
➕ 첫 TBM 시작하기
|
||||
첫 TBM 시작하기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -142,29 +130,20 @@
|
||||
<div id="tbm-manage-tab" class="code-tab-content">
|
||||
<div class="code-section">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">
|
||||
<span class="section-icon">📚</span>
|
||||
TBM 기록
|
||||
</h2>
|
||||
<h2 class="section-title">TBM 기록</h2>
|
||||
<div class="section-actions">
|
||||
<button class="btn btn-secondary" onclick="loadMoreTbmDays()" id="loadMoreBtn">
|
||||
<span class="btn-icon">📅</span>
|
||||
더 보기
|
||||
</button>
|
||||
<button class="btn btn-secondary" onclick="loadMoreTbmDays()" id="loadMoreBtn">더 보기</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="code-stats">
|
||||
<span class="stat-item">
|
||||
<span class="stat-icon">📋</span>
|
||||
총 <span id="totalSessions">0</span>개
|
||||
</span>
|
||||
<span class="stat-item">
|
||||
<span class="stat-icon">✅</span>
|
||||
완료 <span id="completedSessions">0</span>개
|
||||
</span>
|
||||
<span class="stat-item" id="viewModeIndicator" style="display: none;">
|
||||
<span class="stat-icon">👤</span>
|
||||
<span id="viewModeText">내 TBM만</span>
|
||||
</span>
|
||||
</div>
|
||||
@@ -176,7 +155,7 @@
|
||||
|
||||
<!-- Empty State -->
|
||||
<div class="empty-state" id="emptyState" style="display: none;">
|
||||
<div class="empty-icon">🛠️</div>
|
||||
<div class="empty-icon"></div>
|
||||
<h3>등록된 TBM 세션이 없습니다</h3>
|
||||
<p>TBM 입력 탭에서 새로운 TBM을 시작해보세요.</p>
|
||||
</div>
|
||||
@@ -216,12 +195,10 @@
|
||||
<div class="form-section">
|
||||
<div class="section-header" style="margin-bottom: 1rem;">
|
||||
<h3 style="font-size: 1.1rem; font-weight: 600; color: #1f2937;">
|
||||
<span style="margin-right: 0.5rem;">👷</span>
|
||||
작업자 및 작업 정보
|
||||
</h3>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<button type="button" class="btn btn-sm btn-secondary" onclick="openBulkSettingModal()" style="display: flex; align-items: center; gap: 0.25rem;">
|
||||
<span>📋</span>
|
||||
일괄 설정
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" onclick="openWorkerSelectionModal()">
|
||||
@@ -236,7 +213,6 @@
|
||||
<!-- 작업자 카드들이 여기에 동적으로 추가됩니다 -->
|
||||
<div class="empty-state-small" id="workerListEmpty" style="display: flex; align-items: center; justify-content: center; padding: 2rem; border: 2px dashed #d1d5db; border-radius: 0.5rem; color: #6b7280;">
|
||||
<div style="text-align: center;">
|
||||
<div style="font-size: 2rem; margin-bottom: 0.5rem;">👷♂️</div>
|
||||
<p>작업자를 선택해주세요</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -247,9 +223,7 @@
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeTbmModal()">취소</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveTbmSession()">
|
||||
💾 저장하기
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveTbmSession()">저장하기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -264,7 +238,7 @@
|
||||
|
||||
<div class="modal-body">
|
||||
<div style="background: #dbeafe; border: 1px solid #3b82f6; padding: 1rem; border-radius: 0.5rem; margin-bottom: 1.5rem;">
|
||||
<div style="font-weight: 600; color: #1e40af; margin-bottom: 0.25rem;">💡 일괄 설정</div>
|
||||
<div style="font-weight: 600; color: #1e40af; margin-bottom: 0.25rem;">일괄 설정</div>
|
||||
<div style="color: #1e40af; font-size: 0.9rem;">
|
||||
선택한 작업자들의 <strong>첫 번째 작업 라인</strong>에 동일한 정보가 적용됩니다.
|
||||
</div>
|
||||
@@ -290,7 +264,7 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label">프로젝트</label>
|
||||
<button type="button" id="bulkProjectBtn" onclick="openBulkItemSelect('project')" class="btn btn-secondary" style="width: 100%; text-align: left; justify-content: flex-start;">
|
||||
📁 프로젝트 선택
|
||||
프로젝트 선택
|
||||
</button>
|
||||
<input type="hidden" id="bulkProjectId">
|
||||
</div>
|
||||
@@ -299,14 +273,14 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label">공정 *</label>
|
||||
<button type="button" id="bulkWorkTypeBtn" onclick="openBulkItemSelect('workType')" class="btn btn-secondary" style="width: 100%; text-align: left; justify-content: flex-start;">
|
||||
⚙️ 공정 선택
|
||||
공정 선택
|
||||
</button>
|
||||
<input type="hidden" id="bulkWorkTypeId">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">작업 *</label>
|
||||
<button type="button" id="bulkTaskBtn" onclick="openBulkItemSelect('task')" class="btn btn-secondary" style="width: 100%; text-align: left; justify-content: flex-start;" disabled>
|
||||
🔧 작업 선택
|
||||
작업 선택
|
||||
</button>
|
||||
<input type="hidden" id="bulkTaskId">
|
||||
</div>
|
||||
@@ -315,7 +289,7 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label">작업장 *</label>
|
||||
<button type="button" id="bulkWorkplaceBtn" onclick="openBulkWorkplaceSelect()" class="btn btn-secondary" style="width: 100%; text-align: left; justify-content: flex-start;">
|
||||
📍 작업장 선택
|
||||
작업장 선택
|
||||
</button>
|
||||
<input type="hidden" id="bulkWorkplaceCategoryId">
|
||||
<input type="hidden" id="bulkWorkplaceId">
|
||||
@@ -326,7 +300,7 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeBulkSettingModal()">취소</button>
|
||||
<button type="button" class="btn btn-primary" onclick="applyBulkSettings()">
|
||||
✓ 선택한 작업자에 적용
|
||||
선택한 작업자에 적용
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -354,7 +328,7 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeWorkerSelectionModal()">취소</button>
|
||||
<button type="button" class="btn btn-primary" onclick="confirmWorkerSelection()">
|
||||
✓ 선택 완료
|
||||
선택 완료
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -392,7 +366,6 @@
|
||||
<!-- 1단계: 공장 선택 -->
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<h3 style="font-size: 1rem; font-weight: 600; margin-bottom: 0.75rem; color: #374151;">
|
||||
<span style="margin-right: 0.5rem;">🏭</span>
|
||||
1. 공장 선택
|
||||
</h3>
|
||||
<div id="categoryList" style="display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0.75rem; border: 1px solid #e5e7eb; border-radius: 0.5rem; background: #f9fafb;">
|
||||
@@ -403,14 +376,12 @@
|
||||
<!-- 2단계: 작업장 선택 (지도 + 리스트) -->
|
||||
<div id="workplaceSelectionArea" style="display: none;">
|
||||
<h3 style="font-size: 1rem; font-weight: 600; margin-bottom: 0.75rem; color: #374151;">
|
||||
<span style="margin-right: 0.5rem;">📍</span>
|
||||
2. 작업장 선택
|
||||
</h3>
|
||||
|
||||
<!-- 지도 기반 선택 영역 -->
|
||||
<div id="layoutMapArea" style="display: none; margin-bottom: 1.5rem; padding: 1rem; background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 0.5rem;">
|
||||
<div style="font-size: 0.875rem; color: #6b7280; margin-bottom: 0.75rem;">
|
||||
<span style="margin-right: 0.25rem;">🗺️</span>
|
||||
지도에서 작업장을 클릭하여 선택하세요
|
||||
</div>
|
||||
<div style="text-align: center; position: relative; display: inline-block; max-width: 100%;">
|
||||
@@ -421,10 +392,7 @@
|
||||
<!-- 리스트 기반 선택 (오류 대비용) -->
|
||||
<div>
|
||||
<div style="font-size: 0.875rem; color: #6b7280; margin-bottom: 0.75rem; display: flex; align-items: center; justify-content: space-between;">
|
||||
<span>
|
||||
<span style="margin-right: 0.25rem;">📋</span>
|
||||
리스트에서 선택 (지도 오류 시)
|
||||
</span>
|
||||
<span>리스트에서 선택 (지도 오류 시)</span>
|
||||
<button type="button" class="btn btn-sm btn-secondary" onclick="toggleWorkplaceList()" id="toggleListBtn">
|
||||
<span id="toggleListIcon">▼</span>
|
||||
리스트 보기
|
||||
@@ -442,7 +410,7 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeWorkplaceSelectModal()">취소</button>
|
||||
<button type="button" class="btn btn-primary" onclick="confirmWorkplaceSelection()" id="confirmWorkplaceBtn" disabled>
|
||||
✓ 선택 완료
|
||||
선택 완료
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -480,7 +448,7 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeTeamModal()">취소</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveTeamComposition()">
|
||||
👥 팀 구성 완료
|
||||
팀 구성 완료
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -503,7 +471,7 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeSafetyModal()">취소</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveSafetyChecklist()">
|
||||
✅ 안전 체크 완료
|
||||
안전 체크 완료
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -530,7 +498,7 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeCompleteModal()">취소</button>
|
||||
<button type="button" class="btn btn-primary" onclick="completeTbmSession()">
|
||||
✅ 완료
|
||||
완료
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -594,7 +562,7 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeHandoverModal()">취소</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveHandover()">
|
||||
📤 인계 요청
|
||||
인계 요청
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user