Spaces:
Running
Running
Upload 10 files
Browse files- src/views/InstructorView.js +61 -3
src/views/InstructorView.js
CHANGED
|
@@ -1739,6 +1739,41 @@ export function setupInstructorEvents() {
|
|
| 1739 |
// Reset previous badges
|
| 1740 |
document.querySelectorAll('.ai-badge').forEach(e => e.remove());
|
| 1741 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1742 |
cards.forEach(card => {
|
| 1743 |
const checkbox = card.querySelector('input[type="checkbox"]');
|
| 1744 |
if (!checkbox) return;
|
|
@@ -1749,8 +1784,9 @@ export function setupInstructorEvents() {
|
|
| 1749 |
|
| 1750 |
// Find which category this student falls into
|
| 1751 |
let matchedCategory = null;
|
| 1752 |
-
for (const [cat,
|
| 1753 |
-
|
|
|
|
| 1754 |
matchedCategory = cat;
|
| 1755 |
break;
|
| 1756 |
}
|
|
@@ -1771,7 +1807,29 @@ export function setupInstructorEvents() {
|
|
| 1771 |
}
|
| 1772 |
});
|
| 1773 |
|
| 1774 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1775 |
|
| 1776 |
} catch (e) {
|
| 1777 |
console.error(e);
|
|
|
|
| 1739 |
// Reset previous badges
|
| 1740 |
document.querySelectorAll('.ai-badge').forEach(e => e.remove());
|
| 1741 |
|
| 1742 |
+
// Build summary for display
|
| 1743 |
+
let summaryHtml = '<div class="space-y-3">';
|
| 1744 |
+
const categoryOrder = ['creative', 'precise', 'rough', 'gentle', 'parrot', 'spam'];
|
| 1745 |
+
|
| 1746 |
+
// Get student names for display
|
| 1747 |
+
const getStudentName = (userId) => {
|
| 1748 |
+
const student = currentStudents.find(s => s.id === userId);
|
| 1749 |
+
return student?.nickname || student?.displayName || userId.slice(0, 6);
|
| 1750 |
+
};
|
| 1751 |
+
|
| 1752 |
+
categoryOrder.forEach(cat => {
|
| 1753 |
+
const idsRaw = results[cat];
|
| 1754 |
+
if (!idsRaw || idsRaw.length === 0) return;
|
| 1755 |
+
|
| 1756 |
+
// Clean IDs (remove "ID_" prefix if present)
|
| 1757 |
+
const ids = idsRaw.map(id => id.replace(/^ID_/, ''));
|
| 1758 |
+
|
| 1759 |
+
const badge = BadgeMap[cat];
|
| 1760 |
+
if (!badge) return;
|
| 1761 |
+
|
| 1762 |
+
const names = ids.map(id => getStudentName(id)).join(', ');
|
| 1763 |
+
summaryHtml += `
|
| 1764 |
+
<div class="p-3 rounded-lg bg-gray-800 border border-gray-700">
|
| 1765 |
+
<div class="flex items-center gap-2 mb-1">
|
| 1766 |
+
<span class="text-xl">${badge.icon}</span>
|
| 1767 |
+
<span class="${badge.color} font-bold">${badge.label}</span>
|
| 1768 |
+
<span class="text-gray-400 text-sm">(${ids.length}人)</span>
|
| 1769 |
+
</div>
|
| 1770 |
+
<div class="text-gray-300 text-sm">${names}</div>
|
| 1771 |
+
</div>
|
| 1772 |
+
`;
|
| 1773 |
+
});
|
| 1774 |
+
summaryHtml += '</div>';
|
| 1775 |
+
|
| 1776 |
+
// Apply badges to cards
|
| 1777 |
cards.forEach(card => {
|
| 1778 |
const checkbox = card.querySelector('input[type="checkbox"]');
|
| 1779 |
if (!checkbox) return;
|
|
|
|
| 1784 |
|
| 1785 |
// Find which category this student falls into
|
| 1786 |
let matchedCategory = null;
|
| 1787 |
+
for (const [cat, idsRaw] of Object.entries(results)) {
|
| 1788 |
+
const ids = idsRaw?.map(id => id.replace(/^ID_/, '')) || [];
|
| 1789 |
+
if (ids.includes(studentId)) {
|
| 1790 |
matchedCategory = cat;
|
| 1791 |
break;
|
| 1792 |
}
|
|
|
|
| 1807 |
}
|
| 1808 |
});
|
| 1809 |
|
| 1810 |
+
// Show summary modal
|
| 1811 |
+
const existingSummaryModal = document.getElementById('ai-summary-modal');
|
| 1812 |
+
if (existingSummaryModal) existingSummaryModal.remove();
|
| 1813 |
+
|
| 1814 |
+
const summaryModal = document.createElement('div');
|
| 1815 |
+
summaryModal.id = 'ai-summary-modal';
|
| 1816 |
+
summaryModal.className = 'fixed inset-0 bg-black/80 flex items-center justify-center z-[100] p-4';
|
| 1817 |
+
summaryModal.innerHTML = `
|
| 1818 |
+
<div class="bg-gray-900 border border-cyan-500/50 rounded-xl p-6 max-w-md w-full shadow-2xl">
|
| 1819 |
+
<h3 class="text-xl font-bold text-cyan-400 mb-4 flex items-center gap-2">
|
| 1820 |
+
✨ AI 分析結果
|
| 1821 |
+
</h3>
|
| 1822 |
+
<div class="max-h-[60vh] overflow-y-auto">
|
| 1823 |
+
${summaryHtml || '<p class="text-gray-400">���有特別的分類結果</p>'}
|
| 1824 |
+
</div>
|
| 1825 |
+
<button id="close-ai-summary" class="mt-4 w-full py-2 bg-cyan-600 hover:bg-cyan-500 text-white rounded-lg font-bold transition-colors">
|
| 1826 |
+
確定
|
| 1827 |
+
</button>
|
| 1828 |
+
</div>
|
| 1829 |
+
`;
|
| 1830 |
+
document.body.appendChild(summaryModal);
|
| 1831 |
+
|
| 1832 |
+
document.getElementById('close-ai-summary').onclick = () => summaryModal.remove();
|
| 1833 |
|
| 1834 |
} catch (e) {
|
| 1835 |
console.error(e);
|