Files
kestrelos/app/pages/cameras.vue
Keli Grubb 17f28401ba
All checks were successful
ci/woodpecker/push/push Pipeline was successful
minor: heavily simplify server and app content. unify styling (#4)
Co-authored-by: Madison Grubb <madison@elastiflow.com>
Reviewed-on: #4
2026-02-14 04:52:18 +00:00

88 lines
2.6 KiB
Vue

<template>
<div class="p-6">
<h2 class="kestrel-page-heading mb-4">
Cameras
</h2>
<p class="mb-4 text-sm text-kestrel-muted">
Devices and live sessions. Select one to view the stream.
</p>
<div
v-if="!cameras?.length"
class="rounded border border-kestrel-border bg-kestrel-bg px-4 py-8 text-center text-sm text-kestrel-muted"
>
No cameras. Add devices or use
<NuxtLink
to="/share-live"
class="text-kestrel-accent underline"
>
Share live
</NuxtLink>
on your phone to stream; it will appear here and on the map.
</div>
<div
v-else
class="flex flex-col gap-4 md:flex-row md:flex-wrap"
>
<div class="flex-1 md:min-w-[320px]">
<ul class="space-y-2">
<li
v-for="cam in cameras"
:key="cam.id"
class="rounded border transition-colors"
:class="
selectedCamera?.id === cam.id
? 'border-kestrel-accent bg-kestrel-accent-dim'
: 'border-kestrel-border bg-kestrel-surface hover:border-kestrel-accent/50'
"
>
<button
type="button"
class="flex w-full items-center justify-between px-4 py-3 text-left"
@click="selectedCamera = cam"
>
<span class="font-medium text-kestrel-text">{{ cam.name ?? cam.label }}</span>
<span
v-if="cam.hasStream"
class="rounded bg-green-500/20 px-2 py-0.5 text-xs text-green-400"
>
Live
</span>
<span
v-else-if="cam.device_type"
class="rounded bg-kestrel-surface px-2 py-0.5 text-xs text-kestrel-muted capitalize"
>
{{ cam.device_type }}
</span>
</button>
</li>
</ul>
</div>
<div class="flex-1 md:min-w-[360px]">
<CameraViewer
v-if="selectedCamera"
:camera="selectedCamera"
inline
@close="selectedCamera = null"
/>
<div
v-else
class="flex aspect-video items-center justify-center rounded border border-kestrel-border bg-kestrel-bg text-sm text-kestrel-muted"
>
Select a camera to view
</div>
</div>
</div>
</div>
</template>
<script setup>
definePageMeta({ layout: 'default' })
const { cameras, liveSessions } = useCameras()
const selectedCamera = ref(null)
useAutoCloseLiveSession(selectedCamera, liveSessions)
</script>