add
This commit is contained in:
@@ -390,6 +390,31 @@ body {
|
||||
.status-banner.mode-exam { border-left-color: #7c3aed; }
|
||||
.status-banner.mode-exam .monitor-mode-tag { background: #f5f3ff; color: #6d28d9; }
|
||||
|
||||
.exam-panel {
|
||||
border: 1px solid #c4b5fd;
|
||||
background: linear-gradient(135deg, #faf5ff 0%, #fff 100%);
|
||||
padding: 1rem 1.15rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.exam-panel-desc {
|
||||
margin: 0 0 0.85rem;
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.exam-panel-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.exam-wait, .exam-done {
|
||||
font-size: 0.82rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
|
||||
@@ -20,7 +20,8 @@ let stats = {
|
||||
classCode: '',
|
||||
currentPeriod: 0,
|
||||
currentCourseName: '',
|
||||
shifts: []
|
||||
shifts: [],
|
||||
exam: null
|
||||
};
|
||||
|
||||
let chatOpen = false;
|
||||
@@ -65,6 +66,14 @@ function init() {
|
||||
if (data?.staffId) bannerStaffId = Number(data.staffId);
|
||||
pulseChatFab();
|
||||
});
|
||||
window.runtime.EventsOn('exam:paper-sent', () => {
|
||||
if (loggedIn) {
|
||||
window.go.main.App.GetStats().then((s) => {
|
||||
stats = { ...stats, ...s };
|
||||
updateExamPanel();
|
||||
}).catch(console.error);
|
||||
}
|
||||
});
|
||||
checkLogin();
|
||||
}
|
||||
|
||||
@@ -169,6 +178,63 @@ function renderShiftsTable(shifts) {
|
||||
`;
|
||||
}
|
||||
|
||||
function renderExamPanel() {
|
||||
const ex = stats.exam;
|
||||
if (!ex || stats.monitorMode !== 'exam') return '';
|
||||
const paperBtn = ex.paperSent
|
||||
? `<button type="button" class="btn btn-primary" id="btn-exam-paper">📄 Xem đề${ex.paperTitle ? ` (${ex.paperTitle})` : ''}</button>`
|
||||
: `<span class="exam-wait">Chờ giảng viên gửi đề...</span>`;
|
||||
const quizBtn = ex.quizUrl
|
||||
? `<button type="button" class="btn btn-secondary" id="btn-exam-quiz">📝 Làm trắc nghiệm</button>`
|
||||
: '';
|
||||
const submitBtn = ex.submitted
|
||||
? `<span class="exam-done">✓ Đã nộp bài tự luận</span>`
|
||||
: `<button type="button" class="btn btn-primary" id="btn-exam-submit">📦 Nộp bài (chọn folder)</button>`;
|
||||
return `
|
||||
<div class="card exam-panel" id="exam-panel">
|
||||
<div class="card-title-row">
|
||||
<div class="card-title">📝 ${ex.examName || 'Phòng thi'}</div>
|
||||
</div>
|
||||
<p class="exam-panel-desc">Bạn đang trong giờ thi. Làm bài theo hướng dẫn của giảng viên.</p>
|
||||
<div class="exam-panel-actions">
|
||||
${paperBtn}
|
||||
${quizBtn}
|
||||
${submitBtn}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function wireExamPanel() {
|
||||
const paper = document.getElementById('btn-exam-paper');
|
||||
if (paper) paper.addEventListener('click', () => {
|
||||
window.go.main.App.OpenExamPaper().catch((e) => alert(e?.message || e));
|
||||
});
|
||||
const quiz = document.getElementById('btn-exam-quiz');
|
||||
if (quiz) quiz.addEventListener('click', () => {
|
||||
window.go.main.App.OpenExamQuiz().catch((e) => alert(e?.message || e));
|
||||
});
|
||||
const submit = document.getElementById('btn-exam-submit');
|
||||
if (submit) submit.addEventListener('click', async () => {
|
||||
try {
|
||||
const name = await window.go.main.App.SubmitExamWork();
|
||||
alert(`Đã nộp bài: ${name}`);
|
||||
const fresh = await window.go.main.App.GetStats();
|
||||
stats = { ...stats, ...fresh };
|
||||
updateExamPanel();
|
||||
} catch (e) {
|
||||
alert(e?.message || e || 'Nộp bài thất bại');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateExamPanel() {
|
||||
const host = document.getElementById('exam-panel-host');
|
||||
if (!host) return;
|
||||
host.innerHTML = renderExamPanel();
|
||||
wireExamPanel();
|
||||
}
|
||||
|
||||
function renderDashboard() {
|
||||
if (!studentInfo) return;
|
||||
|
||||
@@ -227,6 +293,8 @@ function renderDashboard() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="exam-panel-host">${renderExamPanel()}</div>
|
||||
|
||||
<div class="stats-grid stats-grid--two">
|
||||
<div class="card stat-card">
|
||||
<div class="stat-icon-wrap">📡</div>
|
||||
@@ -275,6 +343,7 @@ function renderDashboard() {
|
||||
await window.go.main.App.Logout();
|
||||
}
|
||||
});
|
||||
wireExamPanel();
|
||||
}
|
||||
|
||||
function ensureChatWidget() {
|
||||
@@ -497,11 +566,17 @@ function startStatsTicker() {
|
||||
|
||||
const statusSubEl = document.getElementById('status-sub');
|
||||
if (statusSubEl) {
|
||||
statusSubEl.innerText = stats.currentPeriod > 0 && stats.currentCourseName
|
||||
? `Ca ${stats.currentPeriod} · ${stats.currentCourseName}`
|
||||
: 'Theo dõi theo lịch học của lớp';
|
||||
if (stats.monitorMode === 'exam' && stats.exam?.examName) {
|
||||
statusSubEl.innerText = stats.exam.examName;
|
||||
} else {
|
||||
statusSubEl.innerText = stats.currentPeriod > 0 && stats.currentCourseName
|
||||
? `Ca ${stats.currentPeriod} · ${stats.currentCourseName}`
|
||||
: 'Theo dõi theo lịch học của lớp';
|
||||
}
|
||||
}
|
||||
|
||||
updateExamPanel();
|
||||
|
||||
const onlineEl = document.getElementById('clock-online');
|
||||
if (onlineEl) onlineEl.innerText = formatDuration(stats.onlineSecs || 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user