- base.html 상단 네비게이션 브랜딩 변경 - 팜큐 약국 관리 시스템 → PharmQ Super Admin (PSA) - UI 일관성 향상을 위한 브랜딩 통합 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
248 lines
8.6 KiB
HTML
248 lines
8.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{{ vm_name }} - VNC 접속</title>
|
|
|
|
<!-- Bootstrap CSS -->
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
|
|
|
<style>
|
|
body {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.vnc-card {
|
|
background: rgba(255, 255, 255, 0.95);
|
|
border-radius: 20px;
|
|
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
|
padding: 3rem;
|
|
max-width: 600px;
|
|
width: 100%;
|
|
text-align: center;
|
|
}
|
|
|
|
.vm-icon {
|
|
font-size: 4rem;
|
|
color: #667eea;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.vm-info {
|
|
background: #f8f9fa;
|
|
border-radius: 10px;
|
|
padding: 1.5rem;
|
|
margin: 2rem 0;
|
|
}
|
|
|
|
.method-card {
|
|
border: 2px solid #e9ecef;
|
|
border-radius: 10px;
|
|
padding: 1.5rem;
|
|
margin: 1rem 0;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.method-card:hover {
|
|
border-color: #667eea;
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3);
|
|
}
|
|
|
|
.method-card.recommended {
|
|
border-color: #28a745;
|
|
background: linear-gradient(145deg, #f8fff8, #ffffff);
|
|
}
|
|
|
|
.btn-vnc {
|
|
padding: 12px 30px;
|
|
font-size: 1.1rem;
|
|
border-radius: 25px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.btn-vnc:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
|
}
|
|
|
|
.countdown {
|
|
font-size: 2rem;
|
|
font-weight: bold;
|
|
color: #667eea;
|
|
}
|
|
|
|
.security-note {
|
|
background: #fff3cd;
|
|
border: 1px solid #ffeaa7;
|
|
border-radius: 8px;
|
|
padding: 1rem;
|
|
margin-top: 2rem;
|
|
font-size: 0.9rem;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="vnc-card">
|
|
<div class="vm-icon">
|
|
<i class="fas fa-desktop"></i>
|
|
</div>
|
|
|
|
<h1 class="mb-3">{{ vm_name }}</h1>
|
|
<p class="lead text-muted">VNC 원격 접속</p>
|
|
|
|
<div class="vm-info">
|
|
<div class="row">
|
|
<div class="col-6">
|
|
<strong><i class="fas fa-server"></i> 노드</strong><br>
|
|
<span class="text-muted">{{ node }}</span>
|
|
</div>
|
|
<div class="col-6">
|
|
<strong><i class="fas fa-tag"></i> VM ID</strong><br>
|
|
<span class="text-muted">{{ vmid }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 방법 1: 직접 Proxmox 접속 (권장) -->
|
|
<div class="method-card recommended">
|
|
<div class="d-flex align-items-center mb-3">
|
|
<i class="fas fa-star text-success me-2"></i>
|
|
<h4 class="mb-0 text-success">권장 방법</h4>
|
|
</div>
|
|
<h5>Proxmox 웹 콘솔로 접속</h5>
|
|
<p class="text-muted">
|
|
Proxmox의 기본 noVNC 콘솔로 직접 연결합니다.<br>
|
|
가장 안정적이고 모든 기능을 사용할 수 있습니다.
|
|
</p>
|
|
|
|
<a href="{{ proxmox_url }}" target="_blank" class="btn btn-success btn-vnc">
|
|
<i class="fas fa-external-link-alt"></i> Proxmox 웹 콘솔 열기
|
|
</a>
|
|
|
|
<div class="mt-3">
|
|
<small class="text-muted">
|
|
<i class="fas fa-info-circle"></i>
|
|
새 탭에서 {{ host }} 웹 인터페이스가 열립니다
|
|
</small>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 방법 2: 수동 접속 -->
|
|
<div class="method-card">
|
|
<h5>수동 접속 방법</h5>
|
|
<p class="text-muted">
|
|
브라우저에서 직접 Proxmox 주소로 이동하여 접속합니다.
|
|
</p>
|
|
|
|
<div class="input-group mb-3">
|
|
<input type="text" class="form-control" value="{{ proxmox_url }}" readonly id="proxmox-url">
|
|
<button class="btn btn-outline-secondary" type="button" onclick="copyToClipboard()">
|
|
<i class="fas fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<button class="btn btn-primary btn-vnc w-100" onclick="openProxmox()">
|
|
<i class="fas fa-globe"></i> 브라우저에서 열기
|
|
</button>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<button class="btn btn-info btn-vnc w-100" onclick="copyToClipboard()">
|
|
<i class="fas fa-copy"></i> URL 복사
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 보안 알림 -->
|
|
<div class="security-note">
|
|
<i class="fas fa-shield-alt"></i>
|
|
<strong>보안 알림:</strong>
|
|
SSL 인증서 경고가 표시되면 "고급" → "{{ host }}로 이동(안전하지 않음)"을 클릭하세요.
|
|
팜큐 내부 네트워크에서만 접근 가능합니다.
|
|
</div>
|
|
|
|
<!-- 뒤로가기 -->
|
|
<div class="mt-4">
|
|
<a href="/vms" class="btn btn-outline-secondary">
|
|
<i class="fas fa-arrow-left"></i> VM 목록으로 돌아가기
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bootstrap JS -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
|
|
<script>
|
|
// Proxmox URL
|
|
const proxmoxUrl = '{{ proxmox_url }}';
|
|
|
|
// Proxmox 웹 콘솔 열기
|
|
function openProxmox() {
|
|
window.open(proxmoxUrl, '_blank');
|
|
}
|
|
|
|
// URL 클립보드 복사
|
|
function copyToClipboard() {
|
|
const urlInput = document.getElementById('proxmox-url');
|
|
urlInput.select();
|
|
urlInput.setSelectionRange(0, 99999); // 모바일 대응
|
|
|
|
try {
|
|
document.execCommand('copy');
|
|
showToast('URL이 클립보드에 복사되었습니다!', 'success');
|
|
} catch (err) {
|
|
// 클립보드 API 사용 (최신 브라우저)
|
|
if (navigator.clipboard) {
|
|
navigator.clipboard.writeText(proxmoxUrl).then(() => {
|
|
showToast('URL이 클립보드에 복사되었습니다!', 'success');
|
|
}).catch(() => {
|
|
showToast('복사에 실패했습니다. 수동으로 복사해주세요.', 'warning');
|
|
});
|
|
} else {
|
|
showToast('복사에 실패했습니다. 수동으로 복사해주세요.', 'warning');
|
|
}
|
|
}
|
|
}
|
|
|
|
// 토스트 메시지 표시
|
|
function showToast(message, type = 'info') {
|
|
const toastContainer = document.createElement('div');
|
|
toastContainer.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
z-index: 1050;
|
|
`;
|
|
|
|
const toast = document.createElement('div');
|
|
toast.className = `alert alert-${type} alert-dismissible fade show`;
|
|
toast.innerHTML = `
|
|
${message}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
`;
|
|
|
|
toastContainer.appendChild(toast);
|
|
document.body.appendChild(toastContainer);
|
|
|
|
// 3초 후 자동 제거
|
|
setTimeout(() => {
|
|
toastContainer.remove();
|
|
}, 3000);
|
|
}
|
|
|
|
// 페이지 로드 시 자동으로 Proxmox 페이지 열기 (옵션)
|
|
// window.addEventListener('load', function() {
|
|
// setTimeout(openProxmox, 2000); // 2초 후 자동 열기
|
|
// });
|
|
</script>
|
|
</body>
|
|
</html> |