fix: 캘린더 모달 중복 카드 문제 및 삭제 권한 개선
- monthly_worker_status 조회 시 GROUP BY로 중복 데이터 합산 - 작업보고서 삭제 권한을 그룹장 이상으로 제한 (admin, system, group_leader) - 중복 데이터 정리를 위한 마이그레이션 SQL 추가 (009_fix_duplicate_monthly_status.sql) - synology_deployment 버전에도 동일 수정 적용
This commit is contained in:
184
synology_deployment/web-ui/pages/profile/admin-settings.html
Normal file
184
synology_deployment/web-ui/pages/profile/admin-settings.html
Normal file
@@ -0,0 +1,184 @@
|
||||
<!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/common.css?v=1">
|
||||
<link rel="stylesheet" href="/css/admin-settings.css?v=1">
|
||||
<link rel="icon" type="image/png" href="/img/favicon.png">
|
||||
<script src="/js/auth-check.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="work-report-container">
|
||||
<!-- 네비게이션 바 -->
|
||||
<div id="navbar-container"></div>
|
||||
|
||||
<!-- 헤더 -->
|
||||
<header class="work-report-header">
|
||||
<h1>⚙️ 관리자 설정</h1>
|
||||
<p class="subtitle">시스템 사용자 계정 및 권한을 관리합니다</p>
|
||||
</header>
|
||||
|
||||
<!-- 메인 콘텐츠 -->
|
||||
<main class="work-report-main">
|
||||
<!-- 뒤로가기 버튼 -->
|
||||
<a href="javascript:history.back()" class="back-button">
|
||||
← 뒤로가기
|
||||
</a>
|
||||
|
||||
<div class="dashboard-main">
|
||||
<div class="page-header">
|
||||
<div class="page-title-section">
|
||||
<h1 class="page-title">
|
||||
<span class="title-icon">⚙️</span>
|
||||
관리자 설정
|
||||
</h1>
|
||||
<p class="page-description">시스템 사용자 계정 및 권한을 관리합니다</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 사용자 관리 섹션 -->
|
||||
<div class="settings-section">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">
|
||||
<span class="section-icon">👥</span>
|
||||
사용자 계정 관리
|
||||
</h2>
|
||||
<button class="btn btn-primary" id="addUserBtn">
|
||||
<span class="btn-icon">➕</span>
|
||||
새 사용자 추가
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="users-container">
|
||||
<div class="users-header">
|
||||
<div class="search-box">
|
||||
<input type="text" id="userSearch" placeholder="사용자 검색..." class="search-input">
|
||||
<span class="search-icon">🔍</span>
|
||||
</div>
|
||||
<div class="filter-buttons">
|
||||
<button class="filter-btn active" data-filter="all">전체</button>
|
||||
<button class="filter-btn" data-filter="admin">관리자</button>
|
||||
<button class="filter-btn" data-filter="leader">그룹장</button>
|
||||
<button class="filter-btn" data-filter="user">작업자</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="users-table-container">
|
||||
<table class="users-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>사용자명</th>
|
||||
<th>아이디</th>
|
||||
<th>역할</th>
|
||||
<th>상태</th>
|
||||
<th>최종 로그인</th>
|
||||
<th>관리</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="usersTableBody">
|
||||
<!-- 사용자 목록이 여기에 동적으로 생성됩니다 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="empty-state" id="emptyState" style="display: none;">
|
||||
<div class="empty-icon">👥</div>
|
||||
<h3>등록된 사용자가 없습니다</h3>
|
||||
<p>새 사용자를 추가해보세요.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- 사용자 추가/수정 모달 -->
|
||||
<div id="userModal" class="modal-overlay" style="display: none;">
|
||||
<div class="modal-container">
|
||||
<div class="modal-header">
|
||||
<h2 id="modalTitle">새 사용자 추가</h2>
|
||||
<button class="modal-close-btn" onclick="closeUserModal()">×</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form id="userForm">
|
||||
<div class="form-group">
|
||||
<label class="form-label">사용자명 *</label>
|
||||
<input type="text" id="userName" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">아이디 *</label>
|
||||
<input type="text" id="userId" class="form-control" required>
|
||||
<small class="form-help">영문, 숫자만 사용 가능 (4-20자)</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group" id="passwordGroup">
|
||||
<label class="form-label">비밀번호 *</label>
|
||||
<input type="password" id="userPassword" class="form-control" required>
|
||||
<small class="form-help">최소 6자 이상</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">역할 *</label>
|
||||
<select id="userRole" class="form-control" required>
|
||||
<option value="">역할 선택</option>
|
||||
<option value="admin">관리자</option>
|
||||
<option value="leader">그룹장</option>
|
||||
<option value="user">작업자</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">이메일</label>
|
||||
<input type="email" id="userEmail" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">전화번호</label>
|
||||
<input type="tel" id="userPhone" class="form-control">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeUserModal()">취소</button>
|
||||
<button type="button" class="btn btn-primary" id="saveUserBtn">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 사용자 삭제 확인 모달 -->
|
||||
<div id="deleteModal" class="modal-overlay" style="display: none;">
|
||||
<div class="modal-container small">
|
||||
<div class="modal-header">
|
||||
<h2>사용자 삭제</h2>
|
||||
<button class="modal-close-btn" onclick="closeDeleteModal()">×</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="delete-warning">
|
||||
<div class="warning-icon">⚠️</div>
|
||||
<p>정말로 이 사용자를 삭제하시겠습니까?</p>
|
||||
<p class="warning-text">삭제된 사용자는 복구할 수 없습니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeDeleteModal()">취소</button>
|
||||
<button type="button" class="btn btn-danger" id="confirmDeleteBtn">삭제</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 토스트 알림 -->
|
||||
<div class="toast-container" id="toastContainer"></div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="/js/api-config.js?v=13"></script>
|
||||
<script src="/js/load-navbar.js?v=4"></script>
|
||||
<script src="/js/admin-settings.js?v=5"></script>
|
||||
</body>
|
||||
</html>
|
||||
391
synology_deployment/web-ui/pages/profile/change-password.html
Normal file
391
synology_deployment/web-ui/pages/profile/change-password.html
Normal file
@@ -0,0 +1,391 @@
|
||||
<!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/main-layout.css">
|
||||
<script src="/js/auth-check.js" defer></script>
|
||||
|
||||
<style>
|
||||
/* 페이지 전용 스타일 */
|
||||
.password-page {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.page-title h1 {
|
||||
font-size: 2rem;
|
||||
color: #333;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.page-title p {
|
||||
color: #666;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* 카드 스타일 */
|
||||
.password-card {
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);
|
||||
color: white;
|
||||
padding: 24px 32px;
|
||||
}
|
||||
|
||||
.card-header h2 {
|
||||
margin: 0;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
/* 알림 박스 */
|
||||
.info-box {
|
||||
background: #e3f2fd;
|
||||
border: 1px solid #90caf9;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.info-box h4 {
|
||||
margin: 0 0 12px 0;
|
||||
color: #1565c0;
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.info-box ul {
|
||||
margin: 0;
|
||||
padding-left: 24px;
|
||||
color: #0d47a1;
|
||||
}
|
||||
|
||||
.info-box li {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
/* 폼 스타일 */
|
||||
.password-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
font-size: 0.95rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
width: 100%;
|
||||
padding: 14px 48px 14px 16px;
|
||||
border: 2px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: #ff9800;
|
||||
box-shadow: 0 0 0 3px rgba(255, 152, 0, 0.1);
|
||||
}
|
||||
|
||||
.password-toggle {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
font-size: 1.2rem;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.password-toggle:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 버튼 */
|
||||
.form-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 14px 28px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #ff9800;
|
||||
color: white;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #f57c00;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(255, 152, 0, 0.3);
|
||||
}
|
||||
|
||||
.btn-primary:disabled {
|
||||
background: #ccc;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: #f5f5f5;
|
||||
color: #666;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
/* 메시지 */
|
||||
.message-box {
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
animation: slideDown 0.3s ease-out;
|
||||
}
|
||||
|
||||
.message-box.error {
|
||||
background: #ffebee;
|
||||
border: 1px solid #ffcdd2;
|
||||
color: #c62828;
|
||||
}
|
||||
|
||||
.message-box.success {
|
||||
background: #e8f5e9;
|
||||
border: 1px solid #c8e6c9;
|
||||
color: #2e7d32;
|
||||
}
|
||||
|
||||
@keyframes slideDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 하단 링크 */
|
||||
.back-link {
|
||||
text-align: center;
|
||||
margin-top: 32px;
|
||||
padding-top: 32px;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.back-link a {
|
||||
color: #1976d2;
|
||||
text-decoration: none;
|
||||
font-size: 0.95rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.back-link a:hover {
|
||||
color: #1565c0;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 반응형 */
|
||||
@media (max-width: 768px) {
|
||||
.password-page {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main-layout-no-sidebar">
|
||||
<div id="navbar-container"></div>
|
||||
|
||||
<div class="password-page">
|
||||
<div class="page-title">
|
||||
<h1>🔐 비밀번호 변경</h1>
|
||||
<p>계정 보안을 위해 정기적으로 비밀번호를 변경해주세요</p>
|
||||
</div>
|
||||
|
||||
<div class="password-card">
|
||||
<div class="card-header">
|
||||
<h2>
|
||||
<span>🔑</span>
|
||||
<span>새 비밀번호 설정</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<!-- 메시지 영역 -->
|
||||
<div id="message-area"></div>
|
||||
|
||||
<!-- 안내 정보 -->
|
||||
<div class="info-box">
|
||||
<h4>
|
||||
<span>ℹ️</span>
|
||||
<span>비밀번호 요구사항</span>
|
||||
</h4>
|
||||
<ul>
|
||||
<li>최소 6자 이상 입력해주세요</li>
|
||||
<li>영문 대/소문자, 숫자, 특수문자를 조합하면 더 안전합니다</li>
|
||||
<li>개인정보나 쉬운 단어는 피해주세요</li>
|
||||
<li>이전 비밀번호와 다르게 설정해주세요</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 비밀번호 변경 폼 -->
|
||||
<form id="changePasswordForm" class="password-form">
|
||||
<div class="form-group">
|
||||
<label for="currentPassword">
|
||||
<span>🔓</span>
|
||||
<span>현재 비밀번호</span>
|
||||
</label>
|
||||
<div class="input-wrapper">
|
||||
<input
|
||||
type="password"
|
||||
id="currentPassword"
|
||||
class="form-control"
|
||||
placeholder="현재 비밀번호를 입력하세요"
|
||||
required
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
<button type="button" class="password-toggle" data-target="currentPassword">👁️</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="newPassword">
|
||||
<span>🔐</span>
|
||||
<span>새 비밀번호</span>
|
||||
</label>
|
||||
<div class="input-wrapper">
|
||||
<input
|
||||
type="password"
|
||||
id="newPassword"
|
||||
class="form-control"
|
||||
placeholder="새 비밀번호를 입력하세요"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<button type="button" class="password-toggle" data-target="newPassword">👁️</button>
|
||||
</div>
|
||||
<div id="passwordStrength"></div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="confirmPassword">
|
||||
<span>✅</span>
|
||||
<span>새 비밀번호 확인</span>
|
||||
</label>
|
||||
<div class="input-wrapper">
|
||||
<input
|
||||
type="password"
|
||||
id="confirmPassword"
|
||||
class="form-control"
|
||||
placeholder="새 비밀번호를 다시 입력하세요"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<button type="button" class="password-toggle" data-target="confirmPassword">👁️</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary" id="submitBtn">
|
||||
<span>🔑</span>
|
||||
<span>비밀번호 변경</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary" id="resetBtn">
|
||||
초기화
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="back-link">
|
||||
<a href="javascript:history.back()">
|
||||
<span>←</span>
|
||||
<span>이전 페이지로 돌아가기</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module" src="/js/load-navbar.js"></script>
|
||||
<script type="module" src="/js/change-password.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
317
synology_deployment/web-ui/pages/profile/my-profile.html
Normal file
317
synology_deployment/web-ui/pages/profile/my-profile.html
Normal file
@@ -0,0 +1,317 @@
|
||||
<!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/main-layout.css">
|
||||
<script src="/js/auth-check.js" defer></script>
|
||||
|
||||
<style>
|
||||
.profile-page {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.profile-header {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.profile-avatar {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 3rem;
|
||||
color: white;
|
||||
margin: 0 auto 20px;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.profile-name {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.profile-role {
|
||||
font-size: 1.2rem;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.profile-cards {
|
||||
display: grid;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.profile-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.08);
|
||||
padding: 28px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.3rem;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 0.85rem;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 1.05rem;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 12px 24px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-decoration: none;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #1976d2;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #1565c0;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: #f5f5f5;
|
||||
color: #333;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
.btn-warning {
|
||||
background: #ff9800;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-warning:hover {
|
||||
background: #f57c00;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* 통계 카드 */
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.stat-box {
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: #1976d2;
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.9rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.profile-page {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.profile-avatar {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.profile-name {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
.info-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main-layout-no-sidebar">
|
||||
<div id="navbar-container"></div>
|
||||
|
||||
<div class="profile-page">
|
||||
<div class="profile-header">
|
||||
<div class="profile-avatar" id="profileAvatar">👤</div>
|
||||
<h1 class="profile-name" id="profileName">사용자</h1>
|
||||
<p class="profile-role" id="profileRole">역할</p>
|
||||
</div>
|
||||
|
||||
<div class="profile-cards">
|
||||
<!-- 기본 정보 -->
|
||||
<div class="profile-card">
|
||||
<h2 class="card-title">
|
||||
<span>📋</span>
|
||||
<span>기본 정보</span>
|
||||
</h2>
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<span class="info-label">사용자 ID</span>
|
||||
<span class="info-value" id="userId">-</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">사용자명</span>
|
||||
<span class="info-value" id="username">-</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">이름</span>
|
||||
<span class="info-value" id="fullName">-</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">권한 레벨</span>
|
||||
<span class="info-value" id="accessLevel">-</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">작업자 ID</span>
|
||||
<span class="info-value" id="workerId">-</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">가입일</span>
|
||||
<span class="info-value" id="createdAt">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 활동 정보 -->
|
||||
<div class="profile-card">
|
||||
<h2 class="card-title">
|
||||
<span>📊</span>
|
||||
<span>활동 정보</span>
|
||||
</h2>
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<span class="info-label">마지막 로그인</span>
|
||||
<span class="info-value" id="lastLogin">-</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">이메일</span>
|
||||
<span class="info-value" id="email">-</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 간단한 통계 (준비중) -->
|
||||
<div class="stats-grid" style="margin-top: 24px; opacity: 0.5;">
|
||||
<div class="stat-box">
|
||||
<span class="stat-number">-</span>
|
||||
<span class="stat-label">작업 보고서</span>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<span class="stat-number">-</span>
|
||||
<span class="stat-label">이번 달 활동</span>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<span class="stat-number">-</span>
|
||||
<span class="stat-label">팀 기여도</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 빠른 작업 -->
|
||||
<div class="profile-card">
|
||||
<h2 class="card-title">
|
||||
<span>⚡</span>
|
||||
<span>빠른 작업</span>
|
||||
</h2>
|
||||
<div class="action-buttons">
|
||||
<a href="/pages/profile/change-password.html" class="action-btn btn-warning">
|
||||
<span>🔐</span>
|
||||
<span>비밀번호 변경</span>
|
||||
</a>
|
||||
<button class="action-btn btn-secondary" disabled>
|
||||
<span>✏️</span>
|
||||
<span>프로필 수정 (준비중)</span>
|
||||
</button>
|
||||
<button class="action-btn btn-secondary" disabled>
|
||||
<span>⚙️</span>
|
||||
<span>설정 (준비중)</span>
|
||||
</button>
|
||||
<a href="javascript:history.back()" class="action-btn btn-secondary">
|
||||
<span>←</span>
|
||||
<span>돌아가기</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module" src="/js/load-navbar.js"></script>
|
||||
<script type="module" src="/js/my-profile.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user