Add Gutenberg dynamic-block wrappers for the front-end shortcodes
CI / No Debug Code (pull_request) Successful in 4s
CI / Tests (PHP 8.2) (pull_request) Successful in 52s
CI / Tests (PHP 8.1) (pull_request) Successful in 54s
CI / Tests (PHP 8.3) (pull_request) Successful in 1m29s
CI / Coding Standards (pull_request) Successful in 1m57s
CI / PHPStan (pull_request) Successful in 2m14s
CI / Build Plugin Zip (pull_request) Has been skipped

Wrap the four shortcodes (us_booking, us_student_login,
us_student_register, us_group_classes) in dynamic blocks so pages can be
previewed and styled in the block editor. Front-end rendering delegates
to the same page objects the shortcodes use; in the editor's
block-renderer REST preview a static, script-free BlockPreview is
rendered instead (no live REST calls, redirects, or Stripe.js). The
editor script (vanilla JS, no build step) registers each block with
wp.serverSideRender previews and shortcode transforms; frontend.css is
attached as the block style so previews pick up theme styling.

Resolves #44

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 12:03:27 -03:00
parent 63e2fbcc5b
commit fc70cde9d5
10 changed files with 624 additions and 20 deletions
+114
View File
@@ -0,0 +1,114 @@
<?php
declare(strict_types=1);
namespace Unsupervised\Schedular;
/**
* Static, script-free markup for the editor previews of the front-end blocks.
*
* The booking and group-class pages are populated by JavaScript on the live
* site, and the registration page requires a valid invite token — none of
* which exist inside the block editor. These previews reproduce the same
* wrapper elements and CSS classes the live pages use, filled with
* representative placeholder content, so themes can be styled against
* realistic markup without firing REST calls, redirects, or Stripe.js.
*/
class BlockPreview {
public static function booking(): string {
$days = [
[
'label' => __( 'Monday', 'unsupervised-schedular' ),
'slots' => [
[ '16:0016:30', 30 ],
[ '16:3017:00', 30 ],
],
],
[
'label' => __( 'Wednesday', 'unsupervised-schedular' ),
'slots' => [
[ '17:0017:45', 45 ],
],
],
];
$dayHtml = '';
foreach ( $days as $day ) {
$slotHtml = '';
foreach ( $day['slots'] as $slot ) {
$slotHtml .= sprintf(
'<div class="us-slot"><span>%s (%d min)</span><button type="button" class="us-book-btn" disabled>%s</button></div>',
esc_html( $slot[0] ),
(int) $slot[1],
esc_html__( 'Book', 'unsupervised-schedular' )
);
}
$dayHtml .= sprintf(
'<div class="us-day"><h3 class="us-day-heading">%s</h3>%s</div>',
esc_html( $day['label'] ),
$slotHtml
);
}
return sprintf(
'<div id="us-booking-app">%s<div id="us-slot-list">%s</div></div>',
self::note( __( 'Editor preview — students see live availability on the published page.', 'unsupervised-schedular' ) ),
$dayHtml
);
}
public static function groupClasses(): string {
return sprintf(
'<div id="us-group-app">%s<div id="us-group-list"><div class="us-class"><h3>%s</h3><p>%s</p><p>%s</p><p>25.00 CAD</p><button type="button" class="us-enrol-btn" disabled>%s</button></div></div></div>',
self::note( __( 'Editor preview — students see live group classes on the published page.', 'unsupervised-schedular' ) ),
esc_html__( 'Beginner Group Class', 'unsupervised-schedular' ),
esc_html__( 'Saturdays 10:0011:00', 'unsupervised-schedular' ),
esc_html__( 'A sample class shown so the page can be styled.', 'unsupervised-schedular' ),
esc_html__( 'Enrol', 'unsupervised-schedular' )
);
}
/**
* The live login form renders fine without any request state, so the
* preview includes the real template (the editing user is logged in, which
* would otherwise short-circuit to an "already logged in" message).
*/
public static function login(): string {
$error = '';
ob_start();
include USC_PLUGIN_DIR . 'templates/frontend/login-page.php';
return self::note( __( 'Editor preview — logged-in visitors are offered a link to the booking page instead.', 'unsupervised-schedular' ) ) . (string) ob_get_clean();
}
public static function registration(): string {
$fields = sprintf(
'<p><label for="us-reg-email">%s</label><input type="email" id="us-reg-email" value="student@example.com" readonly></p>',
esc_html__( 'Email', 'unsupervised-schedular' )
);
$fields .= sprintf(
'<p><label for="us-reg-name">%s</label><input type="text" id="us-reg-name"></p>',
esc_html__( 'Your name', 'unsupervised-schedular' )
);
$fields .= sprintf(
'<p><label for="us-reg-pass">%s</label><input type="password" id="us-reg-pass"></p>',
esc_html__( 'Password', 'unsupervised-schedular' )
);
$fields .= sprintf(
'<p><input type="submit" value="%s" disabled></p>',
esc_attr__( 'Create Account', 'unsupervised-schedular' )
);
return sprintf(
'<div class="us-register-form">%s<form>%s</form></div>',
self::note( __( 'Editor preview — the live form requires a valid invite link and lists signup policies.', 'unsupervised-schedular' ) ),
$fields
);
}
private static function note( string $text ): string {
return '<p class="us-editor-note">' . esc_html( $text ) . '</p>';
}
}