Files
brookhaven.bennyshouse.net/templates/host_responses.html

155 lines
7.6 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Survey Responses</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
.nice-scrollbar::-webkit-scrollbar{height:8px;width:8px}
.nice-scrollbar::-webkit-scrollbar-thumb{background:rgba(255,255,255,.15);border-radius:9999px}
</style>
</head>
<body class="min-h-screen bg-slate-950 text-slate-100">
<!-- gradient header -->
<div class="bg-gradient-to-b from-slate-900 via-slate-900/70 to-transparent">
<header class="mx-auto max-w-7xl px-6 pt-8 pb-6">
<h1 class="text-2xl md:text-3xl font-bold tracking-tight">Survey Responses</h1>
<p class="mt-1 text-sm text-slate-400">Review and export all captured entries.</p>
<div class="mt-4 flex flex-wrap items-center gap-2 text-sm text-slate-300">
<span>Total <span class="font-semibold text-white">{{ total }}</span></span>
<span class="opacity-50"></span>
{% set pages = (total // per_page) + (1 if total % per_page else 0) %}
<span>Page <span class="font-semibold text-white">{{ page }}</span> / {{ pages }}</span>
</div>
</header>
</div>
<main class="mx-auto max-w-7xl px-6 pb-12">
<!-- sticky tools -->
<div class="sticky top-0 z-20 -mx-6 px-6 py-3 border-y border-slate-800/60 backdrop-blur bg-slate-950/65">
<div class="flex items-center gap-2">
<input id="search" type="search" placeholder="Search name, persona, device, email…"
class="w-72 max-w-[70vw] rounded-lg bg-slate-900/80 border border-slate-800 px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-emerald-500" />
<a href="/host/responses.csv"
class="ml-auto inline-flex items-center gap-2 rounded-lg bg-emerald-500 text-black font-semibold px-3 py-2 text-sm hover:bg-emerald-400 transition">
Export CSV
</a>
</div>
</div>
<!-- table card -->
<div class="mt-4 overflow-hidden rounded-xl border border-slate-800 shadow-[0_0_0_1px_rgba(255,255,255,0.03)_inset]">
<div class="overflow-x-auto nice-scrollbar">
<table class="min-w-[1200px] w-full text-sm">
<thead class="bg-slate-900/90">
<tr class="text-slate-300">
<th class="p-3 text-left font-semibold">ID</th>
<th class="p-3 text-left font-semibold">PID</th>
<th class="p-3 text-left font-semibold">Name</th>
<th class="p-3 text-left font-semibold">Persona</th>
<th class="p-3 text-left font-semibold">Online Freq</th>
<th class="p-3 text-left font-semibold">Fulfillment</th>
<th class="p-3 text-left font-semibold">Coupons Use</th>
<th class="p-3 text-left font-semibold">Pref</th>
<th class="p-3 text-left font-semibold">Matters</th>
<th class="p-3 text-left font-semibold">Barriers</th>
<th class="p-3 text-left font-semibold">Device</th>
<th class="p-3 text-left font-semibold">Email</th>
<th class="p-3 text-left font-semibold whitespace-nowrap">Created</th>
</tr>
</thead>
<tbody id="rows" class="[&_tr:nth-child(even)]:bg-slate-900/30">
{% for r in rows %}
{% set a = r.answers or {} %}
<tr class="border-t border-slate-800 hover:bg-slate-900/60 transition">
<td class="p-3 text-slate-300">{{ r.id }}</td>
<td class="p-3 text-slate-300">{{ r.pid }}</td>
<td class="p-3">
<div class="font-medium">{{ r.name }}</div>
{% if a.device %}<div class="text-xs text-slate-400">{{ a.device }}</div>{% endif %}
</td>
<td class="p-3">
{% set persona = r.persona or '-' %}
<span class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-semibold
{% if persona == 'Sharpshooter' %} bg-emerald-500/15 text-emerald-300 border border-emerald-600/40
{% elif persona == 'Speed Demon' %} bg-fuchsia-500/15 text-fuchsia-300 border border-fuchsia-600/40
{% elif persona == 'Tank' %} bg-sky-500/15 text-sky-300 border border-sky-600/40
{% else %} bg-slate-700/40 text-slate-200 border border-slate-600/40 {% endif %}">
{{ persona }}
</span>
</td>
<td class="p-3 text-slate-200">{{ a.shop_online_freq or '-' }}</td>
<td class="p-3 text-slate-200">{{ a.fulfillment_preference or '-' }}</td>
<td class="p-3 text-slate-200">{{ a.digital_coupons_use or '-' }}</td>
<td class="p-3 text-slate-200">{{ a.coupons_preference or '-' }}</td>
<td class="p-3">
{% set wm = (a.what_matters or []) %}
{% if wm %}
<div class="flex flex-wrap gap-1">
{% for item in wm %}
<span class="rounded-full bg-slate-800 px-2 py-0.5 text-xs text-slate-300">{{ item }}</span>
{% endfor %}
</div>
{% else %}-{% endif %}
</td>
<td class="p-3">
{% set br = (a.barriers or []) %}
{% if br %}
<div class="flex flex-wrap gap-1">
{% for item in br %}
<span class="rounded-full bg-slate-800 px-2 py-0.5 text-xs text-slate-300">{{ item }}</span>
{% endfor %}
</div>
{% else %}-{% endif %}
</td>
<td class="p-3 text-slate-200">{{ a.device or '-' }}</td>
<td class="p-3">
{% if a.email_consent and a.email %}
<a class="underline decoration-slate-600 hover:decoration-emerald-400" href="mailto:{{
a.email }}">{{ a.email }}</a>
{% else %}-{% endif %}
</td>
<td class="p-3 whitespace-nowrap text-slate-300">
{% if r.created_at %}{{ r.created_at.strftime('%Y-%m-%d %H:%M') }}{% else %}-{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- pagination -->
<div class="flex items-center gap-2 p-3 bg-slate-900/70 border-t border-slate-800">
{% if page > 1 %}
<a class="px-3 py-1.5 bg-slate-800 rounded-lg hover:bg-slate-700 transition" href="?page={{ page - 1 }}">Prev</a>
{% else %}
<span class="px-3 py-1.5 bg-slate-900 rounded-lg opacity-40">Prev</span>
{% endif %}
<span class="text-sm text-slate-300">Page <span class="text-white font-semibold">{{ page }}</span> / {{ pages }}</span>
{% if page < pages %}
<a class="px-3 py-1.5 bg-slate-800 rounded-lg hover:bg-slate-700 transition" href="?page={{ page + 1 }}">Next</a>
{% else %}
<span class="px-3 py-1.5 bg-slate-900 rounded-lg opacity-40">Next</span>
{% endif %}
<div class="ml-auto text-xs text-slate-400">Showing {{ rows|length }} of {{ total }}</div>
</div>
</div>
</main>
<script>
// simple client-side filter
const q = document.getElementById('search');
const rows = Array.from(document.querySelectorAll('#rows tr'));
q?.addEventListener('input', () => {
const needle = q.value.trim().toLowerCase();
rows.forEach(tr => {
if (!needle) { tr.style.display = ''; return; }
tr.style.display = tr.innerText.toLowerCase().includes(needle) ? '' : 'none';
});
});
</script>
</body>
</html>