Files
Control_Panel/server/frontend/device.html
T
2026-07-15 18:37:19 +09:00

334 lines
12 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>ChemiFactory 설비 기기 관리</title>
<!-- Google Fonts Inter -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<!-- 테마 적용 (base.css보다 먼저 로드해 FOWT 방지) -->
<script src="js/theme.js"></script>
<link rel="stylesheet" href="css/base.css">
<style>
.header-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
gap: 16px;
}
.search-container {
display: flex;
align-items: center;
background-color: var(--overlay-hover);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 0 14px;
width: 300px;
transition: all 0.2s ease;
}
.search-container:focus-within {
border-color: var(--border-focus);
background-color: var(--overlay-strong);
}
.search-input {
background: transparent;
border: none;
color: var(--text-primary);
padding: 10px 0;
font-size: 14px;
width: 100%;
outline: none;
}
.search-input::placeholder {
color: var(--text-muted);
}
.search-icon {
margin-right: 8px;
color: var(--text-secondary);
}
/* Device Cards Grid */
.device-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 24px;
margin-top: 10px;
}
.device-card {
background-color: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 24px;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 220px;
}
.device-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px var(--card-shadow);
border-color: var(--overlay-border);
}
.device-card-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 16px;
}
.device-name {
font-size: 20px;
font-weight: 700;
color: var(--text-primary);
}
.device-badge {
font-size: 11px;
font-weight: 700;
background-color: var(--nav-active-bg);
color: var(--accent-blue);
border: 1px solid var(--accent-blue-glow);
padding: 4px 8px;
border-radius: 6px;
}
.device-details {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px 16px;
font-size: 13px;
color: var(--text-secondary);
border-top: 1px solid var(--border-color);
padding-top: 16px;
}
.detail-item {
display: flex;
flex-direction: column;
gap: 2px;
}
.detail-label {
font-size: 11px;
color: var(--text-muted);
}
.detail-value {
font-weight: 600;
color: var(--text-primary);
}
/* 모달 스타일 */
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: var(--modal-backdrop);
backdrop-filter: blur(4px);
align-items: center;
justify-content: center;
}
.modal-content {
background-color: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 24px;
width: 95%;
max-width: 550px;
max-height: 90vh;
overflow-y: auto;
box-shadow: 0 10px 30px var(--card-shadow);
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
border-bottom: 1px solid var(--border-color);
padding-bottom: 12px;
}
.modal-title {
font-size: 18px;
font-weight: 700;
color: var(--text-primary);
}
.close-btn {
font-size: 24px;
background: none;
border: none;
color: var(--text-secondary);
cursor: pointer;
}
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
@media (max-width: 576px) {
.form-grid {
grid-template-columns: 1fr;
}
}
.form-group {
margin-bottom: 16px;
}
.form-group.full-width {
grid-column: 1 / -1;
}
.form-group label {
display: block;
font-size: 13px;
color: var(--text-secondary);
margin-bottom: 6px;
font-weight: 600;
}
.form-control {
background-color: var(--overlay-hover);
border: 1px solid var(--border-color);
color: var(--text-primary);
padding: 10px 14px;
border-radius: 8px;
font-size: 14px;
width: 100%;
transition: all 0.2s ease;
}
.form-control:focus {
outline: none;
border-color: var(--border-focus);
background-color: var(--overlay-strong);
}
.modal-actions {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 24px;
border-top: 1px solid var(--border-color);
padding-top: 16px;
}
.action-right {
display: flex;
gap: 12px;
}
.btn-secondary {
background-color: var(--overlay-hover);
color: var(--text-primary);
border: 1px solid var(--border-color);
}
.btn-secondary:hover {
background-color: var(--overlay-strong);
}
.btn-danger {
background-color: var(--badge-red-bg);
color: var(--accent-red);
border: 1px solid var(--badge-red-border);
}
.btn-danger:hover {
background-color: var(--badge-red-bg);
box-shadow: 0 0 10px var(--accent-red-glow);
}
</style>
</head>
<body>
<div class="app-container">
<!-- 공통 사이드바 -->
<aside class="sidebar" id="sidebar"></aside>
<!-- 메인 콘텐츠 영역 -->
<main class="main-content">
<header class="content-header">
<div class="page-title">
<h1>설비 기기 마스터 관리</h1>
<p>공장에 등록된 카본 절단 설비의 기본 사양 및 전장 파라미터를 등록하고 편집합니다.</p>
</div>
</header>
<div class="header-row">
<div class="search-container">
<span class="search-icon">🔍</span>
<input type="text" id="search-input" class="search-input" placeholder="기기명 또는 건조타입 검색...">
</div>
<button class="btn btn-primary" id="btn-add-device"> 기기 추가</button>
</div>
<!-- 설비 목록 그리드 -->
<div class="device-grid" id="device-grid-container">
<!-- 설비 카드 동적 바인딩 -->
</div>
</main>
</div>
<!-- 기기 등록/수정 다이얼로그 모달 -->
<div id="device-modal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="modal-title">신규 기기 등록</h3>
<button class="close-btn" id="close-modal-x">&times;</button>
</div>
<form id="device-form">
<input type="hidden" id="device-id">
<div class="form-grid">
<div class="form-group full-width">
<label for="device-name">설비명 *</label>
<input type="text" id="device-name" class="form-control" placeholder="예: 양산 3호기" required>
</div>
<div class="form-group">
<label for="device-bobbins">원사 보빈 수 *</label>
<input type="number" id="device-bobbins" class="form-control" value="10" min="1" required>
</div>
<div class="form-group">
<label for="device-dryer">건조기 타입</label>
<input type="text" id="device-dryer" class="form-control" value="전기" placeholder="예: 전기, 열풍">
</div>
<div class="form-group">
<label for="device-power">사용 전력 (kW)</label>
<input type="number" id="device-power" class="form-control" value="5.0" step="0.1">
</div>
<div class="form-group">
<label for="device-max-cut">최대 절단 속도 (rpm)</label>
<input type="number" id="device-max-cut" class="form-control" value="100">
</div>
<div class="form-group">
<label for="device-max-feed">최대 피드 속도 (mm/s)</label>
<input type="number" id="device-max-feed" class="form-control" value="100">
</div>
<div class="form-group">
<label for="device-ip">IP 주소 *</label>
<input type="text" id="device-ip" class="form-control" value="192.168.1.50" required>
</div>
<div class="form-group">
<label for="device-prefix">MQTT 라인 Prefix *</label>
<input type="text" id="device-prefix" class="form-control" value="line1" required>
</div>
<div class="form-group">
<label for="device-status">동작 상태</label>
<select id="device-status" class="form-control">
<option value="available">가동 가능</option>
<option value="maintenance">점검 중</option>
<option value="broken">고장/정지</option>
</select>
</div>
</div>
<div class="modal-actions">
<button type="button" class="btn btn-danger" id="btn-delete-device" style="display:none;">삭제</button>
<span id="delete-spacer" style="display:none; flex-grow:1;"></span>
<div class="action-right">
<button type="button" class="btn btn-secondary close-modal-btn">취소</button>
<button type="submit" class="btn btn-primary">저장</button>
</div>
</div>
</form>
</div>
</div>
<!-- 공통 및 디바이스 관리 JS 연결 -->
<script src="js/common.js"></script>
<script src="js/device.js"></script>
</body>
</html>