Group-class scheduling, instructor assignment, and details/invite management #99

Merged
thatguygriff merged 1 commits from feature/group-class-scheduling into main 2026-07-23 20:56:59 +00:00
Owner

Summary

Group classes now carry a specific class time (alongside date and duration) and an assigned instructor, students see who teaches each class and when it meets, and the back-office group-class views are reworked into per-class summaries that click through to a full details page from which invite-only membership is managed.

Class time & instructor

  • Schema: add class_time (TIME) to us_offerings; Offering gains normalizeTime and sessionWindows. No version bump — 1.1.0 is unreleased, so this rides the pending 1.0.0→1.1.0 dbDelta upgrade.
  • Offering form gains a class-time field and a studio-admin Instructor picker (plain instructors always own the classes they create).
  • Offering\ClassSlotReconciler: assigning an instructor to a scheduled class clears their open booking slots overlapping each session and flags any already-booked lesson that clashes (a booked lesson is never deleted). Backed by new AvailabilityRepository::findOverlapping.
  • GET /offerings exposes instructor_name; the enrolment page shows the instructor and when the class meets.

Back-office views

  • Instructor My Group Classes and studio-admin Group Classes are now per-class summaries with enrolment counts, not flat student lists.
  • Each links through (?class_id=<id>) to a per-class details page: schedule panel, roster with payment status, and — for invite-only classes — the add/make-available/invite-by-email controls. Invite-only membership is managed entirely from this page.
  • Invite actions are permitted for the class's owning instructor or any view_all_lessons studio admin, so an owner-operator (studio admin who also teaches — for whom the My Group Classes menu is hidden) can reach every class's roster and invites from the Group Classes page.

Instructor name display

  • New Auth\UserName::format() shows the instructor's real name (first + last) or nickname, never their login/username; the front-end instructor_name and both back-end group-class views route through it.

Tests

  • composer test — 513 tests, 1484 assertions, all pass
  • composer lint (PHPStan level 10) — clean
  • composer cs (PHPCS WordPress standards) — clean

Docs (docs/features/offerings.md, docs/features/group-classes.md) and the [1.1.0] CHANGELOG section updated.

🤖 Generated with Claude Code

## Summary Group classes now carry a specific **class time** (alongside date and duration) and an **assigned instructor**, students see who teaches each class and when it meets, and the back-office group-class views are reworked into per-class summaries that click through to a full details page from which invite-only membership is managed. ### Class time & instructor - Schema: add `class_time` (TIME) to `us_offerings`; `Offering` gains `normalizeTime` and `sessionWindows`. No version bump — 1.1.0 is unreleased, so this rides the pending 1.0.0→1.1.0 `dbDelta` upgrade. - Offering form gains a class-time field and a studio-admin **Instructor** picker (plain instructors always own the classes they create). - `Offering\ClassSlotReconciler`: assigning an instructor to a scheduled class clears their **open** booking slots overlapping each session and **flags** any already-booked lesson that clashes (a booked lesson is never deleted). Backed by new `AvailabilityRepository::findOverlapping`. - `GET /offerings` exposes `instructor_name`; the enrolment page shows the instructor and when the class meets. ### Back-office views - Instructor **My Group Classes** and studio-admin **Group Classes** are now per-class summaries with enrolment counts, not flat student lists. - Each links through (`?class_id=<id>`) to a per-class **details page**: schedule panel, roster with payment status, and — for invite-only classes — the add/make-available/invite-by-email controls. Invite-only membership is managed entirely from this page. - Invite actions are permitted for the class's owning instructor **or** any `view_all_lessons` studio admin, so an owner-operator (studio admin who also teaches — for whom the *My Group Classes* menu is hidden) can reach every class's roster and invites from the **Group Classes** page. ### Instructor name display - New `Auth\UserName::format()` shows the instructor's real name (first + last) or nickname, never their login/username; the front-end `instructor_name` and both back-end group-class views route through it. ## Tests - `composer test` — 513 tests, 1484 assertions, all pass - `composer lint` (PHPStan level 10) — clean - `composer cs` (PHPCS WordPress standards) — clean Docs (`docs/features/offerings.md`, `docs/features/group-classes.md`) and the `[1.1.0]` CHANGELOG section updated. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
thatguygriff added 1 commit 2026-07-23 20:52:33 +00:00
Show instructor real name or nickname in group-class views, not the login
CI / Tests (PHP 8.2) (pull_request) Successful in 46s
CI / Tests (PHP 8.1) (pull_request) Successful in 46s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 2m47s
CI / Coding Standards (pull_request) Successful in 2m51s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m41s
CI / Build Plugin Zip (pull_request) Skipped
87cfe921a9
Add Auth\UserName::format(), which prefers a user's first + last name, then
their nickname, avoiding display_name (which can be the login/username).
Route the instructor name through it in both the front-end offerings response
(instructor_name) and the back-end group-class summary and details views.

Tests: composer test (513), composer lint, composer cs all pass.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
thatguygriff merged commit 013558019e into main 2026-07-23 20:56:59 +00:00
thatguygriff deleted branch feature/group-class-scheduling 2026-07-23 20:56:59 +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#99