import { defineStore } from 'pinia' import { ref } from 'vue' import type { Device } from '@/types' export const useDevicesStore = defineStore('devices', () => { const devices = ref([]) const loading = ref(false) const error = ref(null) /** * Fetch the device list. Pass `silent: true` from background refreshes * (pull-to-refresh, visibility-change polling) so the loading spinner * doesn't blink and replace the existing cards mid-fetch. */ async function fetchDevices(opts: { silent?: boolean } = {}) { if (!opts.silent) loading.value = true error.value = null try { const res = await fetch('/api/devices') if (!res.ok) throw new Error('Failed to load devices') devices.value = await res.json() } catch (e) { error.value = e instanceof Error ? e.message : 'Unknown error' } finally { loading.value = false } } async function updateDevice(id: number, patch: Partial>) { const res = await fetch(`/api/devices/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(patch), }) if (!res.ok) throw new Error('Failed to update device') const updated: Device = await res.json() const idx = devices.value.findIndex(d => d.id === id) if (idx !== -1) devices.value[idx] = updated return updated } async function lockImage(deviceId: number, imageId: number): Promise { const res = await fetch(`/api/devices/${deviceId}/lock`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ imageId }), }) if (!res.ok) throw new Error('Failed to lock image') const updated: Device = await res.json() const idx = devices.value.findIndex(d => d.id === deviceId) if (idx !== -1) devices.value[idx] = updated return updated } /** * Owner-initiated remove. Hits the API DELETE; on success splices the * device out of the local list so the UI updates immediately. The * Mercure subscription will also receive a `{deleted: true}` push for * any other tabs the user has open. */ async function removeDevice(id: number): Promise { const res = await fetch(`/api/devices/${id}`, { method: 'DELETE' }) if (!res.ok) throw new Error('Failed to remove device') devices.value = devices.value.filter(d => d.id !== id) } async function unlockImage(deviceId: number): Promise { const res = await fetch(`/api/devices/${deviceId}/lock`, { method: 'DELETE' }) if (!res.ok) throw new Error('Failed to unlock') const updated: Device = await res.json() const idx = devices.value.findIndex(d => d.id === deviceId) if (idx !== -1) devices.value[idx] = updated return updated } return { devices, loading, error, fetchDevices, updateDevice, removeDevice, lockImage, unlockImage } })