import { Video, Wifi, WifiOff, Signal, Battery, Radio, Play, Square } from 'lucide-react' import type { CameraStatus } from '../types' // ── Helpers ──────────────────────────────────────────────────────────────── function formatRelativeTime(iso: string): string { const then = new Date(iso).getTime() if (isNaN(then)) return 'unknown' const diffSec = Math.floor((Date.now() - then) / 1000) if (diffSec < 0) return 'unknown' if (diffSec < 10) return 'just now' if (diffSec < 60) return `${diffSec}s ago` const diffMin = Math.floor(diffSec / 60) if (diffMin < 60) return `${diffMin}m ago` const diffHr = Math.floor(diffMin / 60) if (diffHr < 24) return `${diffHr}h ago` const diffDay = Math.floor(diffHr / 24) return `${diffDay}d ago` } function batteryColor(pct: number | null): { status: 'good' | 'low' | 'critical'; bar: string; text: string } { if (pct === null) return { status: 'critical', bar: 'bg-rig-dark-600', text: 'text-rig-dark-400' } if (pct >= 50) return { status: 'good', bar: 'bg-rig-success', text: 'text-rig-success' } if (pct >= 15) return { status: 'low', bar: 'bg-rig-warning', text: 'text-rig-warning' } return { status: 'critical', bar: 'bg-rig-danger', text: 'text-rig-danger' } } function formatTimeLeft(sec: number): string { if (sec <= 0 || !isFinite(sec)) return '--' const m = Math.floor(sec / 60) const s = Math.floor(sec % 60) return `${m}m ${s}s left` } function cameraStatus(online: boolean, batteryPct: number | null): 'good' | 'warning' | 'critical' { if (!online) return 'critical' if (batteryPct === null) return 'good' if (batteryPct >= 50) return 'good' if (batteryPct >= 15) return 'warning' return 'critical' } const STATUS_BORDER: Record = { good: 'border-l-rig-success', warning: 'border-l-rig-warning', critical: 'border-l-rig-danger', } // ── Component ────────────────────────────────────────────────────────────── interface CameraCardProps { camera: CameraStatus onStart: (cameraId: string) => void onStop: (cameraId: string) => void onViewHistory: (cameraId: string) => void disabled?: boolean } export default function CameraCard({ camera, onStart, onStop, onViewHistory, disabled }: CameraCardProps) { const { camera_id, friendly_name, online, resolution, fps, recording, mode, battery_pct, last_seen, video_remaining_sec, } = camera const batt = batteryColor(battery_pct) const status = cameraStatus(online, battery_pct) const borderColor = STATUS_BORDER[status] return (
{/* ── Header ── */}
{/* Online / Offline badge */} {online ? (
{/* ── Body ── */}
{/* Camera ID */}

{camera_id}

{/* Resolution + FPS */}
{resolution} · {fps} FPS
{/* Recording state */}
{recording ? ( <> REC ) : ( IDLE )} {mode}
{/* Battery */}
Battery {battery_pct !== null ? `${Math.max(0, battery_pct)}%` : 'N/A'}
{/* ── Footer ── */}
{/* Controls row */}
{recording ? ( ) : ( )}
{/* Status strip */}
{online ? ( <> Live ) : ( Offline )} · {formatRelativeTime(last_seen)}
{video_remaining_sec !== null && (
{formatTimeLeft(video_remaining_sec)}
)}
) }