#26 - Loading animation + success message fix

This commit was merged in pull request #31.
This commit is contained in:
Martin Slachta
2026-06-22 11:20:28 +02:00
parent c754e18a82
commit 97ee8fc991
32 changed files with 597 additions and 175 deletions
@@ -74,6 +74,13 @@ class RsvFormReservationElementHandler implements RsvFormElementHandler {
$price_per_block = (float) $def->getAttr('price_per_block', 0);
$result->setValue($name . '_price', $price_per_block * count($payload['timetable_reservations']));
$slots = array_map(fn($t) => [
'start_utc' => (new DateTime($t))->format(DateTime::ATOM),
'end_utc' => $this->end_from_start(new DateTime($t), $timetable->block_size)->format(DateTime::ATOM),
'price' => $price_per_block,
], $payload['timetable_reservations']);
$result->setValue('slots', array_merge($result->getValue('slots') ?? [], $slots));
return true;
}
@@ -16,13 +16,26 @@ final class RsvFormCalculatedValues {
$price_before_discount += (float) $element_calculator($element, $data->getValue($element->getName()));
}
$discount_pct = (new RsvMembershipService())->discount_for($definition, $data);
$discount_detail = (new RsvMembershipService())->discount_detail_for($definition, $data);
$discount_pct = $discount_detail['percent'];
$final_price = $calculator->calculate($definition, $data);
$subtotal = $price_before_discount;
$discount_amount = $subtotal - $final_price;
return [
'price' => $final_price,
'price_before_discount' => $price_before_discount,
'discount_percent' => $discount_pct,
'pricing' => [
'currency' => 'CZK',
'subtotal' => $subtotal,
'discount' => $discount_pct > 0.0 ? [
'percent' => $discount_pct,
'amount' => round($discount_amount, 2),
'reason' => $discount_detail['reason'],
] : null,
'total' => $final_price,
],
];
}
@@ -31,6 +44,6 @@ final class RsvFormCalculatedValues {
* @return list<string>
*/
public static function names(): array {
return ['price', 'price_before_discount', 'discount_percent'];
return ['price', 'price_before_discount', 'discount_percent', 'pricing'];
}
}
@@ -1,7 +1,5 @@
<?php
use Reservair\Templating\RsvTemplateEngine;
class RsvFormHtmlRenderer {
public function draw(RsvFormDefinition $form): bool {
if (!$form->hasElements()) {
@@ -21,37 +19,12 @@ class RsvFormHtmlRenderer {
<?php endforeach; ?>
</form>
<?php $this->draw_success_template($form); ?>
</div>
<?php
return true;
}
/**
* Emits the admin-configured success message as an inert <template> that the
* client clones once the form is submitted. A <reservation-summary> element
* expands to a placeholder div that RsvFormSender fills with the visitor's
* selected slots.
*/
private function draw_success_template(RsvFormDefinition $form): void {
$message = trim($form->getSuccessMessage());
if ($message === '') {
return;
}
global $rsv_template_registry;
$engine = new RsvTemplateEngine(registry: $rsv_template_registry);
// Sanitize admin HTML before rendering, allowing the registered template
// custom elements through so the engine can expand them.
$allowed = $rsv_template_registry->kses_allowed(wp_kses_allowed_html('post'));
$html = $engine->render(wp_kses($message, $allowed));
?>
<template class="rsv-form-success"><?= $html ?></template>
<?php
}
public function draw_element(RsvFormElementDefinition $data): void {
global $rsv_form_registry;
+18 -1
View File
@@ -35,7 +35,24 @@ class RsvFormSubmission {
return ['success' => false, 'errors' => $result->getErrors()];
}
return ['success' => true, 'submit_id' => $submit_id, 'values' => $result->getValues()];
global $rsv_template_registry;
$message = trim($definition->getSuccessMessage());
if ($message !== '') {
$allowed = $rsv_template_registry->kses_allowed(wp_kses_allowed_html('post'));
$template = wp_kses($message, $allowed);
} else {
$template = '';
}
$data = array_merge($result->getValues(), (new RsvFormCalculatedValues())->for($definition, $form_data));
try {
$submit_repo->set_computed($submit_id, $data);
} catch (\Throwable $e) {
Logger::error($e);
}
return ['success' => true, 'submit_id' => $submit_id, 'template' => $template, 'data' => $data];
}
/** Remove a submission whose run failed. */