import { useCallback, useEffect, useState } from 'react'; import { type DeviceRecord, listOwnDevices, revokeDevice } from '@chat-app/shared/auth'; import { useAuth } from '../context/AuthContext'; import { supabase } from '../lib/supabase'; interface State { devices: DeviceRecord[]; loading: boolean; error: string | null; } export function useOwnDevices(): { devices: DeviceRecord[]; loading: boolean; error: string | null; refresh: () => Promise; revoke: (deviceId: string) => Promise; } { const { session } = useAuth(); const userId = session?.user.id ?? null; const [state, setState] = useState({ devices: [], loading: true, error: null }); const refresh = useCallback(async () => { try { setState((s) => ({ ...s, loading: true, error: null })); const list = await listOwnDevices(supabase); setState({ devices: list, loading: false, error: null }); } catch (err) { setState((s) => ({ ...s, loading: false, error: err instanceof Error ? err.message : 'failed to load devices', })); } }, []); useEffect(() => { if (!userId) { setState({ devices: [], loading: false, error: null }); return; } void refresh(); const channel = supabase .channel('devices:list:' + userId) .on( 'postgres_changes', { event: '*', schema: 'public', table: 'devices', filter: 'user_id=eq.' + userId, }, () => { void refresh(); }, ) .subscribe(); return () => { void supabase.removeChannel(channel); }; }, [userId, refresh]); const revoke = useCallback( async (deviceId: string) => { await revokeDevice(supabase, deviceId); await refresh(); }, [refresh], ); return { devices: state.devices, loading: state.loading, error: state.error, refresh, revoke }; }