Group class term dates, single-class embed mode, and offering editing #60

Merged
thatguygriff merged 1 commits from feature/group-class-terms into main 2026-07-06 02:22:06 +00:00
Owner

Closes #59

Term dates for group classes

  • The add/edit Offering form takes a Start date and a Sessions control: one-off (term ends the day it starts) or weekly for N sessions (term_end = term_start + (N−1) weeks, computed by Offering::weeklyTermEnd()).
  • Dates are validated by Offering::normalizeDate() (strict Y-m-d, rejects e.g. 2026-02-30); an invalid date leaves both term columns NULL.
  • Fills the existing term_start/term_end columns — no schema change; REST already round-trips them.
  • The offerings admin list gains ID and Term columns; the student class card shows "Sep 8, 2026" or "Sep 8, 2026 – Nov 10, 2026 (10 weekly sessions)".

Single-class embed mode

  • [us_group_classes offering="<id>"] renders only that class with the full enrolment flow, for embedding on a page describing the class; bare usage still shows the catalog.
  • The Gutenberg block gains an offeringId sidebar option — a dropdown of active group classes fetched from GET /us-scheduler/v1/offerings?kind=group_class (editor script now depends on wp-api-fetch). A stored class that is deleted/deactivated shows as "Unavailable class #N" instead of silently reverting to all classes.
  • A pinned class that is not open shows "This class is not open for enrolment right now."

Offering editing

  • Edit per row prefills the shared form via ?usc_edit=<id>; saving posts usc_action=update. The weekly-sessions control is reconstructed from the stored dates.
  • Add and update share one parser; updates always preserve the original owner and currency, so a forged submission cannot reassign an offering. Non-admin instructors can neither prefill nor update another instructor's offering.
  • The form gains the previously missing description textarea and an Active — open for registration toggle (admin-UI counterpart of the REST is_active flag), so an edit can't wipe fields the form never collected.

Testing

  • New OfferingControllerTest (term parsing incl. invalid dates, update ownership/currency preservation, deactivation, foreign-offering rejection, edit prefill) and GroupClassPageTest (offering attribute handling); OfferingTest covers the new date helpers; BlockRegistrarTest updated for the block attribute.
  • composer test (308 tests), composer lint (PHPStan level 10), composer cs all pass.
  • Note: no Node/JS tooling in this repo, so blocks.js/group-classes.js changes are review-verified only — worth a click-through in the block editor.

🤖 Generated with Claude Code

Closes #59 ## Term dates for group classes - The add/edit Offering form takes a **Start date** and a **Sessions** control: one-off (term ends the day it starts) or weekly for N sessions (`term_end = term_start + (N−1) weeks`, computed by `Offering::weeklyTermEnd()`). - Dates are validated by `Offering::normalizeDate()` (strict `Y-m-d`, rejects e.g. `2026-02-30`); an invalid date leaves both term columns NULL. - Fills the existing `term_start`/`term_end` columns — no schema change; REST already round-trips them. - The offerings admin list gains **ID** and **Term** columns; the student class card shows "Sep 8, 2026" or "Sep 8, 2026 – Nov 10, 2026 (10 weekly sessions)". ## Single-class embed mode - `[us_group_classes offering="<id>"]` renders only that class with the full enrolment flow, for embedding on a page describing the class; bare usage still shows the catalog. - The Gutenberg block gains an `offeringId` sidebar option — a dropdown of active group classes fetched from `GET /us-scheduler/v1/offerings?kind=group_class` (editor script now depends on `wp-api-fetch`). A stored class that is deleted/deactivated shows as "Unavailable class #N" instead of silently reverting to all classes. - A pinned class that is not open shows "This class is not open for enrolment right now." ## Offering editing - **Edit** per row prefills the shared form via `?usc_edit=<id>`; saving posts `usc_action=update`. The weekly-sessions control is reconstructed from the stored dates. - Add and update share one parser; updates **always preserve the original owner and currency**, so a forged submission cannot reassign an offering. Non-admin instructors can neither prefill nor update another instructor's offering. - The form gains the previously missing **description** textarea and an **Active — open for registration** toggle (admin-UI counterpart of the REST `is_active` flag), so an edit can't wipe fields the form never collected. ## Testing - New `OfferingControllerTest` (term parsing incl. invalid dates, update ownership/currency preservation, deactivation, foreign-offering rejection, edit prefill) and `GroupClassPageTest` (offering attribute handling); `OfferingTest` covers the new date helpers; `BlockRegistrarTest` updated for the block attribute. - `composer test` (308 tests), `composer lint` (PHPStan level 10), `composer cs` all pass. - Note: no Node/JS tooling in this repo, so `blocks.js`/`group-classes.js` changes are review-verified only — worth a click-through in the block editor. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
thatguygriff added 1 commit 2026-07-06 02:19:21 +00:00
Group class term dates, single-class embed mode, and offering editing
CI / Tests (PHP 8.2) (pull_request) Successful in 45s
CI / Tests (PHP 8.1) (pull_request) Successful in 48s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 1m14s
CI / PHPStan (pull_request) Successful in 1m16s
CI / Tests (PHP 8.3) (pull_request) Successful in 37s
CI / Build Plugin Zip (pull_request) Has been skipped
cde8704267
Group class offerings now carry real dates: the add/edit form takes a
start date plus a sessions control (one-off, or weekly for N sessions;
the end date is computed as start + (N-1) weeks via
Offering::weeklyTermEnd). Dates are validated strictly (Y-m-d) and shown
in the offerings list and on the student-facing class card, including
the weekly session count.

[us_group_classes offering="<id>"] (block attribute offeringId, chosen
from a dropdown of active classes fetched from the public offerings
endpoint) restricts the page to a single class so the enrolment flow can
be embedded on a page dedicated to that class; a pinned class that is no
longer offered reports itself closed instead of falling back to the
catalog.

Offerings are now editable from the admin screen: an Edit button
prefills the shared add/edit form and saving posts usc_action=update.
Updates always preserve the original owner and currency, and non-admin
instructors can only load and update their own offerings. The form also
gains the previously missing description field and an Active toggle (the
admin-UI counterpart of the REST is_active flag) so an edit cannot wipe
data the form never collected.

Closes #59

Co-Authored-By: Claude Fable 5 <[email protected]>
thatguygriff merged commit a9f0b8c066 into main 2026-07-06 02:22:06 +00:00
thatguygriff deleted branch feature/group-class-terms 2026-07-06 02:22:06 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Unsupervised/unsupervised-scheduler#60