import type { FormEvent } from 'react'; import { useState, useEffect } from 'react'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { toast } from 'sonner'; import { RefreshCw } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { useClient } from 'hooks/useClient'; import { useTranslation } from '@/lib/i18n'; type OcrConfig = { url: string; model: string; }; export const OCRSection = () => { const { t } = useTranslation(); const client = useClient(); const queryClient = useQueryClient(); const { data: config, isLoading } = useQuery({ queryKey: ['OCR_CONFIG'], queryFn: () => client.get('/server-settings/ocr'), }); const [url, setUrl] = useState('http://localhost:64203'); const [model, setModel] = useState('Qwen2.5-VL-7B-Instruct-q4_k_m.gguf'); const [models, setModels] = useState([]); const [modelsLoading, setModelsLoading] = useState(false); const [isSaving, setIsSaving] = useState(false); const [isTesting, setIsTesting] = useState(false); const fetchModels = async (u: string) => { setModelsLoading(true); try { const res = await client.get<{ models?: string[]; error?: string }>( `/server-settings/ocr/models?url=${encodeURIComponent(u)}`, ); if (res.models) setModels(res.models); else setModels([]); } catch { setModels([]); } finally { setModelsLoading(false); } }; useEffect(() => { if (!config) return; setUrl(config.url); setModel(config.model); fetchModels(config.url); }, [config]); const handleSave = async (ev?: FormEvent) => { ev?.preventDefault(); if (isSaving) return; setIsSaving(true); try { await client.put('/server-settings/ocr', { url, model }); queryClient.invalidateQueries({ queryKey: ['OCR_CONFIG'] }); toast.success(t('settings.server.ocr.saved')); } catch { toast.error(t('settings.server.ocr.saveFailed')); } finally { setIsSaving(false); } }; const handleTest = async () => { if (isTesting) return; setIsTesting(true); try { const res = await client.post<{ success?: boolean; error?: string }>('/server-settings/ocr/test', { url, model }); if (res.error) { toast.error(res.error); } else { toast.success(t('settings.server.ocr.reachable')); } } catch (err: unknown) { const raw = (err as { message?: string })?.message; let msg = 'Connection failed'; try { if (raw) msg = JSON.parse(raw).error ?? msg; } catch { /* ignore */ } toast.error(msg); } finally { setIsTesting(false); } }; if (isLoading) return

{t('settings.server.loading')}

; return (
); };