133 lines
6.5 KiB
PHP
133 lines
6.5 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="index.php?city=<?= rawurlencode((string)$route['city']) ?>#results"><?= 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>
|
|
<a class="btn btn-outline-secondary w-100" href="admin.php">Add a route</a>
|
|
</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(); ?>
|