124 lines
6.7 KiB
PHP
124 lines
6.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/app.php';
|
|
|
|
ensure_schema();
|
|
|
|
$requestId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
|
|
$request = $requestId ? fetch_request($requestId) : null;
|
|
|
|
if (!$request) {
|
|
http_response_code(404);
|
|
render_head(app_name() . ' | Request not found', 'The selected request is unavailable.', 'noindex,nofollow');
|
|
render_header('operations');
|
|
?>
|
|
<section class="section-block">
|
|
<div class="container">
|
|
<div class="card-panel text-center py-5">
|
|
<h1 class="h3 mb-3">Request not found</h1>
|
|
<a href="/requests.php" class="btn btn-dark">Back to board</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<?php
|
|
render_footer();
|
|
exit;
|
|
}
|
|
|
|
$recommendedOffers = hydrate_recommended_offers($request);
|
|
$bookedOffer = !empty($request['booked_offer_slug']) ? offer_by_slug((string) $request['booked_offer_slug']) : null;
|
|
|
|
render_head(app_name() . ' | Request #' . (int) $request['id'], 'Detailed taxi request attribution and recommendation view.', 'noindex,follow');
|
|
render_header('operations');
|
|
?>
|
|
<section class="section-block">
|
|
<div class="container">
|
|
<div class="section-heading mb-4">
|
|
<div>
|
|
<div class="eyebrow">Request detail</div>
|
|
<h1 class="section-title">Taxi request #<?= (int) $request['id'] ?></h1>
|
|
</div>
|
|
<div class="d-flex gap-2">
|
|
<a href="/request_success.php?id=<?= (int) $request['id'] ?>" class="btn btn-outline-dark">Open confirmation view</a>
|
|
<a href="/requests.php" class="btn btn-dark">Back to board</a>
|
|
</div>
|
|
</div>
|
|
<div class="row g-4 align-items-start">
|
|
<div class="col-lg-5">
|
|
<div class="card-panel">
|
|
<div class="card-head mb-3">
|
|
<div>
|
|
<h2 class="h5 mb-1">Request summary</h2>
|
|
<p class="text-secondary mb-0">Minimal operational data captured in a single flow record.</p>
|
|
</div>
|
|
<span class="badge rounded-pill <?= h(status_badge_class((string) $request['status'])) ?>"><?= h(str_replace('_', ' ', (string) $request['status'])) ?></span>
|
|
</div>
|
|
<dl class="summary-list mb-0">
|
|
<div><dt>Passenger</dt><dd><?= h($request['passenger_name']) ?></dd></div>
|
|
<div><dt>Pickup point</dt><dd><?= h($request['pickup_point']) ?></dd></div>
|
|
<div><dt>Destination</dt><dd><?= h(destination_label((string) $request['destination_area'])) ?></dd></div>
|
|
<div><dt>Pickup time</dt><dd><?= h(date('d M Y · H:i', strtotime((string) $request['pickup_time']))) ?></dd></div>
|
|
<div><dt>Channel</dt><dd><?= h(source_channel_label((string) $request['source_channel'])) ?></dd></div>
|
|
<div><dt>Party size</dt><dd><?= (int) $request['party_size'] ?></dd></div>
|
|
<div><dt>Notes</dt><dd><?= $request['notes'] ? h((string) $request['notes']) : '—' ?></dd></div>
|
|
</dl>
|
|
</div>
|
|
<div class="card-panel mt-3">
|
|
<div class="card-head mb-3">
|
|
<div>
|
|
<h2 class="h5 mb-1">Attribution timeline</h2>
|
|
<p class="text-secondary mb-0">Simple event capture inside the single record.</p>
|
|
</div>
|
|
</div>
|
|
<div class="timeline-item">
|
|
<strong>Taxi request created</strong>
|
|
<div class="text-secondary small"><?= h(date('d M Y · H:i', strtotime((string) $request['created_at']))) ?></div>
|
|
</div>
|
|
<div class="timeline-item">
|
|
<strong>Recommendations shown</strong>
|
|
<div class="text-secondary small">Offer set: <?= h((string) $request['recommended_offer_slugs']) ?></div>
|
|
</div>
|
|
<div class="timeline-item <?= $request['recommendation_clicked_slug'] ? '' : 'timeline-item-muted' ?>">
|
|
<strong>Recommendation clicked</strong>
|
|
<div class="text-secondary small"><?= $request['recommendation_clicked_slug'] ? h((string) $request['recommendation_clicked_slug']) : 'Pending' ?></div>
|
|
</div>
|
|
<div class="timeline-item <?= $request['booking_completed_at'] ? '' : 'timeline-item-muted' ?>">
|
|
<strong>Booking completed</strong>
|
|
<div class="text-secondary small"><?= $request['booking_completed_at'] ? h(date('d M Y · H:i', strtotime((string) $request['booking_completed_at']))) : 'Pending' ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-7">
|
|
<div class="card-panel">
|
|
<div class="card-head mb-3">
|
|
<div>
|
|
<h2 class="h5 mb-1">Recommended offers</h2>
|
|
<p class="text-secondary mb-0">Stored as the first contextual recommendation set for this request.</p>
|
|
</div>
|
|
</div>
|
|
<div class="row g-3">
|
|
<?php foreach ($recommendedOffers as $offer): ?>
|
|
<div class="col-md-6">
|
|
<article class="offer-card compact-offer <?= $bookedOffer && $bookedOffer['slug'] === $offer['slug'] ? 'offer-card-active' : '' ?>">
|
|
<div class="small text-secondary text-uppercase mb-2"><?= h($offer['sector']) ?></div>
|
|
<h3 class="h6 mb-2"><?= h($offer['title']) ?></h3>
|
|
<p class="text-secondary mb-3"><?= h($offer['description']) ?></p>
|
|
<div class="small text-secondary mb-2">From €<?= (int) $offer['price_from'] ?> · <?= h($offer['duration']) ?></div>
|
|
<?php if ($bookedOffer && $bookedOffer['slug'] === $offer['slug']): ?>
|
|
<span class="badge text-bg-success rounded-pill">Booked</span>
|
|
<?php else: ?>
|
|
<span class="badge text-bg-light rounded-pill border text-dark">Recommended</span>
|
|
<?php endif; ?>
|
|
</article>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<?php render_footer(); ?>
|