147 lines
3.5 KiB
Svelte
147 lines
3.5 KiB
Svelte
<script lang="ts">
|
|
import { pb } from '$lib/pb';
|
|
import { onMount } from 'svelte';
|
|
|
|
const TYPE_LABEL: Record<string, string> = {
|
|
kuehlschrank: 'Kühlschrank',
|
|
tiefkuehl: 'Tiefkühl',
|
|
warmhalte: 'Warmhalte',
|
|
hygiene: 'Hygiene',
|
|
sonstiges: 'Sonstiges'
|
|
};
|
|
|
|
let stations = $state<any[]>([]);
|
|
let loading = $state(true);
|
|
let copied = $state<string | null>(null);
|
|
|
|
onMount(async () => {
|
|
try {
|
|
const user = await pb.collection('users').getOne(pb.authStore.record!.id);
|
|
const tenantId = user.tenant;
|
|
const result = await pb.collection('stations').getFullList({
|
|
filter: `tenant = "${tenantId}" && active = true`,
|
|
sort: 'name'
|
|
});
|
|
stations = result;
|
|
} catch {
|
|
// Keine Stationen
|
|
} finally {
|
|
loading = false;
|
|
}
|
|
});
|
|
|
|
function qrUrl(qrId: string) {
|
|
return `https://checkflo.de/s/${qrId}`;
|
|
}
|
|
|
|
async function copyUrl(qrId: string) {
|
|
await navigator.clipboard.writeText(qrUrl(qrId));
|
|
copied = qrId;
|
|
setTimeout(() => copied = null, 2000);
|
|
}
|
|
</script>
|
|
|
|
<svelte:head><title>Stationen — checkflo</title></svelte:head>
|
|
|
|
<div class="page">
|
|
<h1>Stationen</h1>
|
|
<p class="hint-text">Jeden QR-Code ausdrucken und an der Station befestigen. Der Link öffnet die Checkliste direkt im Browser.</p>
|
|
|
|
{#if loading}
|
|
<p class="hint">Lädt…</p>
|
|
{:else}
|
|
<div class="list">
|
|
{#each stations as s}
|
|
<div class="card">
|
|
<div class="card-head">
|
|
<div>
|
|
<div class="station-name">{s.name}</div>
|
|
<div class="station-type">{TYPE_LABEL[s.type] ?? s.type}
|
|
{#if s.target_temp_min || s.target_temp_max}
|
|
· {s.target_temp_min}° bis {s.target_temp_max}°C
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="qr-row">
|
|
<code class="qr-url">{qrUrl(s.qr_id)}</code>
|
|
<button class="btn-copy" onclick={() => copyUrl(s.qr_id)}>
|
|
{copied === s.qr_id ? '✓ Kopiert' : 'Kopieren'}
|
|
</button>
|
|
<a
|
|
href="https://api.qrserver.com/v1/create-qr-code/?size=200x200&data={encodeURIComponent(qrUrl(s.qr_id))}"
|
|
target="_blank"
|
|
class="btn-qr"
|
|
>
|
|
QR öffnen
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
<style>
|
|
.page { max-width: 800px; }
|
|
h1 { font-size: 1.6rem; font-weight: 800; color: #0B1023; margin-bottom: 0.5rem; }
|
|
.hint-text { color: #666; font-size: 0.9rem; margin-bottom: 2rem; }
|
|
.hint { color: #aaa; }
|
|
|
|
.list { display: flex; flex-direction: column; gap: 1rem; }
|
|
|
|
.card {
|
|
background: #fff;
|
|
border-radius: 12px;
|
|
padding: 1.25rem 1.5rem;
|
|
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
|
|
}
|
|
.card-head { margin-bottom: 1rem; }
|
|
.station-name { font-weight: 700; font-size: 1.05rem; color: #0B1023; }
|
|
.station-type { font-size: 0.85rem; color: #888; margin-top: 0.2rem; }
|
|
|
|
.qr-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
.qr-url {
|
|
flex: 1;
|
|
font-size: 0.8rem;
|
|
background: #F5F7FA;
|
|
padding: 0.5rem 0.75rem;
|
|
border-radius: 6px;
|
|
color: #555;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
.btn-copy, .btn-qr {
|
|
padding: 0.5rem 1rem;
|
|
border-radius: 6px;
|
|
font-size: 0.85rem;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
transition: all 0.15s;
|
|
}
|
|
.btn-copy {
|
|
background: #F5F7FA;
|
|
border: 1.5px solid #ddd;
|
|
color: #555;
|
|
}
|
|
.btn-copy:hover { border-color: #F97316; color: #F97316; }
|
|
|
|
.btn-qr {
|
|
background: #F97316;
|
|
color: #fff;
|
|
border: none;
|
|
text-decoration: none;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
}
|
|
.btn-qr:hover { background: #ea6c10; }
|
|
</style>
|