Group-class enrolment deadline with instructor late-enrolment override #103

Merged
thatguygriff merged 2 commits from feature/group-class-enrollment-deadline into main 2026-07-24 13:45:54 +00:00
3 changed files with 14 additions and 5 deletions
Showing only changes of commit fc7c0fa966 - Show all commits
+1 -1
View File
@@ -14,7 +14,7 @@ each change under the current top section as you work.
## [1.1.3] ## [1.1.3]
### Added ### Added
- Group classes now carry an **enrolment deadline** the instructor sets on the offering. It defaults to the first day of the class, and once it passes students can no longer enrol — the enrolment page shows the class as closed and the API rejects late enrolments. - Group classes now carry an **enrolment deadline** the instructor sets on the offering. It defaults to the first day of the class, and once it passes students can no longer enrol — the enrolment page shows the class as closed and the API rejects late enrolments. While enrolment is open, each class card shows an "Enrol by" date.
- Instructors can add students to any group class by hand from its details page (**Add students directly**), which now appears for public classes too, not just invite-only ones. This bypasses the enrolment deadline and capacity, so a student can be enrolled as a **late enrolment** after the class has closed to self-enrolment. - Instructors can add students to any group class by hand from its details page (**Add students directly**), which now appears for public classes too, not just invite-only ones. This bypasses the enrolment deadline and capacity, so a student can be enrolled as a **late enrolment** after the class has closed to self-enrolment.
## [1.1.2] ## [1.1.2]
+11 -3
View File
@@ -110,11 +110,16 @@
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`; return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
} }
// Enrolment closes at the end of the deadline day — the instructor's set // The effective enrolment deadline: the instructor's set deadline, or the
// deadline, or the first class day by default. Mirrors the server-side // first class day by default. Empty when the class has no dates at all.
function enrolmentDeadline(o) {
return o.enrollment_deadline || o.term_start || '';
}
// Enrolment closes at the end of the deadline day. Mirrors the server-side
// Offering::isEnrollmentOpen() gate. // Offering::isEnrollmentOpen() gate.
function isEnrollmentOpen(o) { function isEnrollmentOpen(o) {
const deadline = o.enrollment_deadline || o.term_start || ''; const deadline = enrolmentDeadline(o);
return !deadline || todayYmd() <= deadline; return !deadline || todayYmd() <= deadline;
} }
@@ -138,6 +143,9 @@
${o.schedule_note ? `<p>${escHtml(o.schedule_note)}</p>` : ''} ${o.schedule_note ? `<p>${escHtml(o.schedule_note)}</p>` : ''}
${o.description ? `<p>${escHtml(o.description)}</p>` : ''} ${o.description ? `<p>${escHtml(o.description)}</p>` : ''}
<p>${escHtml(Number(o.price).toFixed(2))} ${escHtml(o.currency)}</p> <p>${escHtml(Number(o.price).toFixed(2))} ${escHtml(o.currency)}</p>
${!enrolledOfferingIds.has(Number(o.id)) && isEnrollmentOpen(o) && enrolmentDeadline(o)
? `<p class="us-enrol-deadline">Enrol by ${escHtml(formatDate(enrolmentDeadline(o)))}</p>`
: ''}
${enrolledOfferingIds.has(Number(o.id)) ${enrolledOfferingIds.has(Number(o.id))
? '<p class="us-enrolled"><strong>You are enrolled in this class.</strong></p>' ? '<p class="us-enrolled"><strong>You are enrolled in this class.</strong></p>'
: (isEnrollmentOpen(o) : (isEnrollmentOpen(o)
+2 -1
View File
@@ -52,7 +52,8 @@ Enrolment also closes after the class's **enrolment deadline** (the instructor's
`enrollment_deadline`, defaulting to `term_start` — the first class day; see `enrollment_deadline`, defaulting to `term_start` — the first class day; see
`offerings.md`). Past the deadline `POST /enrollments` rejects the enrolment with `offerings.md`). Past the deadline `POST /enrollments` rejects the enrolment with
`403 enrollment_closed`, and the class list shows "Enrolment has closed." in place `403 enrollment_closed`, and the class list shows "Enrolment has closed." in place
of the Enrol button. of the Enrol button. While enrolment is still open the class card shows an
"Enrol by" line with the effective deadline date.
The deadline only bounds student **self**-enrolment. An instructor (or studio admin) The deadline only bounds student **self**-enrolment. An instructor (or studio admin)
can still enrol someone by hand from the class **details page** — the **Add students can still enrol someone by hand from the class **details page** — the **Add students