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:
Hyungi Ahn
2026-02-02 15:09:37 +09:00
parent 09b3cf8e65
commit 4b158de1eb
31 changed files with 298 additions and 946 deletions

View File

@@ -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) {

View File

@@ -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;">&times;</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;">
<!-- 작업장소 목록 -->

View File

@@ -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>

View File

@@ -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>