39656-vm/route.php
2026-04-15 16:05:12 +00:00

137 lines
6.8 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/urban_hikes.php';
$routeId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
$route = $routeId > 0 ? urban_hikes_find($routeId) : null;
$flash = urban_hikes_get_flash();
if (!$route) {
http_response_code(404);
}
$pageTitle = $route ? $route['title'] . ' | ' . urban_hikes_project_name() : 'Route not found | ' . urban_hikes_project_name();
$pageDescription = $route ? $route['summary'] : 'The requested urban hiking route could not be found.';
$related = $route ? urban_hikes_related((string)$route['city'], (int)$route['id']) : [];
urban_hikes_render_head($pageTitle, $pageDescription, $route ? 'index, follow' : 'noindex, nofollow');
urban_hikes_render_nav();
?>
<main>
<section class="section-shell border-bottom">
<div class="container-lg px-3 px-lg-4 py-4 py-lg-5">
<?php if ($flash): ?>
<div class="toast-container position-fixed top-0 end-0 p-3">
<div class="toast app-toast text-bg-dark border-0" id="appToast" role="status" aria-live="polite" aria-atomic="true">
<div class="d-flex">
<div class="toast-body"><?= htmlspecialchars($flash['message']) ?></div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
</div>
<?php endif; ?>
<?php if (!$route): ?>
<div class="panel-card empty-state text-center">
<span class="eyebrow">Route missing</span>
<h1 class="h4 mt-2">We could not find that route.</h1>
<p class="text-muted mb-4">It may have been removed or the link is incomplete.</p>
<a class="btn btn-dark" href="index.php#results">Back to directory</a>
</div>
<?php else: ?>
<nav aria-label="breadcrumb" class="mb-3">
<ol class="breadcrumb small mb-0">
<li class="breadcrumb-item"><a href="index.php">Directory</a></li>
<li class="breadcrumb-item"><a href="city.php?city=<?= rawurlencode((string)$route['city']) ?>"><?= htmlspecialchars($route['city']) ?></a></li>
<li class="breadcrumb-item active" aria-current="page"><?= htmlspecialchars($route['title']) ?></li>
</ol>
</nav>
<div class="row g-4 align-items-start">
<div class="col-lg-8">
<article class="panel-card route-detail-card">
<div class="d-flex flex-wrap gap-2 mb-3">
<span class="badge text-bg-light border"><?= htmlspecialchars($route['city']) ?></span>
<span class="badge text-bg-light border"><?= htmlspecialchars($route['difficulty']) ?></span>
<span class="badge text-bg-light border"><?= htmlspecialchars($route['neighborhood']) ?></span>
</div>
<h1 class="detail-title mb-3"><?= htmlspecialchars($route['title']) ?></h1>
<p class="lead-copy mb-4"><?= htmlspecialchars($route['summary']) ?></p>
<div class="detail-metrics mb-4">
<div class="metric-chip">
<span class="metric-chip-label">Distance</span>
<strong><?= htmlspecialchars(number_format((float)$route['distance_km'], 1)) ?> km</strong>
</div>
<div class="metric-chip">
<span class="metric-chip-label">Duration</span>
<strong><?= htmlspecialchars(number_format((float)$route['duration_hours'], 1)) ?> hr</strong>
</div>
<div class="metric-chip">
<span class="metric-chip-label">Start point</span>
<strong><?= htmlspecialchars($route['start_point']) ?></strong>
</div>
</div>
<div class="divider mb-4"></div>
<div class="row g-4">
<div class="col-md-7">
<h2 class="section-title h5 mb-3">Route highlights</h2>
<ul class="highlights-list large mb-0">
<?php foreach (urban_hikes_highlight_items((string)$route['highlights']) as $item): ?>
<li><?= htmlspecialchars($item) ?></li>
<?php endforeach; ?>
</ul>
</div>
<div class="col-md-5">
<div class="detail-aside-card">
<h2 class="section-title h6 mb-3">Planning notes</h2>
<dl class="detail-list mb-0">
<div>
<dt>Best for</dt>
<dd><?= htmlspecialchars($route['best_for']) ?></dd>
</div>
<div>
<dt>Area</dt>
<dd><?= htmlspecialchars($route['neighborhood']) ?></dd>
</div>
</dl>
<a class="btn btn-dark w-100 mt-4" href="<?= htmlspecialchars($route['map_url']) ?>" target="_blank" rel="noopener">Open route map</a>
</div>
</div>
</div>
</article>
</div>
<div class="col-lg-4">
<div class="panel-card mb-3">
<span class="eyebrow">Next move</span>
<h2 class="section-title h5 mt-2">Want to add another city route?</h2>
<p class="text-muted mb-4">Use the lightweight admin screen to submit a new urban hike and make it searchable right away.</p>
<div class="d-grid gap-2">
<a class="btn btn-outline-secondary" href="city.php?city=<?= rawurlencode((string)$route['city']) ?>">Open city guide</a>
<a class="btn btn-outline-secondary" href="admin.php?id=<?= (int)$route['id'] ?>">Edit this route</a>
<a class="btn btn-outline-secondary" href="admin.php">Add a route</a>
</div>
</div>
<div class="panel-card">
<span class="eyebrow">More in <?= htmlspecialchars($route['city']) ?></span>
<h2 class="section-title h5 mt-2">Related routes</h2>
<?php if (!$related): ?>
<p class="text-muted mb-0">No related routes in this city yet.</p>
<?php else: ?>
<div class="vstack gap-3 mt-3">
<?php foreach ($related as $item): ?>
<a class="subroute-link" href="route.php?id=<?= (int)$item['id'] ?>">
<strong><?= htmlspecialchars($item['title']) ?></strong>
<span><?= htmlspecialchars(number_format((float)$item['distance_km'], 1)) ?> km · <?= htmlspecialchars($item['difficulty']) ?></span>
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php endif; ?>
</div>
</section>
</main>
<?php urban_hikes_render_footer(); ?>