import React, { useState, useEffect } from 'react'; import type { Category } from './AdminCategories'; import { buildStandardWithAI } from '../services/aiService'; import type { AIProvider } from '../types/providers'; interface AdminStandardsProps { apiKey: string; provider: AIProvider; model: string; endpoint?: string; adminApiKey: string; adminModel: string; onAdminConfigSave: (key: string, model: string) => void; } export const AdminStandards: React.FC = ({ apiKey, provider, model, endpoint, adminApiKey, adminModel, onAdminConfigSave }) => { const [categories, setCategories] = useState([]); const [selectedCategory, setSelectedCategory] = useState(''); const [standards, setStandards] = useState([]); const [isLoadingCats, setIsLoadingCats] = useState(true); const [isGenerating, setIsGenerating] = useState(false); const [standardName, setStandardName] = useState(''); const [generatedJson, setGeneratedJson] = useState(''); const [jsonError, setJsonError] = useState(null); const [localAdminKey, setLocalAdminKey] = useState(adminApiKey); const [localAdminModel, setLocalAdminModel] = useState(adminModel); useEffect(() => { fetchCategories(); }, []); useEffect(() => { if (selectedCategory) { fetchStandards(selectedCategory); } else { setStandards([]); } }, [selectedCategory]); const fetchCategories = async () => { try { const res = await fetch('/api/categories'); const data = await res.json(); setCategories(data); if (data.length > 0) setSelectedCategory(data[0].id); } catch (e) { console.error(e); } finally { setIsLoadingCats(false); } }; const fetchStandards = async (catId: string) => { try { const res = await fetch(`/api/standards?categoryId=${catId}`); const data = await res.json(); setStandards(data); } catch (e) { console.error(e); } }; const handleGenerate = async () => { if (!standardName || !selectedCategory) return; const cat = categories.find(c => c.id === selectedCategory); if (!cat) return; setIsGenerating(true); setJsonError(null); try { const jsonObj = await buildStandardWithAI( // Use the admin config if provided, otherwise fallback to the global one localAdminKey ? { provider: 'openrouter', apiKey: localAdminKey, model: localAdminModel } : { provider, apiKey, model, endpoint }, standardName, cat.description ); setGeneratedJson(JSON.stringify(jsonObj, null, 2)); } catch (e: any) { setJsonError(e.message || "Erro ao gerar a norma."); } finally { setIsGenerating(false); } }; const handleSave = async () => { if (!generatedJson) return; try { const parsed = JSON.parse(generatedJson); parsed.categoria_id = selectedCategory; const res = await fetch('/api/standards', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(parsed) }); if (!res.ok) { const errData = await res.json().catch(() => ({})); throw new Error(errData.error || `Erro do servidor: ${res.status}`); } setGeneratedJson(''); setStandardName(''); fetchStandards(selectedCategory); } catch (e: any) { setJsonError(e.message || "Erro ao salvar: JSON inválido ou falha na rede."); } }; const handleDelete = async (id: string) => { if (!confirm('Excluir esta norma? O app não poderá mais validar relatórios contra ela.')) return; try { await fetch(`/api/standards?id=${id}`, { method: 'DELETE' }); fetchStandards(selectedCategory); } catch (e) { console.error(e); } }; if (isLoadingCats) return
Carregando categorias...
; const handleEdit = (s: any) => { setStandardName(s.codigo); setGeneratedJson(JSON.stringify(s, null, 2)); window.scrollTo({ top: 0, behavior: 'smooth' }); }; return (
{/* Admin Engine Config */}

Motor de Engenharia IA (Opcional)

Para criar normas perfeitamente estruturadas, recomendamos utilizar um modelo avançado como Claude 3.5 Sonnet ou GPT-4o via OpenRouter, separado do modelo de leitura rápida usado na página inicial.

setLocalAdminKey(e.target.value)} placeholder="sk-or-v1-..." className="w-full rounded-md border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 px-3 py-1.5 text-sm" />
setLocalAdminModel(e.target.value)} placeholder="ex: anthropic/claude-3.5-sonnet" className="w-full rounded-md border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 px-3 py-1.5 text-sm font-mono" />
{/* Selector */}
{selectedCategory && (
{/* Builder */}

Construtor Assistido por IA

setStandardName(e.target.value)} placeholder="Ex: ASTM A572 Grau 50" className="w-full rounded-lg border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 px-4 py-2 text-slate-900 dark:text-white outline-none focus:ring-2 focus:ring-indigo-500" />
{!(localAdminKey || apiKey) && (

Configure uma Chave de IA (Admin ou Global) primeiro.

)} {jsonError && (
{jsonError}
)} {generatedJson && (