diff --git a/App.tsx b/App.tsx index c43c5a7..48d6da5 100644 --- a/App.tsx +++ b/App.tsx @@ -8,7 +8,7 @@ import { FileUpload } from './components/FileUpload'; import { Loader } from './components/Loader'; import { ReportDisplay } from './components/ReportDisplay'; import { PrintableReport } from './components/PrintableReport'; -import { DownloadIcon, EyeIcon } from './components/Icons'; +import { DownloadIcon, EyeIcon, CogIcon } from './components/Icons'; import { ApiKeySetup } from './components/ApiKeySetup'; const App: React.FC = () => { @@ -21,6 +21,8 @@ const App: React.FC = () => { const [reportsData, setReportsData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); + const [showSetup, setShowSetup] = useState(false); + const [isConfigLoaded, setIsConfigLoaded] = useState(false); useEffect(() => { // 1. Tentar ler do localStorage primeiro @@ -29,12 +31,17 @@ const App: React.FC = () => { const savedModel = localStorage.getItem('model-' + savedProvider); const savedEndpoint = localStorage.getItem('ollama-endpoint'); + let hasLocal = false; if (savedApiKey || savedEndpoint) { setApiKey(savedApiKey || ''); if (savedProvider) setProvider(savedProvider); if (savedModel) setModel(savedModel); if (savedEndpoint) setEndpoint(savedEndpoint); setHasKey(true); + setShowSetup(false); + hasLocal = true; + } else { + setShowSetup(true); } // 2. Sincronizar com as configurações globais persistidas no servidor (mesmo em outros navegadores) @@ -47,6 +54,7 @@ const App: React.FC = () => { if (config.model) setModel(config.model); if (config.endpoint) setEndpoint(config.endpoint); setHasKey(true); + setShowSetup(false); // Sincroniza o localStorage localStorage.setItem('ai-provider', config.provider); @@ -60,9 +68,18 @@ const App: React.FC = () => { if (config.endpoint) { localStorage.setItem('ollama-endpoint', config.endpoint); } + } else if (!hasLocal) { + setShowSetup(true); } + setIsConfigLoaded(true); }) - .catch(err => console.warn('Erro ao carregar configurações do servidor:', err)); + .catch(err => { + console.warn('Erro ao carregar configurações do servidor:', err); + if (!hasLocal) { + setShowSetup(true); + } + setIsConfigLoaded(true); + }); }, []); const handleFileChange = useCallback((selectedFile: File | null) => { @@ -88,6 +105,7 @@ const App: React.FC = () => { localStorage.setItem('ai-provider', newProvider); localStorage.setItem('model-' + newProvider, newModel); setHasKey(true); + setShowSetup(false); // Salvar no servidor para persistência multi-navegador fetch('/api/config', { @@ -156,6 +174,7 @@ const App: React.FC = () => { setApiKey(''); localStorage.removeItem('api-key'); setHasKey(false); + setShowSetup(true); handleReset(); // Limpar no servidor @@ -178,8 +197,12 @@ const App: React.FC = () => {
- {!hasKey ? ( - + {!isConfigLoaded ? ( +
+ +
+ ) : (!hasKey || showSetup) ? ( + setShowSetup(false) : undefined} /> ) : !reportsData ? (
@@ -190,9 +213,18 @@ const App: React.FC = () => {

Carregue seu certificado de qualidade e deixe nossa IA verificar a conformidade.

-
- - {provider.toUpperCase()} • {model} +
+
+ + {provider.toUpperCase()} • {model} +
+
diff --git a/components/ApiKeySetup.tsx b/components/ApiKeySetup.tsx index 7d4f6b8..8f363ec 100644 --- a/components/ApiKeySetup.tsx +++ b/components/ApiKeySetup.tsx @@ -1,10 +1,11 @@ import React, { useState, useCallback, useEffect } from 'react'; -import { KeyIcon, SaveIcon, TestTubeIcon, TrashIcon } from './Icons'; +import { KeyIcon, SaveIcon, TestTubeIcon, TrashIcon, XIcon } from './Icons'; import { PROVIDERS, type AIProvider } from '../types/providers'; import { testApiKey, type ModelInfo } from '../services/apiTestService'; interface ApiKeySetupProps { onKeySave: (key: string, provider: AIProvider, model: string, endpoint?: string) => void; + onCancel?: () => void; } const isValidApiKey = (key: string): boolean => { @@ -12,7 +13,7 @@ const isValidApiKey = (key: string): boolean => { return trimmedKey.length > 10 && /^[A-Za-z0-9_-]+$/.test(trimmedKey); }; -export const ApiKeySetup: React.FC = ({ onKeySave }) => { +export const ApiKeySetup: React.FC = ({ onKeySave, onCancel }) => { const [localApiKey, setLocalApiKey] = useState(''); const [endpoint, setEndpoint] = useState(''); const [error, setError] = useState(null); @@ -168,6 +169,15 @@ export const ApiKeySetup: React.FC = ({ onKeySave }) => {
+ {onCancel && ( + + )}

Configurar API

@@ -371,14 +381,34 @@ export const ApiKeySetup: React.FC = ({ onKeySave }) => { )}
- + {onCancel ? ( +
+ + +
+ ) : ( + + )}
diff --git a/components/Icons.tsx b/components/Icons.tsx index d34e662..f2f2aa3 100644 --- a/components/Icons.tsx +++ b/components/Icons.tsx @@ -100,4 +100,11 @@ export const TrashIcon: React.FC> = (props) => ( +); + +export const CogIcon: React.FC> = (props) => ( + + + + ); \ No newline at end of file