@danhachuel/pandanews 0.4.8 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/backend/__pycache__/__init__.cpython-314.pyc +0 -0
- package/backend/app/main.py +1 -1
- package/backend/core/__pycache__/__init__.cpython-314.pyc +0 -0
- package/backend/core/__pycache__/config.cpython-314.pyc +0 -0
- package/backend/core/__pycache__/llm_router.cpython-314.pyc +0 -0
- package/backend/tests/test_llm_fallback.py +64 -1
- package/frontend/dist/assets/{index-CF0vVO6o.js → index-Iz5spM-E.js} +1 -1
- package/frontend/dist/index.html +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Todas as versões publicadas são registradas aqui antes do publish (regra em AGENTS.md). A etiqueta visual usa PATCH de dois dígitos (ex.: 0.1.00); o registry npm normaliza para a versão canônica (ex.: 0.1.0).
|
|
4
4
|
|
|
5
|
+
## 0.4.10 (2026-11-08)
|
|
6
|
+
|
|
7
|
+
- **Cobertura E2E pelo caminho HTTP real**: o teste de fallback ganhou um cenário que substitui apenas o `httpx.Client` — `chamar_provedor`, a construção da URL, os headers e o `raise_for_status` rodam de verdade. A NVIDIA devolve 410, o Gemini devolve 200 e a notícia nasce do Gemini com o log `Erro na NVIDIA (...). Acionando Google Gemini...` emitido. Fecha a lacuna de testar só a função mockada
|
|
8
|
+
- Teste sobe para 16 verificações, todas verdes local e no CI
|
|
9
|
+
|
|
10
|
+
## 0.4.09 (2026-11-08)
|
|
11
|
+
|
|
12
|
+
- **Frontend — Gemini tratado como a NVIDIA no teste de conexão**: o badge agora distingue `degraded` (âmbar, modelo em fim de vida 404/410) de `falhou` (vermelho) e a mensagem de detalhe usa a cor correspondente. Antes um 404/410 do Gemini aparecia como "falhou" vermelho — agora o usuário entende que é o modelo, não a chave, e que a geração segue pela NVIDIA
|
|
13
|
+
|
|
5
14
|
## 0.4.08 (2026-11-08)
|
|
6
15
|
|
|
7
16
|
- **Mantém o rótulo `gemini` em `noticias.llm_provider`**: a reescrita do router (0.4.07) devolvia o id interno `google`, o que regrediria o alinhamento banco/UI feito na 0.4.05/0.4.06. `gerar_texto` volta a devolver `"gemini"` quando o provedor do Google responde — Dashboards, filtros e exibição continuam consistentes
|
|
Binary file
|
package/backend/app/main.py
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -13,8 +13,10 @@ Cobre exatamente o que a correção promete:
|
|
|
13
13
|
"""
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
|
+
import json
|
|
16
17
|
import logging
|
|
17
18
|
import sys
|
|
19
|
+
import types
|
|
18
20
|
from datetime import timedelta as _timedelta
|
|
19
21
|
from pathlib import Path
|
|
20
22
|
|
|
@@ -165,7 +167,7 @@ resultado_410 = _testar_com_resposta(
|
|
|
165
167
|
check(resultado_410["ok"] is False, "test_provider: HTTP 410 -> ok=False")
|
|
166
168
|
check(resultado_410.get("degraded") is True, "test_provider: HTTP 410 -> degraded=True (fallback avisa)")
|
|
167
169
|
check(
|
|
168
|
-
"fim
|
|
170
|
+
"fim de vida" in resultado_410["detail"] or "410" in resultado_410["detail"],
|
|
169
171
|
"test_provider: a string de erro do provedor volta no JSON para a tela",
|
|
170
172
|
)
|
|
171
173
|
|
|
@@ -181,6 +183,67 @@ check(
|
|
|
181
183
|
"test_provider: HTTP 500 -> código e corpo devolvidos ao frontend",
|
|
182
184
|
)
|
|
183
185
|
|
|
186
|
+
# ------------------------------------ 3b) E2E pelo caminho HTTP real (Chamar)
|
|
187
|
+
|
|
188
|
+
# Diferente dos cenários acima (que trocam `chamar_provedor` por um dublê),
|
|
189
|
+
# aqui só o `httpx.Client` é substituído: `chamar_provedor`, a construção da
|
|
190
|
+
# URL, os headers e o `raise_for_status` rodam de verdade. A NVIDIA devolve
|
|
191
|
+
# 410 e o Gemini devolve 200 — a notícia tem de nascer do Gemini.
|
|
192
|
+
llm_router.chamar_provedor = original_chamar
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class _RespostaHttp:
|
|
196
|
+
def __init__(self, status_code: int, corpo: dict) -> None:
|
|
197
|
+
self.status_code = status_code
|
|
198
|
+
self._corpo = corpo
|
|
199
|
+
self.text = json.dumps(corpo)
|
|
200
|
+
|
|
201
|
+
def raise_for_status(self) -> None:
|
|
202
|
+
if self.status_code >= 400:
|
|
203
|
+
raise RuntimeError(f"HTTP {self.status_code}: {self.text}")
|
|
204
|
+
|
|
205
|
+
def json(self) -> dict:
|
|
206
|
+
return self._corpo
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _post_e2e(self, endpoint, headers=None, json=None):
|
|
210
|
+
# distingue pelo modelo pedido: nvidia (410) vs google/gemini (200)
|
|
211
|
+
modelo = (json or {}).get("model", "")
|
|
212
|
+
if "gemini" in modelo:
|
|
213
|
+
return _RespostaHttp(
|
|
214
|
+
200,
|
|
215
|
+
{"choices": [{"message": {"content": '{"titulo":"T","resumo":"R","corpo":"C"}'}}], "model": modelo},
|
|
216
|
+
)
|
|
217
|
+
return _RespostaHttp(410, {"detail": "The model has reached its end of life"})
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class _ClientE2E:
|
|
221
|
+
def __init__(self, *a, **k) -> None:
|
|
222
|
+
pass
|
|
223
|
+
|
|
224
|
+
def __enter__(self):
|
|
225
|
+
return self
|
|
226
|
+
|
|
227
|
+
def __exit__(self, *a):
|
|
228
|
+
return False
|
|
229
|
+
|
|
230
|
+
def post(self, endpoint, headers=None, json=None):
|
|
231
|
+
return _post_e2e(self, endpoint, headers, json)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
llm_router.httpx.Client = _ClientE2E
|
|
235
|
+
|
|
236
|
+
registros.clear()
|
|
237
|
+
|
|
238
|
+
texto_e2e, provedor_e2e = llm_router.gerar_texto(_db_com_chaves(), "escreva uma noticia")
|
|
239
|
+
|
|
240
|
+
check(provedor_e2e == "gemini", "E2E HTTP: NVIDIA 410 -> Gemini assume (provedor: gemini)")
|
|
241
|
+
check("titulo" in texto_e2e, "E2E HTTP: o conteúdo devolvido é o do Gemini (JSON utilizável)")
|
|
242
|
+
check(
|
|
243
|
+
any("Erro na NVIDIA (" in m and "Acionando Google Gemini" in m for m in registros),
|
|
244
|
+
"E2E HTTP: log 'Erro na NVIDIA (...). Acionando Google Gemini...' emitido",
|
|
245
|
+
)
|
|
246
|
+
|
|
184
247
|
# ------------------------------------------- 4) endpoint replicado do Thunderbolt
|
|
185
248
|
|
|
186
249
|
check(
|
|
@@ -67,4 +67,4 @@ Error generating stack: `+s.message+`
|
|
|
67
67
|
*/function Ys(){return Ys=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Ys.apply(null,arguments)}function Fh(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function $g(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Qg(e,t){return e.button===0&&(!t||t==="_self")&&!$g(e)}const Bg=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],Vg=["aria-current","caseSensitive","className","end","style","to","viewTransition","children"],Kg="6";try{window.__reactRouterVersion=Kg}catch{}const Wg=C.createContext({isTransitioning:!1}),Hg="startTransition",Oc=np[Hg];function qg(e){let{basename:t,children:n,future:r,window:l}=e,s=C.useRef();s.current==null&&(s.current=Zv({window:l,v5Compat:!0}));let i=s.current,[a,o]=C.useState({action:i.action,location:i.location}),{v7_startTransition:c}=r||{},p=C.useCallback(m=>{c&&Oc?Oc(()=>o(m)):o(m)},[o,c]);return C.useLayoutEffect(()=>i.listen(p),[i,p]),C.useEffect(()=>bg(r),[r]),C.createElement(Ug,{basename:t,children:n,location:a.location,navigationType:a.action,navigator:i,future:r})}const Gg=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",Yg=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,ru=C.forwardRef(function(t,n){let{onClick:r,relative:l,reloadDocument:s,replace:i,state:a,target:o,to:c,preventScrollReset:p,viewTransition:m}=t,h=Fh(t,Bg),{basename:x}=C.useContext(pn),j,S=!1;if(typeof c=="string"&&Yg.test(c)&&(j=c,Gg))try{let f=new URL(window.location.href),y=c.startsWith("//")?new URL(f.protocol+c):new URL(c),w=Or(y.pathname,x);y.origin===f.origin&&w!=null?c=w+y.search+y.hash:S=!0}catch{}let E=kg(c,{relative:l}),g=Jg(c,{replace:i,state:a,target:o,preventScrollReset:p,relative:l,viewTransition:m});function d(f){r&&r(f),f.defaultPrevented||g(f)}return C.createElement("a",Ys({},h,{href:j||E,onClick:S||s?r:d,ref:n,target:o}))}),Xg=C.forwardRef(function(t,n){let{"aria-current":r="page",caseSensitive:l=!1,className:s="",end:i=!1,style:a,to:o,viewTransition:c,children:p}=t,m=Fh(t,Vg),h=mi(o,{relative:m.relative}),x=Dr(),j=C.useContext(_h),{navigator:S,basename:E}=C.useContext(pn),g=j!=null&&ey(h)&&c===!0,d=S.encodeLocation?S.encodeLocation(h).pathname:h.pathname,f=x.pathname,y=j&&j.navigation&&j.navigation.location?j.navigation.location.pathname:null;l||(f=f.toLowerCase(),y=y?y.toLowerCase():null,d=d.toLowerCase()),y&&E&&(y=Or(y,E)||y);const w=d!=="/"&&d.endsWith("/")?d.length-1:d.length;let P=f===d||!i&&f.startsWith(d)&&f.charAt(w)==="/",k=y!=null&&(y===d||!i&&y.startsWith(d)&&y.charAt(d.length)==="/"),_={isActive:P,isPending:k,isTransitioning:g},I=P?r:void 0,F;typeof s=="function"?F=s(_):F=[s,P?"active":null,k?"pending":null,g?"transitioning":null].filter(Boolean).join(" ");let T=typeof a=="function"?a(_):a;return C.createElement(ru,Ys({},m,{"aria-current":I,className:F,ref:n,style:T,to:o,viewTransition:c}),typeof p=="function"?p(_):p)});var eo;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(eo||(eo={}));var Lc;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(Lc||(Lc={}));function Zg(e){let t=C.useContext(hi);return t||te(!1),t}function Jg(e,t){let{target:n,replace:r,state:l,preventScrollReset:s,relative:i,viewTransition:a}=t===void 0?{}:t,o=jg(),c=Dr(),p=mi(e,{relative:i});return C.useCallback(m=>{if(Qg(m,n)){m.preventDefault();let h=r!==void 0?r:Gs(c)===Gs(p);o(e,{replace:h,state:l,preventScrollReset:s,relative:i,viewTransition:a})}},[c,o,p,r,l,n,e,s,i,a])}function ey(e,t){t===void 0&&(t={});let n=C.useContext(Wg);n==null&&te(!1);let{basename:r}=Zg(eo.useViewTransitionState),l=mi(e,{relative:t.relative});if(!n.isTransitioning)return!1;let s=Or(n.currentLocation.pathname,r)||n.currentLocation.pathname,i=Or(n.nextLocation.pathname,r)||n.nextLocation.pathname;return Za(l.pathname,i)!=null||Za(l.pathname,s)!=null}function Mh({size:e=36}){return u.jsxs("svg",{width:e,height:e,viewBox:"0 0 100 100","aria-label":"PandaNews",children:[u.jsx("rect",{width:"100",height:"100",rx:"20",fill:"#0b1220",stroke:"#22c55e",strokeWidth:"4"}),u.jsx("circle",{cx:"25",cy:"28",r:"13",fill:"#e6edf3"}),u.jsx("circle",{cx:"75",cy:"28",r:"13",fill:"#e6edf3"}),u.jsx("circle",{cx:"50",cy:"52",r:"30",fill:"#e6edf3"}),u.jsx("ellipse",{cx:"37",cy:"48",rx:"9",ry:"11",fill:"#0b1220",transform:"rotate(-15 37 48)"}),u.jsx("ellipse",{cx:"63",cy:"48",rx:"9",ry:"11",fill:"#0b1220",transform:"rotate(15 63 48)"}),u.jsx("circle",{cx:"38",cy:"49",r:"3",fill:"#22c55e"}),u.jsx("circle",{cx:"62",cy:"49",r:"3",fill:"#22c55e"}),u.jsx("ellipse",{cx:"50",cy:"62",rx:"5",ry:"4",fill:"#0b1220"})]})}const ty=[{to:"/",label:"Dashboard",icon:"📊"},{to:"/blogs",label:"Blogs",icon:"📰"},{to:"/noticias",label:"Notícias",icon:"📝"},{to:"/imagens",label:"Imagens",icon:"🖼️"},{to:"/automacao",label:"Automação",icon:"⏱️"},{to:"/configuracoes",label:"Configurações",icon:"⚙️"},{to:"/logs",label:"Logs",icon:"📜"}];function ny(){return u.jsxs("aside",{className:"hidden w-60 shrink-0 flex-col border-r border-slate-200 bg-white md:flex dark:border-slate-800 dark:bg-card",children:[u.jsxs("div",{className:"flex items-center gap-2.5 px-5 py-5",children:[u.jsx(Mh,{}),u.jsxs("div",{children:[u.jsx("div",{className:"text-lg font-extrabold leading-none",children:"PandaNews"}),u.jsx("div",{className:"text-[11px] text-slate-500",children:"blogs de notícias com IA"})]})]}),u.jsx("nav",{className:"flex-1 space-y-1 px-3 py-2",children:ty.map(e=>u.jsxs(Xg,{to:e.to,end:e.to==="/",className:({isActive:t})=>`flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors ${t?"bg-panda/15 text-panda-dark dark:text-panda":"text-slate-500 hover:bg-slate-100 hover:text-slate-800 dark:text-slate-400 dark:hover:bg-slate-800/60 dark:hover:text-slate-200"}`,children:[u.jsx("span",{children:e.icon}),e.label]},e.to))}),u.jsx("div",{className:"px-5 py-4 text-[11px] text-slate-400 dark:text-slate-600",children:"100% local · SQLite · v0.4.00"})]})}const Ih="/api/v1";async function zh(e){if(e.status!==204){if(!e.ok){let t=`Erro HTTP ${e.status}`;try{const n=await e.json();n&&typeof n.detail=="string"&&(t=n.detail)}catch{}throw new Error(t)}return await e.json()}}function Ae(e){return fetch(Ih+e).then(t=>zh(t))}function Oe(e,t,n){return fetch(Ih+e,{method:t,headers:{"Content-Type":"application/json"},body:n===void 0?void 0:JSON.stringify(n)}).then(r=>zh(r))}const Fc=e=>{let t;const n=new Set,r=(c,p)=>{const m=typeof c=="function"?c(t):c;if(!Object.is(m,t)){const h=t;t=p??(typeof m!="object"||m===null)?m:Object.assign({},t,m),n.forEach(x=>x(t,h))}},l=()=>t,a={setState:r,getState:l,getInitialState:()=>o,subscribe:c=>(n.add(c),()=>n.delete(c))},o=t=e(r,l,a);return a},ry=e=>e?Fc(e):Fc,ly=e=>e;function sy(e,t=ly){const n=fs.useSyncExternalStore(e.subscribe,fs.useCallback(()=>t(e.getState()),[e,t]),()=>t(e.getInitialState()));return fs.useDebugValue(n),n}const Mc=e=>{const t=ry(e),n=r=>sy(t,r);return Object.assign(n,t),n},iy=e=>e?Mc(e):Mc;function Dh(e){document.documentElement.classList.toggle("dark",e==="dark")}function ay(){return localStorage.getItem("pandanews-theme")==="light"?"light":"dark"}const lu=iy((e,t)=>({theme:ay(),toggleTheme:()=>{const n=t().theme==="dark"?"light":"dark";localStorage.setItem("pandanews-theme",n),Dh(n),e({theme:n})},blogAtivo:null,setBlogAtivo:n=>e({blogAtivo:n})}));Dh(lu.getState().theme);function oy(){const{theme:e,toggleTheme:t,blogAtivo:n,setBlogAtivo:r}=lu(),{data:l}=Ke({queryKey:["blogs"],queryFn:()=>Ae("/blogs")});return u.jsxs("header",{className:"flex h-16 items-center justify-between gap-4 border-b border-slate-200 bg-white px-5 dark:border-slate-800 dark:bg-card",children:[u.jsxs("div",{className:"flex items-center gap-3",children:[u.jsx("div",{className:"md:hidden",children:u.jsx(Mh,{size:30})}),u.jsx("span",{className:"hidden text-sm text-slate-500 sm:inline",children:"Blog ativo:"}),u.jsxs("select",{className:"rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-800 outline-none focus:border-panda dark:border-slate-700 dark:bg-night dark:text-slate-200",value:n??"",onChange:s=>r(s.target.value?Number(s.target.value):null),children:[u.jsx("option",{value:"",children:"Todos os blogs"}),(l??[]).map(s=>u.jsx("option",{value:s.id,children:s.nome},s.id))]})]}),u.jsxs("div",{className:"flex items-center gap-3",children:[u.jsx("button",{onClick:t,title:"Alternar tema claro/escuro",className:"flex h-10 w-10 items-center justify-center rounded-lg border border-slate-300 text-lg hover:border-slate-400 dark:border-slate-700 dark:hover:border-slate-500",children:e==="dark"?"☀️":"🌙"}),u.jsx("div",{title:"DanHachuel",className:"flex h-10 w-10 items-center justify-center rounded-full bg-panda/15 text-sm font-bold text-panda-dark dark:text-panda",children:"DH"})]})]})}function Q({children:e,onClick:t,variant:n="primary",type:r="button",disabled:l,title:s}){const i="inline-flex items-center justify-center gap-2 rounded-lg px-4 h-10 text-sm font-semibold transition-colors disabled:opacity-40 disabled:cursor-not-allowed",a={primary:"bg-panda text-slate-900 hover:bg-panda-dark",secondary:"bg-transparent border border-slate-300 text-slate-700 hover:border-slate-400 dark:border-slate-700 dark:text-slate-200 dark:hover:border-slate-500",danger:"bg-red-600 text-white hover:bg-red-700"};return u.jsx("button",{type:r,className:`${i} ${a[n]}`,onClick:t,disabled:l,title:s,children:e})}function Be({children:e,className:t=""}){return u.jsx("div",{className:`rounded-xl border border-slate-200 bg-white p-5 shadow-sm dark:border-slate-800 dark:bg-card ${t}`,children:e})}function ae({children:e,tone:t="neutral"}){const n={neutral:"bg-slate-200 text-slate-600 dark:bg-slate-700/60 dark:text-slate-300",green:"bg-emerald-100 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-400",amber:"bg-amber-100 text-amber-700 dark:bg-amber-500/15 dark:text-amber-400",red:"bg-red-100 text-red-600 dark:bg-red-500/15 dark:text-red-400",blue:"bg-sky-100 text-sky-700 dark:bg-sky-500/15 dark:text-sky-400"};return u.jsx("span",{className:`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold ${n[t]}`,children:e})}function bh({status:e}){const t={rascunho:"amber",aprovado:"green",publicado:"blue",rejeitado:"red",ativo:"green",pausado:"neutral"};return u.jsx(ae,{tone:t[e]??"neutral",children:e})}function uy({open:e,title:t,message:n,onConfirm:r,onCancel:l}){return e?u.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60",onClick:l,children:u.jsxs("div",{className:"w-full max-w-md rounded-xl border border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-card",onClick:s=>s.stopPropagation(),children:[u.jsx("h3",{className:"mb-2 text-lg font-bold",children:t}),u.jsx("p",{className:"mb-6 text-sm text-slate-500 dark:text-slate-400",children:n}),u.jsxs("div",{className:"flex justify-end gap-3",children:[u.jsx(Q,{variant:"secondary",onClick:l,children:"Cancelar"}),u.jsx(Q,{variant:"danger",onClick:r,children:"Excluir"})]})]})}):null}function Hr({title:e,children:t,defaultOpen:n=!1}){const[r,l]=C.useState(n);return u.jsxs("div",{className:"rounded-xl border border-slate-200 bg-white dark:border-slate-800 dark:bg-card",children:[u.jsxs("button",{className:"flex w-full items-center justify-between px-5 py-4 text-left font-semibold",onClick:()=>l(!r),children:[u.jsx("span",{children:e}),u.jsx("span",{className:`text-slate-400 transition-transform ${r?"rotate-180":""}`,children:"▾"})]}),r&&u.jsx("div",{className:"border-t border-slate-200 px-5 py-5 dark:border-slate-800",children:t})]})}function le({label:e,children:t,hint:n}){return u.jsxs("label",{className:"block",children:[u.jsx("span",{className:"mb-1.5 block text-sm font-medium text-slate-500 dark:text-slate-400",children:e}),t,n&&u.jsx("span",{className:"mt-1 block text-xs text-slate-400 dark:text-slate-500",children:n})]})}const se="w-full rounded-lg border border-slate-300 bg-white px-3 py-2.5 text-sm text-slate-800 placeholder-slate-400 outline-none focus:border-panda h-10 dark:border-slate-700 dark:bg-night dark:text-slate-200 dark:placeholder-slate-500",Pl=se;function $l({icon:e,title:t,message:n}){return u.jsxs("div",{className:"flex flex-col items-center justify-center rounded-xl border border-dashed border-slate-300 px-6 py-14 text-center dark:border-slate-700",children:[u.jsx("div",{className:"mb-3 text-4xl",children:e}),u.jsx("h3",{className:"mb-1 font-semibold",children:t}),u.jsx("p",{className:"max-w-sm text-sm text-slate-500",children:n})]})}const Ic=["Coletando feeds RSS","Redigindo com IA","Gerando imagem","Salvando"];function su({open:e,blogs:t,blogInicial:n,onClose:r}){var g;const l=hn(),[s,i]=C.useState(n??((g=t[0])==null?void 0:g.id)??null),[a,o]=C.useState(0),[c,p]=C.useState(null),[m,h]=C.useState(""),x=C.useRef(null);C.useEffect(()=>{n!=null&&i(n)},[n]);const j=Te({mutationFn:d=>Oe("/noticias/gerar","POST",{blog_id:d}),onSuccess:d=>{o(Ic.length),p(d),l.invalidateQueries({queryKey:["noticias"]}),l.invalidateQueries({queryKey:["dashboard"]}),l.invalidateQueries({queryKey:["logs"]})},onError:d=>{o(0),h(d.message)}});if(C.useEffect(()=>(j.isPending?x.current=setInterval(()=>{o(d=>d<2?d+1:d)},4500):x.current&&(clearInterval(x.current),x.current=null),()=>{x.current&&clearInterval(x.current)}),[j.isPending]),!e)return null;function S(){s&&(h(""),p(null),o(0),j.mutate(s))}const E=c!==null;return u.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",onClick:r,children:u.jsxs("div",{className:"w-full max-w-lg rounded-xl border border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-card",onClick:d=>d.stopPropagation(),children:[u.jsx("h3",{className:"mb-4 text-lg font-bold",children:"Gerar notícia agora"}),t.length===0?u.jsx("p",{className:"mb-6 text-sm text-slate-500",children:"Crie um blog primeiro (com fontes RSS) para gerar notícias."}):!E&&!j.isPending&&u.jsxs("label",{className:"mb-6 block",children:[u.jsx("span",{className:"mb-1.5 block text-sm font-medium text-slate-500 dark:text-slate-400",children:"Blog"}),u.jsx("select",{className:Pl,value:s??"",onChange:d=>i(d.target.value?Number(d.target.value):null),children:t.map(d=>u.jsxs("option",{value:d.id,children:[d.nome," (",d.tema,")"]},d.id))})]}),(j.isPending||E)&&u.jsx("ul",{className:"mb-6 space-y-2",children:Ic.map((d,f)=>{const y=E||f<a,w=!E&&f===a;return u.jsxs("li",{className:"flex items-center gap-3 text-sm",children:[u.jsx("span",{className:`flex h-6 w-6 items-center justify-center rounded-full text-xs font-bold ${y?"bg-panda text-slate-900":w?"bg-panda/30 text-panda":"bg-slate-200 text-slate-500 dark:bg-slate-800"}`,children:y?"✓":w?"•":""}),u.jsx("span",{className:y?"text-slate-400 line-through":w?"font-semibold":"text-slate-500",children:d})]},d)})}),E&&c&&u.jsxs("div",{className:"mb-6 rounded-lg border border-panda/40 bg-panda/10 p-4",children:[u.jsxs("div",{className:"mb-1 flex items-center gap-2",children:[u.jsx(ae,{tone:"green",children:"rascunho salvo"}),c.llm_provider&&u.jsxs(ae,{tone:"blue",children:["via ",c.llm_provider]})]}),u.jsx("p",{className:"font-semibold",children:c.titulo}),!c.imagem_url&&u.jsx(ae,{tone:"amber",children:"sem imagem"})]}),m&&u.jsx("p",{className:"mb-4 rounded-lg border border-amber-400/40 bg-amber-500/10 p-3 text-sm text-amber-500",children:m}),u.jsx("div",{className:"flex justify-end gap-3",children:E?u.jsx(Q,{onClick:r,children:"Fechar"}):u.jsxs(u.Fragment,{children:[u.jsx(Q,{variant:"secondary",onClick:r,children:"Cancelar"}),u.jsx(Q,{onClick:S,disabled:j.isPending||!s,children:j.isPending?"Gerando…":"Gerar notícia"})]})})]})})}function cy(){const[e,t]=C.useState(!1),{data:n,isLoading:r}=Ke({queryKey:["dashboard"],queryFn:()=>Ae("/dashboard"),refetchInterval:15e3}),{data:l}=Ke({queryKey:["blogs"],queryFn:()=>Ae("/blogs")});if(r||!n)return u.jsx("p",{className:"text-slate-500",children:"Carregando…"});const s=Math.max(1,...n.geracao_7dias.map(o=>o.total)),i=n.onboarding,a=[{feito:i.llm_configurado,label:"Configure um provedor de LLM (NVIDIA ou Gemini)",to:"/configuracoes"},{feito:i.tem_blog,label:"Crie seu primeiro blog",to:"/blogs"},{feito:i.tem_noticia,label:"Gere a primeira notícia",to:"/noticias"}];return u.jsxs("div",{className:"space-y-6",children:[u.jsxs("div",{className:"flex items-center justify-between",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Dashboard"}),u.jsx(Q,{onClick:()=>t(!0),disabled:(l??[]).length===0,title:(l??[]).length===0?"Crie um blog primeiro":void 0,children:"⚡ Gerar notícia agora"})]}),u.jsx(su,{open:e,blogs:l??[],onClose:()=>t(!1)}),u.jsxs(Be,{children:[u.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[u.jsx("h2",{className:"font-bold",children:"Primeiros passos"}),u.jsxs("span",{className:"text-sm text-slate-500",children:[i.concluidos," de 3 concluídos"]})]}),u.jsx("div",{className:"mb-4 h-2 overflow-hidden rounded-full bg-slate-200 dark:bg-slate-700",children:u.jsx("div",{className:"h-full rounded-full bg-panda transition-all",style:{width:`${i.concluidos/3*100}%`}})}),u.jsx("ul",{className:"space-y-2",children:a.map(o=>u.jsxs("li",{className:"flex items-center justify-between gap-3",children:[u.jsx("span",{className:`text-sm ${o.feito?"text-slate-400 line-through":""}`,children:o.label}),o.feito?u.jsx(ae,{tone:"green",children:"✓ feito"}):u.jsx(ru,{to:o.to,className:"text-sm font-semibold text-panda hover:underline",children:"fazer agora →"})]},o.label))})]}),u.jsxs("div",{className:"grid grid-cols-2 gap-4 lg:grid-cols-4",children:[u.jsx(us,{label:"Blogs",value:n.blogs_total,hint:`${n.blogs_ativos} ativo(s)`}),u.jsx(us,{label:"Notícias hoje",value:n.noticias_hoje,hint:`${n.noticias_total} no total`}),u.jsx(us,{label:"Pendentes de revisão",value:n.noticias_pendentes,hint:"status rascunho"}),u.jsx(us,{label:"Erros registrados",value:n.erros_total,hint:"pipeline e blogs"})]}),u.jsxs(Be,{children:[u.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[u.jsx("h2",{className:"font-bold",children:"Meta de hoje"}),u.jsx(ae,{tone:n.faltam_meta>0?"green":"blue",children:n.faltam_meta>0?`faltam ${n.faltam_meta} para bater a meta`:"meta batida! 🎉"})]}),u.jsx("div",{className:"mb-2 h-2 overflow-hidden rounded-full bg-slate-200 dark:bg-slate-700",children:u.jsx("div",{className:"h-full rounded-full bg-panda transition-all",style:{width:`${Math.min(100,n.noticias_hoje/Math.max(1,n.meta_diaria)*100)}%`}})}),u.jsxs("p",{className:"text-sm text-slate-500",children:[n.noticias_hoje," de ",n.meta_diaria," notícia(s) gerada(s) hoje — configure a meta em Configurações → Agendamento."]})]}),u.jsxs(Be,{children:[u.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[u.jsx("h2",{className:"font-bold",children:"Geração de notícias — últimos 7 dias"}),u.jsxs(ae,{tone:n.scheduler_ativo?"green":"neutral",children:["scheduler ",n.scheduler_ativo?"ativo":"pausado"]})]}),u.jsx("div",{className:"flex h-40 items-end gap-2",children:n.geracao_7dias.map(o=>u.jsxs("div",{className:"flex flex-1 flex-col items-center gap-1",children:[u.jsx("div",{className:"w-full rounded-t-md bg-panda/70",style:{height:`${Math.max(4,o.total/s*100)}%`},title:`${o.data}: ${o.total} notícia(s)`}),u.jsx("span",{className:"text-[10px] text-slate-500",children:o.data.slice(5)})]},o.data))})]}),u.jsxs(Be,{children:[u.jsx("h2",{className:"mb-3 font-bold",children:"Últimos erros"}),n.ultimos_erros.length===0?u.jsx("p",{className:"text-sm text-slate-500",children:"Nenhum erro registrado. 🎉"}):u.jsx("ul",{className:"space-y-2",children:n.ultimos_erros.map(o=>u.jsxs("li",{className:"flex items-start justify-between gap-3 text-sm",children:[u.jsx("span",{className:"text-slate-500",children:o.mensagem}),u.jsx(ae,{tone:"red",children:o.etapa})]},o.id))})]})]})}function us({label:e,value:t,hint:n}){return u.jsxs(Be,{className:"text-center",children:[u.jsx("div",{className:"text-3xl font-extrabold text-panda",children:t}),u.jsx("div",{className:"mt-1 text-sm font-semibold",children:e}),u.jsx("div",{className:"text-xs text-slate-500",children:n})]})}const zc={geral:"Geral",esporte:"Esporte",politica:"Política",economia:"Economia",tecnologia:"Tecnologia"},Dc={nome:"",tema:"geral",regiao:"Brasil",fontes:"",estilo_editorial:"",frequencia_horas:6};function dy(){const e=hn(),{data:t,isLoading:n}=Ke({queryKey:["blogs"],queryFn:()=>Ae("/blogs")}),[r,l]=C.useState(!1),[s,i]=C.useState(null),[a,o]=C.useState(1),[c,p]=C.useState(Dc),[m,h]=C.useState(null),[x,j]=C.useState(""),S=Te({mutationFn:k=>s?Oe(`/blogs/${s.id}`,"PATCH",k):Oe("/blogs","POST",k),onSuccess:()=>{e.invalidateQueries({queryKey:["blogs"]}),y()},onError:k=>j(k.message)}),E=Te({mutationFn:({id:k,status:_})=>Oe(`/blogs/${k}`,"PATCH",{status:_}),onSuccess:()=>e.invalidateQueries({queryKey:["blogs"]})}),g=Te({mutationFn:k=>Oe(`/blogs/${k}`,"DELETE"),onSuccess:()=>{e.invalidateQueries({queryKey:["blogs"]}),h(null)}});function d(){i(null),p(Dc),o(1),j(""),l(!0)}function f(k){i(k),p({nome:k.nome,tema:k.tema,regiao:k.regiao,fontes:k.fontes_rss.join(`
|
|
68
68
|
`),estilo_editorial:k.estilo_editorial,frequencia_horas:k.frequencia_horas}),o(1),j(""),l(!0)}function y(){l(!1),i(null),o(1)}function w(){const k={nome:c.nome.trim(),tema:c.tema,regiao:c.regiao.trim()||"Brasil",fontes_rss:c.fontes.split(`
|
|
69
69
|
`).map(_=>_.trim()).filter(Boolean),estilo_editorial:c.estilo_editorial,frequencia_horas:Number(c.frequencia_horas)||6};if(!k.nome){j("Dê um nome ao blog.");return}S.mutate(k)}const P=c.nome.trim().length>0;return u.jsxs("div",{className:"space-y-6",children:[u.jsxs("div",{className:"flex items-center justify-between",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Blogs"}),u.jsx(Q,{onClick:d,children:"+ Novo blog"})]}),n?u.jsx("p",{className:"text-slate-500",children:"Carregando…"}):!t||t.length===0?u.jsx($l,{icon:"📰",title:"Nenhum blog ainda",message:"Crie seu primeiro blog: escolha tema, região e fontes RSS — em menos de 2 minutos."}):u.jsx("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:t.map(k=>u.jsxs(Be,{children:[u.jsxs("div",{className:"mb-3 flex items-start justify-between gap-3",children:[u.jsxs("div",{children:[u.jsx("h3",{className:"font-bold",children:k.nome}),u.jsxs("div",{className:"mt-0.5 text-xs text-slate-500",children:[zc[k.tema]??k.tema," · ",k.regiao]})]}),u.jsx(bh,{status:k.status})]}),u.jsxs("div",{className:"space-y-1 text-sm text-slate-500",children:[u.jsxs("div",{children:["📰 ",k.fontes_rss.length," fonte(s) RSS"]}),u.jsxs("div",{children:["⏱️ a cada ",k.frequencia_horas,"h"]})]}),u.jsxs("div",{className:"mt-4 flex items-center justify-end gap-2",children:[u.jsx(Q,{variant:"secondary",onClick:()=>E.mutate({id:k.id,status:k.status==="ativo"?"pausado":"ativo"}),children:k.status==="ativo"?"Pausar":"Ativar"}),u.jsx(Q,{variant:"secondary",onClick:()=>f(k),children:"Editar"}),u.jsx(Q,{variant:"danger",onClick:()=>h(k),children:"Excluir"})]})]},k.id))}),r&&u.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",onClick:y,children:u.jsxs("div",{className:"max-h-[90vh] w-full max-w-lg overflow-y-auto rounded-xl border border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-card",onClick:k=>k.stopPropagation(),children:[u.jsx("h3",{className:"mb-1 text-lg font-bold",children:s?`Editar: ${s.nome}`:"Novo blog"}),!s&&u.jsx("div",{className:"mb-5 flex gap-2 text-xs font-semibold",children:["Identidade","Fontes RSS","Estilo"].map((k,_)=>u.jsxs("div",{className:`rounded-full px-3 py-1 ${a===_+1?"bg-panda text-slate-900":a>_+1?"bg-panda/30 text-panda":"bg-slate-200 text-slate-500 dark:bg-slate-800"}`,children:[_+1,". ",k]},k))}),s||a===1?u.jsxs("div",{className:"space-y-4",children:[u.jsx(le,{label:"Nome do blog",children:u.jsx("input",{className:se,value:c.nome,onChange:k=>p({...c,nome:k.target.value}),placeholder:"Ex.: Notícias do Acre"})}),u.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[u.jsx(le,{label:"Tema",children:u.jsx("select",{className:Pl,value:c.tema,onChange:k=>p({...c,tema:k.target.value}),children:Object.entries(zc).map(([k,_])=>u.jsx("option",{value:k,children:_},k))})}),u.jsx(le,{label:"Região",children:u.jsx("input",{className:se,value:c.regiao,onChange:k=>p({...c,regiao:k.target.value}),placeholder:"Ex.: São Paulo, Brasil, Espanha"})})]})]}):null,s||a===2?u.jsx("div",{className:"mt-4",children:u.jsx(le,{label:"Fontes RSS",hint:"Uma URL por linha",children:u.jsx("textarea",{className:`${se} h-auto py-2.5`,rows:4,value:c.fontes,onChange:k=>p({...c,fontes:k.target.value}),placeholder:`https://exemplo.com/feed
|
|
70
|
-
https://outro.com/rss`})})}):null,s||a===3?u.jsxs("div",{className:"mt-4 space-y-4",children:[u.jsx(le,{label:"Estilo editorial",hint:"Prompt base para o LLM (tom, extensão, público)",children:u.jsx("textarea",{className:`${se} h-auto py-2.5`,rows:3,value:c.estilo_editorial,onChange:k=>p({...c,estilo_editorial:k.target.value}),placeholder:"Ex.: notícias diretas em português do Brasil, tom jornalístico, 3 parágrafos"})}),u.jsx(le,{label:"Frequência de geração (horas)",children:u.jsx("input",{type:"number",min:1,max:168,className:se,value:c.frequencia_horas,onChange:k=>p({...c,frequencia_horas:Number(k.target.value)})})})]}):null,x&&u.jsx("p",{className:"mt-4 text-sm text-red-400",children:x}),u.jsxs("div",{className:"mt-6 flex justify-between gap-3",children:[!s&&a>1?u.jsx(Q,{variant:"secondary",onClick:()=>o(a-1),children:"← Voltar"}):u.jsx("span",{}),!s&&a<3?u.jsx(Q,{onClick:()=>o(a+1),disabled:!P,children:"Avançar →"}):u.jsx(Q,{onClick:w,disabled:S.isPending,children:s?"Salvar alterações":"Criar blog"})]})]})}),u.jsx(uy,{open:m!==null,title:`Excluir "${m==null?void 0:m.nome}"?`,message:"O blog e todas as suas notícias serão removidos. Esta ação não pode ser desfeita.",onConfirm:()=>m&&g.mutate(m.id),onCancel:()=>h(null)})]})}function fy(){const e=hn(),{blogAtivo:t}=lu(),[n,r]=C.useState(""),[l,s]=C.useState(!1),[i,a]=C.useState(null),[o,c]=C.useState({titulo:"",resumo:"",corpo:""}),[p,m]=C.useState(""),{data:h}=Ke({queryKey:["blogs"],queryFn:()=>Ae("/blogs")}),{data:x,isLoading:j}=Ke({queryKey:["noticias",t,n],queryFn:()=>{const f=new URLSearchParams;return t&&f.set("blog_id",String(t)),n&&f.set("status",n),Ae(`/noticias${f.toString()?`?${f}`:""}`)}}),S=f=>{var y;return((y=h==null?void 0:h.find(w=>w.id===f))==null?void 0:y.nome)??`Blog #${f}`},E=Te({mutationFn:({id:f,body:y})=>Oe(`/noticias/${f}`,"PATCH",y),onSuccess:()=>e.invalidateQueries({queryKey:["noticias"]})}),g=Te({mutationFn:f=>Oe(`/noticias/${f.id}`,"PATCH",{titulo:o.titulo,resumo:o.resumo,corpo:o.corpo}),onSuccess:()=>{e.invalidateQueries({queryKey:["noticias"]}),a(null)},onError:f=>m(f.message)}),d=Te({mutationFn:f=>Oe(`/noticias/${f}/regenerar`,"POST"),onSuccess:()=>{e.invalidateQueries({queryKey:["noticias"]}),e.invalidateQueries({queryKey:["dashboard"]})}});return u.jsxs("div",{className:"space-y-6",children:[u.jsxs("div",{className:"flex items-center justify-between",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Notícias"}),u.jsxs("div",{className:"flex items-center gap-3",children:[u.jsxs("select",{className:`${Pl} w-44`,value:n,onChange:f=>r(f.target.value),children:[u.jsx("option",{value:"",children:"Todos os status"}),u.jsx("option",{value:"rascunho",children:"Rascunho (pendente)"}),u.jsx("option",{value:"aprovado",children:"Aprovado"}),u.jsx("option",{value:"rejeitado",children:"Rejeitado"}),u.jsx("option",{value:"publicado",children:"Publicado"})]}),u.jsx(Q,{onClick:()=>s(!0),disabled:(h??[]).length===0,title:(h??[]).length===0?"Crie um blog primeiro":void 0,children:"⚡ Gerar notícia"})]})]}),u.jsx(su,{open:l,blogs:h??[],blogInicial:t,onClose:()=>s(!1)}),j?u.jsx("p",{className:"text-slate-500",children:"Carregando…"}):!x||x.length===0?u.jsx($l,{icon:"📝",title:"Nenhuma notícia ainda",message:"O pipeline de geração (coleta RSS → redação via LLM → imagem) chega na próxima versão; notícias geradas aparecem aqui para revisão."}):u.jsx("div",{className:"space-y-4",children:x.map(f=>u.jsxs(Be,{children:[u.jsxs("div",{className:"mb-2 flex flex-wrap items-center gap-2",children:[u.jsx(bh,{status:f.status}),f.llm_provider&&u.jsxs(ae,{tone:"blue",children:["via ",f.llm_provider]}),u.jsxs("span",{className:"text-xs text-slate-500",children:[S(f.blog_id)," · ",new Date(f.created_at).toLocaleString("pt-BR")]})]}),u.jsx("h3",{className:"text-lg font-bold",children:f.titulo||"(sem título)"}),f.resumo&&u.jsx("p",{className:"mt-1 text-sm text-slate-500",children:f.resumo}),f.imagem_url?u.jsx("img",{src:f.imagem_url,alt:"",className:"mt-3 max-h-48 rounded-lg"}):f.status==="rascunho"&&u.jsx(ae,{tone:"amber",children:"sem imagem"}),u.jsxs("div",{className:"mt-4 flex flex-wrap justify-end gap-2",children:[f.fonte_titulo&&u.jsx(Q,{variant:"secondary",onClick:()=>d.mutate(f.id),disabled:d.isPending,title:"Re-escrever a partir da fonte original",children:"↻ Regenerar"}),u.jsx(Q,{variant:"secondary",onClick:()=>{m(""),c({titulo:f.titulo,resumo:f.resumo,corpo:f.corpo}),a(f)},children:"Editar"}),u.jsx(Q,{variant:"danger",onClick:()=>E.mutate({id:f.id,body:{status:"rejeitado"}}),children:"Rejeitar"}),u.jsx(Q,{onClick:()=>E.mutate({id:f.id,body:{status:"aprovado"}}),children:"Aprovar"})]})]},f.id))}),i&&u.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",onClick:()=>a(null),children:u.jsxs("div",{className:"max-h-[90vh] w-full max-w-2xl overflow-y-auto rounded-xl border border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-card",onClick:f=>f.stopPropagation(),children:[u.jsx("h3",{className:"mb-4 text-lg font-bold",children:"Editar notícia manualmente"}),u.jsxs("div",{className:"space-y-4",children:[u.jsx(le,{label:"Título",children:u.jsx("input",{className:se,value:o.titulo,onChange:f=>c({...o,titulo:f.target.value})})}),u.jsx(le,{label:"Resumo",children:u.jsx("textarea",{className:`${se} h-auto py-2.5`,rows:2,value:o.resumo,onChange:f=>c({...o,resumo:f.target.value})})}),u.jsx(le,{label:"Corpo",children:u.jsx("textarea",{className:`${se} h-auto py-2.5`,rows:10,value:o.corpo,onChange:f=>c({...o,corpo:f.target.value})})})]}),p&&u.jsx("p",{className:"mt-3 text-sm text-red-400",children:p}),u.jsxs("div",{className:"mt-6 flex justify-end gap-3",children:[u.jsx(Q,{variant:"secondary",onClick:()=>a(null),children:"Cancelar"}),u.jsx(Q,{onClick:()=>g.mutate(i),disabled:g.isPending,children:"Salvar"})]})]})})]})}function hy(){const e=hn(),[t,n]=C.useState(""),[r,l]=C.useState(null),{data:s,isLoading:i}=Ke({queryKey:["imagens"],queryFn:()=>Ae("/imagens")}),a=Te({mutationFn:o=>Oe("/imagens/gerar","POST",{prompt:o}),onSuccess:o=>{l(o),o.ok&&(n(""),e.invalidateQueries({queryKey:["imagens"]}),e.invalidateQueries({queryKey:["noticias"]}))},onError:o=>l({ok:!1,detail:o.message})});return u.jsxs("div",{className:"space-y-6",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Imagens"}),i?u.jsx("p",{className:"text-slate-500",children:"Carregando…"}):!s||s.length===0?u.jsx($l,{icon:"🖼️",title:"Galeria vazia",message:"Imagens geradas pelo pipeline (e manualmente abaixo) aparecem aqui, reutilizáveis nas notícias."}):u.jsx("div",{className:"grid gap-4 sm:grid-cols-2 xl:grid-cols-3",children:s.map(o=>u.jsxs(Be,{className:"p-3",children:[u.jsx("a",{href:o.url,target:"_blank",rel:"noreferrer",children:u.jsx("img",{src:o.url,alt:o.titulo,className:"h-44 w-full rounded-lg object-cover"})}),u.jsx("p",{className:"mt-2 line-clamp-2 text-sm font-medium",children:o.titulo}),u.jsx("p",{className:"text-xs text-slate-500",children:new Date(o.created_at).toLocaleString("pt-BR")})]},o.noticia_id))}),u.jsxs(Be,{children:[u.jsx("h2",{className:"mb-1 font-bold",children:"Gerar imagem manualmente"}),u.jsx("p",{className:"mb-4 text-sm text-slate-500",children:"Prompt livre para a Gemini Image (requer API key do Google configurada em Configurações)."}),u.jsxs("div",{className:"space-y-4",children:[u.jsx(le,{label:"Prompt visual",children:u.jsx("textarea",{className:`${se} h-auto py-2.5`,rows:3,value:t,onChange:o=>n(o.target.value),placeholder:"Ex.: estádio lotado ao entardecer, fotojornalismo"})}),u.jsx(Q,{onClick:()=>t.trim()&&a.mutate(t.trim()),disabled:a.isPending||!t.trim(),children:a.isPending?"Gerando…":"Gerar imagem"}),r&&!r.ok&&u.jsx("p",{className:"rounded-lg border border-red-400/40 bg-red-500/10 p-3 text-sm text-red-400",children:r.detail}),(r==null?void 0:r.ok)&&r.url&&u.jsxs("div",{className:"rounded-lg border border-panda/40 bg-panda/10 p-3",children:[u.jsx(ae,{tone:"green",children:"imagem gerada"}),u.jsx("img",{src:r.url,alt:"Imagem gerada",className:"mt-2 max-h-56 rounded-lg"})]})]})]})]})}function py(){const e=hn(),[t,n]=C.useState(null),[r,l]=C.useState(!1),{data:s}=Ke({queryKey:["configuracoes"],queryFn:()=>Ae("/configuracoes")}),{data:i}=Ke({queryKey:["automacao-status"],queryFn:()=>Ae("/automacao/status"),refetchInterval:3e4}),{data:a}=Ke({queryKey:["blogs"],queryFn:()=>Ae("/blogs")}),o=Te({mutationFn:h=>Oe("/configuracoes","PUT",h),onSuccess:()=>{e.invalidateQueries({queryKey:["configuracoes"]}),e.invalidateQueries({queryKey:["automacao-status"]}),e.invalidateQueries({queryKey:["dashboard"]})}}),c=Te({mutationFn:({id:h,status:x})=>Oe(`/blogs/${h}`,"PATCH",{status:x}),onSuccess:()=>{e.invalidateQueries({queryKey:["blogs"]}),e.invalidateQueries({queryKey:["automacao-status"]})}}),p=(i==null?void 0:i.ativo)??(s==null?void 0:s.scheduler_ativo)??!0,m=new Map(((i==null?void 0:i.jobs)??[]).map(h=>[h.blog_id,h.proxima_execucao]));return u.jsxs("div",{className:"space-y-6",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Automação"}),u.jsxs(Be,{children:[u.jsxs("div",{className:"flex items-center justify-between gap-4",children:[u.jsxs("div",{children:[u.jsx("h2",{className:"font-bold",children:"Agendador global"}),u.jsx("p",{className:"mt-1 text-sm text-slate-500",children:"Cada blog ativo gera notícias automaticamente conforme sua frequência (horas). O toggle liga/desliga o scheduler de verdade — o estado é aplicado na hora."})]}),u.jsx("button",{onClick:()=>o.mutate({scheduler_ativo:!p}),className:`relative h-10 w-20 shrink-0 rounded-full transition-colors ${p?"bg-panda":"bg-slate-300 dark:bg-slate-700"}`,title:p?"Clique para pausar":"Clique para ativar",children:u.jsx("span",{className:`absolute top-1 h-8 w-8 rounded-full bg-white shadow transition-all ${p?"left-11":"left-1"}`})})]}),u.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[u.jsxs(ae,{tone:p?"green":"neutral",children:["scheduler ",p?"ativo":"pausado"]}),u.jsxs(ae,{children:[((i==null?void 0:i.jobs)??[]).length," job(s) agendado(s)"]}),u.jsxs(ae,{children:["intervalo padrão: ",(s==null?void 0:s.intervalo_padrao_horas)??6,"h"]})]})]}),u.jsx("h2",{className:"pt-2 font-bold",children:"Por blog"}),!a||a.length===0?u.jsx($l,{icon:"⏱️",title:"Nenhum blog",message:"Crie um blog para configurar sua frequência de geração."}):u.jsx("div",{className:"grid gap-4 md:grid-cols-2",children:a.map(h=>{const x=m.get(h.id);return u.jsxs(Be,{children:[u.jsxs("div",{className:"mb-3 flex items-center justify-between gap-3",children:[u.jsxs("div",{children:[u.jsx("div",{className:"font-semibold",children:h.nome}),u.jsxs("div",{className:"text-xs text-slate-500",children:["a cada ",h.frequencia_horas,"h · ",h.tema," · ",h.regiao]})]}),u.jsx("button",{onClick:()=>c.mutate({id:h.id,status:h.status==="ativo"?"pausado":"ativo"}),className:`relative h-8 w-16 shrink-0 rounded-full transition-colors ${h.status==="ativo"?"bg-panda":"bg-slate-300 dark:bg-slate-700"}`,title:h.status==="ativo"?"Clique para pausar":"Clique para ativar",children:u.jsx("span",{className:`absolute top-1 h-6 w-6 rounded-full bg-white shadow transition-all ${h.status==="ativo"?"left-9":"left-1"}`})})]}),u.jsxs("div",{className:"flex items-center justify-between gap-3 text-xs text-slate-500",children:[u.jsx("span",{children:h.status==="ativo"&&p&&x?`próxima execução: ${new Date(x).toLocaleString("pt-BR")}`:h.status==="pausado"?"blog pausado":p?"aguardando agendamento…":"scheduler pausado"}),u.jsx("button",{className:"font-semibold text-panda hover:underline",onClick:()=>{n(h.id),l(!0)},children:"⚡ Executar agora"})]})]},h.id)})}),u.jsx(su,{open:r,blogs:a??[],blogInicial:t,onClose:()=>{l(!1),n(null)}})]})}const my={nvidia:"NVIDIA NIM",google:"Google Gemini"};function vy(){var I,F;const e=hn(),{data:t}=Ke({queryKey:["configuracoes"],queryFn:()=>Ae("/configuracoes")}),[n,r]=C.useState({nvidia_api_key:"",google_api_key:"",supabase_service_role_key:""}),[l,s]=C.useState({nvidia_base_url:"",nvidia_model:"",google_base_url:"",google_model:"",llm_fallback_ordem:"nvidia,google",supabase_url:"",intervalo_padrao_horas:6,meta_diaria:3}),[i,a]=C.useState({}),[o,c]=C.useState(""),[p,m]=C.useState("");C.useEffect(()=>{t&&s({nvidia_base_url:t.nvidia_base_url,nvidia_model:t.nvidia_model,google_base_url:t.google_base_url,google_model:t.google_model,llm_fallback_ordem:t.llm_fallback_ordem,supabase_url:t.supabase_url,intervalo_padrao_horas:t.intervalo_padrao_horas,meta_diaria:t.meta_diaria})},[t]);const h=Te({mutationFn:T=>Oe("/configuracoes","PUT",T),onSuccess:()=>{e.invalidateQueries({queryKey:["configuracoes"]}),e.invalidateQueries({queryKey:["dashboard"]}),c("Configurações salvas com sucesso."),r({nvidia_api_key:"",google_api_key:"",supabase_service_role_key:""})},onError:T=>c(`Falha ao salvar: ${T.message}`)}),x=Te({mutationFn:T=>Oe("/llm/test","POST",{provider:T}),onSuccess:(T,Ee)=>a(me=>({...me,[Ee]:T}))}),j=Te({mutationFn:()=>Oe("/configuracoes/testar-supabase","POST")}),{data:S,isFetching:E,refetch:g}=Ke({queryKey:["nvidia-models"],queryFn:()=>Ae("/configuracoes/llm/nvidia/models"),retry:!1,staleTime:5*60*1e3}),d=(S==null?void 0:S.models)??[],f=(S==null?void 0:S.modelo_atual_disponivel)===!1&&d.length>0,y=Te({mutationFn:()=>Ae("/configuracoes/schema-supabase"),onSuccess:T=>m(T.sql)}),w=Te({mutationFn:()=>Oe("/configuracoes/migrar-supabase","POST"),onSuccess:()=>c("")});function P(){const T={...l};n.nvidia_api_key.trim()&&(T.nvidia_api_key=n.nvidia_api_key.trim()),n.google_api_key.trim()&&(T.google_api_key=n.google_api_key.trim()),n.supabase_service_role_key.trim()&&(T.supabase_service_role_key=n.supabase_service_role_key.trim()),c(""),h.mutate(T)}function k(T,Ee){const me=l.llm_fallback_ordem.split(",").map(br=>br.trim()),mn=me.indexOf(T),Vn=mn+Ee;mn<0||Vn<0||Vn>=me.length||([me[mn],me[Vn]]=[me[Vn],me[mn]],s({...l,llm_fallback_ordem:me.join(",")}))}const _=T=>T.configured?`${T.preview} — deixe vazio para manter`:"Não configurado";return u.jsxs("div",{className:"space-y-4",children:[u.jsxs("div",{className:"flex items-center justify-between",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Configurações"}),u.jsx(Q,{onClick:P,disabled:h.isPending||!t,children:"Salvar configurações"})]}),o&&u.jsx("p",{className:`text-sm ${o.startsWith("Falha")?"text-red-400":"text-panda"}`,children:o}),u.jsxs("div",{className:"space-y-4",children:[u.jsxs(Hr,{title:"NVIDIA NIM (provedor primário)",defaultOpen:!0,children:[u.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[u.jsx(le,{label:"API Key",children:u.jsx("input",{type:"password",className:se,value:n.nvidia_api_key,onChange:T=>r({...n,nvidia_api_key:T.target.value}),placeholder:t?_(t.nvidia_api_key):""})}),u.jsx(le,{label:"Base URL",children:u.jsx("input",{className:se,value:l.nvidia_base_url,onChange:T=>s({...l,nvidia_base_url:T.target.value})})}),u.jsxs(le,{label:"Modelo",hint:d.length>0?`${d.length} modelos disponíveis para sua chave NVIDIA`:"Lista carregada dinamicamente da NVIDIA NIM",children:[u.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[u.jsxs("select",{className:se,value:l.nvidia_model,onChange:T=>s({...l,nvidia_model:T.target.value}),disabled:E,children:[E&&u.jsx("option",{value:"",children:"Carregando modelos…"}),l.nvidia_model&&!d.includes(l.nvidia_model)&&u.jsxs("option",{value:l.nvidia_model,children:[l.nvidia_model," (atual)"]}),d.map(T=>u.jsx("option",{value:T,children:T},T))]}),((I=i.nvidia)==null?void 0:I.degraded)&&u.jsx("span",{className:"inline-flex items-center rounded bg-red-600 px-2 py-1 text-xs font-bold text-white",title:"Modelo indisponível na NVIDIA (404/410) — o fallback Gemini será usado nas gerações",children:"[Indisponível]"}),u.jsx(Q,{variant:"secondary",onClick:()=>g(),disabled:E,title:"Atualizar lista da NVIDIA",children:"↻"})]}),f&&u.jsxs("p",{className:"mt-2 text-xs text-red-400",children:["O modelo ",u.jsx("code",{className:"font-mono",children:S==null?void 0:S.modelo_atual})," não está mais no catálogo da NVIDIA (404/410 — fim de vida). Escolha outro na lista: as gerações estão caindo no Gemini por fallback."]}),!E&&d.length===0&&u.jsx("p",{className:"mt-2 text-xs text-amber-500",children:"Lista indisponível (chave não configurada ou NVIDIA fora do ar) — o modelo atual é mantido. Configure a API key e clique em ↻ para buscar."})]}),u.jsxs("div",{className:"flex items-end gap-2",children:[u.jsx(Q,{variant:"secondary",onClick:()=>x.mutate("nvidia"),disabled:x.isPending,children:"Testar conexão"}),i.nvidia&&u.jsx(ae,{tone:i.nvidia.ok?"green":i.nvidia.degraded?"amber":"red",children:i.nvidia.ok?`ok · ${i.nvidia.latency_ms}ms`:i.nvidia.degraded?"degraded":"falhou"})]})]}),i.nvidia&&!i.nvidia.ok&&u.jsx("p",{className:`mt-3 text-xs ${i.nvidia.degraded?"text-amber-500":"text-red-400"}`,children:i.nvidia.detail})]}),u.jsxs(Hr,{title:"Google Gemini (provedor de fallback)",children:[u.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[u.jsx(le,{label:"API Key",children:u.jsx("input",{type:"password",className:se,value:n.google_api_key,onChange:T=>r({...n,google_api_key:T.target.value}),placeholder:t?_(t.google_api_key):""})}),u.jsx(le,{label:"Base URL",children:u.jsx("input",{className:se,value:l.google_base_url,onChange:T=>s({...l,google_base_url:T.target.value})})}),u.jsx(le,{label:"Modelo",children:u.jsx("input",{className:se,value:l.google_model,onChange:T=>s({...l,google_model:T.target.value})})}),u.jsxs("div",{className:"flex items-end gap-2",children:[u.jsx(Q,{variant:"secondary",onClick:()=>x.mutate("google"),disabled:x.isPending,children:"Testar conexão"}),i.google&&u.jsx(ae,{tone:i.google.ok?"green":"red",children:i.google.ok?`ok · ${i.google.latency_ms}ms`:"falhou"})]})]}),i.google&&!i.google.ok&&u.jsx("p",{className:"mt-3 text-xs text-red-400",children:i.google.detail})]}),u.jsx(Hr,{title:"Ordem de fallback dos provedores",children:u.jsx("ul",{className:"space-y-2",children:l.llm_fallback_ordem.split(",").map((T,Ee,me)=>u.jsxs("li",{className:"flex items-center justify-between rounded-lg border border-slate-200 px-4 py-2.5 dark:border-slate-700",children:[u.jsxs("span",{className:"font-semibold",children:[Ee+1,". ",my[T.trim()]??T]}),u.jsxs("span",{className:"flex gap-2",children:[u.jsx(Q,{variant:"secondary",onClick:()=>k(T.trim(),-1),disabled:Ee===0,title:"Subir na prioridade",children:"↑"}),u.jsx(Q,{variant:"secondary",onClick:()=>k(T.trim(),1),disabled:Ee===me.length-1,title:"Descer na prioridade",children:"↓"})]})]},T))})}),u.jsxs(Hr,{title:"Banco de dados (SQLite local → Supabase opcional)",children:[u.jsxs("div",{className:"mb-4 space-y-3 rounded-lg border border-slate-200 p-4 dark:border-slate-700",children:[u.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[u.jsx(ae,{tone:"green",children:"Backend ativo: SQLite local"}),t!=null&&t.supabase_detectado?u.jsx(ae,{tone:"blue",children:"credenciais Supabase detectadas"}):u.jsx(ae,{children:"credenciais Supabase não configuradas"})]}),u.jsxs("p",{className:"text-xs text-slate-500",children:["100% local por padrão. O Supabase é opcional: informe o projeto + ",u.jsx("code",{children:"service_role_key"}),", teste a conexão, crie as tabelas com o schema SQL e migre seus dados quando quiser. O app continua funcionando localmente de forma independente."]}),u.jsxs("div",{className:"flex flex-wrap gap-2",children:[u.jsx(Q,{variant:"secondary",onClick:()=>j.mutate(),disabled:j.isPending,children:"Testar conexão"}),u.jsx(Q,{variant:"secondary",onClick:()=>y.mutate(),disabled:y.isPending,children:"Ver schema SQL"}),u.jsx(Q,{onClick:()=>w.mutate(),disabled:w.isPending||!(t!=null&&t.supabase_detectado),title:t!=null&&t.supabase_detectado?"Copiar dados do SQLite para o Supabase":"Configure as credenciais do Supabase primeiro",children:w.isPending?"Migrando…":"Migrar dados do SQLite"})]}),j.data&&u.jsxs("p",{className:`text-xs ${j.data.ok?"text-panda":"text-amber-500"}`,children:[j.data.detail,j.data.ok&&` (credencial em: ${j.data.credencial_em})`]}),((F=w.data)==null?void 0:F.ok)&&w.data.migrados&&u.jsxs("p",{className:"text-xs text-panda",children:["Migrado: ",Object.entries(w.data.migrados).map(([T,Ee])=>`${T} (${Ee})`).join(" · ")]}),w.data&&!w.data.ok&&u.jsx("p",{className:"text-xs text-red-400",children:w.data.detail})]}),u.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[u.jsx(le,{label:"Supabase URL",hint:"Detectada automaticamente quando SUPABASE_URL está no ambiente",children:u.jsx("input",{className:se,value:l.supabase_url,onChange:T=>s({...l,supabase_url:T.target.value}),placeholder:"https://xxxx.supabase.co"})}),u.jsx(le,{label:"Service Role Key",children:u.jsx("input",{type:"password",className:se,value:n.supabase_service_role_key,onChange:T=>r({...n,supabase_service_role_key:T.target.value}),placeholder:t?_(t.supabase_service_role_key):""})})]})]}),u.jsx(Hr,{title:"Agendamento",children:u.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[u.jsx(le,{label:"Intervalo padrão de geração (horas)",hint:"Aplicado a novos blogs; cada blog pode ter seu próprio intervalo",children:u.jsx("input",{type:"number",min:1,max:168,className:`${se} w-40`,value:l.intervalo_padrao_horas,onChange:T=>s({...l,intervalo_padrao_horas:Number(T.target.value)})})}),u.jsx(le,{label:"Meta diária de notícias",hint:"Usada no Dashboard ('faltam X notícias para bater a meta')",children:u.jsx("input",{type:"number",min:0,max:100,className:`${se} w-40`,value:l.meta_diaria,onChange:T=>s({...l,meta_diaria:Number(T.target.value)})})})]})})]}),p&&u.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",onClick:()=>m(""),children:u.jsxs("div",{className:"max-h-[85vh] w-full max-w-2xl overflow-y-auto rounded-xl border border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-card",onClick:T=>T.stopPropagation(),children:[u.jsx("h3",{className:"mb-2 font-bold",children:"Schema SQL para o Supabase"}),u.jsx("p",{className:"mb-4 text-xs text-slate-500",children:"Execute este SQL no SQL Editor do painel do Supabase antes de migrar. Ele cria as tabelas blogs, noticias, configuracoes e logs com os mesmos campos do banco local."}),u.jsx("pre",{className:"overflow-x-auto rounded-lg bg-night p-4 text-xs text-emerald-300 dark:bg-slate-900",children:u.jsx("code",{children:p})}),u.jsx("div",{className:"mt-4 flex justify-end",children:u.jsx(Q,{onClick:()=>m(""),children:"Fechar"})})]})}),u.jsx(Be,{children:u.jsx("p",{className:"text-xs text-slate-500",children:"Nada de travas de pré-registro: as credenciais só são exigidas no momento da ação que precisa delas. Sem validação, tudo nesta página é opcional."})})]})}function gy(){const[e,t]=C.useState(""),[n,r]=C.useState(""),{data:l,isLoading:s}=Ke({queryKey:["logs",e,n],queryFn:()=>{const i=new URLSearchParams;return e&&i.set("status",e),n&&i.set("etapa",n),Ae(`/logs${i.toString()?`?${i}`:""}`)}});return u.jsxs("div",{className:"space-y-6",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Logs"}),u.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[u.jsxs("select",{className:`${Pl} w-44`,value:e,onChange:i=>t(i.target.value),children:[u.jsx("option",{value:"",children:"Todos os status"}),u.jsx("option",{value:"sucesso",children:"Sucesso"}),u.jsx("option",{value:"erro",children:"Erro"})]}),u.jsxs("select",{className:`${Pl} w-44`,value:n,onChange:i=>r(i.target.value),children:[u.jsx("option",{value:"",children:"Todas as etapas"}),u.jsx("option",{value:"blog",children:"Blog"}),u.jsx("option",{value:"coleta",children:"Coleta"}),u.jsx("option",{value:"redacao",children:"Redação"}),u.jsx("option",{value:"imagem",children:"Imagem"}),u.jsx("option",{value:"publicacao",children:"Publicação"})]})]}),s?u.jsx("p",{className:"text-slate-500",children:"Carregando…"}):!l||l.length===0?u.jsx($l,{icon:"📜",title:"Nenhum log ainda",message:"Execuções do pipeline (coleta, redação, imagem, publicação) aparecem aqui conforme o scheduler roda."}):u.jsx(Be,{className:"overflow-x-auto",children:u.jsxs("table",{className:"w-full text-left text-sm",children:[u.jsx("thead",{children:u.jsxs("tr",{className:"border-b border-slate-200 text-xs uppercase text-slate-500 dark:border-slate-700",children:[u.jsx("th",{className:"pb-2 pr-4",children:"Quando"}),u.jsx("th",{className:"pb-2 pr-4",children:"Etapa"}),u.jsx("th",{className:"pb-2 pr-4",children:"Status"}),u.jsx("th",{className:"pb-2",children:"Mensagem"})]})}),u.jsx("tbody",{children:l.map(i=>u.jsxs("tr",{className:"border-b border-slate-100 last:border-0 dark:border-slate-800",children:[u.jsx("td",{className:"py-2 pr-4 text-slate-500",children:new Date(i.created_at).toLocaleString("pt-BR")}),u.jsx("td",{className:"py-2 pr-4",children:i.etapa}),u.jsx("td",{className:"py-2 pr-4",children:u.jsx(ae,{tone:i.status==="erro"?"red":"green",children:i.status})}),u.jsx("td",{className:"py-2 text-slate-500",children:i.mensagem})]},i.id))})]})})]})}const yy={blogs:"Blogs",noticias:"Notícias",imagens:"Imagens",automacao:"Automação",configuracoes:"Configurações",logs:"Logs"};function xy(){const{pathname:e}=Dr(),[t]=e.split("/").filter(Boolean);if(!t)return null;const n=yy[t]??t;return u.jsxs("nav",{className:"mb-4 text-sm text-slate-500","aria-label":"Breadcrumb",children:[u.jsx(ru,{to:"/",className:"hover:underline",children:"Dashboard"}),u.jsx("span",{className:"mx-2",children:"/"}),u.jsx("span",{className:"font-semibold text-slate-700 dark:text-slate-300",children:n})]})}const wy=new Av({defaultOptions:{queries:{refetchOnWindowFocus:!1,retry:1}}});function Sy(){return u.jsx(pv,{client:wy,children:u.jsx(qg,{children:u.jsxs("div",{className:"flex min-h-screen",children:[u.jsx(ny,{}),u.jsxs("div",{className:"flex min-w-0 flex-1 flex-col",children:[u.jsx(oy,{}),u.jsxs("main",{className:"mx-auto w-full max-w-6xl flex-1 p-6",children:[u.jsx(xy,{}),u.jsxs(Ag,{children:[u.jsx(It,{path:"/",element:u.jsx(cy,{})}),u.jsx(It,{path:"/blogs",element:u.jsx(dy,{})}),u.jsx(It,{path:"/noticias",element:u.jsx(fy,{})}),u.jsx(It,{path:"/imagens",element:u.jsx(hy,{})}),u.jsx(It,{path:"/automacao",element:u.jsx(py,{})}),u.jsx(It,{path:"/configuracoes",element:u.jsx(vy,{})}),u.jsx(It,{path:"/logs",element:u.jsx(gy,{})})]})]})]})]})})})}const ky=document.getElementById("root");oh(ky).render(u.jsx(Sy,{}));
|
|
70
|
+
https://outro.com/rss`})})}):null,s||a===3?u.jsxs("div",{className:"mt-4 space-y-4",children:[u.jsx(le,{label:"Estilo editorial",hint:"Prompt base para o LLM (tom, extensão, público)",children:u.jsx("textarea",{className:`${se} h-auto py-2.5`,rows:3,value:c.estilo_editorial,onChange:k=>p({...c,estilo_editorial:k.target.value}),placeholder:"Ex.: notícias diretas em português do Brasil, tom jornalístico, 3 parágrafos"})}),u.jsx(le,{label:"Frequência de geração (horas)",children:u.jsx("input",{type:"number",min:1,max:168,className:se,value:c.frequencia_horas,onChange:k=>p({...c,frequencia_horas:Number(k.target.value)})})})]}):null,x&&u.jsx("p",{className:"mt-4 text-sm text-red-400",children:x}),u.jsxs("div",{className:"mt-6 flex justify-between gap-3",children:[!s&&a>1?u.jsx(Q,{variant:"secondary",onClick:()=>o(a-1),children:"← Voltar"}):u.jsx("span",{}),!s&&a<3?u.jsx(Q,{onClick:()=>o(a+1),disabled:!P,children:"Avançar →"}):u.jsx(Q,{onClick:w,disabled:S.isPending,children:s?"Salvar alterações":"Criar blog"})]})]})}),u.jsx(uy,{open:m!==null,title:`Excluir "${m==null?void 0:m.nome}"?`,message:"O blog e todas as suas notícias serão removidos. Esta ação não pode ser desfeita.",onConfirm:()=>m&&g.mutate(m.id),onCancel:()=>h(null)})]})}function fy(){const e=hn(),{blogAtivo:t}=lu(),[n,r]=C.useState(""),[l,s]=C.useState(!1),[i,a]=C.useState(null),[o,c]=C.useState({titulo:"",resumo:"",corpo:""}),[p,m]=C.useState(""),{data:h}=Ke({queryKey:["blogs"],queryFn:()=>Ae("/blogs")}),{data:x,isLoading:j}=Ke({queryKey:["noticias",t,n],queryFn:()=>{const f=new URLSearchParams;return t&&f.set("blog_id",String(t)),n&&f.set("status",n),Ae(`/noticias${f.toString()?`?${f}`:""}`)}}),S=f=>{var y;return((y=h==null?void 0:h.find(w=>w.id===f))==null?void 0:y.nome)??`Blog #${f}`},E=Te({mutationFn:({id:f,body:y})=>Oe(`/noticias/${f}`,"PATCH",y),onSuccess:()=>e.invalidateQueries({queryKey:["noticias"]})}),g=Te({mutationFn:f=>Oe(`/noticias/${f.id}`,"PATCH",{titulo:o.titulo,resumo:o.resumo,corpo:o.corpo}),onSuccess:()=>{e.invalidateQueries({queryKey:["noticias"]}),a(null)},onError:f=>m(f.message)}),d=Te({mutationFn:f=>Oe(`/noticias/${f}/regenerar`,"POST"),onSuccess:()=>{e.invalidateQueries({queryKey:["noticias"]}),e.invalidateQueries({queryKey:["dashboard"]})}});return u.jsxs("div",{className:"space-y-6",children:[u.jsxs("div",{className:"flex items-center justify-between",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Notícias"}),u.jsxs("div",{className:"flex items-center gap-3",children:[u.jsxs("select",{className:`${Pl} w-44`,value:n,onChange:f=>r(f.target.value),children:[u.jsx("option",{value:"",children:"Todos os status"}),u.jsx("option",{value:"rascunho",children:"Rascunho (pendente)"}),u.jsx("option",{value:"aprovado",children:"Aprovado"}),u.jsx("option",{value:"rejeitado",children:"Rejeitado"}),u.jsx("option",{value:"publicado",children:"Publicado"})]}),u.jsx(Q,{onClick:()=>s(!0),disabled:(h??[]).length===0,title:(h??[]).length===0?"Crie um blog primeiro":void 0,children:"⚡ Gerar notícia"})]})]}),u.jsx(su,{open:l,blogs:h??[],blogInicial:t,onClose:()=>s(!1)}),j?u.jsx("p",{className:"text-slate-500",children:"Carregando…"}):!x||x.length===0?u.jsx($l,{icon:"📝",title:"Nenhuma notícia ainda",message:"O pipeline de geração (coleta RSS → redação via LLM → imagem) chega na próxima versão; notícias geradas aparecem aqui para revisão."}):u.jsx("div",{className:"space-y-4",children:x.map(f=>u.jsxs(Be,{children:[u.jsxs("div",{className:"mb-2 flex flex-wrap items-center gap-2",children:[u.jsx(bh,{status:f.status}),f.llm_provider&&u.jsxs(ae,{tone:"blue",children:["via ",f.llm_provider]}),u.jsxs("span",{className:"text-xs text-slate-500",children:[S(f.blog_id)," · ",new Date(f.created_at).toLocaleString("pt-BR")]})]}),u.jsx("h3",{className:"text-lg font-bold",children:f.titulo||"(sem título)"}),f.resumo&&u.jsx("p",{className:"mt-1 text-sm text-slate-500",children:f.resumo}),f.imagem_url?u.jsx("img",{src:f.imagem_url,alt:"",className:"mt-3 max-h-48 rounded-lg"}):f.status==="rascunho"&&u.jsx(ae,{tone:"amber",children:"sem imagem"}),u.jsxs("div",{className:"mt-4 flex flex-wrap justify-end gap-2",children:[f.fonte_titulo&&u.jsx(Q,{variant:"secondary",onClick:()=>d.mutate(f.id),disabled:d.isPending,title:"Re-escrever a partir da fonte original",children:"↻ Regenerar"}),u.jsx(Q,{variant:"secondary",onClick:()=>{m(""),c({titulo:f.titulo,resumo:f.resumo,corpo:f.corpo}),a(f)},children:"Editar"}),u.jsx(Q,{variant:"danger",onClick:()=>E.mutate({id:f.id,body:{status:"rejeitado"}}),children:"Rejeitar"}),u.jsx(Q,{onClick:()=>E.mutate({id:f.id,body:{status:"aprovado"}}),children:"Aprovar"})]})]},f.id))}),i&&u.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",onClick:()=>a(null),children:u.jsxs("div",{className:"max-h-[90vh] w-full max-w-2xl overflow-y-auto rounded-xl border border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-card",onClick:f=>f.stopPropagation(),children:[u.jsx("h3",{className:"mb-4 text-lg font-bold",children:"Editar notícia manualmente"}),u.jsxs("div",{className:"space-y-4",children:[u.jsx(le,{label:"Título",children:u.jsx("input",{className:se,value:o.titulo,onChange:f=>c({...o,titulo:f.target.value})})}),u.jsx(le,{label:"Resumo",children:u.jsx("textarea",{className:`${se} h-auto py-2.5`,rows:2,value:o.resumo,onChange:f=>c({...o,resumo:f.target.value})})}),u.jsx(le,{label:"Corpo",children:u.jsx("textarea",{className:`${se} h-auto py-2.5`,rows:10,value:o.corpo,onChange:f=>c({...o,corpo:f.target.value})})})]}),p&&u.jsx("p",{className:"mt-3 text-sm text-red-400",children:p}),u.jsxs("div",{className:"mt-6 flex justify-end gap-3",children:[u.jsx(Q,{variant:"secondary",onClick:()=>a(null),children:"Cancelar"}),u.jsx(Q,{onClick:()=>g.mutate(i),disabled:g.isPending,children:"Salvar"})]})]})})]})}function hy(){const e=hn(),[t,n]=C.useState(""),[r,l]=C.useState(null),{data:s,isLoading:i}=Ke({queryKey:["imagens"],queryFn:()=>Ae("/imagens")}),a=Te({mutationFn:o=>Oe("/imagens/gerar","POST",{prompt:o}),onSuccess:o=>{l(o),o.ok&&(n(""),e.invalidateQueries({queryKey:["imagens"]}),e.invalidateQueries({queryKey:["noticias"]}))},onError:o=>l({ok:!1,detail:o.message})});return u.jsxs("div",{className:"space-y-6",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Imagens"}),i?u.jsx("p",{className:"text-slate-500",children:"Carregando…"}):!s||s.length===0?u.jsx($l,{icon:"🖼️",title:"Galeria vazia",message:"Imagens geradas pelo pipeline (e manualmente abaixo) aparecem aqui, reutilizáveis nas notícias."}):u.jsx("div",{className:"grid gap-4 sm:grid-cols-2 xl:grid-cols-3",children:s.map(o=>u.jsxs(Be,{className:"p-3",children:[u.jsx("a",{href:o.url,target:"_blank",rel:"noreferrer",children:u.jsx("img",{src:o.url,alt:o.titulo,className:"h-44 w-full rounded-lg object-cover"})}),u.jsx("p",{className:"mt-2 line-clamp-2 text-sm font-medium",children:o.titulo}),u.jsx("p",{className:"text-xs text-slate-500",children:new Date(o.created_at).toLocaleString("pt-BR")})]},o.noticia_id))}),u.jsxs(Be,{children:[u.jsx("h2",{className:"mb-1 font-bold",children:"Gerar imagem manualmente"}),u.jsx("p",{className:"mb-4 text-sm text-slate-500",children:"Prompt livre para a Gemini Image (requer API key do Google configurada em Configurações)."}),u.jsxs("div",{className:"space-y-4",children:[u.jsx(le,{label:"Prompt visual",children:u.jsx("textarea",{className:`${se} h-auto py-2.5`,rows:3,value:t,onChange:o=>n(o.target.value),placeholder:"Ex.: estádio lotado ao entardecer, fotojornalismo"})}),u.jsx(Q,{onClick:()=>t.trim()&&a.mutate(t.trim()),disabled:a.isPending||!t.trim(),children:a.isPending?"Gerando…":"Gerar imagem"}),r&&!r.ok&&u.jsx("p",{className:"rounded-lg border border-red-400/40 bg-red-500/10 p-3 text-sm text-red-400",children:r.detail}),(r==null?void 0:r.ok)&&r.url&&u.jsxs("div",{className:"rounded-lg border border-panda/40 bg-panda/10 p-3",children:[u.jsx(ae,{tone:"green",children:"imagem gerada"}),u.jsx("img",{src:r.url,alt:"Imagem gerada",className:"mt-2 max-h-56 rounded-lg"})]})]})]})]})}function py(){const e=hn(),[t,n]=C.useState(null),[r,l]=C.useState(!1),{data:s}=Ke({queryKey:["configuracoes"],queryFn:()=>Ae("/configuracoes")}),{data:i}=Ke({queryKey:["automacao-status"],queryFn:()=>Ae("/automacao/status"),refetchInterval:3e4}),{data:a}=Ke({queryKey:["blogs"],queryFn:()=>Ae("/blogs")}),o=Te({mutationFn:h=>Oe("/configuracoes","PUT",h),onSuccess:()=>{e.invalidateQueries({queryKey:["configuracoes"]}),e.invalidateQueries({queryKey:["automacao-status"]}),e.invalidateQueries({queryKey:["dashboard"]})}}),c=Te({mutationFn:({id:h,status:x})=>Oe(`/blogs/${h}`,"PATCH",{status:x}),onSuccess:()=>{e.invalidateQueries({queryKey:["blogs"]}),e.invalidateQueries({queryKey:["automacao-status"]})}}),p=(i==null?void 0:i.ativo)??(s==null?void 0:s.scheduler_ativo)??!0,m=new Map(((i==null?void 0:i.jobs)??[]).map(h=>[h.blog_id,h.proxima_execucao]));return u.jsxs("div",{className:"space-y-6",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Automação"}),u.jsxs(Be,{children:[u.jsxs("div",{className:"flex items-center justify-between gap-4",children:[u.jsxs("div",{children:[u.jsx("h2",{className:"font-bold",children:"Agendador global"}),u.jsx("p",{className:"mt-1 text-sm text-slate-500",children:"Cada blog ativo gera notícias automaticamente conforme sua frequência (horas). O toggle liga/desliga o scheduler de verdade — o estado é aplicado na hora."})]}),u.jsx("button",{onClick:()=>o.mutate({scheduler_ativo:!p}),className:`relative h-10 w-20 shrink-0 rounded-full transition-colors ${p?"bg-panda":"bg-slate-300 dark:bg-slate-700"}`,title:p?"Clique para pausar":"Clique para ativar",children:u.jsx("span",{className:`absolute top-1 h-8 w-8 rounded-full bg-white shadow transition-all ${p?"left-11":"left-1"}`})})]}),u.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[u.jsxs(ae,{tone:p?"green":"neutral",children:["scheduler ",p?"ativo":"pausado"]}),u.jsxs(ae,{children:[((i==null?void 0:i.jobs)??[]).length," job(s) agendado(s)"]}),u.jsxs(ae,{children:["intervalo padrão: ",(s==null?void 0:s.intervalo_padrao_horas)??6,"h"]})]})]}),u.jsx("h2",{className:"pt-2 font-bold",children:"Por blog"}),!a||a.length===0?u.jsx($l,{icon:"⏱️",title:"Nenhum blog",message:"Crie um blog para configurar sua frequência de geração."}):u.jsx("div",{className:"grid gap-4 md:grid-cols-2",children:a.map(h=>{const x=m.get(h.id);return u.jsxs(Be,{children:[u.jsxs("div",{className:"mb-3 flex items-center justify-between gap-3",children:[u.jsxs("div",{children:[u.jsx("div",{className:"font-semibold",children:h.nome}),u.jsxs("div",{className:"text-xs text-slate-500",children:["a cada ",h.frequencia_horas,"h · ",h.tema," · ",h.regiao]})]}),u.jsx("button",{onClick:()=>c.mutate({id:h.id,status:h.status==="ativo"?"pausado":"ativo"}),className:`relative h-8 w-16 shrink-0 rounded-full transition-colors ${h.status==="ativo"?"bg-panda":"bg-slate-300 dark:bg-slate-700"}`,title:h.status==="ativo"?"Clique para pausar":"Clique para ativar",children:u.jsx("span",{className:`absolute top-1 h-6 w-6 rounded-full bg-white shadow transition-all ${h.status==="ativo"?"left-9":"left-1"}`})})]}),u.jsxs("div",{className:"flex items-center justify-between gap-3 text-xs text-slate-500",children:[u.jsx("span",{children:h.status==="ativo"&&p&&x?`próxima execução: ${new Date(x).toLocaleString("pt-BR")}`:h.status==="pausado"?"blog pausado":p?"aguardando agendamento…":"scheduler pausado"}),u.jsx("button",{className:"font-semibold text-panda hover:underline",onClick:()=>{n(h.id),l(!0)},children:"⚡ Executar agora"})]})]},h.id)})}),u.jsx(su,{open:r,blogs:a??[],blogInicial:t,onClose:()=>{l(!1),n(null)}})]})}const my={nvidia:"NVIDIA NIM",google:"Google Gemini"};function vy(){var I,F;const e=hn(),{data:t}=Ke({queryKey:["configuracoes"],queryFn:()=>Ae("/configuracoes")}),[n,r]=C.useState({nvidia_api_key:"",google_api_key:"",supabase_service_role_key:""}),[l,s]=C.useState({nvidia_base_url:"",nvidia_model:"",google_base_url:"",google_model:"",llm_fallback_ordem:"nvidia,google",supabase_url:"",intervalo_padrao_horas:6,meta_diaria:3}),[i,a]=C.useState({}),[o,c]=C.useState(""),[p,m]=C.useState("");C.useEffect(()=>{t&&s({nvidia_base_url:t.nvidia_base_url,nvidia_model:t.nvidia_model,google_base_url:t.google_base_url,google_model:t.google_model,llm_fallback_ordem:t.llm_fallback_ordem,supabase_url:t.supabase_url,intervalo_padrao_horas:t.intervalo_padrao_horas,meta_diaria:t.meta_diaria})},[t]);const h=Te({mutationFn:T=>Oe("/configuracoes","PUT",T),onSuccess:()=>{e.invalidateQueries({queryKey:["configuracoes"]}),e.invalidateQueries({queryKey:["dashboard"]}),c("Configurações salvas com sucesso."),r({nvidia_api_key:"",google_api_key:"",supabase_service_role_key:""})},onError:T=>c(`Falha ao salvar: ${T.message}`)}),x=Te({mutationFn:T=>Oe("/llm/test","POST",{provider:T}),onSuccess:(T,Ee)=>a(me=>({...me,[Ee]:T}))}),j=Te({mutationFn:()=>Oe("/configuracoes/testar-supabase","POST")}),{data:S,isFetching:E,refetch:g}=Ke({queryKey:["nvidia-models"],queryFn:()=>Ae("/configuracoes/llm/nvidia/models"),retry:!1,staleTime:5*60*1e3}),d=(S==null?void 0:S.models)??[],f=(S==null?void 0:S.modelo_atual_disponivel)===!1&&d.length>0,y=Te({mutationFn:()=>Ae("/configuracoes/schema-supabase"),onSuccess:T=>m(T.sql)}),w=Te({mutationFn:()=>Oe("/configuracoes/migrar-supabase","POST"),onSuccess:()=>c("")});function P(){const T={...l};n.nvidia_api_key.trim()&&(T.nvidia_api_key=n.nvidia_api_key.trim()),n.google_api_key.trim()&&(T.google_api_key=n.google_api_key.trim()),n.supabase_service_role_key.trim()&&(T.supabase_service_role_key=n.supabase_service_role_key.trim()),c(""),h.mutate(T)}function k(T,Ee){const me=l.llm_fallback_ordem.split(",").map(br=>br.trim()),mn=me.indexOf(T),Vn=mn+Ee;mn<0||Vn<0||Vn>=me.length||([me[mn],me[Vn]]=[me[Vn],me[mn]],s({...l,llm_fallback_ordem:me.join(",")}))}const _=T=>T.configured?`${T.preview} — deixe vazio para manter`:"Não configurado";return u.jsxs("div",{className:"space-y-4",children:[u.jsxs("div",{className:"flex items-center justify-between",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Configurações"}),u.jsx(Q,{onClick:P,disabled:h.isPending||!t,children:"Salvar configurações"})]}),o&&u.jsx("p",{className:`text-sm ${o.startsWith("Falha")?"text-red-400":"text-panda"}`,children:o}),u.jsxs("div",{className:"space-y-4",children:[u.jsxs(Hr,{title:"NVIDIA NIM (provedor primário)",defaultOpen:!0,children:[u.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[u.jsx(le,{label:"API Key",children:u.jsx("input",{type:"password",className:se,value:n.nvidia_api_key,onChange:T=>r({...n,nvidia_api_key:T.target.value}),placeholder:t?_(t.nvidia_api_key):""})}),u.jsx(le,{label:"Base URL",children:u.jsx("input",{className:se,value:l.nvidia_base_url,onChange:T=>s({...l,nvidia_base_url:T.target.value})})}),u.jsxs(le,{label:"Modelo",hint:d.length>0?`${d.length} modelos disponíveis para sua chave NVIDIA`:"Lista carregada dinamicamente da NVIDIA NIM",children:[u.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[u.jsxs("select",{className:se,value:l.nvidia_model,onChange:T=>s({...l,nvidia_model:T.target.value}),disabled:E,children:[E&&u.jsx("option",{value:"",children:"Carregando modelos…"}),l.nvidia_model&&!d.includes(l.nvidia_model)&&u.jsxs("option",{value:l.nvidia_model,children:[l.nvidia_model," (atual)"]}),d.map(T=>u.jsx("option",{value:T,children:T},T))]}),((I=i.nvidia)==null?void 0:I.degraded)&&u.jsx("span",{className:"inline-flex items-center rounded bg-red-600 px-2 py-1 text-xs font-bold text-white",title:"Modelo indisponível na NVIDIA (404/410) — o fallback Gemini será usado nas gerações",children:"[Indisponível]"}),u.jsx(Q,{variant:"secondary",onClick:()=>g(),disabled:E,title:"Atualizar lista da NVIDIA",children:"↻"})]}),f&&u.jsxs("p",{className:"mt-2 text-xs text-red-400",children:["O modelo ",u.jsx("code",{className:"font-mono",children:S==null?void 0:S.modelo_atual})," não está mais no catálogo da NVIDIA (404/410 — fim de vida). Escolha outro na lista: as gerações estão caindo no Gemini por fallback."]}),!E&&d.length===0&&u.jsx("p",{className:"mt-2 text-xs text-amber-500",children:"Lista indisponível (chave não configurada ou NVIDIA fora do ar) — o modelo atual é mantido. Configure a API key e clique em ↻ para buscar."})]}),u.jsxs("div",{className:"flex items-end gap-2",children:[u.jsx(Q,{variant:"secondary",onClick:()=>x.mutate("nvidia"),disabled:x.isPending,children:"Testar conexão"}),i.nvidia&&u.jsx(ae,{tone:i.nvidia.ok?"green":i.nvidia.degraded?"amber":"red",children:i.nvidia.ok?`ok · ${i.nvidia.latency_ms}ms`:i.nvidia.degraded?"degraded":"falhou"})]})]}),i.nvidia&&!i.nvidia.ok&&u.jsx("p",{className:`mt-3 text-xs ${i.nvidia.degraded?"text-amber-500":"text-red-400"}`,children:i.nvidia.detail})]}),u.jsxs(Hr,{title:"Google Gemini (provedor de fallback)",children:[u.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[u.jsx(le,{label:"API Key",children:u.jsx("input",{type:"password",className:se,value:n.google_api_key,onChange:T=>r({...n,google_api_key:T.target.value}),placeholder:t?_(t.google_api_key):""})}),u.jsx(le,{label:"Base URL",children:u.jsx("input",{className:se,value:l.google_base_url,onChange:T=>s({...l,google_base_url:T.target.value})})}),u.jsx(le,{label:"Modelo",children:u.jsx("input",{className:se,value:l.google_model,onChange:T=>s({...l,google_model:T.target.value})})}),u.jsxs("div",{className:"flex items-end gap-2",children:[u.jsx(Q,{variant:"secondary",onClick:()=>x.mutate("google"),disabled:x.isPending,children:"Testar conexão"}),i.google&&u.jsx(ae,{tone:i.google.ok?"green":i.google.degraded?"amber":"red",children:i.google.ok?`ok · ${i.google.latency_ms}ms`:i.google.degraded?"degraded":"falhou"})]})]}),i.google&&!i.google.ok&&u.jsx("p",{className:`mt-3 text-xs ${i.google.degraded?"text-amber-500":"text-red-400"}`,children:i.google.detail})]}),u.jsx(Hr,{title:"Ordem de fallback dos provedores",children:u.jsx("ul",{className:"space-y-2",children:l.llm_fallback_ordem.split(",").map((T,Ee,me)=>u.jsxs("li",{className:"flex items-center justify-between rounded-lg border border-slate-200 px-4 py-2.5 dark:border-slate-700",children:[u.jsxs("span",{className:"font-semibold",children:[Ee+1,". ",my[T.trim()]??T]}),u.jsxs("span",{className:"flex gap-2",children:[u.jsx(Q,{variant:"secondary",onClick:()=>k(T.trim(),-1),disabled:Ee===0,title:"Subir na prioridade",children:"↑"}),u.jsx(Q,{variant:"secondary",onClick:()=>k(T.trim(),1),disabled:Ee===me.length-1,title:"Descer na prioridade",children:"↓"})]})]},T))})}),u.jsxs(Hr,{title:"Banco de dados (SQLite local → Supabase opcional)",children:[u.jsxs("div",{className:"mb-4 space-y-3 rounded-lg border border-slate-200 p-4 dark:border-slate-700",children:[u.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[u.jsx(ae,{tone:"green",children:"Backend ativo: SQLite local"}),t!=null&&t.supabase_detectado?u.jsx(ae,{tone:"blue",children:"credenciais Supabase detectadas"}):u.jsx(ae,{children:"credenciais Supabase não configuradas"})]}),u.jsxs("p",{className:"text-xs text-slate-500",children:["100% local por padrão. O Supabase é opcional: informe o projeto + ",u.jsx("code",{children:"service_role_key"}),", teste a conexão, crie as tabelas com o schema SQL e migre seus dados quando quiser. O app continua funcionando localmente de forma independente."]}),u.jsxs("div",{className:"flex flex-wrap gap-2",children:[u.jsx(Q,{variant:"secondary",onClick:()=>j.mutate(),disabled:j.isPending,children:"Testar conexão"}),u.jsx(Q,{variant:"secondary",onClick:()=>y.mutate(),disabled:y.isPending,children:"Ver schema SQL"}),u.jsx(Q,{onClick:()=>w.mutate(),disabled:w.isPending||!(t!=null&&t.supabase_detectado),title:t!=null&&t.supabase_detectado?"Copiar dados do SQLite para o Supabase":"Configure as credenciais do Supabase primeiro",children:w.isPending?"Migrando…":"Migrar dados do SQLite"})]}),j.data&&u.jsxs("p",{className:`text-xs ${j.data.ok?"text-panda":"text-amber-500"}`,children:[j.data.detail,j.data.ok&&` (credencial em: ${j.data.credencial_em})`]}),((F=w.data)==null?void 0:F.ok)&&w.data.migrados&&u.jsxs("p",{className:"text-xs text-panda",children:["Migrado: ",Object.entries(w.data.migrados).map(([T,Ee])=>`${T} (${Ee})`).join(" · ")]}),w.data&&!w.data.ok&&u.jsx("p",{className:"text-xs text-red-400",children:w.data.detail})]}),u.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[u.jsx(le,{label:"Supabase URL",hint:"Detectada automaticamente quando SUPABASE_URL está no ambiente",children:u.jsx("input",{className:se,value:l.supabase_url,onChange:T=>s({...l,supabase_url:T.target.value}),placeholder:"https://xxxx.supabase.co"})}),u.jsx(le,{label:"Service Role Key",children:u.jsx("input",{type:"password",className:se,value:n.supabase_service_role_key,onChange:T=>r({...n,supabase_service_role_key:T.target.value}),placeholder:t?_(t.supabase_service_role_key):""})})]})]}),u.jsx(Hr,{title:"Agendamento",children:u.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[u.jsx(le,{label:"Intervalo padrão de geração (horas)",hint:"Aplicado a novos blogs; cada blog pode ter seu próprio intervalo",children:u.jsx("input",{type:"number",min:1,max:168,className:`${se} w-40`,value:l.intervalo_padrao_horas,onChange:T=>s({...l,intervalo_padrao_horas:Number(T.target.value)})})}),u.jsx(le,{label:"Meta diária de notícias",hint:"Usada no Dashboard ('faltam X notícias para bater a meta')",children:u.jsx("input",{type:"number",min:0,max:100,className:`${se} w-40`,value:l.meta_diaria,onChange:T=>s({...l,meta_diaria:Number(T.target.value)})})})]})})]}),p&&u.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",onClick:()=>m(""),children:u.jsxs("div",{className:"max-h-[85vh] w-full max-w-2xl overflow-y-auto rounded-xl border border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-card",onClick:T=>T.stopPropagation(),children:[u.jsx("h3",{className:"mb-2 font-bold",children:"Schema SQL para o Supabase"}),u.jsx("p",{className:"mb-4 text-xs text-slate-500",children:"Execute este SQL no SQL Editor do painel do Supabase antes de migrar. Ele cria as tabelas blogs, noticias, configuracoes e logs com os mesmos campos do banco local."}),u.jsx("pre",{className:"overflow-x-auto rounded-lg bg-night p-4 text-xs text-emerald-300 dark:bg-slate-900",children:u.jsx("code",{children:p})}),u.jsx("div",{className:"mt-4 flex justify-end",children:u.jsx(Q,{onClick:()=>m(""),children:"Fechar"})})]})}),u.jsx(Be,{children:u.jsx("p",{className:"text-xs text-slate-500",children:"Nada de travas de pré-registro: as credenciais só são exigidas no momento da ação que precisa delas. Sem validação, tudo nesta página é opcional."})})]})}function gy(){const[e,t]=C.useState(""),[n,r]=C.useState(""),{data:l,isLoading:s}=Ke({queryKey:["logs",e,n],queryFn:()=>{const i=new URLSearchParams;return e&&i.set("status",e),n&&i.set("etapa",n),Ae(`/logs${i.toString()?`?${i}`:""}`)}});return u.jsxs("div",{className:"space-y-6",children:[u.jsx("h1",{className:"text-2xl font-extrabold",children:"Logs"}),u.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[u.jsxs("select",{className:`${Pl} w-44`,value:e,onChange:i=>t(i.target.value),children:[u.jsx("option",{value:"",children:"Todos os status"}),u.jsx("option",{value:"sucesso",children:"Sucesso"}),u.jsx("option",{value:"erro",children:"Erro"})]}),u.jsxs("select",{className:`${Pl} w-44`,value:n,onChange:i=>r(i.target.value),children:[u.jsx("option",{value:"",children:"Todas as etapas"}),u.jsx("option",{value:"blog",children:"Blog"}),u.jsx("option",{value:"coleta",children:"Coleta"}),u.jsx("option",{value:"redacao",children:"Redação"}),u.jsx("option",{value:"imagem",children:"Imagem"}),u.jsx("option",{value:"publicacao",children:"Publicação"})]})]}),s?u.jsx("p",{className:"text-slate-500",children:"Carregando…"}):!l||l.length===0?u.jsx($l,{icon:"📜",title:"Nenhum log ainda",message:"Execuções do pipeline (coleta, redação, imagem, publicação) aparecem aqui conforme o scheduler roda."}):u.jsx(Be,{className:"overflow-x-auto",children:u.jsxs("table",{className:"w-full text-left text-sm",children:[u.jsx("thead",{children:u.jsxs("tr",{className:"border-b border-slate-200 text-xs uppercase text-slate-500 dark:border-slate-700",children:[u.jsx("th",{className:"pb-2 pr-4",children:"Quando"}),u.jsx("th",{className:"pb-2 pr-4",children:"Etapa"}),u.jsx("th",{className:"pb-2 pr-4",children:"Status"}),u.jsx("th",{className:"pb-2",children:"Mensagem"})]})}),u.jsx("tbody",{children:l.map(i=>u.jsxs("tr",{className:"border-b border-slate-100 last:border-0 dark:border-slate-800",children:[u.jsx("td",{className:"py-2 pr-4 text-slate-500",children:new Date(i.created_at).toLocaleString("pt-BR")}),u.jsx("td",{className:"py-2 pr-4",children:i.etapa}),u.jsx("td",{className:"py-2 pr-4",children:u.jsx(ae,{tone:i.status==="erro"?"red":"green",children:i.status})}),u.jsx("td",{className:"py-2 text-slate-500",children:i.mensagem})]},i.id))})]})})]})}const yy={blogs:"Blogs",noticias:"Notícias",imagens:"Imagens",automacao:"Automação",configuracoes:"Configurações",logs:"Logs"};function xy(){const{pathname:e}=Dr(),[t]=e.split("/").filter(Boolean);if(!t)return null;const n=yy[t]??t;return u.jsxs("nav",{className:"mb-4 text-sm text-slate-500","aria-label":"Breadcrumb",children:[u.jsx(ru,{to:"/",className:"hover:underline",children:"Dashboard"}),u.jsx("span",{className:"mx-2",children:"/"}),u.jsx("span",{className:"font-semibold text-slate-700 dark:text-slate-300",children:n})]})}const wy=new Av({defaultOptions:{queries:{refetchOnWindowFocus:!1,retry:1}}});function Sy(){return u.jsx(pv,{client:wy,children:u.jsx(qg,{children:u.jsxs("div",{className:"flex min-h-screen",children:[u.jsx(ny,{}),u.jsxs("div",{className:"flex min-w-0 flex-1 flex-col",children:[u.jsx(oy,{}),u.jsxs("main",{className:"mx-auto w-full max-w-6xl flex-1 p-6",children:[u.jsx(xy,{}),u.jsxs(Ag,{children:[u.jsx(It,{path:"/",element:u.jsx(cy,{})}),u.jsx(It,{path:"/blogs",element:u.jsx(dy,{})}),u.jsx(It,{path:"/noticias",element:u.jsx(fy,{})}),u.jsx(It,{path:"/imagens",element:u.jsx(hy,{})}),u.jsx(It,{path:"/automacao",element:u.jsx(py,{})}),u.jsx(It,{path:"/configuracoes",element:u.jsx(vy,{})}),u.jsx(It,{path:"/logs",element:u.jsx(gy,{})})]})]})]})]})})})}const ky=document.getElementById("root");oh(ky).render(u.jsx(Sy,{}));
|
package/frontend/dist/index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
9
9
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
10
10
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-Iz5spM-E.js"></script>
|
|
12
12
|
<link rel="stylesheet" crossorigin href="/assets/index-ExoYg5_I.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
package/package.json
CHANGED