## 주요 변경사항 - 프로젝트/작업자/코드 관리 페이지 2단 레이아웃(사이드바+메인) 적용 - 통일된 3열 카드 그리드 레이아웃 구현 - 코드 관리 페이지 탭 및 카드 디자인 개선 - 관리 페이지 표준 가이드 문서 작성 ## 세부 내용 ### HTML 구조 개선 - `.page-container` flexbox 레이아웃으로 변경 - 240px 고정폭 사이드바 네비게이션 추가 - 페이지 헤더를 카드 형태로 분리 ### CSS 개선 - admin-pages.css 신규 생성 (v7) - 3열 그리드 레이아웃 (repeat(3, 1fr)) - 카드 높이 통일 (프로젝트/작업자: 420px, 코드: 최소 200px) - 반응형 디자인 (1200px: 2열, 768px: 1열) ### 코드 관리 페이지 특화 - 탭 네비게이션 스타일 개선 - 상태별/심각도별 컬러 보더 적용 - 해결 가이드 섹션 스타일링 - 아이콘 48x48 둥근 박스 디자인 ### 문서화 - ADMIN_PAGE_STANDARD.md 생성 - HTML 템플릿, CSS 클래스, 파일 명명 규칙 정의 - 3가지 페이지 타입(카드 그리드/테이블/탭) 표준화 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
18 KiB
18 KiB
관리 페이지 표준 가이드 (Admin Page Standard)
작성일: 2026-01-26 버전: 1.0.0 용도: 관리자 페이지(Admin Pages) 통합 개발 표준
📋 목차
1. 용어 정의
1.1 관리 페이지 (Admin Page)
정의: 데이터의 CRUD(Create, Read, Update, Delete) 작업을 수행하는 관리자 전용 페이지
특징:
- 2단 레이아웃 (사이드바 + 메인 콘텐츠)
- 카드/그리드 방식의 데이터 표시
- 검색, 필터, 통계 기능 포함
- 모달을 통한 추가/수정 기능
명명 규칙: {엔티티}-management 또는 {엔티티}s.html
예시:
- ✅ 프로젝트 관리 (
projects.html) - ✅ 작업자 관리 (
workers.html) - ✅ 코드 관리 (
codes.html)
1.2 관리 페이지의 구성 요소
| 용어 | 영문 | 설명 | 클래스명 |
|---|---|---|---|
| 사이드바 | Sidebar | 좌측 네비게이션 메뉴 | .sidebar |
| 메인 콘텐츠 | Main Content | 우측 콘텐츠 영역 | .main-content |
| 페이지 헤더 | Page Header | 타이틀 + 액션 버튼 | .page-header |
| 검색 섹션 | Search Section | 검색바 + 필터 | .search-section |
| 통계 카드 | Statistics | 데이터 통계 표시 | .project-stats, .stat-item |
| 데이터 그리드 | Data Grid | 카드/테이블 그리드 | .projects-grid |
| 데이터 카드 | Data Card | 개별 데이터 표시 카드 | .project-card |
2. 페이지 유형 분류
2.1 Type A: 카드 그리드 관리 페이지
용도: 시각적으로 정보를 표시하고 관리하는 페이지
레이아웃:
┌─────────┬────────────────────────────────┐
│ │ 페이지 헤더 (타이틀 + 버튼) │
│ ├────────────────────────────────┤
│ 사이드바 │ 검색 섹션 (검색바 + 필터) │
│ ├────────────────────────────────┤
│ │ 통계 (활성/비활성/총) │
│ ├────────────────────────────────┤
│ │ [카드1] [카드2] [카드3] │
│ │ [카드4] [카드5] [카드6] │
│ │ 데이터 카드 그리드 │
└─────────┴────────────────────────────────┘
적용 페이지:
- 프로젝트 관리 (
projects.html) - 작업자 관리 (
workers.html)
그리드 설정:
- 기본: 3열 (
grid-template-columns: repeat(3, 1fr)) - 카드 높이: 고정 420px
2.2 Type B: 테이블 관리 페이지
용도: 텍스트 중심의 데이터를 테이블 형태로 관리
레이아웃:
┌─────────┬────────────────────────────────┐
│ │ 페이지 헤더 (타이틀 + 버튼) │
│ ├────────────────────────────────┤
│ 사이드바 │ 검색 섹션 (검색바 + 필터) │
│ ├────────────────────────────────┤
│ │ ┌──────────────────────────┐ │
│ │ │ 테이블 헤더 │ │
│ │ ├──────────────────────────┤ │
│ │ │ 데이터 행 1 │ │
│ │ │ 데이터 행 2 │ │
│ │ │ 데이터 행 3 │ │
│ │ └──────────────────────────┘ │
└─────────┴────────────────────────────────┘
적용 가능 페이지:
- 로그 관리
- 권한 관리
2.3 Type C: 탭 기반 관리 페이지
용도: 여러 카테고리의 데이터를 탭으로 구분하여 관리
레이아웃:
┌─────────┬────────────────────────────────┐
│ │ 페이지 헤더 (타이틀 + 버튼) │
│ ├────────────────────────────────┤
│ 사이드바 │ [탭1] [탭2] [탭3] [탭4] │
│ ├────────────────────────────────┤
│ │ 검색 섹션 │
│ ├────────────────────────────────┤
│ │ 현재 탭의 콘텐츠 표시 │
│ │ (테이블 또는 카드) │
└─────────┴────────────────────────────────┘
적용 페이지:
- 코드 관리 (
codes.html)
3. 표준 레이아웃 구조
3.1 2단 레이아웃 (Sidebar + Main)
CSS Flexbox 구조:
.page-container {
display: flex; /* 가로 배치 */
min-height: calc(100vh - 80px);
}
.sidebar {
width: 240px; /* 고정 너비 */
min-width: 240px;
flex-shrink: 0; /* 줄어들지 않음 */
}
.main-content {
flex: 1; /* 나머지 공간 차지 */
padding: 2rem;
}
3.2 반응형 Breakpoints
| 화면 크기 | 사이드바 | 그리드 열 | 비고 |
|---|---|---|---|
| 1400px+ | 240px | 3열 | 대형 데스크탑 |
| 1200px ~ 1399px | 240px | 3열 | 일반 데스크탑 |
| 1024px ~ 1199px | 240px | 2열 | 중형 화면 |
| 768px ~ 1023px | 200px | 2열 | 태블릿 |
| 767px 이하 | 숨김 | 1열 | 모바일 |
4. HTML 구조 템플릿
4.1 기본 HTML 템플릿
<!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/admin-pages.css?v=6">
<link rel="icon" type="image/png" href="/img/favicon.png">
<script src="/js/auth-check.js" defer></script>
</head>
<body>
<!-- 네비게이션 바 -->
<div id="navbar-container"></div>
<!-- 메인 레이아웃: 사이드바 + 콘텐츠 -->
<div class="page-container">
<!-- 사이드바 -->
<aside class="sidebar">
<nav class="sidebar-nav">
<div class="sidebar-header">
<h3 class="sidebar-title">관리 메뉴</h3>
</div>
<ul class="sidebar-menu">
<li class="menu-item {active-if-current}">
<a href="/pages/admin/{page}.html">
<span class="menu-icon">{icon}</span>
<span class="menu-text">{메뉴명}</span>
</a>
</li>
<!-- 반복... -->
<li class="menu-divider"></li>
<li class="menu-item">
<a href="/pages/admin/index.html">
<span class="menu-icon">◀</span>
<span class="menu-text">작업관리로</span>
</a>
</li>
</ul>
</nav>
</aside>
<!-- 메인 콘텐츠 -->
<main class="main-content">
<div class="dashboard-main">
<!-- 페이지 헤더 -->
<div class="page-header">
<div class="page-title-section">
<h1 class="page-title">
<span class="title-icon">{icon}</span>
{엔티티명} 관리
</h1>
<p class="page-description">{설명}</p>
</div>
<div class="page-actions">
<button class="btn btn-primary" onclick="open{Entity}Modal()">
<span class="btn-icon">➕</span>
새 {엔티티} 등록
</button>
<button class="btn btn-secondary" onclick="refresh{Entity}List()">
<span class="btn-icon">🔄</span>
새로고침
</button>
</div>
</div>
<!-- 검색 섹션 -->
<div class="search-section">
<div class="search-bar">
<input type="text" id="searchInput" placeholder="검색..." class="search-input">
<button class="search-btn" onclick="search{Entities}()">
<span class="search-icon">🔍</span>
</button>
</div>
<!-- 필터 옵션 -->
</div>
<!-- 데이터 섹션 -->
<div class="projects-section">
<div class="section-header">
<h2 class="section-title">등록된 {엔티티}</h2>
<div class="project-stats">
<!-- 통계 카드 -->
</div>
</div>
<!-- 데이터 그리드 -->
<div class="projects-grid" id="{entities}Grid">
<!-- 카드들이 동적 생성 -->
</div>
</div>
</div>
</main>
</div>
<!-- 모달 -->
<div id="{entity}Modal" class="modal-overlay" style="display: none;">
<!-- 모달 콘텐츠 -->
</div>
<!-- JavaScript -->
<script type="module" src="/js/api-config.js"></script>
<script type="module" src="/js/load-navbar.js"></script>
<script type="module" src="/js/{entity}-management.js"></script>
</body>
</html>
4.2 사이드바 메뉴 구조
<ul class="sidebar-menu">
<li class="menu-item active"> <!-- active는 현재 페이지에만 -->
<a href="/pages/admin/projects.html">
<span class="menu-icon">📁</span>
<span class="menu-text">프로젝트 관리</span>
</a>
</li>
<li class="menu-item">
<a href="/pages/admin/workers.html">
<span class="menu-icon">👥</span>
<span class="menu-text">작업자 관리</span>
</a>
</li>
<li class="menu-item">
<a href="/pages/admin/codes.html">
<span class="menu-icon">🏷️</span>
<span class="menu-text">코드 관리</span>
</a>
</li>
<li class="menu-divider"></li>
<li class="menu-item">
<a href="/pages/admin/index.html">
<span class="menu-icon">◀</span>
<span class="menu-text">작업관리로</span>
</a>
</li>
</ul>
5. CSS 클래스 규칙
5.1 필수 클래스 목록
| 클래스명 | 용도 | 부모 | 필수 여부 |
|---|---|---|---|
.page-container |
전체 레이아웃 컨테이너 | <body> |
✅ 필수 |
.sidebar |
사이드바 | .page-container |
✅ 필수 |
.main-content |
메인 콘텐츠 영역 | .page-container |
✅ 필수 |
.dashboard-main |
대시보드 메인 | .main-content |
✅ 필수 |
.page-header |
페이지 헤더 | .dashboard-main |
✅ 필수 |
.search-section |
검색 영역 | .dashboard-main |
✅ 필수 |
.projects-section |
데이터 섹션 | .dashboard-main |
✅ 필수 |
.projects-grid |
데이터 그리드 | .projects-section |
✅ 필수 |
.project-card |
개별 카드 | .projects-grid |
✅ 필수 |
5.2 클래스 네이밍 규칙
패턴: {영역}-{요소}-{수식어}
예시:
- ✅
.page-header(페이지 헤더) - ✅
.search-section(검색 섹션) - ✅
.stat-item(통계 항목) - ✅
.menu-item(메뉴 항목) - ✅
.btn-primary(주요 버튼)
금지:
- ❌
.header1,.section2(숫자 사용) - ❌
.pageHeader(camelCase) - ❌
.Page_Header(underscore + PascalCase)
5.3 카드 표준 스타일
.project-card {
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 0.75rem;
padding: 1.5rem;
height: 420px; /* 고정 높이 */
min-height: 420px;
max-height: 420px;
display: flex;
flex-direction: column;
cursor: pointer;
transition: all 0.2s ease;
}
.project-card:hover {
border-color: #2563eb;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
transform: translateY(-4px);
}
6. JavaScript 규칙
6.1 파일 구조
각 관리 페이지는 독립적인 JavaScript 파일을 가져야 합니다.
파일명 패턴: {entity}-management.js
예시:
/js/project-management.js/js/worker-management.js/js/code-management.js
6.2 필수 함수 목록
모든 관리 페이지는 다음 함수를 구현해야 합니다:
// 1. 페이지 초기화
function initializePage() { }
// 2. 데이터 로드
async function load{Entities}() { }
// 3. 데이터 렌더링
function render{Entities}() { }
// 4. 검색
function search{Entities}() { }
// 5. 필터
function filter{Entities}() { }
// 6. 모달 열기
function open{Entity}Modal() { }
// 7. 모달 닫기
function close{Entity}Modal() { }
// 8. 데이터 저장
async function save{Entity}() { }
// 9. 데이터 삭제
async function delete{Entity}(id) { }
// 10. 목록 새로고침
function refresh{Entity}List() { }
6.3 네이밍 규칙
함수명: camelCase
- ✅
loadProjects(),openWorkerModal() - ❌
load_projects(),OpenWorkerModal()
변수명: camelCase
- ✅
allProjects,currentEditingProject - ❌
all_projects,CurrentEditingProject
상수: UPPER_SNAKE_CASE
- ✅
API_BASE_URL,DEFAULT_PAGE_SIZE - ❌
apiBaseUrl,defaultPageSize
7. 파일 네이밍 규칙
7.1 디렉터리 구조
/pages/admin/
├── index.html # 관리 대시보드
├── projects.html # 프로젝트 관리
├── workers.html # 작업자 관리
├── codes.html # 코드 관리
└── {entity}s.html # 새 관리 페이지
/css/
├── design-system.css # 디자인 시스템
└── admin-pages.css # 관리 페이지 공통 CSS
/js/
├── project-management.js
├── worker-management.js
├── code-management.js
└── {entity}-management.js
7.2 파일명 규칙
HTML 파일:
- 복수형 사용:
{entities}.html - ✅
projects.html,workers.html - ❌
project.html,worker.html
JavaScript 파일:
- 하이픈 구분:
{entity}-management.js - ✅
project-management.js - ❌
projectManagement.js,project_management.js
CSS 파일:
- 공통:
admin-pages.css(모든 관리 페이지가 공유) - 개별: 필요시
{entity}-page.css
8. 체크리스트
새로운 관리 페이지를 생성할 때 다음 체크리스트를 확인하세요:
8.1 HTML 체크리스트
- 2단 레이아웃 구조 (사이드바 + 메인)
- 사이드바 메뉴에 현재 페이지 active 표시
- 페이지 헤더 (타이틀 + 설명 + 액션 버튼)
- 검색 섹션 (검색바 + 필터)
- 통계 섹션 (활성/비활성/총)
- 데이터 그리드 (3열 기본)
- 모달 (추가/수정/삭제)
- CSS 버전 쿼리스트링 (
?v=6) - JavaScript 모듈 로드
8.2 CSS 체크리스트
.page-container { display: flex }적용.sidebar고정 너비 (240px).main-content { flex: 1 }적용.projects-grid3열 그리드- 카드 고정 높이 (420px)
- 반응형 breakpoints 구현
- 호버 효과 구현
8.3 JavaScript 체크리스트
- 10개 필수 함수 구현
- API 연동 (GET, POST, PUT, DELETE)
- 에러 핸들링
- 로딩 상태 표시
- 검색/필터 기능
- 모달 열기/닫기
- 데이터 유효성 검사
8.4 접근성 체크리스트
- 키보드 네비게이션 지원
- 버튼에 적절한
title속성 - 로딩 중 상태 표시
- 에러 메시지 명확히 표시
- 모바일 반응형 지원
9. 예시 코드
9.1 카드 렌더링 (JavaScript)
function renderProjects() {
const projectsHtml = filteredProjects.map(project => {
const isInactive = project.is_active === 0 || project.is_active === false;
return `
<div class="project-card ${isInactive ? 'inactive' : ''}" onclick="editProject(${project.project_id})">
<div class="project-header">
<div class="project-info">
<div class="project-job-no">${project.job_no || 'Job No. 없음'}</div>
<h3 class="project-name">${project.project_name}</h3>
<div class="project-meta">
<div class="meta-row">
<span class="meta-label">상태</span>
<span class="meta-value">${project.status}</span>
</div>
<div class="meta-row">
<span class="meta-label">PM</span>
<span class="meta-value">${project.pm || '-'}</span>
</div>
<!-- 더 많은 필드 -->
</div>
</div>
<div class="project-actions">
<button class="btn-edit" onclick="event.stopPropagation(); editProject(${project.project_id})">
✏️ 수정
</button>
<button class="btn-delete" onclick="event.stopPropagation(); deleteProject(${project.project_id})">
🗑️ 삭제
</button>
</div>
</div>
</div>
`;
}).join('');
document.getElementById('projectsGrid').innerHTML = projectsHtml;
}
10. 버전 히스토리
| 버전 | 날짜 | 변경 내용 |
|---|---|---|
| 1.0.0 | 2026-01-26 | 초기 버전 작성 |
11. 참고 자료
- DOCUMENTATION_STANDARD.md - 문서 작성 표준
- TBM_DEPLOYMENT_GUIDE.md - TBM 배포 가이드
/css/admin-pages.css- 관리 페이지 공통 CSS/pages/admin/projects.html- 프로젝트 관리 참고 구현
문서 작성자: Claude Code 최종 수정일: 2026-01-26