Files
unsupervised-scheduler/CHANGELOG.md
T
thatguygriff 7c91e1eef7
CI / Tests (PHP 8.1) (pull_request) Successful in 45s
CI / PHPStan (pull_request) Successful in 2m50s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m45s
CI / Build Plugin Zip (pull_request) Skipped
CI / Tests (PHP 8.2) (pull_request) Successful in 52s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 2m52s
Add the changelog entry missed by #135
The upcoming-lessons layout fix shipped without one.
2026-07-28 23:04:29 -03:00

91 lines
15 KiB
Markdown

# Changelog
All notable changes to Unsupervised Scheduler are documented in this file, one
section per version, newest first. The top section is always the version the code
on `main` currently carries (the `Version:` header in `unsupervised-schedular.php`).
Whether a version is "released" is purely a matter of whether its tag exists — the
changelog itself does not track that.
When a `v*` tag is pushed, `.gitea/workflows/release.yml` publishes the matching
`## [x.y.z]` section verbatim as the Gitea release notes, then opens a PR that bumps
the plugin to the next patch version and adds a fresh section here for it. Record
each change under the current top section as you work.
## [1.2.4]
### Fixed
- A student's **upcoming lessons no longer pile on top of each other**. On the booking page, the lesson name, its date and time, the status badge and the **Cancel** button could render over one another instead of sitting in a tidy row — worst with a long lesson-type name, and on narrow screens, where the row had no phone layout at all. The panel now keeps its shape whatever the theme around it does, long names wrap instead of shoving the Cancel button out of the row, and on a phone the lesson details stack above the buttons.
## [1.2.3]
### Changed
- A **monthly group class is now billed its price once per month**, however many times the class meets in that month. Previously the monthly charge multiplied the price by the number of sessions in the month — a class priced at `40.00 CAD` meeting weekly was billed `160.00 CAD` on the 1st — which no studio could quote honestly on a class card. A monthly **private lesson** is unchanged: its price is a per-lesson fee and the month is still billed one fee per lesson, which is why it is quoted per lesson. Studios running a monthly group class should check the class price now reads as the monthly fee they intend to charge.
### Added
- Every price a student sees now says **when** it is due. Lesson types in the booking form read `50.00 CAD at booking`, and group-class cards read `120.00 CAD up front`, `40.00 CAD weekly` or `40.00 CAD monthly` — the offering's billing mode, in the student's words. A monthly **private lesson** is quoted per lesson (`50.00 CAD per lesson monthly`), since its monthly charge covers every lesson booked that month; a monthly group class is quoted as the monthly figure it is. A free offering still just reads **Free**.
- The **Policies** admin page can now **show you what is actually in a version**. Every row in the versions table has a **View** button that opens that version's text below the table, rendered exactly as students see it at booking and signup, whether the version is the published one, an old archived one, or a draft nobody has seen yet. The text is editable straight from the viewer, and what happens when you save depends on the version: a draft is simply updated in place, while editing a **published or archived version saves your text as a new draft version** and leaves the original exactly as students accepted it. The new draft then opens in the viewer ready to publish. Nothing a student has agreed to is ever rewritten.
- Booking a lesson and enrolling in a class now take a **second confirmation that the student agrees to pay**. Above the Confirm button the form restates the price with its cadence, spells out how it is collected ("Charged on the 1st of each month, for that month's lessons"), adds the studio's HST so the figure matches the total actually billed, and requires a tick on "I agree to pay 56.50 CAD at booking." before it will submit — separate from, and in addition to, the studio policies the student accepts above it. Reserving a time weekly quotes the per-lesson fee and the most it can add up to ("up to 12 lessons, 678.00 CAD in total"), since a week another student takes first is simply not booked. Free offerings have nothing to agree to and show no price block.
### Fixed
- Policies are **readable where students have to accept them**. A policy typed as plain paragraphs — the normal way to write one, with no HTML — was being dropped into the booking, enrolment, and signup forms unformatted, collapsing the whole document into a single squashed line with a horizontal scrollbar and words piling on top of each other. Policy text is now formatted the same way WordPress formats post content, so blank lines become real paragraphs, and the acceptance box is styled as a proper bounded reading panel: long policies scroll vertically instead of running off the side of the page, long pasted links wrap rather than forcing the page sideways, and the "I have read and agree" tick stays in view. Policies written with HTML are unaffected. The studio registration page was also missing the plugin's stylesheet entirely, which is why the problem was at its worst there.
## [1.2.2]
### Added
- The **Lesson Booking** block gained three embedding options in its sidebar. **Lesson type** pins the block to a single private-lesson type — only the times bookable as that type are listed and it is the only thing bookable there, auto-selected on the registration form — so a page about one lesson type can carry its own calendar. **Show the lesson-type filter** turns the **Show Only** control on or off. **Sections** embeds just one half of the page: booking calendar only, or the student's upcoming lessons only, so the two can live on different pages. All three are available to the shortcode as `[us_booking lesson_type="…" show_filter="no" show="booking|upcoming"]`, and the block's editor preview follows the chosen sections.
- The booking calendar now has a **Show Only** button beside the List/Week toggle that opens a lesson-type filter, so a student browsing open times can narrow them to the types they actually want. Because not every open time can be booked as every private-lesson type — some times are tied to a specific type, others only take types of a matching length — the filter shows just the times bookable as the ticked types, and re-anchors the week view on the earliest one so it never opens on an empty week. Picking one of those times narrows the **Lesson type** picker on the registration form to the same list, and when only one type is left it is chosen automatically with its questions loaded. The type list starts collapsed and can be tucked away again without losing the filter; the button shows how many types are ticked. Tick nothing (or use **Show all types**) to see every open time as before. The filter is hidden when the studio only offers one private-lesson type.
- The **Group Classes** block can now be pinned to a single class, under **Classes shown → Class** in the block sidebar (shortcode: `[us_group_classes offering="…"]`). Pick a class and the block shows only that one, so it can be embedded on a page that describes the class. In this mode the class's own description is left out to avoid repeating the page copy — the card shows the schedule, instructor, price, enrolment deadline and the enrol/withdraw controls. Leaving it on **All classes** keeps the full browsable catalog with descriptions.
- The **Student Registration** block can now send students onward to a page of your choosing once they finish registering. Its **After email confirmation** panel is now **After registration**: the page you pick there is where the link shown to a newly registered student points — the "Sign in to your account" link after they confirm their email, and a "Continue to your account" link for an invited student, who is signed in immediately. A new **Redirect automatically** option takes them straight there instead of showing the link. Registration errors are never skipped — a failed sign-up and an expired confirmation link still show their message on the page, as does the "check your email to confirm your address" step. The redirect needs a page to be chosen; with none set, students see the link (or, for invited students, just the confirmation) as before.
## [1.2.1]
### Fixed
- Registration questions, offering titles/notes, and policy names longer than their storage limit are no longer silently discarded. Previously typing a fixed-size field past its maximum length reported success but saved nothing — the database quietly rejected the over-long value. These fields now cap the input in the form, and the API rejects an over-long value with a clear error.
- Students can no longer reach the WordPress dashboard. A student who navigates to `wp-admin` is redirected to the site front end and the admin toolbar is hidden for them, so they only ever see the studio's booking pages. Anyone who runs the studio — administrators, studio admins, and instructors — keeps full `wp-admin` access.
- The instructor picker on the **Add/Edit Offering** form no longer comes up empty for a solo studio owner. When the person running the studio teaches from a WordPress administrator account (the default single-account setup), they now appear in the instructor dropdown and can be assigned to a class.
## [1.2.0]
### Added
- Offerings can now bill on a schedule: **weekly** (a pending payment 24 hours before each lesson) or **monthly** (one payment on the 1st for that month's lessons), alongside the existing one-time and full-term modes. Applies to both private lessons and group classes. A daily job generates due payments, and each student receives one consolidated itemised email per scan; batched payments share a reference so the admin Payments queue groups them with a lump-sum total for e-transfer reconciliation. Cancelling a lesson never voids a scheduled payment.
- Cancelling a lesson that was **already paid for** now credits the student that money instead of leaving it as a manual refund. The credit is one lesson's share of what they paid — the whole amount for a single lesson, or a per-lesson slice of a monthly charge or a full-term series. The daily billing scan automatically applies any available credit against a student's upcoming weekly/monthly charges before emailing their notice, which shows the credit applied and the reduced total due; a charge fully covered by credit is settled and leaves the admin Payments queue. A student's outstanding credit balance is shown on their **student detail** page in the studio admin. Still-pending (unpaid) payments continue to be voided on cancellation as before.
- 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.
- Group classes now also carry a **withdrawal deadline** the instructor sets per class. Up to that day a student can withdraw themselves from the class (the group-class page shows a **Withdraw** button) — this frees their seat and voids any pending payment but does **not** credit their account. After the deadline self-withdrawal closes and the student must ask the studio, who can still withdraw them by hand from the student detail page. Leaving the deadline blank keeps self-withdrawal open indefinitely.
- The **Add/Edit Offering** form now shows only the fields relevant to the selected kind: the group-class settings (capacity, dates, times, enrolment/withdrawal deadlines, sessions, schedule note, invite-only) appear only for a group class, and the weekly-reservation option only for a private lesson.
- 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.
- Studio admins and instructors can open a **lesson detail view** from the Scheduler and My Lessons lists, showing the offering booked, the policy versions the student accepted (with acceptance time and IP), and their intake answers. On My Lessons an instructor may only open their own lessons; the studio Scheduler may open any.
- The **Student Registration** block's "registration is by invitation only" message is now customisable, under a new **Invitation-only notice** panel (shortcode: `invite_only_message`). Leaving it blank keeps the default wording.
### Changed
- The student **upcoming lessons** panel now shows each booked offering's name and length beside the time, and lists only the soonest five lessons with a "Show all" reveal. The Scheduler and My Lessons week/list views likewise show the booked offering.
### Fixed
- Accepting an invitation now keeps the student signed in. Previously the registration form processed the submission after the page had started rendering, so the sign-in cookie was never sent and the new student was bounced back to the (logged-out) registration page; it is now handled before any output, and the student lands logged in.
- Account-registration questions now save. On sites first installed before account-scope questions existed, the `us_questions.offering_id` column was left `NOT NULL` (the schema migration relied on `dbDelta`, which does not reliably relax a column to allow `NULL`), so saving an account question failed with "Column 'offering_id' cannot be null". A one-time, self-healing migration relaxes the column on the next load.
## [1.1.1]
### Fixed
- The **Enable auto-updates** toggle now appears for the plugin on the Plugins screen. The self-updater now reports the plugin to WordPress even when it is already current, so core marks it update-supported and shows the toggle; previously the toggle was hidden between releases.
## [1.1.0]
### Added
- Invite-only group classes, so a class can be restricted to students who hold an invite.
- Instructor group-class roster view under **My Lessons**.
- Cancellation cutoff that limits how close to a lesson a student can cancel.
- Studio-defined account-registration questions collected during student sign-up.
- Group classes now carry a specific class time (alongside the date and duration), and studio admins can assign the teaching instructor. Assigning an instructor clears their open booking slots at the class time and flags any already-booked lesson that clashes.
- Students see who teaches each group class and when it meets on the enrolment page. Instructor names in the group-class views (front and back end) show the instructor's real name (first + last) or nickname, never their login/username.
### Changed
- Plugin metadata links now point at Unsupervised and the Gitea repository.
- The instructor **My Group Classes** view is now a summary of classes with enrolment counts; each class links through to a per-class **details page** (class schedule, roster, and — for invite-only classes — the controls to add or invite students), rather than listing every student inline. Managing who is in an invite-only class is now done from that details page. The studio-admin **Group Classes** page is likewise a per-class summary that links through to the same details page, so a studio admin — including an owner-operator who also teaches — can view any class's roster and manage its invite-only membership.
## [1.0.0]
First stable release: instructor/student lesson scheduling for WordPress, including
availability management, one-on-one and group-class booking, Stripe payments, student
self-registration with email confirmation and admin approval, group invite links, and
self-update from tagged Gitea releases.