- Persist selected date across month navigation using module-level vars; datesSet re-applies is-selected and restores slots when returning - Show "No availability this month" overlay after a fetch returns empty; gated on initializedRef+fetchedRef so auto-advance phase is silent - Fix Dec 31 overflow: showNonCurrentDates:false hides adjacent-month days - Fix fc-day-disabled background tint in calendar.css - Gate auto-advance on loading() callback so removeAllEventSources() spurious eventsSet() fires don't trigger premature month jumping - Inline overlay styles to avoid Tailwind cascade uncertainty; document the module-level CX constant pattern as the general fix - firstName added to booking form; storeSlot sends email directly when full contact info present, skipping tempstore redirect - Remove BookingForm.php and /schedule/book route (replaced by inline form) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
97 lines
2.8 KiB
Text
97 lines
2.8 KiB
Text
<?php
|
||
|
||
use Drupal\Core\Breadcrumb\Breadcrumb;
|
||
use Drupal\Core\Link;
|
||
use Drupal\Core\Routing\RouteMatchInterface;
|
||
|
||
function riverside_pt_page_attachments(array &$attachments): void {
|
||
$route = \Drupal::routeMatch()->getRouteName() ?? '';
|
||
if (!str_starts_with($route, 'riverside_pt.')) {
|
||
return;
|
||
}
|
||
$attachments['#attached']['library'][] = 'riverside_pt/app';
|
||
}
|
||
|
||
function riverside_pt_theme(): array {
|
||
return [
|
||
'riverside_pt_header' => [
|
||
'variables' => [
|
||
'site_name' => NULL,
|
||
'home_url' => NULL,
|
||
'menu_items' => [],
|
||
'current_path' => NULL,
|
||
],
|
||
],
|
||
'riverside_pt_home' => [
|
||
'variables' => [],
|
||
],
|
||
];
|
||
}
|
||
|
||
function riverside_pt_page_top(array &$page_top): void {
|
||
$route = \Drupal::routeMatch()->getRouteName() ?? '';
|
||
if (!str_starts_with($route, 'riverside_pt.')) {
|
||
return;
|
||
}
|
||
$page_top['rpt_header'] = [
|
||
'#theme' => 'riverside_pt_header',
|
||
'#cache' => ['contexts' => ['url.path', 'route']],
|
||
];
|
||
}
|
||
|
||
function riverside_pt_preprocess_riverside_pt_header(array &$variables): void {
|
||
$variables['site_name'] = \Drupal::config('system.site')->get('name');
|
||
$variables['home_url'] = \Drupal\Core\Url::fromRoute('<front>')->toString();
|
||
|
||
$tree_service = \Drupal::service('menu.link_tree');
|
||
$params = new \Drupal\Core\Menu\MenuTreeParameters();
|
||
$params->setMaxDepth(1);
|
||
$tree = $tree_service->load('main', $params);
|
||
$tree = $tree_service->transform($tree, [
|
||
['callable' => 'menu.default_tree_manipulators:checkAccess'],
|
||
['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
|
||
]);
|
||
|
||
$seen = [];
|
||
$items = [];
|
||
foreach ($tree as $element) {
|
||
if (!$element->access->isAllowed()) {
|
||
continue;
|
||
}
|
||
$url = $element->link->getUrlObject()->toString();
|
||
if (in_array($url, $seen, TRUE)) {
|
||
continue;
|
||
}
|
||
$seen[] = $url;
|
||
$title = (string) $element->link->getTitle();
|
||
$items[] = [
|
||
'title' => $title,
|
||
'url' => $url,
|
||
'is_cta' => ($title === 'Book An Appointment' || $title === 'Contact'),
|
||
];
|
||
}
|
||
$variables['menu_items'] = $items;
|
||
$variables['current_path'] = \Drupal::request()->getPathInfo();
|
||
}
|
||
|
||
function riverside_pt_mail(string $key, array &$message, array $params): void {
|
||
if ($key !== 'booking_request') {
|
||
return;
|
||
}
|
||
|
||
$start = new \DateTime($params['start']);
|
||
$end = new \DateTime($params['end']);
|
||
|
||
$message['subject'] = 'Booking request — ' . $start->format('M j, Y g:i A');
|
||
$lines = [
|
||
'Name: ' . $params['first_name'] . ' ' . $params['last_name'],
|
||
'Phone: ' . $params['phone'],
|
||
'Slot: ' . $start->format('l, F j, Y') . ', ' . $start->format('g:i A') . '–' . $end->format('g:i A'),
|
||
];
|
||
|
||
if (!empty($params['comments'])) {
|
||
$lines[] = 'Comments: ' . $params['comments'];
|
||
}
|
||
|
||
$message['body'][] = implode("\n", $lines);
|
||
}
|