diff --git a/public/app.js b/public/app.js
index 369d3b6..a017844 100644
--- a/public/app.js
+++ b/public/app.js
@@ -332,6 +332,21 @@ function markAllSeen(studentId, ids) {
localStorage.setItem(inboxSeenKey(studentId), JSON.stringify([...ids]));
}
+function renderGradeCard(r, isNew) {
+ const pct = r.points_possible ? Math.round((r.score / r.points_possible) * 100) : null;
+ const scoreClass = pct !== null ? (pct >= 80 ? 'score-good' : 'score-bad') : '';
+ const date = new Date(r.graded_at + 'Z').toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
+ return `
+
+
${esc(r.courseName)} ยท ${esc(r.unitName)} ยท ${date}
+ ${r.points_possible !== null ? `
๐ ${r.score} / ${r.points_possible}${pct !== null ? ` (${pct}%)` : ''}
` : ''}
+ ${r.parent_comment ? `` : ''}
+
`;
+}
+
async function loadInbox() {
const sid = currentStudent?.id;
if (!sid) return;
@@ -340,29 +355,33 @@ async function loadInbox() {
api(`/api/students/${sid}/messages`),
]);
const seen = getSeenIds(sid);
+ const newItems = items.filter((r) => !seen.has(r.submissionId));
+ const gradedItems = items.filter((r) => seen.has(r.submissionId));
- $('#inbox-empty').hidden = items.length > 0;
- $('#inbox-list').innerHTML = items.map((r) => {
- const pct = r.points_possible ? Math.round((r.score / r.points_possible) * 100) : null;
- const isNew = !seen.has(r.submissionId);
- const scoreClass = pct !== null ? (pct >= 80 ? 'score-good' : 'score-bad') : '';
- const date = new Date(r.graded_at + 'Z').toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
- return `
-
-
${esc(r.courseName)} ยท ${esc(r.unitName)} ยท ${date}
- ${r.points_possible !== null ? `
๐ ${r.score} / ${r.points_possible}${pct !== null ? ` (${pct}%)` : ''}
` : ''}
- ${r.parent_comment ? `` : ''}
-
`;
- }).join('');
+ $('#inbox-list').innerHTML = newItems.map((r) => renderGradeCard(r, true)).join('');
+ $('#inbox-empty').hidden = newItems.length > 0;
+
+ $('#graded-list').innerHTML = gradedItems.map((r) => renderGradeCard(r, false)).join('');
+ $('#graded-empty').hidden = gradedItems.length > 0;
+
+ const newBadge = $('#inbox-new-badge');
+ if (newBadge) { newBadge.hidden = newItems.length === 0; newBadge.textContent = newItems.length; }
markAllSeen(sid, items.map((r) => r.submissionId));
updateInboxBadge(sid, 0);
renderMsgThread(msgs);
}
+document.querySelectorAll('.inbox-subtab').forEach((btn) => {
+ btn.addEventListener('click', () => {
+ document.querySelectorAll('.inbox-subtab').forEach((b) => b.classList.remove('active'));
+ btn.classList.add('active');
+ const sub = btn.dataset.sub;
+ $('#inbox-sub-new').hidden = sub !== 'new';
+ $('#inbox-sub-graded').hidden = sub !== 'graded';
+ });
+});
+
function renderMsgThread(msgs) {
const thread = $('#msg-thread');
if (!thread) return;
diff --git a/public/index.html b/public/index.html
index daa7354..e15b78c 100644
--- a/public/index.html
+++ b/public/index.html
@@ -102,8 +102,18 @@
-
-
No grades yet โ check back after your parent reviews your work!
+
+
+
+
+
+
+
No new grades โ check back after your parent reviews your work!
+
+
+
+
No graded items yet.
+
๐ฌ Messages
diff --git a/public/styles.css b/public/styles.css
index 1bd9e6d..dd5ae4c 100644
--- a/public/styles.css
+++ b/public/styles.css
@@ -1251,6 +1251,9 @@ body.bg-bubbles {
border-left: 4px solid var(--good);
font-size: 1.05rem;
}
+.inbox-subtabs { display: flex; gap: 0.5rem; margin-bottom: 1rem; }
+.inbox-subtab { flex: 1; padding: 0.5rem 1rem; border: 1.5px solid #e2dccf; border-radius: 999px; background: var(--card); color: var(--text); font-size: 0.9rem; font-weight: 600; cursor: pointer; position: relative; }
+.inbox-subtab.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.inbox-card { background: var(--card); border: 1.5px solid #e2dccf; border-radius: 14px; padding: 1rem; margin-bottom: 0.75rem; }
.inbox-card.inbox-new { border-color: var(--accent); }
.inbox-card-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.25rem; }