@fudrouter/fsrouter 0.6.75 → 0.6.77
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/dist/open-sse/providers/registry/index.js +80 -74
- package/dist/open-sse/providers/registry/nous-research.js +312 -0
- package/dist/routes/headroom/extras/route.js +2 -2
- package/dist/shared/constants/providers.js +1 -1
- package/open-sse/providers/registry/index.js +80 -74
- package/open-sse/providers/registry/nous-research.js +312 -0
- package/package.json +1 -1
- package/public/assets/EndpointPageClient.Osv85Epz.js +6 -0
- package/public/assets/Loading.C4opFudF.js +1 -0
- package/public/assets/NoAuthProxyCard.DYzT0KlD.js +89 -0
- package/public/assets/index.BUwEfcda.js +89 -0
- package/public/assets/page.B1CLc4po.js +5 -0
- package/public/assets/page.B8YgkFHK.js +1 -0
- package/public/assets/page.B8kxZc2Y.js +64 -0
- package/public/assets/page.BFDSjQpd.js +1 -0
- package/public/assets/page.BFZp_qPq.js +1 -0
- package/public/assets/page.BG42OMpT.js +1 -0
- package/public/assets/page.BILXfXsW.js +1 -0
- package/public/assets/page.Bce00fwX.js +1 -0
- package/public/assets/page.BgTbepiA.js +1 -0
- package/public/assets/page.BpplqrTU.js +4 -0
- package/public/assets/page.By-A1n6z.js +1 -0
- package/public/assets/page.CDPEISSH.js +1 -0
- package/public/assets/page.CFYSnWK-.js +1 -0
- package/public/assets/page.CJHC8rlD.js +1 -0
- package/public/assets/page.CL24j_vl.js +1 -0
- package/public/assets/page.CVp9dx-p.js +1 -0
- package/public/assets/page.CWMQbyIX.js +1 -0
- package/public/assets/page.CXzpy7o7.js +2 -0
- package/public/assets/page.CZ5cK15O.js +1 -0
- package/public/assets/page.CcLeXz-1.js +1 -0
- package/public/assets/page.CmTVuMQi.js +1 -0
- package/public/assets/page.CvOd2GpF.js +5 -0
- package/public/assets/page.D2Smj9fq.js +1 -0
- package/public/assets/page.D5Kar16p.js +1 -0
- package/public/assets/page.D7I-i-ax.js +2 -0
- package/public/assets/page.D7fztYuT.js +31 -0
- package/public/assets/page.DHZbcbCI.js +1 -0
- package/public/assets/page.DZnaImDr.js +6 -0
- package/public/assets/page.Da6589dY.js +1 -0
- package/public/assets/page.DmWtn36o.js +1 -0
- package/public/assets/page.Do8LQFv0.js +1 -0
- package/public/assets/page.Lw1SQsqM.js +1 -0
- package/public/assets/page.duNVVU1K.js +23 -0
- package/public/assets/page.gNbjulUj.js +6 -0
- package/public/assets/page.lo-3-G3U.js +1 -0
- package/public/assets/page.uT-1kFm4.js +1 -0
- package/public/assets/page.vwT279sS.js +1 -0
- package/public/index.html +1 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{a as ot,j as e,B as i,M as I,C as lt}from"./index.BUwEfcda.js";import{b as l}from"./router.Cjj1--8t.js";import{C as Pe,B as k,T as ie,I as y}from"./NoAuthProxyCard.DYzT0KlD.js";import{C as Se}from"./Loading.C4opFudF.js";import"./zustand.akaTi5uX.js";function at(x){return x==="active"?"success":x==="error"?"error":"default"}function nt(x){if(!x)return"Never";const W=new Date(x);return Number.isNaN(W.getTime())?"Never":W.toLocaleString()}function ce(x={}){return{name:x.name||"",proxyUrl:x.proxyUrl||"",noProxy:x.noProxy||"",isActive:x.isActive!==!1,strictProxy:x.strictProxy===!0}}function ht(){const[x,W]=l.useState([]),[De,A]=l.useState(!1),[$,B]=l.useState(""),[b,L]=l.useState([]),[E,Y]=l.useState(null),[c,U]=l.useState([]),[Te,Ie]=l.useState(!0),[Ae,K]=l.useState(!1),[$e,Q]=l.useState(!1),[Ee,de]=l.useState(!1),[Ue,xe]=l.useState(!1),[Oe,me]=l.useState(!1),[O,M]=l.useState(!1),[V,he]=l.useState(null),[u,C]=l.useState(ce()),[X,ue]=l.useState(""),[F,Z]=l.useState({vercelToken:"",projectName:"vercel-relay"}),[j,_]=l.useState({accountId:"",apiToken:"",projectName:"cloudflare-relay"}),[N,q]=l.useState({denoToken:"",orgDomain:"",projectName:""}),[R,pe]=l.useState(!1),[J,fe]=l.useState(!1),[p,S]=l.useState(!1),[ee,ye]=l.useState(null),[h,H]=l.useState([]),[v,ge]=l.useState(!1),[be,te]=l.useState({current:0,total:0}),[z,D]=l.useState(!1),[g,w]=l.useState(null),se=l.useRef(null),n=ot();l.useEffect(()=>{const t=s=>{se.current&&!se.current.contains(s.target)&&M(!1)};return O&&document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[O]);const f=l.useCallback(async()=>{try{const t=await fetch("/api/proxy-pools?includeUsage=true",{cache:"no-store"}),s=await t.json();t.ok&&U(s.proxyPools||[])}catch(t){console.log("Error fetching proxy pools:",t)}finally{Ie(!1)}},[]),G=l.useCallback(async()=>{try{const t=await fetch("/api/proxy-combos",{cache:"no-store"}),s=await t.json();t.ok&&W(s.combos||[])}catch{}},[]);l.useEffect(()=>{f(),G()},[f,G]);const je=()=>{he(null),C(ce())},ve=()=>{je(),K(!0)},Me=t=>{he(t),C(ce(t)),K(!0)},re=()=>{K(!1),je()},Fe=async()=>{const t={name:u.name.trim(),proxyUrl:u.proxyUrl.trim(),noProxy:u.noProxy.trim(),isActive:u.isActive===!0,strictProxy:u.strictProxy===!0};if(!(!t.name||!t.proxyUrl)){pe(!0);try{const s=!!V,r=await fetch(s?`/api/proxy-pools/${V.id}`:"/api/proxy-pools",{method:s?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(r.ok)await f(),re(),n.success(V?"Proxy pool updated":"Proxy pool created");else{const o=await r.json();n.error(o.error||"Failed to save proxy pool")}}catch(s){console.log("Error saving proxy pool:",s)}finally{pe(!1)}}},Re=async t=>{w({title:"Delete Proxy Pool",message:`Delete proxy pool "${t.name}"?`,onConfirm:async()=>{w(null);try{const s=await fetch(`/api/proxy-pools/${t.id}`,{method:"DELETE"});if(s.ok){U(o=>o.filter(a=>a.id!==t.id)),n.success("Proxy pool deleted");return}const r=await s.json();s.status===409?n.warning(`Cannot delete: ${r.boundConnectionCount||0} connection(s) are still using this pool.`):n.error(r.error||"Failed to delete proxy pool")}catch(s){console.log("Error deleting proxy pool:",s),n.error("Failed to delete proxy pool")}}})},ze=async t=>{ye(t);try{const s=await fetch(`/api/proxy-pools/${t}/test`,{method:"POST"}),r=await s.json();if(!s.ok){n.error(r.error||"Failed to test proxy");return}await f(),n.success(r.ok?"Proxy test passed":"Proxy test failed")}catch(s){console.log("Error testing proxy pool:",s),n.error("Failed to test proxy")}finally{ye(null)}},We=async t=>{const s=!t.isActive;U(r=>r.map(o=>o.id===t.id?{...o,isActive:s}:o));try{(await fetch(`/api/proxy-pools/${t.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:s})})).ok||(U(o=>o.map(a=>a.id===t.id?{...a,isActive:t.isActive}:a)),n.error("Failed to update active state"))}catch(r){console.log("Error toggling active:",r),U(o=>o.map(a=>a.id===t.id?{...a,isActive:t.isActive}:a))}},oe=c.length>0&&h.length===c.length,Be=t=>H(s=>s.includes(t)?s.filter(r=>r!==t):[...s,t]),Le=()=>H(oe?[]:c.map(t=>t.id)),ke=()=>H([]),Ce=async t=>{const s=h.length>0?h:c.map(r=>r.id);if(s.length!==0){D(!0);try{let r=0,o=0;for(const a of s)try{(await fetch(`/api/proxy-pools/${a}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:t})})).ok?r+=1:o+=1}catch{o+=1}await f(),n.success(`${t?"Activated":"Deactivated"} ${r}${o?`, failed ${o}`:""}`)}finally{D(!1)}}},Ve=async()=>{h.length!==0&&w({title:"Delete Proxy Pools",message:`Delete ${h.length} proxy pool(s)?`,onConfirm:async()=>{w(null),D(!0);try{let t=0,s=0,r=0;for(const o of h)try{const a=await fetch(`/api/proxy-pools/${o}`,{method:"DELETE"});a.ok?t+=1:a.status===409?s+=1:r+=1}catch{r+=1}await f(),ke(),n.success(`Deleted ${t}${s?`, ${s} bound`:""}${r?`, ${r} failed`:""}`)}finally{D(!1)}}})},_e=async()=>{const t=h.length>0?c.filter(d=>h.includes(d.id)):c;if(t.length===0)return;ge(!0),te({current:0,total:t.length});let s=0;const r=[];let o=0;const a=10,m=[...t],P=async()=>{for(;m.length>0;){const d=m.shift();if(!d)break;try{const T=await fetch(`/api/proxy-pools/${d.id}/test`,{method:"POST"}),we=await T.json();T.ok&&we.ok?s+=1:r.push(d.id)}catch{r.push(d.id)}finally{o+=1,te({current:o,total:t.length})}}};await Promise.all(Array.from({length:Math.min(a,t.length)},P)),await f(),ge(!1),te({current:0,total:0}),r.length>0?w({title:"Disable Dead Proxies",message:`Alive: ${s}, Dead: ${r.length}.
|
|
2
|
+
|
|
3
|
+
Disable ${r.length} dead proxies?`,onConfirm:async()=>{w(null),D(!0);try{for(const d of r)try{await fetch(`/api/proxy-pools/${d}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:!1})})}catch{}await f(),n.success(`Disabled ${r.length} dead proxies`)}finally{D(!1)}}}):n.success(`Health check done. Alive: ${s}, Dead: ${r.length}`)};l.useEffect(()=>{H(t=>t.filter(s=>c.some(r=>r.id===s)))},[c]);const qe=()=>{ue(""),Q(!0)},Ne=()=>{J||Q(!1)},Je=()=>{Z({vercelToken:"",projectName:"vercel-relay"}),de(!0)},le=()=>{p||de(!1)},He=()=>{_({accountId:"",apiToken:"",projectName:"cloudflare-relay"}),xe(!0)},ae=()=>{p||xe(!1)},Ge=()=>{q({denoToken:"",orgDomain:"",projectName:""}),me(!0)},ne=()=>{p||me(!1)},Ye=async()=>{if(F.vercelToken.trim()){S(!0);try{const t=await fetch("/api/proxy-pools/vercel-deploy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(F)}),s=await t.json();t.ok?(await f(),le(),n.success(`Deployed: ${s.deployUrl}`)):n.error(s.error||"Deploy failed")}catch(t){console.log("Error deploying Vercel relay:",t),n.error("Deploy failed")}finally{S(!1)}}},Ke=async()=>{if(!(!j.accountId.trim()||!j.apiToken.trim())){S(!0);try{const t=await fetch("/api/proxy-pools/cloudflare-deploy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(j)}),s=await t.json();t.ok?(await f(),ae(),n.success(`Deployed: ${s.deployUrl}`)):n.error(s.error||"Deploy failed")}catch(t){console.log("Error deploying Cloudflare relay:",t),n.error("Deploy failed")}finally{S(!1)}}},Qe=async()=>{if(N.denoToken.trim()){S(!0);try{const t=await fetch("/api/proxy-pools/deno-deploy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(N)}),s=await t.json();t.ok?(await f(),ne(),n.success(`Deployed: ${s.deployUrl}`)):n.error(s.error||"Deploy failed")}catch(t){console.log("Error deploying Deno relay:",t),n.error("Deploy failed")}finally{S(!1)}}},Xe=t=>{const s=t.trim();if(!s)return null;if(s.includes("://")){const o=new URL(s),a=o.port?`${o.hostname}:${o.port}`:o.hostname;return{proxyUrl:o.toString(),name:`Imported ${a}`}}const r=s.split(":");if(r.length===4){const[o,a,m,P]=r;if(!o||!a||!m||!P)throw new Error("Invalid host:port:user:pass format");const d=`http://${encodeURIComponent(m)}:${encodeURIComponent(P)}@${o}:${a}`;return{proxyUrl:new URL(d).toString(),name:`Imported ${o}:${a}`}}throw new Error("Unsupported format")},Ze=async()=>{const t=X.split(/\r?\n/).map(o=>o.trim()).filter(Boolean);if(t.length===0){n.warning("Please paste at least one proxy line.");return}const s=[],r=[];if(t.forEach((o,a)=>{try{const m=Xe(o);m&&s.push({...m,lineNumber:a+1})}catch(m){r.push(`Line ${a+1}: ${m.message}`)}}),r.length>0){n.error(`Invalid proxy format:
|
|
4
|
+
${r.join(`
|
|
5
|
+
`)}`);return}fe(!0);try{const o=new Set(c.map(d=>`${(d.proxyUrl||"").trim()}|||${(d.noProxy||"").trim()}`));let a=0,m=0,P=0;for(const d of s){const T=`${d.proxyUrl}|||`;if(o.has(T)){m+=1;continue}(await fetch("/api/proxy-pools",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:d.name,proxyUrl:d.proxyUrl,noProxy:"",isActive:!0})})).ok?(a+=1,o.add(T)):P+=1}await f(),Q(!1),n.success(`Batch import completed: Created ${a}, Skipped ${m}, Failed ${P}`)}catch(o){console.log("Error batch importing proxies:",o),n.error("Batch import failed")}finally{fe(!1)}},et=l.useMemo(()=>c.filter(t=>t.isActive===!0).length,[c]);if(Te)return e.jsxs("div",{className:"mx-auto flex w-full max-w-5xl flex-col gap-4 px-1 sm:gap-6 sm:px-0",children:[e.jsx(Se,{}),e.jsx(Se,{})]});const tt=async()=>{if(!$.trim()||b.length===0)return;const t=E?"PUT":"POST",s=E?{id:E.id,name:$,poolIds:b}:{name:$,poolIds:b};await fetch("/api/proxy-combos",{method:t,headers:{"Content-Type":"application/json"},body:JSON.stringify(s)}),A(!1),B(""),L([]),Y(null),G()},st=async t=>{await fetch("/api/proxy-combos",{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:t})}),G()},rt=t=>{var s;return((s=c.find(r=>r.id===t))==null?void 0:s.name)||t.slice(0,8)};return e.jsxs("div",{className:"mx-auto flex w-full max-w-5xl flex-col gap-4 px-1 sm:gap-6 sm:px-0",children:[e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[e.jsx("div",{className:"min-w-0",children:e.jsx("h1",{className:"text-xl font-semibold sm:text-2xl",children:"Proxy Pools"})}),e.jsxs("div",{className:"grid grid-cols-1 gap-2 sm:flex sm:items-center",children:[e.jsxs("div",{className:"relative",ref:se,children:[e.jsxs(i,{size:"sm",variant:"secondary",icon:"rocket_launch",onClick:()=>M(!O),children:["Deploy Relay",e.jsx("span",{className:"material-symbols-outlined ml-1 text-[18px]",children:O?"expand_less":"expand_more"})]}),O&&e.jsxs("div",{className:"absolute left-0 top-full z-50 mt-1 w-48 rounded-xl border border-black/10 bg-white p-1 shadow-xl dark:border-white/10 dark:bg-zinc-900 sm:left-auto sm:right-0",children:[e.jsxs("button",{onClick:()=>{He(),M(!1)},className:"flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-text-main transition-colors hover:bg-black/5 dark:hover:bg-white/5",children:[e.jsx("span",{className:"material-symbols-outlined text-[20px] text-orange-500",children:"cloud"}),"Cloudflare Relay"]}),e.jsxs("button",{onClick:()=>{Je(),M(!1)},className:"flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-text-main transition-colors hover:bg-black/5 dark:hover:bg-white/5",children:[e.jsx("span",{className:"material-symbols-outlined text-[20px] text-blue-500",children:"cloud_upload"}),"Vercel Relay"]}),e.jsxs("button",{onClick:()=>{Ge(),M(!1)},className:"flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-text-main transition-colors hover:bg-black/5 dark:hover:bg-white/5",children:[e.jsx("span",{className:"material-symbols-outlined text-[20px] text-green-500",children:"terminal"}),"Deno Relay"]})]})]}),e.jsx(i,{size:"sm",variant:"secondary",icon:"upload",onClick:qe,children:"Batch Import"}),e.jsx(i,{size:"sm",icon:"add",onClick:ve,children:"Add Proxy Pool"})]})]}),e.jsxs(Pe,{children:[e.jsxs("div",{className:"mb-4 flex flex-wrap items-center gap-2",children:[c.length>0&&e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-text-muted cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:oe,onChange:Le,className:"size-4 rounded border-black/20 dark:border-white/20"}),oe?"Unselect all":"Select all"]}),e.jsxs(k,{variant:"default",children:["Total: ",c.length]}),e.jsxs(k,{variant:"success",children:["Active: ",et]})]}),(h.length>0||v)&&e.jsxs("div",{className:"mb-4 flex flex-wrap items-center gap-2 rounded-lg border border-primary/30 bg-primary/5 px-3 py-2",children:[e.jsx("span",{className:"material-symbols-outlined text-[18px] text-primary",children:"checklist"}),e.jsx("span",{className:"text-xs font-medium text-primary",children:h.length>0?`${h.length} selected`:"All pools"}),e.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-2",children:[e.jsx(i,{size:"sm",icon:v?"progress_activity":"health_and_safety",onClick:_e,disabled:v||z||c.length===0,children:v?`Checking ${be.current}/${be.total}`:"Health Check"}),h.length>0&&e.jsxs(e.Fragment,{children:[e.jsx(i,{size:"sm",variant:"secondary",icon:"toggle_on",onClick:()=>Ce(!0),disabled:z||v,children:"Activate"}),e.jsx(i,{size:"sm",variant:"secondary",icon:"toggle_off",onClick:()=>Ce(!1),disabled:z||v,children:"Deactivate"}),e.jsx(i,{size:"sm",variant:"secondary",icon:"delete",onClick:Ve,disabled:z||v,children:"Delete"}),e.jsx(i,{size:"sm",variant:"ghost",onClick:ke,disabled:z||v,children:"Clear"})]})]})]}),c.length===0?e.jsxs("div",{className:"text-center py-10",children:[e.jsx("p",{className:"text-text-main font-medium mb-1",children:"No proxy pool entries yet"}),e.jsx("p",{className:"text-sm text-text-muted mb-4",children:"Create a proxy pool entry, then assign it to connections."}),e.jsx(i,{icon:"add",onClick:ve,children:"Add Proxy Pool"})]}):e.jsx("div",{className:"flex flex-col divide-y divide-black/[0.04] dark:divide-white/[0.05]",children:c.map(t=>e.jsxs("div",{className:"flex flex-col gap-3 py-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{className:"flex items-start gap-3 min-w-0 flex-1",children:[e.jsx("input",{type:"checkbox",checked:h.includes(t.id),onChange:()=>Be(t.id),className:"mt-1 size-4 shrink-0 rounded border-black/20 dark:border-white/20"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("p",{className:"min-w-0 max-w-full truncate text-sm font-medium sm:max-w-[18rem]",children:t.name}),e.jsx(k,{variant:at(t.testStatus),size:"sm",dot:!0,children:t.testStatus||"unknown"}),e.jsx(k,{variant:t.isActive?"success":"default",size:"sm",children:t.isActive?"active":"inactive"}),t.type==="vercel"&&e.jsx(k,{variant:"default",size:"sm",children:"vercel relay"}),t.type==="cloudflare"&&e.jsx(k,{variant:"default",size:"sm",children:"cloudflare relay"}),e.jsxs(k,{variant:"default",size:"sm",children:[t.boundConnectionCount||0," bound"]})]}),e.jsx("p",{className:"text-xs text-text-muted truncate mt-1",children:t.proxyUrl}),t.noProxy?e.jsxs("p",{className:"text-xs text-text-muted truncate",children:["No proxy: ",t.noProxy]}):null,e.jsxs("p",{className:"text-[11px] text-text-muted mt-1",children:["Last tested: ",nt(t.lastTestedAt),t.lastError?` · ${t.lastError}`:""]})]})]}),e.jsxs("div",{className:"flex items-center justify-end gap-1",children:[e.jsx(ie,{size:"sm",checked:t.isActive===!0,onChange:()=>We(t),title:t.isActive?"Disable":"Enable"}),e.jsx("button",{onClick:()=>ze(t.id),className:"p-2 rounded hover:bg-black/5 dark:hover:bg-white/5 text-text-muted hover:text-primary",title:"Test proxy",disabled:ee===t.id,children:e.jsx("span",{className:"material-symbols-outlined text-[18px]",style:ee===t.id?{animation:"spin 1s linear infinite"}:void 0,children:ee===t.id?"progress_activity":"science"})}),e.jsx("button",{onClick:()=>Me(t),className:"p-2 rounded hover:bg-black/5 dark:hover:bg-white/5 text-text-muted hover:text-primary",title:"Edit",children:e.jsx("span",{className:"material-symbols-outlined text-[18px]",children:"edit"})}),e.jsx("button",{onClick:()=>Re(t),className:"p-2 rounded hover:bg-red-500/10 text-red-500",title:"Delete",children:e.jsx("span",{className:"material-symbols-outlined text-[18px]",children:"delete"})})]})]},t.id))})]}),e.jsx(I,{isOpen:$e,title:"Batch Import Proxies",onClose:Ne,children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium text-text-main mb-1 block",children:"Paste Proxy List (One per line)"}),e.jsx("textarea",{value:X,onChange:t=>ue(t.target.value),placeholder:`http://user:pass@127.0.0.1:7897
|
|
6
|
+
127.0.0.1:7897:user:pass`,className:"w-full min-h-[180px] py-2 px-3 text-sm text-text-main bg-white dark:bg-white/5 border border-black/10 dark:border-white/10 rounded-md focus:ring-1 focus:ring-primary/30 focus:border-primary/50 focus:outline-none transition-all"}),e.jsx("p",{className:"text-xs text-text-muted mt-1",children:"Supported formats: protocol://user:pass@host:port, host:port:user:pass"})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-2 sm:grid-cols-2",children:[e.jsx(i,{fullWidth:!0,onClick:Ze,disabled:!X.trim()||J,children:J?"Importing...":"Import"}),e.jsx(i,{fullWidth:!0,variant:"ghost",onClick:Ne,disabled:J,children:"Cancel"})]})]})}),e.jsx(I,{isOpen:Ee,title:"Deploy Vercel Relay",onClose:le,children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{className:"rounded-lg bg-blue-500/5 border border-blue-500/10 p-3 flex flex-col gap-1.5",children:[e.jsx("p",{className:"text-sm text-text-main font-medium",children:"What is Vercel Relay?"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Deploys an edge relay function to Vercel. All AI provider requests will be forwarded through Vercel's edge network, masking your real IP from providers."}),e.jsxs("ul",{className:"text-xs text-text-muted list-disc pl-4 space-y-0.5",children:[e.jsx("li",{children:"Your IP is replaced by Vercel's dynamic edge IPs (hundreds of IPs across 20+ global regions)"}),e.jsx("li",{children:"Vercel serves millions of apps — providers can't block Vercel IPs without affecting legitimate traffic"}),e.jsx("li",{children:"Free tier: 100GB bandwidth/month, 500K edge invocations"}),e.jsx("li",{children:"Deploy multiple relays on different accounts for more IP diversity"})]})]}),e.jsx(y,{label:"Vercel API Token",value:F.vercelToken,onChange:t=>Z(s=>({...s,vercelToken:t.target.value})),placeholder:"your-vercel-api-token",hint:e.jsxs(e.Fragment,{children:["Token is used once for deployment and not stored. ",e.jsx("a",{href:"https://vercel.com/account/tokens",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"Get token →"})]}),type:"password"}),e.jsx(y,{label:"Project Name",value:F.projectName,onChange:t=>Z(s=>({...s,projectName:t.target.value})),placeholder:"my-relay",hint:"Unique name for your Vercel project. Leave empty for auto-generated name."}),e.jsxs("div",{className:"grid grid-cols-1 gap-2 sm:grid-cols-2",children:[e.jsx(i,{fullWidth:!0,onClick:Ye,disabled:!F.vercelToken.trim()||p,children:p?"Deploying... (may take ~1 min)":"Deploy"}),e.jsx(i,{fullWidth:!0,variant:"ghost",onClick:le,disabled:p,children:"Cancel"})]})]})}),e.jsx(I,{isOpen:Ue,title:"Deploy Cloudflare Relay",onClose:ae,children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{className:"rounded-lg bg-orange-500/5 border border-orange-500/10 p-3 flex flex-col gap-1.5",children:[e.jsx("p",{className:"text-sm text-text-main font-medium",children:"What is Cloudflare Relay?"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Deploys a Cloudflare Worker as a proxy relay. All AI provider requests will be forwarded through Cloudflare's global edge network."}),e.jsxs("ul",{className:"text-xs text-text-muted list-disc pl-4 space-y-0.5",children:[e.jsx("li",{children:"High performance global routing and IP masking via Cloudflare Workers"}),e.jsx("li",{children:"Free tier: 100,000 requests per day"}),e.jsx("li",{children:"Requires Cloudflare Account ID and a Workers API Token (Edit Workers permission)"})]}),e.jsxs("div",{className:"mt-2 pt-2 border-t border-orange-500/10 text-xs text-text-muted",children:[e.jsx("p",{className:"font-medium text-text-main mb-1",children:"How to generate your API Token:"}),e.jsxs("ol",{className:"list-decimal pl-4 space-y-0.5",children:[e.jsxs("li",{children:["Go to ",e.jsx("b",{children:"My Profile"})," → ",e.jsx("b",{children:"API Tokens"})," → ",e.jsx("b",{children:"Create Token"})]}),e.jsxs("li",{children:["Scroll down to ",e.jsx("b",{children:"Custom Token"})," and click ",e.jsx("b",{children:"Get started"})]}),e.jsxs("li",{children:["Under ",e.jsx("b",{children:"Permissions"}),": Account | Workers Scripts | Edit"]}),e.jsxs("li",{children:["Under ",e.jsx("b",{children:"Account Resources"}),": Include | Account | ",e.jsx("i",{children:"Your Account Name"})]}),e.jsxs("li",{children:["Click ",e.jsx("b",{children:"Continue to summary"})," → ",e.jsx("b",{children:"Create Token"})]})]})]})]}),e.jsx(y,{label:"Account ID",value:j.accountId,onChange:t=>_(s=>({...s,accountId:t.target.value})),placeholder:"your-cloudflare-account-id",hint:e.jsx(e.Fragment,{children:"Found on the right side of the Cloudflare dashboard overview page."})}),e.jsx(y,{label:"API Token",value:j.apiToken,onChange:t=>_(s=>({...s,apiToken:t.target.value})),placeholder:"your-cloudflare-api-token",hint:e.jsxs(e.Fragment,{children:['Requires "Workers Scripts: Edit" permission. ',e.jsx("a",{href:"https://dash.cloudflare.com/profile/api-tokens",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"Get token →"})]}),type:"password"}),e.jsx(y,{label:"Worker Name",value:j.projectName,onChange:t=>_(s=>({...s,projectName:t.target.value})),placeholder:"my-relay",hint:"Unique name for your Cloudflare Worker. Leave empty for auto-generated name."}),e.jsxs("div",{className:"grid grid-cols-1 gap-2 sm:grid-cols-2",children:[e.jsx(i,{fullWidth:!0,onClick:Ke,disabled:!j.accountId.trim()||!j.apiToken.trim()||p,children:p?"Deploying...":"Deploy Worker"}),e.jsx(i,{fullWidth:!0,variant:"ghost",onClick:ae,disabled:p,children:"Cancel"})]})]})}),e.jsx(I,{isOpen:Oe,title:"Deploy Deno Relay",onClose:ne,children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{className:"rounded-lg bg-black/5 dark:bg-white/5 border border-black/10 dark:border-white/10 p-3 flex flex-col gap-1.5",children:[e.jsx("p",{className:"text-sm text-text-main font-medium",children:"What is Deno Relay?"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Deploys a relay worker to Deno Deploy's global edge network. All AI provider requests are forwarded through Deno's edge, masking your real IP."}),e.jsxs("ul",{className:"text-xs text-text-muted list-disc pl-4 space-y-0.5",children:[e.jsx("li",{children:"Deno Deploy v2 runs on a high-performance global edge network"}),e.jsx("li",{children:"Free tier: 1M requests & 100GiB outbound traffic per month"}),e.jsx("li",{children:"No per-request CPU time limits (unlike Vercel/Cloudflare)"}),e.jsx("li",{children:"Support up to 20 active apps & 50 custom domains"}),e.jsx("li",{children:"Deploy multiple relays for maximum IP diversity"})]}),e.jsxs("div",{className:"mt-2 pt-2 border-t border-black/10 dark:border-white/10 text-xs text-text-muted",children:[e.jsx("p",{className:"font-medium text-text-main mb-1",children:"How to generate API token:"}),e.jsxs("ol",{className:"list-decimal pl-4 space-y-0.5",children:[e.jsxs("li",{children:["Go to ",e.jsx("b",{children:"console.deno.com"})]}),e.jsxs("li",{children:["Select your ",e.jsx("b",{children:"Organization"})," → ",e.jsx("b",{children:"Settings"})," → ",e.jsx("b",{children:"Organization Tokens"})]}),e.jsxs("li",{children:["Create a ",e.jsx("b",{children:"Organization Token"})," (prefix ",e.jsx("b",{children:"ddo_"}),")"]})]})]})]}),e.jsx(y,{label:"Deno Deploy API Token",value:N.denoToken,onChange:t=>q(s=>({...s,denoToken:t.target.value})),placeholder:"ddo_xxxxxxxxxxxxxxxx",hint:e.jsx(e.Fragment,{children:"Token is used once for deployment, not stored. Found in Organization Settings."}),type:"password"}),e.jsx(y,{label:"Organization Domain",value:N.orgDomain,onChange:t=>q(s=>({...s,orgDomain:t.target.value})),placeholder:"your-org.deno.net",hint:"Organization's default domain. Your relay URL will be in the format: https://my-relay.your-org.deno.net"}),e.jsx(y,{label:"App Name",value:N.projectName,onChange:t=>q(s=>({...s,projectName:t.target.value})),placeholder:"deno-relay",hint:"Unique app name. Leave empty for auto-generated name."}),e.jsxs("div",{className:"grid grid-cols-1 gap-2 sm:grid-cols-2",children:[e.jsx(i,{fullWidth:!0,onClick:Qe,disabled:!N.denoToken.trim()||!N.orgDomain.trim()||p,children:p?"Deploying...":"Deploy Relay"}),e.jsx(i,{fullWidth:!0,variant:"ghost",onClick:ne,disabled:p,children:"Cancel"})]})]})}),e.jsx(I,{isOpen:Ae,title:V?"Edit Proxy Pool":"Add Proxy Pool",onClose:re,children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(y,{label:"Name",value:u.name,onChange:t=>C(s=>({...s,name:t.target.value})),placeholder:"Office Proxy"}),e.jsx(y,{label:"Proxy URL",value:u.proxyUrl,onChange:t=>C(s=>({...s,proxyUrl:t.target.value})),placeholder:"http://127.0.0.1:7897"}),e.jsx(y,{label:"No Proxy",value:u.noProxy,onChange:t=>C(s=>({...s,noProxy:t.target.value})),placeholder:"localhost,127.0.0.1,.internal",hint:"Comma-separated hosts/domains to bypass proxy"}),e.jsxs("div",{className:"flex flex-col gap-3 rounded-lg border border-border/50 p-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium text-sm",children:"Active"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Inactive pools are ignored by runtime resolution."})]}),e.jsx(ie,{checked:u.isActive===!0,onChange:()=>C(t=>({...t,isActive:!t.isActive})),disabled:R})]}),e.jsxs("div",{className:"flex flex-col gap-3 rounded-lg border border-border/50 p-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium text-sm",children:"Strict Proxy"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Fail request if proxy is unreachable instead of falling back to direct."})]}),e.jsx(ie,{checked:u.strictProxy===!0,onChange:()=>C(t=>({...t,strictProxy:!t.strictProxy})),disabled:R})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-2 sm:grid-cols-2",children:[e.jsx(i,{fullWidth:!0,onClick:Fe,disabled:!u.name.trim()||!u.proxyUrl.trim()||R,children:R?"Saving...":"Save"}),e.jsx(i,{fullWidth:!0,variant:"ghost",onClick:re,disabled:R,children:"Cancel"})]})]})}),e.jsxs(Pe,{children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Proxy Combos"}),e.jsx("p",{className:"text-xs text-text-muted",children:"Round-robin rotation across multiple pools"})]}),e.jsx(i,{size:"sm",icon:"add",onClick:()=>{Y(null),B(""),L([]),A(!0)},children:"Add Combo"})]}),x.length===0?e.jsx("p",{className:"text-sm text-text-muted py-4 text-center",children:"No combos yet. Create one to rotate proxies automatically."}):e.jsx("div",{className:"space-y-2",children:x.map(t=>e.jsxs("div",{className:"flex items-center justify-between p-3 rounded-lg border border-border-subtle bg-surface hover:bg-surface/50",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"font-medium text-sm text-text-main",children:t.name}),e.jsx("p",{className:"text-xs text-text-muted mt-0.5",children:(t.poolIds||[]).map((s,r)=>e.jsxs("span",{children:[r>0?" → ":"",rt(s)]},s))})]}),e.jsxs("div",{className:"flex items-center gap-2 ml-3",children:[e.jsxs(k,{variant:"success",size:"sm",children:[(t.poolIds||[]).length," pools"]}),e.jsx("button",{onClick:()=>{Y(t),B(t.name),L(t.poolIds||[]),A(!0)},className:"text-xs text-brand-400 hover:text-brand-300 cursor-pointer",children:"Edit"}),e.jsx("button",{onClick:()=>st(t.id),className:"text-xs text-red-400 hover:text-red-300 cursor-pointer",children:"Delete"})]})]},t.id))})]}),e.jsx(I,{isOpen:De,onClose:()=>A(!1),title:E?"Edit Combo":"Create Proxy Combo",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium text-text-muted block mb-1",children:"Combo Name"}),e.jsx(y,{value:$,onChange:t=>B(t.target.value),placeholder:"e.g. Free Proxy Round Robin"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium text-text-muted block mb-2",children:"Select Pools (click to toggle)"}),e.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1 rounded-lg border border-border-subtle p-2",children:c.map(t=>e.jsxs("label",{className:`flex items-center gap-2 p-2 rounded cursor-pointer text-sm transition-colors ${b.includes(t.id)?"bg-primary/10 text-primary":"hover:bg-surface-2 text-text-main"}`,children:[e.jsx("input",{type:"checkbox",checked:b.includes(t.id),onChange:s=>{L(s.target.checked?[...b,t.id]:b.filter(r=>r!==t.id))},className:"rounded"}),t.name]},t.id))})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(i,{fullWidth:!0,onClick:tt,disabled:!$.trim()||b.length===0,children:E?"Save Changes":"Create Combo"}),e.jsx(i,{fullWidth:!0,variant:"ghost",onClick:()=>A(!1),children:"Cancel"})]})]})}),e.jsx(lt,{isOpen:!!g,onClose:()=>w(null),onConfirm:g==null?void 0:g.onConfirm,title:(g==null?void 0:g.title)||"Confirm",message:g==null?void 0:g.message,variant:"danger"})]})}export{ht as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./index.BUwEfcda.js";import{b as r}from"./router.Cjj1--8t.js";import{C as j}from"./Loading.C4opFudF.js";import"./zustand.akaTi5uX.js";function P(){return e.jsx(r.Suspense,{fallback:e.jsx(j,{}),children:e.jsx(y,{})})}function y(){const[a,h]=r.useState([]),[p,b]=r.useState(!0),[s,f]=r.useState(""),[o,n]=r.useState(null),[i,d]=r.useState(!1),[l,c]=r.useState(""),[x,m]=r.useState(null);r.useEffect(()=>{fetch("/api/media-providers/webSearch").then(t=>t.json()).then(t=>{h(Array.isArray(t)?t:[]),t.length>0&&c(t[0].id)}).catch(()=>{}).finally(()=>b(!1))},[]);const u=async()=>{if(s.trim()){d(!0),m(null),n(null);try{const t=await fetch("/api/media/webSearch",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:s,providerId:l||void 0})});if(!t.ok)throw new Error(`HTTP ${t.status}`);const g=await t.json();n(g)}catch(t){m(t.message)}finally{d(!1)}}};return e.jsxs("div",{className:"flex min-w-0 flex-col gap-6 px-1 sm:px-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"material-symbols-outlined text-[28px] text-primary",children:"search"}),e.jsx("h1",{className:"text-xl font-semibold text-text-main",children:"Search"})]}),e.jsxs("div",{className:"rounded-xl border border-border-subtle bg-surface p-4",children:[e.jsx("h2",{className:"text-sm font-semibold text-text-main mb-3",children:"Search Providers"}),p?e.jsx("p",{className:"text-xs text-text-muted",children:"Loading providers..."}):a.length===0?e.jsx("p",{className:"text-xs text-text-muted",children:"No search providers configured. Add one in Media Providers."}):e.jsx("div",{className:"flex flex-wrap gap-2",children:a.map(t=>e.jsx("button",{onClick:()=>c(t.id),className:`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors cursor-pointer ${l===t.id?"bg-primary/10 text-primary border border-primary/30":"bg-surface-2 text-text-muted hover:text-text-main border border-transparent"}`,children:t.name||t.id},t.id))})]}),e.jsxs("div",{className:"rounded-xl border border-border-subtle bg-surface p-4",children:[e.jsx("h2",{className:"text-sm font-semibold text-text-main mb-3",children:"Test Search"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"text",value:s,onChange:t=>f(t.target.value),onKeyDown:t=>t.key==="Enter"&&u(),placeholder:"Enter search query...",className:"flex-1 rounded-lg border border-border-subtle bg-surface-2 px-3 py-2 text-sm text-text-main placeholder:text-text-muted/50 focus:outline-none focus:ring-1 focus:ring-primary/50"}),e.jsx("button",{onClick:u,disabled:i||!s.trim(),className:"px-4 py-2 rounded-lg bg-primary text-white text-sm font-medium hover:bg-primary/90 disabled:opacity-50 transition-colors cursor-pointer",children:i?"Searching...":"Search"})]})]}),x&&e.jsx("div",{className:"rounded-xl border border-red-500/30 bg-red-500/10 p-4",children:e.jsx("p",{className:"text-sm text-red-400",children:x})}),o&&e.jsxs("div",{className:"rounded-xl border border-border-subtle bg-surface p-4",children:[e.jsx("h2",{className:"text-sm font-semibold text-text-main mb-3",children:"Results"}),e.jsx("pre",{className:"text-xs text-text-muted overflow-auto max-h-96 bg-surface-2 rounded-lg p-3 font-mono whitespace-pre-wrap",children:JSON.stringify(o,null,2)})]})]})}export{P as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./index.BUwEfcda.js";import{b as s}from"./router.Cjj1--8t.js";import"./zustand.akaTi5uX.js";function A(){const[a,y]=s.useState({currentVersion:"",latestVersion:"",hasUpdate:!1}),[k,b]=s.useState(!0),[f,i]=s.useState(!1),[c,g]=s.useState(0),[S,o]=s.useState(""),[m,h]=s.useState([]),[j,r]=s.useState(""),x=s.useRef(null),v=async()=>{try{b(!0);const n=await(await fetch("/api/version")).json();y(n)}catch(t){console.error(t),r("Gagal memuat informasi versi.")}finally{b(!1)}};s.useEffect(()=>{v()},[]),s.useEffect(()=>{x.current&&x.current.scrollIntoView({behavior:"smooth"})},[m]);const w=async()=>{if(window.confirm("Apakah Anda yakin ingin memulai update otomatis?")){i(!0),g(0),h([]),o("Menghubungi server untuk memulai update..."),r("");try{const n=await(await fetch("/api/version/update",{method:"POST"})).json();if(n.success){const d=new EventSource("/api/version/update");d.onmessage=u=>{const l=JSON.parse(u.data);if(g(l.progress||0),h(l.logs||[]),l.status==="updating")o(`Sedang memproses update... (${l.progress}%)`);else if(l.status==="done"||l.progress===100){d.close(),o("Update berhasil diselesaikan! Server sedang merestart...");let p=0;const N=setInterval(async()=>{p++,o(`Menunggu server online kembali... (Mencoba menghubungkan: ${p}s)`);try{(await fetch("/api/health")).ok&&(clearInterval(N),o("Update Selesai! Halaman akan dimuat ulang..."),setTimeout(()=>{window.location.reload()},1500))}catch{}p>90&&(clearInterval(N),i(!1),r("Server memakan waktu terlalu lama untuk online kembali. Silakan periksa status PM2 Anda secara manual."))},2e3)}},d.onerror=u=>{console.error("EventSource error:",u),c>80?d.close():(d.close(),r("Koneksi ke server terputus saat proses update berjalan."),i(!1))}}else r(n.message||"Gagal memulai update otomatis."),i(!1)}catch(t){console.error(t),r("Koneksi gagal saat memulai update."),i(!1)}}};return e.jsxs("div",{className:"max-w-4xl mx-auto p-4 space-y-6",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("h1",{className:"text-2xl font-bold text-text-main flex items-center gap-2",children:[e.jsx("span",{className:"material-symbols-outlined text-[28px] text-primary",children:"system_update"}),"FSRouter System Update"]}),e.jsx("p",{className:"text-xs text-text-muted",children:"Kelola dan perbarui versi FSRouter Anda langsung dari repositori GitHub atau NPM registry."})]}),k?e.jsx("div",{className:"flex items-center justify-center p-12 border border-border-subtle rounded-[14px] bg-surface",children:e.jsxs("div",{className:"flex flex-col items-center gap-3",children:[e.jsx("span",{className:"material-symbols-outlined text-4xl animate-spin text-primary",children:"sync"}),e.jsx("span",{className:"text-sm text-text-muted",children:"Memuat informasi versi..."})]})}):e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"p-6 rounded-[14px] border border-border-subtle bg-surface flex flex-col gap-4",children:[e.jsx("h2",{className:"text-sm font-semibold text-text-main",children:"Detail Versi"}),e.jsxs("div",{className:"flex items-center justify-between border-b border-border-subtle pb-3",children:[e.jsx("span",{className:"text-xs text-text-muted",children:"Versi Saat Ini"}),e.jsxs("span",{className:"text-sm font-mono font-semibold text-text-main",children:["v",a.currentVersion||"0.0.0"]})]}),e.jsxs("div",{className:"flex items-center justify-between border-b border-border-subtle pb-3",children:[e.jsx("span",{className:"text-xs text-text-muted",children:"Versi Terbaru di GitHub"}),e.jsxs("span",{className:"text-sm font-mono font-semibold text-text-main",children:["v",a.latestVersion||"0.0.0"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-text-muted",children:"Status"}),a.hasUpdate?e.jsx("span",{className:"px-2 py-0.5 rounded-full text-[10px] font-semibold bg-amber-500/10 text-amber-500 border border-amber-500/20",children:"Update Tersedia"}):e.jsx("span",{className:"px-2 py-0.5 rounded-full text-[10px] font-semibold bg-green-500/10 text-green-500 border border-green-500/20",children:"Versi Terbaru"})]})]}),e.jsxs("div",{className:"p-6 rounded-[14px] border border-border-subtle bg-surface flex flex-col justify-between gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-text-main",children:"Aksi Pembaruan"}),e.jsx("p",{className:"text-xs text-text-muted leading-relaxed",children:a.hasUpdate?"Versi baru tersedia! Update otomatis akan menginstal versi terbaru, memperbarui dependensi, membangun ulang kode, dan me-restart server FSRouter Anda secara mulus.":"FSRouter Anda sudah menggunakan versi terbaru. Tidak ada pembaruan yang diperlukan saat ini."})]}),f?e.jsxs("div",{className:"p-4 rounded-lg bg-primary/5 border border-primary/20 space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-primary",children:[e.jsx("span",{className:"material-symbols-outlined text-[16px] animate-spin",children:"sync"}),"Proses Update Sedang Berjalan: ",c,"%"]}),e.jsx("div",{className:"w-full bg-border-subtle rounded-full h-2.5 overflow-hidden",children:e.jsx("div",{className:"bg-primary h-2.5 rounded-full transition-all duration-500",style:{width:`${c}%`}})}),e.jsx("p",{className:"text-[11px] text-text-muted leading-relaxed",children:S})]}):e.jsxs("div",{className:"space-y-2",children:[j&&e.jsx("p",{className:"text-xs text-red-500 font-semibold bg-red-500/10 border border-red-500/20 p-3 rounded-lg",children:j}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("button",{disabled:!a.hasUpdate,onClick:w,className:`flex-1 py-2 px-4 rounded-lg text-xs font-semibold text-white transition-colors flex items-center justify-center gap-2 ${a.hasUpdate?"bg-primary hover:bg-primary/90 cursor-pointer":"bg-border-subtle text-text-muted cursor-not-allowed"}`,children:[e.jsx("span",{className:"material-symbols-outlined text-[16px]",children:"download"}),"Otomatis Update Sekarang"]}),e.jsx("button",{onClick:v,className:"py-2 px-3 rounded-lg border border-border-subtle text-text-main text-xs hover:bg-surface-2 transition-colors cursor-pointer",title:"Periksa Ulang",children:e.jsx("span",{className:"material-symbols-outlined text-[16px] block",children:"refresh"})})]})]})]})]}),f&&m.length>0&&e.jsxs("div",{className:"p-4 rounded-[14px] border border-border-subtle bg-black text-green-400 font-mono text-xs overflow-hidden flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between pb-2 border-b border-green-900/50",children:[e.jsxs("span",{className:"text-green-500 font-semibold flex items-center gap-1.5",children:[e.jsx("span",{className:"size-2 rounded-full bg-green-500 animate-pulse"}),"Logs Konsol Pembaruan"]}),e.jsx("span",{className:"text-[10px] text-green-600",children:"FSRouter Updater"})]}),e.jsxs("div",{className:"max-h-[300px] overflow-y-auto space-y-1 custom-scrollbar",children:[m.map((t,n)=>e.jsx("pre",{className:"whitespace-pre-wrap leading-relaxed break-all font-mono",children:t},n)),e.jsx("div",{ref:x})]})]})]})}export{A as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{h as et,j as e,U as tt,P as Ae}from"./index.BUwEfcda.js";import{b as c}from"./router.Cjj1--8t.js";import{C as rt}from"./Loading.C4opFudF.js";import{C as ce,T as st,E as nt}from"./NoAuthProxyCard.DYzT0KlD.js";import"./zustand.akaTi5uX.js";function at(s){if(!s)return"-";try{const u=(typeof s=="string"?new Date(s):s)-new Date;if(u<=0)return"-";const l=Math.ceil(u/(1e3*60));if(l<60)return`${l}m`;const a=Math.floor(l/60),x=l%60;if(a<24)return`${a}h ${x}m`;const h=Math.floor(a/24),p=a%24;return`${h}d ${p}h ${x}m`}catch{return"-"}}function $e(s,n){return!n||n===0?0:!s||s<0?100:s>=n?0:Math.round((n-s)/n*100)}function it(s){return(s==null?void 0:s.remaining)!==void 0?Math.max(0,Math.round(s.remaining)):(s==null?void 0:s.remainingPercentage)!==void 0?Math.round(s.remainingPercentage):$e(s==null?void 0:s.used,s==null?void 0:s.total)}function ot(s,n){if(!n||typeof n!="object")return[];const o=[];try{switch(s.toLowerCase()){case"github":n.quotas&&Object.entries(n.quotas).forEach(([l,a])=>{o.push({name:l,used:a.used||0,total:a.total||0,resetAt:a.resetAt||null})});break;case"antigravity":n.quotas&&Object.entries(n.quotas).forEach(([l,a])=>{o.push({name:a.displayName||l,modelKey:l,used:a.used||0,total:a.total||0,resetAt:a.resetAt||null,remainingPercentage:a.remainingPercentage})});break;case"codex":if(n.quotas){const l={session:"Session (5h)",weekly:"Weekly (7d)",code_review:"Code Review",code_review_weekly:"Code Review Weekly",spark:"Spark",spark_weekly:"Spark Weekly"};Object.entries(n.quotas).forEach(([a,x])=>{o.push({name:x.displayName||l[a]||a,used:x.used||0,total:x.total||0,remaining:x.remaining,resetAt:x.resetAt||null})})}n.bankedResetCredits!==void 0&&n.bankedResetCredits>0&&o.push({name:"Banked Reset Credits",used:0,total:n.bankedResetCredits,remaining:n.bankedResetCredits,resetAt:null});break;case"kiro":n.quotas&&Object.entries(n.quotas).forEach(([l,a])=>{o.push({name:l,used:a.used||0,total:a.total||0,resetAt:a.resetAt||null})});break;case"qoder":n.quotas&&Object.entries(n.quotas).forEach(([l,a])=>{l==="organization"&&(!a||(Number(a.total)||0)===0)||o.push({name:l==="user"?"Personal":l==="organization"?"Organization":l,used:a.used||0,total:a.total||0,unit:a.unit,resetAt:a.resetAt||null})});break;case"claude":n.message?o.push({name:"error",used:0,total:0,resetAt:null,message:n.message}):n.quotas&&Object.entries(n.quotas).forEach(([l,a])=>{o.push({name:l,used:a.used||0,total:a.total||0,resetAt:a.resetAt||null})});break;case"leonardo":n.quotas&&Object.entries(n.quotas).forEach(([l,a])=>{o.push({name:l==="tokens"?"Tokens":l,used:a.used||0,total:a.total||0,resetAt:a.resetAt||null,unit:a.unit||null,remaining:a.remaining!==void 0?a.remaining:null})});break;case"weavy":n.quotas&&Object.entries(n.quotas).forEach(([l,a])=>{o.push({name:l==="tokens"?"tokens":l,used:a.used||0,total:a.total||0,resetAt:a.resetAt||null,unit:a.unit||null,remaining:a.remaining!==void 0?a.remaining:null})});break;case"cloudflare-ai":n.quotas&&Object.entries(n.quotas).forEach(([l,a])=>{o.push({name:l,used:a.used||0,total:a.total||0,resetAt:a.resetAt||null,unit:a.unit||"neurons"})});break;default:n.quotas&&Object.entries(n.quotas).forEach(([l,a])=>{o.push({name:l,used:a.used||0,total:a.total||0,resetAt:a.resetAt||null,unit:a.unit||null,remaining:a.remaining!==void 0?a.remaining:null})})}}catch(l){return console.error(`Error parsing quota data for ${s}:`,l),[]}const u=et(s);if(u.length>0){const l=new Map(u.map((a,x)=>[a.id,x]));o.sort((a,x)=>{const h=a.modelKey||a.name,p=x.modelKey||x.name,U=l.get(h)??999,G=l.get(p)??999;return U-G})}return o}const W=10;function lt(s){if(!s)return null;try{const n=new Date(s),o=new Date,u=new Date(o.getFullYear(),o.getMonth(),o.getDate()),l=new Date(u);l.setDate(l.getDate()+1);let a="";n>=u&&n<l?a="Today":n>=l&&n<new Date(l.getTime()+1440*60*1e3)?a="Tomorrow":a=n.toLocaleDateString("en-US",{month:"short",day:"numeric"});const x=n.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0});return`${a}, ${x}`}catch{return null}}function ct(s){return s>70?{text:"text-green-600 dark:text-green-400",bg:"bg-green-500",bgLight:"bg-green-500/10",emoji:"🟢"}:s>=30?{text:"text-yellow-600 dark:text-yellow-400",bg:"bg-yellow-500",bgLight:"bg-yellow-500/10",emoji:"🟡"}:{text:"text-red-600 dark:text-red-400",bg:"bg-red-500",bgLight:"bg-red-500/10",emoji:"🔴"}}function dt(s,n){return n==="remaining-asc"?[...s].sort((o,u)=>o.remaining-u.remaining||o.name.localeCompare(u.name)):n==="remaining-desc"?[...s].sort((o,u)=>u.remaining-o.remaining||o.name.localeCompare(u.name)):s}function ut({quotas:s=[],compact:n=!1,sortMode:o="default",showSortLabel:u=!1}){const[l,a]=c.useState(1),x=c.useMemo(()=>s.map((m,f)=>({...m,index:f,remaining:it(m)})),[s]),h=c.useMemo(()=>dt(x,o),[x,o]),p=Math.max(1,Math.ceil(h.length/W));if(c.useEffect(()=>{a(1)},[o,s]),c.useEffect(()=>{a(m=>Math.min(m,p))},[p]),!s||s.length===0)return null;const U=h.slice((l-1)*W,l*W),G=h.length===0?0:(l-1)*W+1,V=Math.min(l*W,h.length),b=n?"py-1 px-1.5":"py-2 px-3",q=n?"text-[11px]":"text-sm",v=n?"text-[11px]":"text-sm",J=n?"text-[10px] leading-tight":"text-xs";return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"text-[10px] text-text-muted",children:[h.length," quota",h.length>1?"s":""]}),u&&e.jsx("div",{className:"rounded-md border border-black/10 bg-black/[0.02] px-2 py-1 text-[10px] text-text-muted dark:border-white/10 dark:bg-white/[0.03]",children:"Sorted by account remaining"})]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsx("table",{className:"w-full table-fixed text-left",children:e.jsx("tbody",{children:U.map(m=>{var B;const f=ct(m.remaining),I=at(m.resetAt),D=lt(m.resetAt),te=((B=m.name)==null?void 0:B.toLowerCase())==="tokens"?Math.max(0,m.total-m.used):m.used;return e.jsxs("tr",{className:"border-b border-black/5 dark:border-white/5 hover:bg-black/[0.02] dark:hover:bg-white/[0.02] transition-colors",children:[e.jsx("td",{className:`${b} w-[30%]`,children:e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[e.jsx("span",{className:"text-[10px] shrink-0",children:f.emoji}),e.jsx("span",{className:`${q} font-medium text-text-primary truncate`,children:m.name})]})}),e.jsx("td",{className:`${b} w-[45%]`,children:e.jsxs("div",{className:n?"space-y-1":"space-y-1.5",children:[e.jsx("div",{className:`${n?"h-1":"h-1.5"} rounded-full overflow-hidden border ${f.bgLight} ${m.remaining===0?"border-black/10 dark:border-white/10":"border-transparent"}`,children:e.jsx("div",{className:`h-full transition-all duration-300 ${f.bg}`,style:{width:`${Math.min(m.remaining,100)}%`}})}),e.jsxs("div",{className:`flex items-center justify-between ${n?"text-[10px]":"text-xs"}`,children:[e.jsxs("span",{className:"text-text-muted",children:[te.toLocaleString()," / ",m.total>0?m.total.toLocaleString():"∞"]}),e.jsxs("span",{className:`font-medium ${f.text}`,children:[m.remaining,"%"]})]})]})}),e.jsx("td",{className:`${b} w-[25%]`,children:I!=="-"||D?n?e.jsx("div",{className:`${v} text-text-primary font-medium truncate`,title:D||"",children:I!=="-"?`in ${I}`:D}):e.jsxs("div",{className:"space-y-0.5",children:[I!=="-"&&e.jsxs("div",{className:`${v} text-text-primary font-medium`,children:["in ",I]}),D&&e.jsx("div",{className:`${J} text-text-muted`,children:D})]}):e.jsx("div",{className:`${v} text-text-muted italic`,children:"N/A"})})]},`${m.name}-${m.index}`)})})})}),p>1&&e.jsxs("div",{className:"rounded-md border border-black/10 bg-black/[0.02] px-2 py-1.5 dark:border-white/10 dark:bg-white/[0.03]",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 text-[10px] text-text-muted",children:[e.jsxs("span",{children:["Showing ",G,"-",V," of ",h.length]}),e.jsxs("span",{children:["Page ",l," / ",p]})]}),e.jsxs("div",{className:"mt-1.5 flex items-center justify-end gap-1",children:[e.jsx("button",{type:"button",onClick:()=>a(m=>Math.max(1,m-1)),disabled:l===1,className:"flex h-6 items-center rounded-md border border-black/10 px-2 text-[10px] text-text-primary transition-colors hover:bg-black/5 disabled:cursor-not-allowed disabled:opacity-40 dark:border-white/10 dark:hover:bg-white/5",children:"Prev"}),e.jsx("button",{type:"button",onClick:()=>a(m=>Math.min(p,m+1)),disabled:l===p,className:"flex h-6 items-center rounded-md border border-black/10 px-2 text-[10px] text-text-primary transition-colors hover:bg-black/5 disabled:cursor-not-allowed disabled:opacity-40 dark:border-white/10 dark:hover:bg-white/5",children:"Next"})]})]})]})}function X(s){const n=o=>typeof o=="string"&&/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(o);return n(s.email)?s.email:(n(s.name),s.name)}function mt(s,n,o){if(!o)return s;const u=l=>{var x;const a=(((x=n[l.id])==null?void 0:x.quotas)||[]).map(h=>h.resetAt?new Date(h.resetAt).getTime():Number.POSITIVE_INFINITY).filter(h=>Number.isFinite(h));return a.length>0?Math.min(...a):Number.POSITIVE_INFINITY};return[...s].sort((l,a)=>{const x=u(l)-u(a);return x!==0?x:(l.provider||"").localeCompare(a.provider||"")||(X(l)||"").localeCompare(X(a)||"")})}function Pe(s){const n={};return s.forEach(o=>{n[o.id]=!0}),n}function Z(s,n){const o=new Set(n.map(u=>u.id));return Object.fromEntries(Object.entries(s).filter(([u])=>o.has(u)))}function xt(s){if(!s.total)return{start:0,end:0};const n=(s.page-1)*s.pageSize+1,o=Math.min(s.page*s.pageSize,s.total);return{start:n,end:o}}function ht(s,n,o){return s.eligibleConnections?s.providerFilteredConnections?{icon:"filter_alt_off",title:"No Accounts On This Page",description:"Try moving to another page or refreshing the current filters."}:{icon:"filter_alt_off",title:"No Accounts Match Current Filters",description:n==="all"?"Try changing the account status filter to see more quota trackers.":`No ${o==="inactive"?"turned off":o==="active"?"active":"matching"} accounts found for ${n}.`}:{icon:"cloud_off",title:"No Providers Connected",description:"Connect to providers with OAuth to track your API quota limits and usage."}}function pt(s){const{start:n,end:o}=xt(s);return`Showing ${n}-${o} of ${s.total}`}function bt(s,n){return s||{page:1,pageSize:n,total:0,totalPages:1}}function gt(s,n=0){return s||{eligibleConnections:n,providerFilteredConnections:n}}function de(s,n){return s!==n}function ft(s,n){return(s==null?void 0:s.page)||n}function yt(s){return s||[]}async function ue(s,n){return await s(n)}const he="quotaCacheData";function Me(){if(typeof window>"u")return{};try{const s=window.localStorage.getItem(he);return s?JSON.parse(s):{}}catch(s){return console.error("Error reading quota cache:",s),{}}}function Te(s,n){if(!(typeof window>"u"))try{const o=Me();o[s]={...n,cachedAt:new Date().toISOString()},window.localStorage.setItem(he,JSON.stringify(o))}catch(o){console.error("Error writing quota cache:",o)}}const Oe=6e4,vt=5,Ie="quotaAutoRefresh",wt=[{value:"all",label:"All accounts"},{value:"active",label:"Active"},{value:"inactive",label:"Turned off"}],kt=[{value:"default",label:"Default order"},{value:"remaining-asc",label:"Least credits first"},{value:"remaining-desc",label:"Most credits first"},{value:"balance-asc",label:"Saldo Terendah (Lowest Balance)"},{value:"balance-desc",label:"Saldo Tertinggi (Highest Balance)"}],me=20,De=[10,20,50,100],xe=500;function jt(){const[s,n]=c.useState([]),[o,u]=c.useState({}),[l,a]=c.useState({}),[x,h]=c.useState({}),[p,U]=c.useState(!0),[G,V]=c.useState(null),[b,q]=c.useState(!1),[v,J]=c.useState(!1),[pe,m]=c.useState(60),[f,I]=c.useState(!0),[D,ee]=c.useState(null),[te,B]=c.useState(null),[_e,re]=c.useState(!1),[R,se]=c.useState(null),[Re,Le]=c.useState([]),[A,ne]=c.useState("all"),[Fe,be]=c.useState([]),[L,ge]=c.useState("all"),[P,fe]=c.useState("default"),[F,ze]=c.useState(!1),[Nt,St]=c.useState(!1),[Y,ye]=c.useState(!1),[w,C]=c.useState(1),[$,ae]=c.useState(me),[ie,Q]=c.useState(String(me)),[E,ve]=c.useState({page:1,pageSize:me,total:0,totalPages:1}),[k,we]=c.useState({eligibleConnections:0,providerFilteredConnections:0}),T=c.useRef(null),O=c.useRef(null),j=c.useCallback(async(t=w)=>{try{let r="priority";F?r="expiring":P==="remaining-asc"?r="usage-asc":P==="remaining-desc"?r="usage-desc":P==="balance-asc"?r="balance-asc":P==="balance-desc"&&(r="balance-desc");const i=new URLSearchParams({page:String(t),pageSize:String($),accountStatus:L,sort:r});A!=="all"&&i.set("provider",A);const d=await fetch(`/api/providers/client?${i.toString()}`);if(!d.ok)throw new Error("Failed to fetch connections");const N=await d.json(),g=N.connections||[],y=bt(N.pagination,$),S=gt(N.totals,g.length);return n(g),be(yt(N.providerOptions)),ve(y),we(S),C(ft(N.pagination,t)),g}catch(r){return console.error("Error fetching connections:",r),n([]),be([]),ve({page:1,pageSize:$,total:0,totalPages:1}),we({eligibleConnections:0,providerFilteredConnections:0}),[]}},[L,F,w,$,A,P]),M=c.useCallback(async(t,r)=>{a(i=>({...i,[t]:!0})),h(i=>({...i,[t]:null}));try{const i=await fetch(`/api/usage/${t}`);if(!i.ok){const S=(await i.json().catch(()=>({}))).error||i.statusText;if(i.status===404)return;if(i.status===401){const _={quotas:[],message:S};u(H=>({...H,[t]:_})),Te(t,_);return}throw new Error(`HTTP ${i.status}: ${S}`)}const d=await i.json(),g={quotas:ot(r,d),plan:d.plan||null,message:d.message||null,raw:d};u(y=>({...y,[t]:g})),Te(t,g)}catch(i){h(d=>({...d,[t]:i.message||"Failed to fetch quota"}))}finally{a(i=>({...i,[t]:!1}))}},[]),Ue=c.useCallback(async(t,r)=>{await M(t,r),V(new Date)},[M]),Qe=c.useCallback(async t=>{if(confirm("Delete this connection?")){ee(t);try{if((await fetch(`/api/providers/${t}`,{method:"DELETE"})).ok){if(u(i=>{const d={...i};return delete d[t],d}),a(i=>{const d={...i};return delete d[t],d}),h(i=>{const d={...i};return delete d[t],d}),typeof window<"u")try{const i=Me();i[t]&&(delete i[t],window.localStorage.setItem(he,JSON.stringify(i)))}catch(i){console.error("Error deleting cache entry:",i)}await ue(j,w)}}catch(r){console.error("Error deleting connection:",r)}finally{ee(null)}}},[j,w]),He=c.useCallback(async(t,r)=>{B(t);try{(await fetch(`/api/providers/${t}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:r})})).ok&&(u(d=>({...d})),await ue(j,w))}catch(i){console.error("Error updating connection status:",i)}finally{B(null)}},[j,w]),Ve=c.useCallback(async t=>{if(!(R!=null&&R.id))return;const r=R.id,i=R.provider;try{(await fetch(`/api/providers/${r}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).ok&&(await j(),re(!1),se(null),tt.includes(i)&&await M(r,i))}catch(d){console.error("Error saving connection:",d)}},[R,j,M]);c.useEffect(()=>{let t=!1;return fetch("/api/proxy-pools?isActive=true",{cache:"no-store"}).then(r=>r.json()).then(r=>{!t&&(r!=null&&r.proxyPools)&&Le(r.proxyPools)}).catch(()=>{}),()=>{t=!0}},[]);const K=c.useCallback(async()=>{if(!v){J(!0),m(60);try{const t=await j(w);a(Pe(t)),h(r=>Z(r,t)),u(r=>Z(r,t)),await Promise.all(t.map(r=>M(r.id,r.provider))),V(new Date)}catch(t){console.error("Error refreshing all providers:",t)}finally{J(!1)}}},[v,j,M,w]);c.useEffect(()=>{if(!b)return;(async()=>{I(!0);const r=await j(w);I(!1),a(Pe(r)),h(i=>Z(i,r)),u(i=>Z(i,r)),await Promise.all(r.map(i=>M(i.id,i.provider))),V(new Date)})()},[j,M,w,b]);const ke="quotaProviderFilter",je="quotaAccountFilter",Ne="quotaSortMode";c.useEffect(()=>{if(typeof window>"u")return;const t=window.localStorage.getItem(Ie);U(t===null?!0:t==="true");const r=window.localStorage.getItem(ke);r&&ne(r);const i=window.localStorage.getItem(je);i&&ge(i);const d=window.localStorage.getItem(Ne);d&&fe(d),q(!0)},[]),c.useEffect(()=>{typeof window>"u"||!b||window.localStorage.setItem(Ie,String(p))},[p,b]),c.useEffect(()=>{typeof window>"u"||!b||window.localStorage.setItem(ke,A)},[A,b]),c.useEffect(()=>{typeof window>"u"||!b||window.localStorage.setItem(je,L)},[L,b]),c.useEffect(()=>{typeof window>"u"||!b||window.localStorage.setItem(Ne,P)},[P,b]),c.useEffect(()=>{if(!b||!p){T.current&&(clearInterval(T.current),T.current=null),O.current&&(clearInterval(O.current),O.current=null);return}return T.current=setInterval(()=>{K()},Oe),O.current=setInterval(()=>{m(t=>t<=1?60:t-1)},1e3),()=>{T.current&&clearInterval(T.current),O.current&&clearInterval(O.current)}},[p,K,b]),c.useEffect(()=>{const t=()=>{document.hidden?(T.current&&(clearInterval(T.current),T.current=null),O.current&&(clearInterval(O.current),O.current=null)):p&&b&&(T.current=setInterval(K,Oe),O.current=setInterval(()=>{m(r=>r<=1?60:r-1)},1e3))};return document.addEventListener("visibilitychange",t),()=>{document.removeEventListener("visibilitychange",t)}},[p,K,b]);const z=c.useMemo(()=>mt(s,o,F),[s,o,F]),Se=t=>{var i;const r=(i=o[t.id])==null?void 0:i.quotas;return r!=null&&r.length?r.some(d=>!d.total||d.total<=0?!1:$e(d.used,d.total)<=vt):!1},Ce=t=>{const r=o[t.id];return r&&r.message==="Account disabled (Credits exhausted)"},oe=c.useCallback(async(t,r)=>{if(!(!t.length||Y)){ye(!0);try{await Promise.all(t.map(i=>fetch(`/api/providers/${i}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:r})}))),await ue(j,w)}catch(i){console.error("Error bulk toggling connections:",i)}finally{ye(!1)}}},[Y,j,w]),Be=()=>{const t=z.filter(r=>(r.isActive??!0)&&Se(r)).map(r=>r.id);oe(t,!1)},Ye=()=>{const t=z.filter(r=>(r.isActive??!0)&&Ce(r)).map(r=>r.id);oe(t,!1)},Ke=()=>{const t=z.filter(r=>!(r.isActive??!0)&&!Se(r)&&!Ce(r)).map(r=>r.id);oe(t,!0)},{totalCredits:We,providerStats:Ge,exhaustedCount:Ee}=c.useMemo(()=>{var N;let t=0;const r={};let i=0;z.forEach(g=>{const y=o[g.id];if(y&&y.message==="Account disabled (Credits exhausted)"&&(i+=1),!y)return;const S=g.provider;r[S]||(r[S]={accounts:0,credits:0}),r[S].accounts+=1,y.quotas&&y.quotas.forEach(_=>{let H=typeof _.remaining=="number"&&Number.isFinite(_.remaining)?_.remaining:Math.max(0,(_.total||0)-(_.used||0));Number.isFinite(H)&&H>0&&S!=="cloudflare-ai"&&(t+=H,r[S].credits+=H)})});const d=((N=k==null?void 0:k.providerCounts)==null?void 0:N["cloudflare-ai"])||0;if(d>0){const g=(k==null?void 0:k.cloudflareAi)!==void 0?Math.max(0,k.cloudflareAi.total-k.cloudflareAi.used):d*1e4;r["cloudflare-ai"]||(r["cloudflare-ai"]={accounts:d,credits:0}),r["cloudflare-ai"].accounts=d,r["cloudflare-ai"].credits=g,t+=g}return{totalCredits:t,providerStats:r,exhaustedCount:i}},[o,z,k]),Je=k.eligibleConnections>0,Ze=z.length>0,le=ht(k,A,L),Xe=pt(E),qe=!De.includes($);return!f&&!Je?e.jsx(ce,{padding:"lg",children:e.jsxs("div",{className:"text-center py-12",children:[e.jsx("span",{className:"material-symbols-outlined text-[64px] text-text-muted opacity-20",children:"cloud_off"}),e.jsx("h3",{className:"mt-4 text-lg font-semibold text-text-primary",children:"No Providers Connected"}),e.jsx("p",{className:"mt-2 text-sm text-text-muted max-w-md mx-auto",children:"Connect to providers with OAuth to track your API quota limits and usage."})]})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm font-medium text-text-primary px-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5 bg-black/5 dark:bg-white/10 px-2.5 py-1 rounded-md",title:"Total active accounts on this page",children:[e.jsx("span",{className:"material-symbols-outlined text-[16px] text-text-muted",children:"group"}),e.jsxs("span",{children:[k.providerFilteredConnections," Accounts"]})]}),e.jsxs("div",{className:"flex items-center gap-1.5 bg-primary/10 px-2.5 py-1 rounded-md",title:"Total credits across these accounts",children:[e.jsx("span",{className:"material-symbols-outlined text-[16px] text-primary",children:"database"}),e.jsxs("span",{className:"text-primary",children:[Math.floor(We)," Credits"]})]}),Ee>0&&e.jsxs("div",{className:"flex items-center gap-1.5 bg-red-500/10 px-2.5 py-1 rounded-md",title:"Total exhausted accounts",children:[e.jsx("span",{className:"material-symbols-outlined text-[16px] text-red-500",children:"warning"}),e.jsxs("span",{className:"text-red-500",children:[Ee," Exhausted"]})]}),e.jsx("div",{className:"flex flex-wrap items-center gap-1 ml-2",children:Object.entries(Ge).map(([t,r])=>e.jsxs("div",{className:"flex items-center gap-1 bg-black/5 dark:bg-white/5 px-2 py-0.5 rounded text-xs text-text-muted border border-black/10 dark:border-white/10",title:`${r.accounts} accounts`,children:[e.jsx("span",{className:"capitalize",children:t}),": ",e.jsx("span",{className:"font-semibold text-text-primary",children:Math.floor(r.credits)})]},t))})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1 justify-end",children:[e.jsxs("div",{className:"flex flex-wrap gap-1",children:[e.jsxs("button",{type:"button",onClick:()=>{de(A,"all")&&C(1),ne("all")},className:`flex h-8 items-center gap-1.5 rounded-lg px-2.5 text-xs font-medium transition-colors ${A==="all"?"bg-primary/15 text-primary border border-primary/30":"bg-black/5 text-text-muted border border-transparent hover:bg-black/10 dark:bg-white/5 dark:hover:bg-white/10"}`,children:[e.jsx("span",{className:"material-symbols-outlined text-[14px]",children:"apps"}),e.jsx("span",{children:"All"})]}),Fe.map(t=>e.jsxs("button",{type:"button",onClick:()=>{de(A,t)&&C(1),ne(t)},className:`flex h-8 items-center gap-1.5 rounded-lg px-2.5 text-xs font-medium transition-colors ${A===t?"bg-primary/15 text-primary border border-primary/30":"bg-black/5 text-text-muted border border-transparent hover:bg-black/10 dark:bg-white/5 dark:hover:bg-white/10"}`,children:[e.jsx(Ae,{src:t==="codebuddy"||t==="cb"?"/providers/codebuddy.svg":`/providers/${t}.png`,alt:t,size:16,className:"size-4 rounded object-contain",fallbackText:t.slice(0,2).toUpperCase()}),e.jsx("span",{className:"capitalize",children:t})]},t))]}),e.jsx("select",{value:L,onChange:t=>{const r=t.target.value;de(L,r)&&C(1),ge(r)},className:"h-8 rounded-lg border border-black/10 bg-black/[0.02] px-2 text-xs text-text-primary outline-none transition-colors hover:bg-black/5 dark:border-white/10 dark:bg-white/[0.03] dark:hover:bg-white/10","aria-label":"Filter accounts by status",children:wt.map(t=>e.jsx("option",{value:t.value,children:t.label},t.value))}),e.jsx("select",{value:P,onChange:t=>fe(t.target.value),className:"h-8 rounded-lg border border-black/10 bg-black/[0.02] px-2 text-xs text-text-primary outline-none transition-colors hover:bg-black/5 dark:border-white/10 dark:bg-white/[0.03] dark:hover:bg-white/10","aria-label":"Sort quotas by remaining",children:kt.map(t=>e.jsx("option",{value:t.value,children:t.label},t.value))}),e.jsxs("button",{type:"button",onClick:()=>ze(t=>!t),"aria-pressed":F,className:`flex h-8 shrink-0 items-center gap-1 rounded-lg border px-2 text-xs transition-colors ${F?"border-amber-500/40 bg-amber-500/10 text-amber-500":"border-black/10 text-text-primary hover:bg-black/5 dark:border-white/10 dark:hover:bg-white/5"}`,title:"Sort accounts by earliest quota reset time",children:[e.jsx("span",{className:"material-symbols-outlined text-[14px]",children:"hourglass_top"}),e.jsx("span",{className:"hidden sm:inline",children:"Expiring first"})]}),e.jsxs("button",{type:"button",onClick:Be,disabled:Y,className:"flex h-8 shrink-0 items-center gap-1 rounded-lg border border-red-500/30 px-2 text-xs text-red-500 transition-colors hover:bg-red-500/10 disabled:opacity-50",title:"Disable connections with depleted quota on the current page",children:[e.jsx("span",{className:"material-symbols-outlined text-[14px]",children:"block"}),e.jsx("span",{className:"hidden sm:inline",children:"Turn off Empty"})]}),e.jsxs("button",{type:"button",onClick:Ye,disabled:Y,className:"flex h-8 shrink-0 items-center gap-1 rounded-lg border border-red-500/30 px-2 text-xs text-red-500 transition-colors hover:bg-red-500/10 disabled:opacity-50",title:"Disable connections that are exhausted",children:[e.jsx("span",{className:"material-symbols-outlined text-[14px]",children:"block"}),e.jsx("span",{className:"hidden sm:inline",children:"Disable Exhausted"})]}),e.jsxs("button",{type:"button",onClick:Ke,disabled:Y,className:"flex h-8 shrink-0 items-center gap-1 rounded-lg border border-emerald-500/30 px-2 text-xs text-emerald-500 transition-colors hover:bg-emerald-500/10 disabled:opacity-50",title:"Enable connections that still have quota on the current page",children:[e.jsx("span",{className:"material-symbols-outlined text-[14px]",children:"check_circle"}),e.jsx("span",{className:"hidden sm:inline",children:"Turn on Available"})]}),e.jsxs("button",{onClick:()=>U(t=>!t),className:"flex h-8 shrink-0 items-center gap-1 rounded-lg border border-black/10 px-2 text-xs transition-colors hover:bg-black/5 dark:border-white/10 dark:hover:bg-white/5",title:p?"Disable auto-refresh":"Enable auto-refresh",children:[e.jsx("span",{className:`material-symbols-outlined text-[14px] ${p?"text-primary":"text-text-muted"}`,children:p?"toggle_on":"toggle_off"}),e.jsx("span",{className:"hidden text-text-primary sm:inline",children:"Auto-refresh"}),p&&e.jsxs("span",{className:"text-[10px] text-text-muted tabular-nums",children:["(",pe,"s)"]})]}),e.jsx("button",{type:"button",onClick:K,disabled:v,className:"flex h-8 shrink-0 items-center gap-1 rounded-lg border border-black/10 px-2 text-xs text-text-primary transition-colors hover:bg-black/5 dark:border-white/10 dark:hover:bg-white/5 disabled:opacity-50",title:"Refresh all",children:e.jsx("span",{className:`material-symbols-outlined text-[14px] ${v?"animate-spin":""}`,children:"refresh"})})]})]}),(F||P!=="default")&&e.jsx("div",{className:"rounded-xl border border-amber-500/20 bg-amber-500/10 px-3 py-2 text-xs text-amber-700 dark:text-amber-300 mb-3",children:"Sorting currently reorders accounts inside the current page. Cross-page ordering still follows backend pagination. Try increasing the page size to sort across more accounts."}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:!f&&!Ze?e.jsx("div",{className:"col-span-1 md:col-span-2",children:e.jsx(ce,{padding:"lg",children:e.jsxs("div",{className:"text-center py-12",children:[e.jsx("span",{className:"material-symbols-outlined text-[64px] text-text-muted opacity-20",children:le.icon}),e.jsx("h3",{className:"mt-4 text-lg font-semibold text-text-primary",children:le.title}),e.jsx("p",{className:"mt-2 text-sm text-text-muted max-w-md mx-auto",children:le.description})]})})}):z.map(t=>{var y;const r=o[t.id],i=l[t.id],d=x[t.id],N=t.isActive===!1,g=D===t.id||te===t.id;return e.jsxs(ce,{padding:"none",className:`min-w-0 ${N?"opacity-60":""}`,children:[e.jsx("div",{className:"px-3 py-2 border-b border-black/10 dark:border-white/10",children:e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx("div",{className:"w-8 h-8 shrink-0 rounded-md flex items-center justify-center overflow-hidden",children:e.jsx(Ae,{src:t.provider==="codebuddy"||t.provider==="cb"?"/providers/codebuddy.svg":`/providers/${t.provider}.png`,alt:t.provider,size:32,className:"object-contain",fallbackText:((y=t.provider)==null?void 0:y.slice(0,2).toUpperCase())||"PR"})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("h3",{className:"text-sm font-semibold text-text-primary capitalize truncate",children:t.provider}),X(t)?e.jsx("p",{className:"text-xs text-text-muted truncate",children:X(t)}):null]})]}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[e.jsx("button",{type:"button",onClick:()=>Ue(t.id,t.provider),disabled:i||g,"aria-label":"Refresh quota",className:"p-1.5 rounded-lg hover:bg-black/5 dark:hover:bg-white/5 transition-colors disabled:opacity-50",title:"Refresh quota",children:e.jsx("span",{className:`material-symbols-outlined text-[18px] text-text-muted ${i?"animate-spin":""}`,children:"refresh"})}),e.jsx("button",{type:"button",onClick:()=>{se(t),re(!0)},disabled:g,"aria-label":"Edit connection",className:"p-1.5 rounded-lg hover:bg-black/5 dark:hover:bg-white/5 text-text-muted hover:text-primary transition-colors disabled:opacity-50",title:"Edit connection",children:e.jsx("span",{className:"material-symbols-outlined text-[18px]",children:"edit"})}),e.jsx("button",{type:"button",onClick:()=>Qe(t.id),disabled:g,"aria-label":"Delete connection",className:"p-1.5 rounded-lg hover:bg-red-500/10 text-red-500 transition-colors disabled:opacity-50",title:"Delete connection",children:e.jsx("span",{className:`material-symbols-outlined text-[18px] ${D===t.id?"animate-pulse":""}`,children:"delete"})}),e.jsx("div",{className:"inline-flex items-center pl-0.5",title:t.isActive??!0?"Disable connection":"Enable connection",children:e.jsx(st,{size:"sm",checked:t.isActive??!0,disabled:g,onChange:S=>He(t.id,S)})})]})]})}),e.jsx("div",{className:"px-2 py-1.5",children:i?e.jsx("div",{className:"text-center py-5 text-text-muted",children:e.jsx("span",{className:"material-symbols-outlined text-[28px] animate-spin",children:"progress_activity"})}):d?e.jsxs("div",{className:"text-center py-5",children:[e.jsx("span",{className:"material-symbols-outlined text-[28px] text-red-500",children:"error"}),e.jsx("p",{className:"mt-1.5 text-xs text-text-muted",children:d})]}):r!=null&&r.message?e.jsx("div",{className:"text-center py-5",children:e.jsx("p",{className:"text-xs text-text-muted",children:r.message})}):e.jsx(ut,{quotas:r==null?void 0:r.quotas,compact:!0,sortMode:"default",showSortLabel:t.provider==="codex"&&P!=="default"})})]},t.id)})}),e.jsx("div",{className:"rounded-xl border border-black/10 bg-black/[0.02] px-3 py-2 dark:border-white/10 dark:bg-white/[0.03]",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs text-text-muted",children:Xe}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("select",{value:qe?"custom":String($),onChange:t=>{const r=t.target.value;if(r==="custom")return;const i=Number.parseInt(r,10);Number.isFinite(i)&&(C(1),ae(i),Q(String(i)))},className:"h-8 rounded-lg border border-black/10 bg-black/[0.02] px-2 text-xs text-text-primary outline-none transition-colors hover:bg-black/5 dark:border-white/10 dark:bg-white/[0.03] dark:hover:bg-white/10","aria-label":"Accounts per page",children:[De.map(t=>e.jsxs("option",{value:String(t),children:[t," / page"]},t)),e.jsx("option",{value:"500",children:"500 / page"}),e.jsx("option",{value:"1000",children:"1000 / page"}),e.jsx("option",{value:"custom",children:"Custom"})]}),e.jsx("input",{type:"number",min:"1",max:String(xe),inputMode:"numeric",value:ie,onChange:t=>Q(t.target.value),onBlur:()=>{const t=Number.parseInt(ie,10);if(!Number.isFinite(t)){Q(String($));return}const r=Math.min(xe,Math.max(1,t));C(1),ae(r),Q(String(r))},onKeyDown:t=>{if(t.key!=="Enter")return;const r=Number.parseInt(ie,10);if(!Number.isFinite(r)){Q(String($));return}const i=Math.min(xe,Math.max(1,r));C(1),ae(i),Q(String(i))},className:"h-8 w-20 rounded-lg border border-black/10 bg-black/[0.02] px-2 text-xs text-text-primary outline-none transition-colors hover:bg-black/5 dark:border-white/10 dark:bg-white/[0.03] dark:hover:bg-white/10","aria-label":"Custom accounts per page",placeholder:"Custom"}),e.jsxs("span",{className:"text-xs text-text-muted",children:["Page ",E.page," / ",E.totalPages]})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("button",{suppressHydrationWarning:!0,type:"button",onClick:()=>C(1),disabled:E.page<=1||f||v,className:"flex h-8 items-center rounded-lg border border-black/10 px-3 text-xs text-text-primary transition-colors hover:bg-black/5 disabled:cursor-not-allowed disabled:opacity-40 dark:border-white/10 dark:hover:bg-white/5",children:"First Page"}),e.jsx("button",{suppressHydrationWarning:!0,type:"button",onClick:()=>C(t=>Math.max(1,t-1)),disabled:E.page<=1||f||v,className:"flex h-8 w-8 items-center justify-center rounded-lg border border-black/10 text-text-primary transition-colors hover:bg-black/5 disabled:cursor-not-allowed disabled:opacity-40 dark:border-white/10 dark:hover:bg-white/5","aria-label":"Previous accounts page",children:e.jsx("span",{className:"material-symbols-outlined text-[16px]",children:"chevron_left"})}),e.jsx("button",{suppressHydrationWarning:!0,type:"button",onClick:()=>C(t=>Math.min(E.totalPages,t+1)),disabled:E.page>=E.totalPages||f||v,className:"flex h-8 w-8 items-center justify-center rounded-lg border border-black/10 text-text-primary transition-colors hover:bg-black/5 disabled:cursor-not-allowed disabled:opacity-40 dark:border-white/10 dark:hover:bg-white/5","aria-label":"Next accounts page",children:e.jsx("span",{className:"material-symbols-outlined text-[16px]",children:"chevron_right"})}),e.jsx("button",{suppressHydrationWarning:!0,type:"button",onClick:()=>C(E.totalPages),disabled:E.page>=E.totalPages||f||v,className:"flex h-8 items-center rounded-lg border border-black/10 px-3 text-xs text-text-primary transition-colors hover:bg-black/5 disabled:cursor-not-allowed disabled:opacity-40 dark:border-white/10 dark:hover:bg-white/5",children:"Last Page"})]})]})}),e.jsx(nt,{isOpen:_e,connection:R,proxyPools:Re,onSave:Ve,onClose:()=>{re(!1),se(null)}})]})}function Ot(){return e.jsx(c.Suspense,{fallback:e.jsx(rt,{}),children:e.jsx(jt,{})})}export{Ot as default};
|
package/public/index.html
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
11
11
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
12
12
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
|
|
13
|
-
<script type="module" crossorigin src="/assets/index.
|
|
13
|
+
<script type="module" crossorigin src="/assets/index.BUwEfcda.js"></script>
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/assets/router.Cjj1--8t.js">
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/zustand.akaTi5uX.js">
|
|
16
16
|
<link rel="stylesheet" crossorigin href="/assets/index.COMgQZYj.css">
|