Show enrolment status on the student group classes page
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / Tests (PHP 8.1) (pull_request) Successful in 49s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 1m17s
CI / Tests (PHP 8.3) (pull_request) Successful in 37s
CI / Coding Standards (pull_request) Successful in 2m47s
CI / Build Plugin Zip (pull_request) Has been skipped
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / Tests (PHP 8.1) (pull_request) Successful in 49s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 1m17s
CI / Tests (PHP 8.3) (pull_request) Successful in 37s
CI / Coding Standards (pull_request) Successful in 2m47s
CI / Build Plugin Zip (pull_request) Has been skipped
The class list now loads the student's own enrolments alongside the catalog; a class they already have an active enrolment in shows "You are enrolled in this class." instead of the Enrol button, in both the browse-all catalog and the single-class embed mode. Previously the button always rendered and a duplicate attempt walked the student through the whole questions/policies flow before failing with 409 already_enrolled. A cancelled enrolment does not block re-enrolling, matching the server-side duplicate rule. Closes #61 Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
@@ -89,7 +89,7 @@
|
|||||||
return `${formatDate(o.term_start)} – ${formatDate(o.term_end)} (${sessions} weekly sessions)`;
|
return `${formatDate(o.term_start)} – ${formatDate(o.term_end)} (${sessions} weekly sessions)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderClasses(offerings) {
|
function renderClasses(offerings, enrolledOfferingIds) {
|
||||||
let groups = offerings.filter((o) => o.kind === 'group_class');
|
let groups = offerings.filter((o) => o.kind === 'group_class');
|
||||||
if (singleOfferingId) {
|
if (singleOfferingId) {
|
||||||
groups = groups.filter((o) => Number(o.id) === singleOfferingId);
|
groups = groups.filter((o) => Number(o.id) === singleOfferingId);
|
||||||
@@ -108,7 +108,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>
|
||||||
<button data-offering-id="${o.id}" class="us-enrol-btn">Enrol</button>
|
${enrolledOfferingIds.has(Number(o.id))
|
||||||
|
? '<p class="us-enrolled"><strong>You are enrolled in this class.</strong></p>'
|
||||||
|
: `<button data-offering-id="${o.id}" class="us-enrol-btn">Enrol</button>`}
|
||||||
</div>
|
</div>
|
||||||
`).join('');
|
`).join('');
|
||||||
|
|
||||||
@@ -188,8 +190,20 @@
|
|||||||
clearError();
|
clearError();
|
||||||
list.style.display = 'block';
|
list.style.display = 'block';
|
||||||
confirm.style.display = 'none';
|
confirm.style.display = 'none';
|
||||||
apiFetch('offerings?kind=group_class')
|
// The student's own enrolments are fetched alongside the catalog so a
|
||||||
.then(renderClasses)
|
// class they already have an active enrolment in shows its status
|
||||||
|
// instead of offering to enrol them again (the API would reject the
|
||||||
|
// duplicate anyway). A cancelled enrolment does not block re-enrolling.
|
||||||
|
Promise.all([
|
||||||
|
apiFetch('offerings?kind=group_class'),
|
||||||
|
apiFetch('enrollments'),
|
||||||
|
])
|
||||||
|
.then(([offerings, enrollments]) => renderClasses(
|
||||||
|
offerings,
|
||||||
|
new Set(enrollments
|
||||||
|
.filter((e) => e.status === 'active')
|
||||||
|
.map((e) => Number(e.offering_id)))
|
||||||
|
))
|
||||||
.catch((err) => showError(err.message));
|
.catch((err) => showError(err.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ sessions. The class card on the enrolment page shows the date or date range
|
|||||||
with the session count.
|
with the session count.
|
||||||
|
|
||||||
## Enrolment Flow
|
## Enrolment Flow
|
||||||
|
The class list is loaded together with the student's own enrolments
|
||||||
|
(`GET /enrollments`); a class the student already has an `active` enrolment in
|
||||||
|
shows "You are enrolled in this class." instead of the Enrol button (the
|
||||||
|
server would reject the duplicate with `409 already_enrolled` regardless — a
|
||||||
|
cancelled enrolment does not block re-enrolling).
|
||||||
|
|
||||||
1. Student opens a group class from the offering catalog.
|
1. Student opens a group class from the offering catalog.
|
||||||
2. Student answers the offering's questions (`GET /offerings/{id}/questions`).
|
2. Student answers the offering's questions (`GET /offerings/{id}/questions`).
|
||||||
3. Student accepts the current published policy versions (`GET /policies`) — required to continue.
|
3. Student accepts the current published policy versions (`GET /policies`) — required to continue.
|
||||||
|
|||||||
Reference in New Issue
Block a user