39282-vm/preset.php
Flatlogic Bot 16b7d41fc5 v1
2026-03-23 19:19:15 +00:00

115 lines
6.0 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
require_once __DIR__ . '/app.php';
ensure_recliner_schema();
$meta = project_meta();
$presetId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
$preset = $presetId ? get_preset((int) $presetId) : null;
http_response_code($preset ? 200 : 404);
$assetVersion = (string) max(@filemtime(__DIR__ . '/assets/css/custom.css') ?: time(), @filemtime(__DIR__ . '/assets/js/main.js') ?: time());
$pageTitle = ($preset ? $preset['name'] . ' · ' : '') . $meta['name'];
$pageDescription = $preset
? 'Preset detail for ' . $preset['name'] . ' with a saved recline angle of ' . $preset['angle_deg'] . ' degrees.'
: $meta['description'];
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= e($pageTitle) ?></title>
<meta name="description" content="<?= e($pageDescription) ?>">
<meta name="theme-color" content="#0b0d10">
<?php if (!empty($meta['image'])): ?>
<meta property="og:image" content="<?= e($meta['image']) ?>">
<meta property="twitter:image" content="<?= e($meta['image']) ?>">
<?php endif; ?>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="/assets/css/custom.css?v=<?= e($assetVersion) ?>">
</head>
<body>
<header class="border-bottom border-secondary-subtle shell-header">
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container-xxl py-2">
<a class="navbar-brand fw-semibold" href="/index.php">Recliner Haptics</a>
<div class="ms-auto d-flex gap-2">
<a class="btn btn-sm btn-outline-light" href="/index.php#presets">Back to presets</a>
<?php if ($preset): ?>
<a class="btn btn-sm btn-light" href="/index.php?preset=<?= e((string) $preset['id']) ?>#simulator">Open in simulator</a>
<?php endif; ?>
</div>
</div>
</nav>
</header>
<main class="py-4 py-lg-5">
<div class="container-xl">
<?php if (!$preset): ?>
<section class="panel p-4 p-lg-5 text-center mx-auto" style="max-width: 720px;">
<div class="small-label">Preset detail</div>
<h1 class="h3 mb-3">Preset not found</h1>
<p class="text-secondary mb-4">The requested preset does not exist yet or may have been removed.</p>
<a class="btn btn-light" href="/index.php#presets">Return to the simulator</a>
</section>
<?php else: ?>
<section class="hero-panel panel p-4 p-lg-5 mb-4">
<div class="row g-4 align-items-center">
<div class="col-lg-8">
<div class="eyebrow mb-3">Preset detail · #<?= e((string) $preset['id']) ?></div>
<h1 class="display-title mb-3"><?= e($preset['name']) ?></h1>
<p class="lead text-secondary mb-4">A saved recliner profile for repeatable haptic demos. Use this screen to review the settings, then reopen it in the simulator to test with a connected controller.</p>
<div class="d-flex flex-wrap gap-2 meta-pills">
<span class="chip"><?= e((string) $preset['angle_deg']) ?>° angle</span>
<span class="chip"><?= e((string) $preset['intensity_pct']) ?>% intensity</span>
<span class="chip"><?= e(ucfirst((string) $preset['pattern_mode'])) ?> rumble</span>
<span class="chip"><?= e((string) $preset['duration_ms']) ?> ms</span>
</div>
</div>
<div class="col-lg-4">
<div class="panel inset-panel p-3 h-100">
<div class="small-label mb-3">Profile tone</div>
<div class="h4 mb-2"><?= e(preset_tone((int) $preset['angle_deg'])) ?></div>
<p class="text-secondary small mb-0">Saved on <?= e(date('F j, Y  H:i', strtotime((string) $preset['created_at']))) ?> UTC.</p>
</div>
</div>
</div>
</section>
<div class="row g-4">
<div class="col-lg-7">
<section class="panel p-4 h-100">
<div class="small-label mb-3">Settings overview</div>
<div class="spec-list preset-detail-specs">
<div><span>Recline angle</span><strong><?= e((string) $preset['angle_deg']) ?>°</strong></div>
<div><span>Vibration intensity</span><strong><?= e((string) $preset['intensity_pct']) ?>%</strong></div>
<div><span>Pattern</span><strong><?= e(ucfirst((string) $preset['pattern_mode'])) ?></strong></div>
<div><span>Duration</span><strong><?= e((string) $preset['duration_ms']) ?> ms</strong></div>
<div><span>Saved at</span><strong><?= e((string) $preset['created_at']) ?></strong></div>
</div>
<hr class="border-secondary-subtle my-4">
<div class="small-label mb-2">Operator notes</div>
<p class="text-secondary mb-0"><?= e($preset['notes'] ?: 'No notes added for this preset.') ?></p>
</section>
</div>
<div class="col-lg-5">
<section class="panel p-4 h-100 d-flex flex-column justify-content-between">
<div>
<div class="small-label mb-3">Next action</div>
<h2 class="h4 mb-2">Load this profile into the simulator</h2>
<p class="text-secondary mb-4">Jump back into the main workspace with these saved values prefilled. Then press <strong>Test vibration</strong> to drive the controller.</p>
</div>
<div class="d-grid gap-2">
<a class="btn btn-light" href="/index.php?preset=<?= e((string) $preset['id']) ?>#simulator">Open in simulator</a>
<a class="btn btn-outline-light" href="/index.php#presets">Browse recent presets</a>
</div>
</section>
</div>
</div>
<?php endif; ?>
</div>
</main>
</body>
</html>