Files
tk-factory-services/system1-factory/web/pages/work/report-create.html
Hyungi Ahn 0de9d5bb48 feat(sso): 인앱 브라우저 SSO 토큰 릴레이 — 카톡 WebView 쿠키 미공유 해결
카카오톡 인앱 WebView는 서브도메인 간 쿠키를 공유하지 않아
tkds에서 로그인 후 tkfb로 리다이렉트 시 인증이 풀리는 문제.

- sso-relay.js: URL hash의 _sso= 토큰을 로컬 쿠키+localStorage로 설정
- gateway dashboard: 로그인 후 redirect URL에 #_sso=<token> 추가
- 전 서비스 HTML: core JS 직전에 sso-relay.js 로드 (81개 파일)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:44:02 +09:00

164 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>작업보고서 작성 - TK 공장관리</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/static/css/tkfb.css?v=2026040103">
<link rel="stylesheet" href="/css/daily-work-report.css?v=2026031401">
</head>
<body class="bg-gray-50">
<header class="bg-orange-700 text-white sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-14">
<div class="flex items-center gap-3">
<button id="mobileMenuBtn" class="lg:hidden text-orange-200 hover:text-white">
<i class="fas fa-bars text-xl"></i>
</button>
<i class="fas fa-industry text-xl text-orange-200"></i>
<h1 class="text-lg font-semibold">TK 공장관리</h1>
</div>
<div class="flex items-center gap-4">
<span id="headerUserName" class="text-sm hidden sm:block">-</span>
<div id="headerUserAvatar" class="w-8 h-8 bg-orange-600 rounded-full flex items-center justify-center text-sm font-bold">-</div>
<button onclick="doLogout()" class="text-orange-200 hover:text-white" title="로그아웃">
<i class="fas fa-sign-out-alt"></i>
</button>
</div>
</div>
</div>
</header>
<!-- Mobile overlay -->
<div id="mobileOverlay" class="hidden fixed inset-0 bg-black/50 z-30 lg:hidden"></div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 fade-in">
<div class="flex gap-6">
<!-- Sidebar Nav -->
<nav id="sideNav" class="hidden lg:flex flex-col gap-1 w-52 flex-shrink-0 pt-2 fixed lg:static z-40 bg-white lg:bg-transparent p-4 lg:p-0 rounded-lg lg:rounded-none shadow-lg lg:shadow-none top-14 left-0 bottom-0 overflow-y-auto"></nav>
<div class="flex-1 min-w-0">
<!-- 탭 메뉴 -->
<div class="tab-menu" style="margin-bottom: 1.5rem;">
<button class="tab-btn active" id="tbmReportTab" onclick="switchTab('tbm')">
작업보고서 작성
</button>
<button class="tab-btn" id="completedReportTab" onclick="switchTab('completed')">
작성 완료 보고서
</button>
</div>
<!-- 메시지 영역 -->
<div id="message-container"></div>
<!-- TBM 작업보고 섹션 -->
<div id="tbmReportSection" class="step-section active">
<div id="tbmWorkList"></div>
</div>
<!-- 작성 완료 보고서 섹션 -->
<div id="completedReportSection" class="step-section" style="display: none;">
<div class="form-group" style="max-width: 300px; margin-bottom: 1.25rem;">
<label for="completedReportDate" class="form-label">조회 날짜</label>
<input type="date" id="completedReportDate" class="form-input" onchange="loadCompletedReports()">
</div>
<div id="completedReportsList"></div>
</div>
</div>
</div>
</div>
<!-- 저장 결과 모달 -->
<div id="saveResultModal" class="modal-overlay" style="display: none;">
<div class="modal-container result-modal">
<div class="modal-header">
<h2 id="resultModalTitle">저장 결과</h2>
<button class="modal-close-btn" onclick="closeSaveResultModal()">×</button>
</div>
<div class="modal-body">
<div id="resultModalContent" class="result-content"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclick="closeSaveResultModal()">확인</button>
</div>
</div>
</div>
<!-- 작업장소 선택 모달 (지도 기반) -->
<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;">작업장소 선택</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;">
<div id="categorySelectionArea">
<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>
</div>
<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 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;">지도에서 작업장을 클릭하여 선택하세요</div>
<div style="text-align: center; position: relative; display: inline-block; max-width: 100%;">
<canvas id="workplaceMapCanvas" style="max-width: 100%; border-radius: 0.5rem; cursor: pointer; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"></canvas>
</div>
</div>
<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>
</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;"></div>
</div>
<div style="display: flex; gap: 0.75rem; justify-content: flex-end; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid #e5e7eb;">
<button type="button" class="btn btn-secondary" onclick="closeWorkplaceModal()">취소</button>
<button type="button" class="btn btn-primary" id="confirmWorkplaceBtn" onclick="confirmWorkplaceSelection()" disabled>선택 완료</button>
</div>
</div>
</div>
</div>
</div>
<!-- 시간 선택 팝오버 -->
<div id="timePickerOverlay" class="time-picker-overlay" style="display: none;" onclick="closeTimePicker()">
<div class="time-picker-popup" onclick="event.stopPropagation()">
<div class="time-picker-header">
<h3 id="timePickerTitle">작업시간 선택</h3>
<button class="time-picker-close" onclick="closeTimePicker()">&times;</button>
</div>
<div class="quick-time-grid">
<button type="button" class="time-btn" onclick="setTimeValue(0.5)"><span class="time-value">30분</span></button>
<button type="button" class="time-btn" onclick="setTimeValue(1)"><span class="time-value">1시간</span></button>
<button type="button" class="time-btn" onclick="setTimeValue(2)"><span class="time-value">2시간</span></button>
<button type="button" class="time-btn" onclick="setTimeValue(4)"><span class="time-value">4시간</span></button>
<button type="button" class="time-btn" onclick="setTimeValue(8)"><span class="time-value">8시간</span></button>
</div>
<div class="time-adjust-area">
<span class="current-time-label">현재:</span>
<strong id="currentTimeDisplay" class="current-time-value">0시간</strong>
<div class="adjust-buttons">
<button type="button" class="adjust-btn" onclick="adjustTime(-0.5)">-30분</button>
<button type="button" class="adjust-btn" onclick="adjustTime(0.5)">+30분</button>
</div>
</div>
<button type="button" class="confirm-btn" onclick="confirmTimeSelection()">확인</button>
</div>
</div>
<script src="/js/sso-relay.js?v=20260401"></script>
<script src="/static/js/tkfb-core.js?v=2026040105"></script>
<script src="/js/api-base.js?v=2026031401"></script>
<script src="/js/common/utils.js?v=2026031401"></script>
<script src="/js/common/base-state.js?v=2026031401"></script>
<script src="/js/daily-work-report/state.js?v=2026031401"></script>
<script src="/js/daily-work-report/utils.js?v=2026031401"></script>
<script src="/js/daily-work-report/api.js?v=2026031401"></script>
<script defer src="/js/daily-work-report.js?v=2026031401"></script>
<script>initAuth();</script>
</body>
</html>