import { useState, useEffect, useCallback } from 'react'; import { scanningApi } from '../api/scanning.api'; import type { ScanningSession, ScanningDevice, ScanningResult, ScanningFilters, ScanningSessionsResponse, CreateScanningSessionDto, UpdateScanningSessionDto, ScanningConfig, ScanningTemplate, } from '../../shared/types/api.types'; // ============================================================================ // Sessions Hooks // ============================================================================ export function useScanningSessions(filters?: ScanningFilters) { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const fetch = useCallback(async () => { setIsLoading(true); setError(null); try { const response = await scanningApi.getAll(filters); setData(response); } catch (err) { setError(err instanceof Error ? err.message : 'Error fetching sessions'); } finally { setIsLoading(false); } }, [ filters?.search, filters?.page, filters?.limit, filters?.status, filters?.deviceId, filters?.startDate, filters?.endDate, ]); useEffect(() => { fetch(); }, [fetch]); const create = useCallback(async (dto: CreateScanningSessionDto): Promise => { const session = await scanningApi.create(dto); await fetch(); return session; }, [fetch]); const update = useCallback(async (id: string, dto: UpdateScanningSessionDto): Promise => { const session = await scanningApi.update(id, dto); await fetch(); return session; }, [fetch]); const remove = useCallback(async (id: string): Promise => { await scanningApi.delete(id); await fetch(); }, [fetch]); return { data, isLoading, error, refresh: fetch, create, update, remove }; } export function useScanningSession(id: string) { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const fetch = useCallback(async () => { if (!id) return; setIsLoading(true); setError(null); try { const response = await scanningApi.getById(id); setData(response); } catch (err) { setError(err instanceof Error ? err.message : 'Error fetching session'); } finally { setIsLoading(false); } }, [id]); useEffect(() => { fetch(); }, [fetch]); const update = useCallback(async (dto: UpdateScanningSessionDto): Promise => { const session = await scanningApi.update(id, dto); setData(session); return session; }, [id]); const start = useCallback(async (): Promise => { const session = await scanningApi.start(id); setData(session); return session; }, [id]); const pause = useCallback(async (): Promise => { const session = await scanningApi.pause(id); setData(session); return session; }, [id]); const resume = useCallback(async (): Promise => { const session = await scanningApi.resume(id); setData(session); return session; }, [id]); const stop = useCallback(async (): Promise => { const session = await scanningApi.stop(id); setData(session); return session; }, [id]); return { data, isLoading, error, refresh: fetch, update, start, pause, resume, stop, }; } // ============================================================================ // Devices Hooks // ============================================================================ export function useScanningDevices() { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const fetch = useCallback(async () => { setIsLoading(true); setError(null); try { const response = await scanningApi.getDevices(); setData(response); } catch (err) { setError(err instanceof Error ? err.message : 'Error fetching devices'); } finally { setIsLoading(false); } }, []); useEffect(() => { fetch(); }, [fetch]); const register = useCallback(async (device: Partial): Promise => { const registered = await scanningApi.registerDevice(device); await fetch(); return registered; }, [fetch]); const update = useCallback(async (id: string, device: Partial): Promise => { const updated = await scanningApi.updateDevice(id, device); await fetch(); return updated; }, [fetch]); const remove = useCallback(async (id: string): Promise => { await scanningApi.removeDevice(id); await fetch(); }, [fetch]); return { data, isLoading, error, refresh: fetch, register, update, remove }; } export function useScanningDevice(id: string) { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const fetch = useCallback(async () => { if (!id) return; setIsLoading(true); setError(null); try { const response = await scanningApi.getDevice(id); setData(response); } catch (err) { setError(err instanceof Error ? err.message : 'Error fetching device'); } finally { setIsLoading(false); } }, [id]); useEffect(() => { fetch(); }, [fetch]); const update = useCallback(async (device: Partial): Promise => { const updated = await scanningApi.updateDevice(id, device); setData(updated); return updated; }, [id]); return { data, isLoading, error, refresh: fetch, update }; } // ============================================================================ // Templates Hooks // ============================================================================ export function useScanningTemplates() { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const fetch = useCallback(async () => { setIsLoading(true); setError(null); try { const response = await scanningApi.getTemplates(); setData(response); } catch (err) { setError(err instanceof Error ? err.message : 'Error fetching templates'); } finally { setIsLoading(false); } }, []); useEffect(() => { fetch(); }, [fetch]); const create = useCallback(async (template: Partial): Promise => { const created = await scanningApi.createTemplate(template); await fetch(); return created; }, [fetch]); const update = useCallback(async (id: string, template: Partial): Promise => { const updated = await scanningApi.updateTemplate(id, template); await fetch(); return updated; }, [fetch]); const remove = useCallback(async (id: string): Promise => { await scanningApi.deleteTemplate(id); await fetch(); }, [fetch]); return { data, isLoading, error, refresh: fetch, create, update, remove }; } export function useScanningTemplate(id: string) { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const fetch = useCallback(async () => { if (!id) return; setIsLoading(true); setError(null); try { const response = await scanningApi.getTemplate(id); setData(response); } catch (err) { setError(err instanceof Error ? err.message : 'Error fetching template'); } finally { setIsLoading(false); } }, [id]); useEffect(() => { fetch(); }, [fetch]); const update = useCallback(async (template: Partial): Promise => { const updated = await scanningApi.updateTemplate(id, template); setData(updated); return updated; }, [id]); return { data, isLoading, error, refresh: fetch, update }; } // ============================================================================ // Results Hooks // ============================================================================ export function useScanningResults(sessionId: string) { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const fetch = useCallback(async () => { if (!sessionId) return; setIsLoading(true); setError(null); try { const response = await scanningApi.getResults(sessionId); setData(response); } catch (err) { setError(err instanceof Error ? err.message : 'Error fetching results'); } finally { setIsLoading(false); } }, [sessionId]); useEffect(() => { fetch(); }, [fetch]); const exportResults = useCallback(async (format: 'json' | 'csv' | 'pdf'): Promise => { return scanningApi.exportResults(sessionId, format); }, [sessionId]); const importData = useCallback(async (file: File): Promise => { await scanningApi.importData(file, sessionId); await fetch(); }, [sessionId, fetch]); const validateData = useCallback(async (data: unknown, templateId: string): Promise => { return scanningApi.validateData(data, templateId); }, []); return { data, isLoading, error, refresh: fetch, exportResults, importData, validateData }; } // ============================================================================ // Config Hook // ============================================================================ export function useScanningConfig() { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const fetch = useCallback(async () => { setIsLoading(true); setError(null); try { const response = await scanningApi.getConfig(); setData(response); } catch (err) { setError(err instanceof Error ? err.message : 'Error fetching config'); } finally { setIsLoading(false); } }, []); useEffect(() => { fetch(); }, [fetch]); const update = useCallback(async (config: Partial): Promise => { const updated = await scanningApi.updateConfig(config); setData(updated); return updated; }, []); return { data, isLoading, error, refresh: fetch, update }; } // ============================================================================ // Utility Functions (Non-hook async functions) // ============================================================================ export async function createScanningSession(dto: CreateScanningSessionDto): Promise { return scanningApi.create(dto); } export async function exportScanningResults( sessionId: string, format: 'json' | 'csv' | 'pdf' ): Promise { return scanningApi.exportResults(sessionId, format); } export async function importScanningData(file: File, sessionId?: string): Promise { await scanningApi.importData(file, sessionId); } export async function validateScanningData(data: unknown, templateId: string): Promise { return scanningApi.validateData(data, templateId); }