77 lines
4.4 KiB
PHP
77 lines
4.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/app.php';
|
|
|
|
ensure_schema();
|
|
|
|
$requests = fetch_requests(50);
|
|
$stats = fetch_dashboard_stats();
|
|
|
|
render_head(app_name() . ' | Operations board', 'Operations board for taxi requests, conversions, and recommendation performance.');
|
|
render_header('operations');
|
|
?>
|
|
<section class="section-block">
|
|
<div class="container">
|
|
<div class="section-heading mb-4">
|
|
<div>
|
|
<div class="eyebrow">Operations board</div>
|
|
<h1 class="section-title">Taxi → consumption performance snapshot.</h1>
|
|
</div>
|
|
<a href="/" class="btn btn-dark">New taxi request</a>
|
|
</div>
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-6 col-lg-3"><div class="metric-card h-100"><span class="metric-label">Taxi requests</span><strong><?= (int) $stats['total_requests'] ?></strong><small>captured</small></div></div>
|
|
<div class="col-6 col-lg-3"><div class="metric-card h-100"><span class="metric-label">Clicks</span><strong><?= (int) $stats['offers_clicked'] ?></strong><small>recommendation engagement</small></div></div>
|
|
<div class="col-6 col-lg-3"><div class="metric-card h-100"><span class="metric-label">CTR</span><strong><?= h(number_format((float) $stats['ctr'], 1)) ?>%</strong><small>click-through rate</small></div></div>
|
|
<div class="col-6 col-lg-3"><div class="metric-card h-100"><span class="metric-label">Conversion</span><strong><?= h(number_format((float) $stats['conversion'], 1)) ?>%</strong><small>booking from request</small></div></div>
|
|
</div>
|
|
<div class="card-panel p-0 overflow-hidden">
|
|
<?php if ($requests === []): ?>
|
|
<div class="empty-state text-center">
|
|
<div class="empty-icon"><i class="bi bi-clipboard-data"></i></div>
|
|
<h2 class="h4">No activity yet</h2>
|
|
<p>The board will populate after the first taxi request and recommendation booking.</p>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="table-responsive">
|
|
<table class="table table-slim align-middle mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Passenger</th>
|
|
<th>Route context</th>
|
|
<th>Offer booked</th>
|
|
<th>Status</th>
|
|
<th>Created</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($requests as $request): ?>
|
|
<tr>
|
|
<td>#<?= (int) $request['id'] ?></td>
|
|
<td>
|
|
<div class="fw-semibold"><?= h($request['passenger_name']) ?></div>
|
|
<div class="text-secondary small"><?= h(source_channel_label((string) $request['source_channel'])) ?></div>
|
|
</td>
|
|
<td>
|
|
<div><?= h($request['pickup_point']) ?></div>
|
|
<div class="text-secondary small">to <?= h(destination_label((string) $request['destination_area'])) ?></div>
|
|
</td>
|
|
<td><?= $request['booked_offer_title'] ? h((string) $request['booked_offer_title']) : '<span class="text-secondary">Pending</span>' ?></td>
|
|
<td><span class="badge rounded-pill <?= h(status_badge_class((string) $request['status'])) ?>"><?= h(str_replace('_', ' ', (string) $request['status'])) ?></span></td>
|
|
<td><?= h(date('d M H:i', strtotime((string) $request['created_at']))) ?></td>
|
|
<td class="text-end"><a href="/request_detail.php?id=<?= (int) $request['id'] ?>" class="btn btn-sm btn-outline-dark">Detail</a></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<?php render_footer(); ?>
|