mirror of
https://github.com/sailor-sh/CK-X.git
synced 2026-05-24 01:12:49 +00:00
273 lines
16 KiB
HTML
273 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>CK-X Simulator - Exam</title>
|
|
<!-- Google Fonts -->
|
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
<!-- Bootstrap CSS -->
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<!-- xterm.js CSS -->
|
|
<link href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.min.css" rel="stylesheet">
|
|
<!-- Custom CSS -->
|
|
<link rel="stylesheet" href="/css/exam.css">
|
|
</head>
|
|
<body>
|
|
<!-- Loader -->
|
|
<div class="loader" id="pageLoader">
|
|
<div class="spinner-border text-light" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Toast Container for notifications -->
|
|
<div class="toast-container position-fixed top-0 end-0 pt-5 pr-3" id="toastContainer">
|
|
<!-- Toasts will be added here dynamically -->
|
|
</div>
|
|
|
|
<!-- Exam End Modal -->
|
|
<div class="modal fade" id="examEndModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="examEndModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="examEndModalLabel">Exam Time Complete</h5>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="alert alert-info mb-3">
|
|
<strong>Time's up! ⏳ Your exam has ended. </strong>
|
|
</div>
|
|
<p>We're now evaluating your results.</p>
|
|
<p>Your environment session will remain available for review until you choose to end it.</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary" id="viewResultsBtn">View Results</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Start Exam Modal -->
|
|
<div class="modal fade" id="startExamModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="startExamModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="startExamModalLabel">Ready to Begin Your Exam</h5>
|
|
</div>
|
|
|
|
<!-- New Exam Content (default) -->
|
|
<div class="modal-body" id="newExamContent">
|
|
<div class="alert alert-success mb-3">
|
|
<strong>Important:</strong> Please treat this as a real exam. Focus on completing tasks accurately and efficiently as you would in a certification exam.
|
|
</div>
|
|
<p>When you click "Start Exam", the following will happen:</p>
|
|
<ul>
|
|
<li>Your exam timer will begin counting down.</li>
|
|
<li>You will be connected to the Kubernetes environment.</li>
|
|
<li>The application will enter fullscreen mode</li>
|
|
<li>When you click on the <span class="inline-code">highlighted</span> content, it will be copied to the clipboard.</li> </ul>
|
|
<p class="mb-0">Are you ready to start?</p>
|
|
</div>
|
|
|
|
<!-- Exam In Progress Content (initially hidden) -->
|
|
<div class="modal-body" id="examInProgressContent" style="display: none;">
|
|
<div class="alert alert-warning mb-3">
|
|
<strong>Note:</strong> You already have an exam in progress.
|
|
</div>
|
|
<p>Your previous session will be restored, including your remaining time.</p>
|
|
<p>You can continue where you left off.</p>
|
|
</div>
|
|
|
|
<!-- Exam Completed Content (initially hidden) -->
|
|
<div class="modal-body" id="examCompletedContent" style="display: none;">
|
|
<div class="alert alert-info mb-3">
|
|
<strong>Note:</strong> You've already completed this exam session.
|
|
</div>
|
|
<p>Your session is still available. You can continue to view the environment, but your answers have already been submitted.</p>
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary" id="startExamBtn">Start Exam</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Header -->
|
|
<div class="header">
|
|
<div class="header-title-section">
|
|
<div class="header-title">CK-X Simulator</div>
|
|
<div class="timer" id="examTimer">120:00</div>
|
|
</div>
|
|
<div class="header-controls">
|
|
<div class="dropdown d-inline-block">
|
|
<button class="btn-custom dropdown-toggle" type="button" id="examInterfaceDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
|
Exam Interface
|
|
</button>
|
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="examInterfaceDropdown">
|
|
<li><a class="dropdown-item" href="#" id="resizeTerminalBtn">Resize Terminal</a></li>
|
|
<li><a class="dropdown-item" href="#" id="fullscreenBtn">Toggle Fullscreen</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item" href="#" id="toggleViewBtn">Switch to Terminal</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item" href="https://github.com/sailor-sh/CK-X">Help</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="dropdown d-inline-block">
|
|
<button class="btn-custom dropdown-toggle" type="button" id="examControlsDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
|
Exam Controls
|
|
</button>
|
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="examControlsDropdown">
|
|
<li><a class="dropdown-item" href="#" id="endExamBtnDropdown">End Exam</a></li>
|
|
<li><a class="dropdown-item text-danger" href="#" id="terminateSessionBtn">Terminate Session</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="dropdown d-inline-block">
|
|
<button class="btn-custom dropdown-toggle" type="button" id="examInfoDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
|
Exam Information
|
|
</button>
|
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="examInfoDropdown">
|
|
<li><a class="dropdown-item" href="https://docs.linuxfoundation.org/tc-docs/certification" target="_blank">Exam Instructions</a></li>
|
|
<li><a class="dropdown-item" href="https://kubernetes.io/docs/home/" target="_blank">Kubernetes Documentation</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main Container -->
|
|
<div class="main-container" id="mainContainer">
|
|
<!-- Question Panel (Left) -->
|
|
<div class="question-panel" id="questionPanel">
|
|
<!-- Question Navigation -->
|
|
<div class="question-nav">
|
|
<button class="nav-arrow" id="prevBtn"><</button>
|
|
<div class="dropdown question-select">
|
|
<button class="btn btn-light w-100 dropdown-toggle" type="button" id="questionDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
|
Question 1
|
|
</button>
|
|
<ul class="dropdown-menu w-100" aria-labelledby="questionDropdown" id="questionDropdownMenu">
|
|
<li><a class="dropdown-item" href="#" data-question="1">Question 1</a></li>
|
|
<li><a class="dropdown-item" href="#" data-question="2">Question 2</a></li>
|
|
<li><a class="dropdown-item" href="#" data-question="3">Question 3</a></li>
|
|
<li><a class="dropdown-item" href="#" data-question="4">Question 4</a></li>
|
|
<li><a class="dropdown-item" href="#" data-question="5">Question 5</a></li>
|
|
</ul>
|
|
</div>
|
|
<button class="nav-arrow" id="nextBtn">></button>
|
|
</div>
|
|
|
|
<!-- Question Content -->
|
|
<div class="question-content" id="questionContent">
|
|
<!-- Question will be loaded here dynamically -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Resizable Divider -->
|
|
<div class="panel-divider" id="panelDivider">
|
|
<div class="divider-hint">
|
|
<span class="divider-arrows">⟷</span>
|
|
<span class="divider-tooltip">Drag to resize</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- VNC Panel (Right) -->
|
|
<div class="vnc-panel" id="vncPanel">
|
|
<div class="terminal-container">
|
|
<div class="terminal-controls">
|
|
<button class="btn btn-sm btn-outline-secondary me-2" id="reconnectVncBtn" title="Reconnect to session">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-repeat" viewBox="0 0 16 16">
|
|
<path d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"/>
|
|
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z"/>
|
|
</svg>
|
|
</button>
|
|
<button class="btn btn-sm btn-outline-secondary" id="fullscreenVncBtn">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrows-fullscreen" viewBox="0 0 16 16">
|
|
<path fill-rule="evenodd" d="M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707zm4.344 0a.5.5 0 0 1 .707 0l4.096 4.096V11.5a.5.5 0 1 1 1 0v3.975a.5.5 0 0 1-.5.5H11.5a.5.5 0 0 1 0-1h2.768l-4.096-4.096a.5.5 0 0 1 0-.707zm0-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707zm-4.344 0a.5.5 0 0 1-.707 0L1.025 1.732V4.5a.5.5 0 0 1-1 0V.525a.5.5 0 0 1 .5-.5H4.5a.5.5 0 0 1 0 1H1.732l4.096 4.096a.5.5 0 0 1 0 .707z"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<iframe id="vnc-frame" class="terminal-iframe" src="about:blank"></iframe>
|
|
<div id="connectionStatus" class="connection-status">Connecting to Session...</div>
|
|
</div>
|
|
|
|
<!-- SSH Terminal Container (initially hidden) -->
|
|
<div class="ssh-terminal-container" id="sshTerminalContainer" style="display: none;">
|
|
<div class="terminal-controls">
|
|
<button class="btn btn-sm btn-outline-secondary" id="fullscreenTerminalBtn">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrows-fullscreen" viewBox="0 0 16 16">
|
|
<path fill-rule="evenodd" d="M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707zm4.344 0a.5.5 0 0 1 .707 0l4.096 4.096V11.5a.5.5 0 1 1 1 0v3.975a.5.5 0 0 1-.5.5H11.5a.5.5 0 0 1 0-1h2.768l-4.096-4.096a.5.5 0 0 1 0-.707zm0-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707zm-4.344 0a.5.5 0 0 1-.707 0L1.025 1.732V4.5a.5.5 0 0 1-1 0V.525a.5.5 0 0 1 .5-.5H4.5a.5.5 0 0 1 0 1H1.732l4.096 4.096a.5.5 0 0 1 0 .707z"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div id="terminal" class="terminal"></div>
|
|
<div id="sshConnectionStatus" class="connection-status">Connecting to SSH...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Confirm Modal -->
|
|
<div class="modal fade" id="confirmModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">End Exam Confirmation</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Are you sure you want to end the exam? This action cannot be undone.</p>
|
|
<div class="alert alert-success mt-2">
|
|
<p class="mb-1"><strong>What happens next:</strong></p>
|
|
<ul class="mb-0">
|
|
<li>Your submissions will be evaluated.</li>
|
|
<li>You will be redirected to the results page.</li>
|
|
<li>Your session will remain intact until you choose to terminate it.</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-danger" id="confirmEndBtn">End Exam</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Terminate Session Modal -->
|
|
<div class="modal fade" id="terminateModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Terminate Session Warning</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="alert alert-warning">
|
|
<h6 class="alert-heading">Warning!</h6>
|
|
<p>Terminating this session will:</p>
|
|
<ul>
|
|
<li>Immediately clean up all environment resources</li>
|
|
<li>End your exam without evaluating your answers</li>
|
|
</ul>
|
|
<p>This action <strong>cannot</strong> be undone.</p>
|
|
</div>
|
|
<p>Would you like to proceed with terminating this session?</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="button" class="btn btn-danger" id="confirmTerminateBtn">Terminate Session</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bootstrap JS -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
|
<!-- xterm.js -->
|
|
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.min.js"></script>
|
|
<!-- Socket.io -->
|
|
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@4.7.2/dist/socket.io.min.js"></script>
|
|
<!-- Custom JS -->
|
|
<script type="module" src="/js/exam.js"></script>
|
|
<script src="/js/panel-resizer.js"></script>
|
|
</body>
|
|
</html> |