feat: 권한 탭 분리 + 부서 인원 표시 + 다수 시스템 개선
- tkuser: 권한 관리를 별도 탭으로 분리, 부서 클릭 시 소속 인원 목록 표시 - system1: 모바일 UI 개선, nginx 권한 보정, 신고 카테고리 타입 마이그레이션 - system2: 신고 상세/보고서 개선, 내 보고서 페이지 추가 - system3: 이슈 뷰/수신함/관리함 개선 - gateway: 포털 라우팅 수정 - user-management API: 부서별 권한 벌크 설정 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
|
||||
.type-badge.nonconformity { background: #fff7ed; color: #c2410c; }
|
||||
.type-badge.safety { background: #fef2f2; color: #b91c1c; }
|
||||
.type-badge.facility { background: #eff6ff; color: #1d4ed8; }
|
||||
|
||||
/* 심각도 배지 */
|
||||
.severity-badge {
|
||||
@@ -441,6 +442,29 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 유형 이관 모달 -->
|
||||
<div class="modal-overlay" id="transferModal">
|
||||
<div class="modal-content">
|
||||
<h3 class="modal-title">유형 이관</h3>
|
||||
<div class="modal-form-group">
|
||||
<label>이관할 유형</label>
|
||||
<select id="transferCategoryType">
|
||||
<option value="">유형 선택</option>
|
||||
<option value="safety">안전</option>
|
||||
<option value="facility">시설설비</option>
|
||||
<option value="nonconformity">부적합</option>
|
||||
</select>
|
||||
</div>
|
||||
<p style="font-size: 0.8125rem; color: #6b7280; margin-top: 0.5rem;">
|
||||
유형을 변경하면 해당 유형의 목록에서 조회됩니다. 원래 카테고리/항목 정보는 유지됩니다.
|
||||
</p>
|
||||
<div class="modal-actions">
|
||||
<button class="action-btn" onclick="closeTransferModal()">취소</button>
|
||||
<button class="action-btn primary" onclick="submitTransfer()">이관</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 사진 확대 모달 -->
|
||||
<div class="photo-modal" id="photoModal" onclick="closePhotoModal()">
|
||||
<span class="photo-modal-close">×</span>
|
||||
|
||||
@@ -18,39 +18,6 @@
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.report-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
background: white;
|
||||
padding: 0.875rem 1rem;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.report-header .back-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 1.5rem;
|
||||
cursor: pointer;
|
||||
padding: 0.25rem;
|
||||
color: #374151;
|
||||
line-height: 1;
|
||||
}
|
||||
.report-header h1 {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 700;
|
||||
color: #1f2937;
|
||||
}
|
||||
.report-header .header-link {
|
||||
margin-left: auto;
|
||||
font-size: 0.8125rem;
|
||||
color: #6b7280;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Step indicator */
|
||||
.step-indicator {
|
||||
display: flex;
|
||||
@@ -506,13 +473,6 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header -->
|
||||
<div class="report-header">
|
||||
<button class="back-btn" onclick="history.back()">←</button>
|
||||
<h1>신고 등록</h1>
|
||||
<a href="/pages/safety/report-status.html" class="header-link">신고현황 →</a>
|
||||
</div>
|
||||
|
||||
<!-- Step Indicator (5 steps) -->
|
||||
<div class="step-indicator">
|
||||
<div class="step active"><span class="step-dot">1</span><span>유형</span></div>
|
||||
|
||||
327
system2-report/web/pages/safety/my-reports.html
Normal file
327
system2-report/web/pages/safety/my-reports.html
Normal file
@@ -0,0 +1,327 @@
|
||||
<!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/common.css?v=2">
|
||||
<link rel="stylesheet" href="/css/project-management.css?v=3">
|
||||
<link rel="icon" type="image/png" href="/img/favicon.png">
|
||||
<script src="/js/api-base.js"></script>
|
||||
<script src="/js/app-init.js?v=2" defer></script>
|
||||
<script src="https://instant.page/5.2.0" type="module"></script>
|
||||
<style>
|
||||
/* 통계 카드 */
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: white;
|
||||
padding: 1.25rem;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.875rem;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.stat-card.reported .stat-number { color: #3b82f6; }
|
||||
.stat-card.received .stat-number { color: #f97316; }
|
||||
.stat-card.in_progress .stat-number { color: #8b5cf6; }
|
||||
.stat-card.completed .stat-number { color: #10b981; }
|
||||
|
||||
/* 필터 바 */
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 1.5rem;
|
||||
padding: 1rem 1.25rem;
|
||||
background: white;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.filter-bar select,
|
||||
.filter-bar input {
|
||||
padding: 0.625rem 0.875rem;
|
||||
border: 1px solid #d1d5db;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.875rem;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.filter-bar select:focus,
|
||||
.filter-bar input:focus {
|
||||
outline: none;
|
||||
border-color: #ef4444;
|
||||
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
|
||||
}
|
||||
|
||||
.btn-new-report {
|
||||
margin-left: auto;
|
||||
padding: 0.625rem 1.25rem;
|
||||
background: #ef4444;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.btn-new-report:hover {
|
||||
background: #dc2626;
|
||||
}
|
||||
|
||||
/* 신고 목록 */
|
||||
.issue-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.issue-card {
|
||||
background: white;
|
||||
border-radius: 0.75rem;
|
||||
padding: 1.25rem;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.issue-card:hover {
|
||||
border-color: #fecaca;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.issue-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.issue-id {
|
||||
font-size: 0.875rem;
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.issue-status {
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.issue-status.reported {
|
||||
background: #dbeafe;
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.issue-status.received {
|
||||
background: #fed7aa;
|
||||
color: #c2410c;
|
||||
}
|
||||
|
||||
.issue-status.in_progress {
|
||||
background: #e9d5ff;
|
||||
color: #7c3aed;
|
||||
}
|
||||
|
||||
.issue-status.completed {
|
||||
background: #d1fae5;
|
||||
color: #047857;
|
||||
}
|
||||
|
||||
.issue-status.closed {
|
||||
background: #f3f4f6;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.issue-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.issue-category-badge {
|
||||
display: inline-block;
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
margin-right: 0.5rem;
|
||||
background: #fef2f2;
|
||||
color: #b91c1c;
|
||||
}
|
||||
|
||||
/* 유형별 배지 색상 */
|
||||
.type-badge-safety {
|
||||
background: #fef2f2;
|
||||
color: #b91c1c;
|
||||
}
|
||||
|
||||
.type-badge-facility {
|
||||
background: #eff6ff;
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.type-badge-nonconformity {
|
||||
background: #fefce8;
|
||||
color: #a16207;
|
||||
}
|
||||
|
||||
.issue-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
font-size: 0.875rem;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.issue-meta-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.375rem;
|
||||
}
|
||||
|
||||
.issue-photos {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.issue-photos img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
object-fit: cover;
|
||||
border-radius: 0.375rem;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
/* 빈 상태 */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 4rem 1.5rem;
|
||||
color: #6b7280;
|
||||
background: white;
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
|
||||
.empty-state-title {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.filter-bar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.btn-new-report {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="work-report-container">
|
||||
<div id="navbar-container"></div>
|
||||
|
||||
<main class="work-report-main">
|
||||
<div class="dashboard-main">
|
||||
<div class="page-header">
|
||||
<div class="page-title-section">
|
||||
<h1 class="page-title">내 신고 현황</h1>
|
||||
<p class="page-description">내가 신고한 안전, 시설설비, 부적합 현황을 확인합니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 통계 카드 -->
|
||||
<div class="stats-grid" id="statsGrid">
|
||||
<div class="stat-card reported">
|
||||
<div class="stat-number" id="statReported">-</div>
|
||||
<div class="stat-label">신고</div>
|
||||
</div>
|
||||
<div class="stat-card received">
|
||||
<div class="stat-number" id="statReceived">-</div>
|
||||
<div class="stat-label">접수</div>
|
||||
</div>
|
||||
<div class="stat-card in_progress">
|
||||
<div class="stat-number" id="statProgress">-</div>
|
||||
<div class="stat-label">처리중</div>
|
||||
</div>
|
||||
<div class="stat-card completed">
|
||||
<div class="stat-number" id="statCompleted">-</div>
|
||||
<div class="stat-label">완료</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 필터 바 -->
|
||||
<div class="filter-bar">
|
||||
<select id="filterType">
|
||||
<option value="">전체 유형</option>
|
||||
<option value="safety">안전</option>
|
||||
<option value="facility">시설설비</option>
|
||||
<option value="nonconformity">부적합</option>
|
||||
</select>
|
||||
|
||||
<select id="filterStatus">
|
||||
<option value="">전체 상태</option>
|
||||
<option value="reported">신고</option>
|
||||
<option value="received">접수</option>
|
||||
<option value="in_progress">처리중</option>
|
||||
<option value="completed">완료</option>
|
||||
<option value="closed">종료</option>
|
||||
</select>
|
||||
|
||||
<input type="date" id="filterStartDate" title="시작일">
|
||||
<input type="date" id="filterEndDate" title="종료일">
|
||||
|
||||
<a href="/pages/safety/issue-report.html" class="btn-new-report">+ 신고하기</a>
|
||||
</div>
|
||||
|
||||
<!-- 신고 목록 -->
|
||||
<div class="issue-list" id="issueList">
|
||||
<div class="empty-state">
|
||||
<div class="empty-state-title">로딩 중...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="/js/my-report-list.js?v=1"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user