Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | 22x 21x 22x 20x 20x 20x 20x 21x 12x 12x 22x 22x 20x 20x 12x 3x 15x | /**
* EI-2966 — Group upcoming assignments by their due-date day-bucket.
*
* Pure helper backing the student-dashboard Calendar widget. Takes
* an array of upcoming assignment summaries (shape from
* `GET /v1/student/dashboard/assignments/upcoming/fetch`) and groups
* them by their `date_close` calendar day, sorted ascending.
*
* Day bucket = the calendar date in the student's local timezone,
* formatted as `YYYY-MM-DD` (lexicographic-sort friendly).
*
* Rules:
* - `assignments` must be an array; non-array / null / undefined
* returns `[]` (defensive).
* - Entries missing a parseable `date_close` are dropped (defensive
* — we never render a date-less row in a calendar).
* - Each returned bucket is `{ day: 'YYYY-MM-DD', items: [...] }`
* where `items` keeps the original assignment object order.
* - Buckets are sorted ascending by `day` so the earliest due-date
* comes first (the natural "what's due next" reading order).
*/
function _toLocalDayKey(value) {
if (!value) return null;
const d = value instanceof Date ? value : new Date(value);
if (Number.isNaN(d.getTime())) return null;
const y = d.getFullYear();
const m = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
return `${y}-${m}-${day}`;
}
export function groupAssignmentsByDate(assignments) {
if (!Array.isArray(assignments) || assignments.length === 0) return [];
const byDay = new Map();
for (const a of assignments) {
const key = _toLocalDayKey(a?.date_close);
if (!key) continue;
if (!byDay.has(key)) byDay.set(key, []);
byDay.get(key).push(a);
}
return Array.from(byDay.entries())
.sort(([a], [b]) => a.localeCompare(b))
.map(([day, items]) => ({ day, items }));
}
|