feat: add CogIcon for model change and direct boot to document upload

This commit is contained in:
2026-06-23 17:14:24 +00:00
parent 3a0771667c
commit d194dbf383
3 changed files with 86 additions and 17 deletions
+39 -7
View File
@@ -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<ReportData[] | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [showSetup, setShowSetup] = useState<boolean>(false);
const [isConfigLoaded, setIsConfigLoaded] = useState<boolean>(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 = () => {
<Header onReset={handleReset} onClearKey={handleClearKey} hasKey={hasKey} provider={provider} />
<main className="container mx-auto p-4 sm:p-6 md:p-8 max-w-7xl">
{!hasKey ? (
<ApiKeySetup onKeySave={handleKeySave} />
{!isConfigLoaded ? (
<div className="flex justify-center items-center py-20">
<span className="w-10 h-10 border-4 border-blue-500 border-t-transparent rounded-full animate-spin"></span>
</div>
) : (!hasKey || showSetup) ? (
<ApiKeySetup onKeySave={handleKeySave} onCancel={hasKey ? () => setShowSetup(false) : undefined} />
) : !reportsData ? (
<div className="max-w-2xl mx-auto pt-8">
<div className="bg-white/70 dark:bg-slate-800/60 backdrop-blur-md border border-white/20 dark:border-slate-700/50 shadow-xl p-6 sm:p-10 rounded-2xl">
@@ -190,9 +213,18 @@ const App: React.FC = () => {
<p className="text-slate-500 dark:text-slate-400">
Carregue seu certificado de qualidade e deixe nossa IA verificar a conformidade.
</p>
<div className="mt-4 inline-flex items-center gap-2 px-3 py-1 bg-slate-100 dark:bg-slate-700 rounded-full text-xs text-slate-600 dark:text-slate-300">
<span className="w-2 h-2 bg-green-500 rounded-full"></span>
{provider.toUpperCase()} {model}
<div className="mt-4 flex items-center justify-center gap-2">
<div className="inline-flex items-center gap-2 px-3 py-1 bg-slate-100 dark:bg-slate-700 rounded-full text-xs text-slate-600 dark:text-slate-300">
<span className="w-2 h-2 bg-green-500 rounded-full"></span>
{provider.toUpperCase()} {model}
</div>
<button
onClick={() => setShowSetup(true)}
className="p-1 rounded-full text-slate-400 hover:text-blue-500 dark:hover:text-blue-400 hover:bg-slate-100 dark:hover:bg-slate-700/50 transition-colors"
title="Configurar API / Trocar Modelo"
>
<CogIcon className="w-4 h-4" />
</button>
</div>
</div>