Spaces:
Running
Running
Upload 8 files
Browse files- src/views/InstructorView.js +43 -0
src/views/InstructorView.js
CHANGED
|
@@ -131,6 +131,10 @@ export async function renderInstructorView() {
|
|
| 131 |
</h2>
|
| 132 |
|
| 133 |
<div class="flex items-center space-x-4 bg-gray-900 rounded-full px-4 py-1.5 border border-gray-600">
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
<!-- Pen Tools -->
|
| 135 |
<button class="annotation-tool p-2 rounded-full hover:bg-gray-700 transition-colors ring-2 ring-transparent focus:outline-none" data-color="#ef4444" onclick="setPenColor('#ef4444', this)">
|
| 136 |
<div class="w-4 h-4 rounded-full bg-red-500"></div>
|
|
@@ -761,6 +765,38 @@ export function setupInstructorEvents() {
|
|
| 761 |
});
|
| 762 |
|
| 763 |
// Modal Events
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 764 |
window.closeBroadcast = () => {
|
| 765 |
const modal = document.getElementById('broadcast-modal');
|
| 766 |
const content = document.getElementById('broadcast-content');
|
|
@@ -823,6 +859,9 @@ export function setupInstructorEvents() {
|
|
| 823 |
|
| 824 |
// Collect Prompts
|
| 825 |
let prompts = [];
|
|
|
|
|
|
|
|
|
|
| 826 |
|
| 827 |
if (type === 'student') {
|
| 828 |
const student = currentStudents.find(s => s.id === id);
|
|
@@ -836,6 +875,8 @@ export function setupInstructorEvents() {
|
|
| 836 |
title: challenge ? challenge.title : '未知題目',
|
| 837 |
prompt: p.prompt,
|
| 838 |
author: student.nickname,
|
|
|
|
|
|
|
| 839 |
time: p.completedAt ? new Date(p.completedAt.seconds * 1000).toLocaleString() : ''
|
| 840 |
};
|
| 841 |
});
|
|
@@ -850,6 +891,8 @@ export function setupInstructorEvents() {
|
|
| 850 |
title: student.nickname, // When viewing challenge, title is student name
|
| 851 |
prompt: p.prompt,
|
| 852 |
author: student.nickname,
|
|
|
|
|
|
|
| 853 |
time: p.completedAt ? new Date(p.completedAt.seconds * 1000).toLocaleString() : ''
|
| 854 |
});
|
| 855 |
}
|
|
|
|
| 131 |
</h2>
|
| 132 |
|
| 133 |
<div class="flex items-center space-x-4 bg-gray-900 rounded-full px-4 py-1.5 border border-gray-600">
|
| 134 |
+
<!-- Anonymous Toggle -->
|
| 135 |
+
<button id="btn-anonymous-toggle" class="bg-gray-700 hover:bg-gray-600 text-white font-bold py-1 px-3 rounded text-xs transition-colors mr-2" onclick="toggleAnonymous(this)">
|
| 136 |
+
👀 隱藏姓名
|
| 137 |
+
</button>
|
| 138 |
<!-- Pen Tools -->
|
| 139 |
<button class="annotation-tool p-2 rounded-full hover:bg-gray-700 transition-colors ring-2 ring-transparent focus:outline-none" data-color="#ef4444" onclick="setPenColor('#ef4444', this)">
|
| 140 |
<div class="w-4 h-4 rounded-full bg-red-500"></div>
|
|
|
|
| 765 |
});
|
| 766 |
|
| 767 |
// Modal Events
|
| 768 |
+
window.showBroadcastModal = (userId, challengeId) => {
|
| 769 |
+
const modal = document.getElementById('broadcast-modal');
|
| 770 |
+
const content = document.getElementById('broadcast-content');
|
| 771 |
+
|
| 772 |
+
// Find Data
|
| 773 |
+
const student = currentStudents.find(s => s.id === userId);
|
| 774 |
+
if (!student) return alert('找不到學員資料');
|
| 775 |
+
|
| 776 |
+
const p = student.progress ? student.progress[challengeId] : null;
|
| 777 |
+
if (!p) return alert('找不到該作品資料');
|
| 778 |
+
|
| 779 |
+
const challenge = cachedChallenges.find(c => c.id === challengeId);
|
| 780 |
+
const title = challenge ? challenge.title : '未知題目';
|
| 781 |
+
|
| 782 |
+
// Populate UI
|
| 783 |
+
document.getElementById('broadcast-avatar').textContent = student.nickname[0] || '?';
|
| 784 |
+
document.getElementById('broadcast-author').textContent = student.nickname;
|
| 785 |
+
document.getElementById('broadcast-challenge').textContent = title;
|
| 786 |
+
document.getElementById('broadcast-prompt').textContent = p.prompt || '(無內容)';
|
| 787 |
+
|
| 788 |
+
// Store IDs for Actions (Reject/BroadcastAll)
|
| 789 |
+
modal.dataset.userId = userId;
|
| 790 |
+
modal.dataset.challengeId = challengeId;
|
| 791 |
+
|
| 792 |
+
// Show
|
| 793 |
+
modal.classList.remove('hidden');
|
| 794 |
+
setTimeout(() => {
|
| 795 |
+
content.classList.remove('scale-95', 'opacity-0');
|
| 796 |
+
content.classList.add('opacity-100', 'scale-100');
|
| 797 |
+
}, 10);
|
| 798 |
+
};
|
| 799 |
+
|
| 800 |
window.closeBroadcast = () => {
|
| 801 |
const modal = document.getElementById('broadcast-modal');
|
| 802 |
const content = document.getElementById('broadcast-content');
|
|
|
|
| 859 |
|
| 860 |
// Collect Prompts
|
| 861 |
let prompts = [];
|
| 862 |
+
// Fix: Reset selection when opening new list to prevent cross-contamination
|
| 863 |
+
selectedPrompts = [];
|
| 864 |
+
updateCompareButton();
|
| 865 |
|
| 866 |
if (type === 'student') {
|
| 867 |
const student = currentStudents.find(s => s.id === id);
|
|
|
|
| 875 |
title: challenge ? challenge.title : '未知題目',
|
| 876 |
prompt: p.prompt,
|
| 877 |
author: student.nickname,
|
| 878 |
+
studentId: student.id,
|
| 879 |
+
challengeId: challengeId,
|
| 880 |
time: p.completedAt ? new Date(p.completedAt.seconds * 1000).toLocaleString() : ''
|
| 881 |
};
|
| 882 |
});
|
|
|
|
| 891 |
title: student.nickname, // When viewing challenge, title is student name
|
| 892 |
prompt: p.prompt,
|
| 893 |
author: student.nickname,
|
| 894 |
+
studentId: student.id,
|
| 895 |
+
challengeId: id,
|
| 896 |
time: p.completedAt ? new Date(p.completedAt.seconds * 1000).toLocaleString() : ''
|
| 897 |
});
|
| 898 |
}
|