| 12 |
- import{i as e}from"./chunk-aKtaBQYM.js";import{C as t,D as n,v as r,w as i}from"./client-BdOyoZJz.js";import{n as a}from"./QueryClientProvider-Clbyr4Jg.js";import{t as o}from"./useQuery-CCy0EwsM.js";import{t as s}from"./play-DROvjtg7.js";import{t as c}from"./x-Dctff5l9.js";import{v as l}from"./date-G9KUauqz.js";import{Hn as u,Tt as d,Wt as f,bt as p,xn as m}from"./index-BoVbGTav.js";var h=e(n(),1),g=t();function _({type:e,deviceId:t,onClose:n}){let{t:a}=i(),[o,l]=(0,h.useState)(!1),[u,d]=(0,h.useState)(``),[p,m]=(0,h.useState)(``),[_,v]=(0,h.useState)(!1);(0,h.useEffect)(()=>{let e=e=>{e.key===`Escape`&&!o&&n()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[o,n]);let y=(0,h.useCallback)(async()=>{l(!0),d(``),m(``),v(!0);try{d(a(`spoolbuddy.diagnostic.queuing`,`Queuing diagnostic on device...
- `)),await r.queueDiagnostics(t,e);let n=null,i=0;for(;i<60&&!n;){await new Promise(e=>setTimeout(e,500));try{n=await r.getDiagnosticResult(t,e);break}catch{i++,i%4==0&&d(e=>e+`.`)}}if(!n)throw Error(`Diagnostic timed out - device did not report results`);d(n.output),n.success||m(`Exit code: ${n.exit_code}`)}catch(e){m(e instanceof Error?e.message:`Unknown error`),d(``)}finally{l(!1)}},[e,t,a]);return(0,g.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/70 animate-fade-in`,onClick:n,children:(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg shadow-xl w-full max-w-2xl mx-4 max-h-[80vh] flex flex-col animate-slide-up`,onClick:e=>e.stopPropagation(),children:[(0,g.jsxs)(`div`,{className:`flex justify-between items-center p-4 border-b border-zinc-700`,children:[(0,g.jsx)(`h2`,{className:`text-lg font-semibold text-white`,children:e===`scale`?a(`spoolbuddy.diagnostic.scaleTitle`,`Scale Diagnostic`):e===`read_tag`?a(`spoolbuddy.diagnostic.readTagTitle`,`Read Tag Diagnostic`):a(`spoolbuddy.diagnostic.nfcTitle`,`NFC Reader Diagnostic`)}),(0,g.jsx)(`button`,{onClick:n,className:`text-zinc-400 hover:text-white transition-colors`,"aria-label":`Close`,children:(0,g.jsx)(c,{size:20})})]}),(0,g.jsx)(`div`,{className:`flex-1 overflow-auto p-4 bg-black/50 font-mono text-sm`,children:o?(0,g.jsxs)(`div`,{className:`flex items-center gap-2 text-green-400`,children:[(0,g.jsx)(`div`,{className:`animate-spin w-4 h-4 border-2 border-green-400 border-t-transparent rounded-full`}),(0,g.jsx)(`span`,{children:a(`spoolbuddy.diagnostic.running`,`Running diagnostic on device...`)})]}):u?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`div`,{className:`text-green-400 whitespace-pre-wrap break-words`,children:u}),p&&(0,g.jsxs)(`div`,{className:`text-red-400 mt-2`,children:[`❌ `,p]})]}):_?(0,g.jsx)(`div`,{children:p?(0,g.jsxs)(`div`,{className:`text-red-400`,children:[`ERROR: `,p]}):(0,g.jsx)(`span`,{className:`text-green-400`,children:a(`spoolbuddy.diagnostic.completed`,`Diagnostic completed successfully.`)})}):(0,g.jsxs)(`div`,{className:`text-zinc-500`,children:[a(`spoolbuddy.diagnostic.clickStart`,`Click "Run Diagnostic" to start the hardware diagnostic on`),` `,t,`.`]})}),(0,g.jsxs)(`div`,{className:`flex gap-2 p-4 border-t border-zinc-700 bg-zinc-800`,children:[(0,g.jsx)(`button`,{onClick:y,disabled:o,className:`flex-1 flex items-center justify-center gap-2 bg-green-600 hover:bg-green-700 disabled:bg-gray-600 disabled:cursor-not-allowed px-4 py-2 rounded font-semibold text-white transition-colors`,children:o?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`div`,{className:`animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full`}),a(`spoolbuddy.diagnostic.runningBtn`,`Running...`)]}):_?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(f,{size:16}),a(`spoolbuddy.diagnostic.runAgain`,`Run Again`)]}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(s,{size:16}),a(`spoolbuddy.diagnostic.runBtn`,`Run Diagnostic`)]})}),(0,g.jsx)(`button`,{onClick:n,className:`px-4 py-2 rounded bg-zinc-700 hover:bg-zinc-600 text-white font-semibold transition-colors`,children:a(`spoolbuddy.diagnostic.close`,`Close`)})]})]})})}function v(e){return e<60?`${e}s`:e<3600?`${Math.floor(e/60)}m`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}function y(e){if(!e)return`-`;let t=l(e);return t?t.toLocaleDateString(void 0,{month:`short`,day:`numeric`})+` `+t.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`}):`-`}var b=[{label:`Off`,value:0},{label:`1m`,value:60},{label:`2m`,value:120},{label:`5m`,value:300},{label:`10m`,value:600},{label:`30m`,value:1800}];function x({device:e}){let{t}=i(),[n,a]=(0,h.useState)(null),[o,s]=(0,h.useState)(``),[c,l]=(0,h.useState)(``),[u,f]=(0,h.useState)(!1),[y,b]=(0,h.useState)(null);return(0,h.useEffect)(()=>{!o&&e.backend_url&&s(e.backend_url)},[e.backend_url,o]),(0,g.jsxs)(`div`,{className:`space-y-2`,children:[(0,g.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-semibold text-zinc-300 mb-2`,children:t(`spoolbuddy.settings.nfcReader`,`NFC Reader`)}),(0,g.jsxs)(`div`,{className:`space-y-1.5 text-xs`,children:[(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.type`,`Type`)}),(0,g.jsx)(`span`,{className:`text-zinc-300 font-mono`,children:e.nfc_reader_type||`N/A`})]}),(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.connection`,`Connection`)}),(0,g.jsx)(`span`,{className:`text-zinc-300 font-mono`,children:e.nfc_connection||`N/A`})]}),(0,g.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.status.status`,`Status`)}),(0,g.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,g.jsx)(`div`,{className:`w-2 h-2 rounded-full ${e.nfc_ok?`bg-green-500`:e.nfc_reader_type?`bg-red-500`:`bg-zinc-600`}`}),(0,g.jsx)(`span`,{className:e.nfc_ok?`text-green-400`:e.nfc_reader_type?`text-red-400`:`text-zinc-500`,children:e.nfc_ok?t(`spoolbuddy.status.nfcReady`,`Ready`):e.nfc_reader_type?t(`common.error`,`Error`):t(`spoolbuddy.settings.notConnected`,`N/A`)})]})]})]})]}),(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-semibold text-zinc-300 mb-2`,children:t(`spoolbuddy.settings.deviceInfo`,`Device Info`)}),(0,g.jsxs)(`div`,{className:`space-y-1.5 text-xs`,children:[(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.hostname`,`Host`)}),(0,g.jsx)(`span`,{className:`text-zinc-300 truncate ml-2`,children:e.hostname})]}),(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:`IP`}),(0,g.jsx)(`span`,{className:`text-zinc-300`,children:e.ip_address})]}),(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.uptime`,`Uptime`)}),(0,g.jsx)(`span`,{className:`text-zinc-300`,children:v(e.uptime_s)})]}),(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:`ID`}),(0,g.jsx)(`span`,{className:`text-zinc-400 font-mono truncate ml-2`,children:e.device_id})]})]})]})]}),(0,g.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3 space-y-2`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-semibold text-zinc-300`,children:t(`spoolbuddy.settings.systemConfig`,`Backend & Auth`)}),(0,g.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),placeholder:`http://192.168.1.100:5000`,className:`w-full px-2 py-1.5 rounded bg-zinc-900 border border-zinc-700 text-zinc-100 text-xs`}),(0,g.jsxs)(`div`,{className:`flex gap-2`,children:[(0,g.jsx)(`input`,{type:`password`,value:c,onChange:e=>l(e.target.value),placeholder:t(`spoolbuddy.settings.apiTokenPlaceholder`,`API token`),className:`flex-1 px-2 py-1.5 rounded bg-zinc-900 border border-zinc-700 text-zinc-100 text-xs`}),(0,g.jsx)(`button`,{onClick:async()=>{if(!o.trim()){b({type:`error`,text:t(`spoolbuddy.settings.systemFieldsRequired`,`Backend URL is required.`)});return}f(!0),b(null);try{await r.updateSystemConfig(e.device_id,o.trim(),c.trim()||void 0),b({type:`ok`,text:t(`spoolbuddy.settings.systemQueued`,`Config queued.`)})}catch(e){b({type:`error`,text:e instanceof Error?e.message:t(`common.error`,`Error`)})}finally{f(!1)}},disabled:u,className:`px-3 py-1.5 rounded bg-green-700 hover:bg-green-600 disabled:bg-zinc-700 text-xs font-medium text-zinc-100`,children:t(`spoolbuddy.settings.saveConfig`,`Save`)})]}),y&&(0,g.jsx)(`div`,{className:`text-xs ${y.type===`ok`?`text-green-400`:`text-red-400`}`,children:y.text})]}),(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3 flex flex-col gap-2`,children:[(0,g.jsxs)(`button`,{onClick:()=>a(`nfc`),className:`flex-1 bg-blue-700 hover:bg-blue-600 transition-colors rounded-lg p-2 flex items-center gap-2`,children:[(0,g.jsx)(d,{className:`w-4 h-4 text-blue-300 shrink-0`}),(0,g.jsx)(`span`,{className:`text-xs font-medium text-blue-100`,children:t(`spoolbuddy.settings.nfcDiagnostic`,`NFC Diagnostic`)})]}),(0,g.jsxs)(`button`,{onClick:()=>a(`scale`),className:`flex-1 bg-yellow-700 hover:bg-yellow-600 transition-colors rounded-lg p-2 flex items-center gap-2`,children:[(0,g.jsx)(p,{className:`w-4 h-4 text-yellow-300 shrink-0`}),(0,g.jsx)(`span`,{className:`text-xs font-medium text-yellow-100`,children:t(`spoolbuddy.settings.scaleDiagnostic`,`Scale Diagnostic`)})]}),(0,g.jsxs)(`button`,{onClick:()=>a(`read_tag`),className:`flex-1 bg-emerald-700 hover:bg-emerald-600 transition-colors rounded-lg p-2 flex items-center gap-2`,children:[(0,g.jsx)(m,{className:`w-4 h-4 text-emerald-300 shrink-0`}),(0,g.jsx)(`span`,{className:`text-xs font-medium text-emerald-100`,children:t(`spoolbuddy.settings.readTagDiagnostic`,`Read Tag`)})]})]})]}),n&&e&&(0,g.jsx)(_,{type:n,deviceId:e.device_id,onClose:()=>a(null)})]})}function S({device:e,onBrightnessChange:t}){let{t:n}=i(),[a,o]=(0,h.useState)(e.display_brightness),[s,c]=(0,h.useState)(e.display_blank_timeout),[l,u]=(0,h.useState)(!1),d=(0,h.useRef)(void 0),f=(0,h.useRef)(void 0);(0,h.useEffect)(()=>{o(e.display_brightness),c(e.display_blank_timeout)},[e.display_brightness,e.display_blank_timeout]);let p=(0,h.useCallback)(()=>{u(!0),f.current&&clearTimeout(f.current),f.current=setTimeout(()=>u(!1),1500)},[]),m=(0,h.useCallback)((t,n)=>{d.current&&clearTimeout(d.current),d.current=setTimeout(()=>{r.updateDisplay(e.device_id,t,n).then(()=>p()).catch(e=>console.error(`Failed to update display:`,e))},300)},[e.device_id,p]),_=e=>{o(e),t(e),m(e,s)},v=e=>{c(e),m(a,e)};return(0,g.jsxs)(`div`,{className:`space-y-4`,children:[(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-4`,children:[(0,g.jsxs)(`div`,{className:`flex items-center justify-between mb-3`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-semibold text-zinc-300`,children:n(`spoolbuddy.settings.brightness`,`Brightness`)}),l&&(0,g.jsxs)(`span`,{className:`text-xs text-green-400 flex items-center gap-1 animate-pulse`,children:[(0,g.jsx)(`svg`,{className:`w-3 h-3`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:3,children:(0,g.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M5 13l4 4L19 7`})}),n(`spoolbuddy.settings.saved`,`Saved`)]})]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,g.jsx)(`svg`,{className:`w-4 h-4 text-zinc-500 flex-shrink-0`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:(0,g.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z`})}),(0,g.jsx)(`input`,{type:`range`,min:0,max:100,value:a,onChange:e=>_(parseInt(e.target.value)),className:`flex-1 h-2 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-green-500`}),(0,g.jsxs)(`span`,{className:`text-sm font-mono text-zinc-400 w-10 text-right`,children:[a,`%`]})]}),!e.has_backlight&&(0,g.jsx)(`p`,{className:`text-xs text-zinc-600 mt-2`,children:n(`spoolbuddy.settings.noBacklight`,`No DSI backlight detected. Brightness control requires a DSI display.`)})]}),(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-4`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-semibold text-zinc-300 mb-1`,children:n(`spoolbuddy.settings.screenBlank`,`Screen Blank Timeout`)}),(0,g.jsx)(`p`,{className:`text-xs text-zinc-500 mb-3`,children:n(`spoolbuddy.settings.screenBlankDesc`,`Screen turns off after inactivity. Touch to wake.`)}),(0,g.jsx)(`div`,{className:`grid grid-cols-3 gap-2`,children:b.map(e=>(0,g.jsx)(`button`,{onClick:()=>v(e.value),className:`px-3 py-2 rounded-lg text-sm font-medium transition-colors min-h-[40px] ${s===e.value?`bg-green-600 text-white`:`bg-zinc-700 text-zinc-300 hover:bg-zinc-600`}`,children:e.label},e.value))})]}),(0,g.jsx)(`p`,{className:`text-xs text-zinc-600 text-center`,children:n(`spoolbuddy.settings.displayNote`,`Brightness is applied as a software filter.`)})]})}function C({step:e,labels:t}){return(0,g.jsxs)(`div`,{className:`flex flex-col items-center w-16 shrink-0 pt-1`,children:[(0,g.jsx)(`div`,{className:`flex items-center justify-center w-7 h-7 rounded-full text-xs font-bold ${e===`tare`?`bg-green-600 text-white`:`bg-green-600/20 text-green-400`}`,children:e===`weight`?(0,g.jsx)(`svg`,{className:`w-3.5 h-3.5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:3,children:(0,g.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M5 13l4 4L19 7`})}):`1`}),(0,g.jsx)(`span`,{className:`text-[10px] mt-0.5 ${e===`tare`?`text-green-400 font-medium`:`text-green-400/60`}`,children:t.tare}),(0,g.jsx)(`div`,{className:`w-px h-5 my-1 ${e===`weight`?`bg-green-600/40`:`bg-zinc-700`}`}),(0,g.jsx)(`div`,{className:`flex items-center justify-center w-7 h-7 rounded-full text-xs font-bold ${e===`weight`?`bg-green-600 text-white`:`bg-zinc-700 text-zinc-500`}`,children:`2`}),(0,g.jsx)(`span`,{className:`text-[10px] mt-0.5 ${e===`weight`?`text-green-400 font-medium`:`text-zinc-600`}`,children:t.weight})]})}function w({device:e,weight:t,weightStable:n,rawAdc:o}){let{t:s}=i(),c=a(),[l,u]=(0,h.useState)(`idle`),[d,f]=(0,h.useState)(`500`),[p,m]=(0,h.useState)(null),[_,v]=(0,h.useState)(!1),[b,x]=(0,h.useState)(null),[S,w]=(0,h.useState)(null),T=(0,h.useRef)(null);(0,h.useEffect)(()=>()=>{T.current&&clearTimeout(T.current)},[]);let E=(0,h.useCallback)(e=>{T.current&&clearTimeout(T.current),T.current=setTimeout(()=>x(null),e)},[]);(0,h.useEffect)(()=>{if(!S)return;let e=()=>Date.now()-S.startedAtMs,t=setInterval(()=>{c.invalidateQueries({queryKey:[`spoolbuddy-devices`]})},1e3),n=setTimeout(()=>{w(null),x({type:`error`,msg:s(`spoolbuddy.settings.tareTimedOut`,`Tare timed out — is the SpoolBuddy daemon running?`)}),E(5e3)},Math.max(0,15e3-e()));return()=>{clearInterval(t),clearTimeout(n)}},[S,c,s,E]),(0,h.useEffect)(()=>{S&&(e?.last_calibrated_at??null)!==S.snapshot&&(w(null),x({type:`ok`,msg:s(`spoolbuddy.settings.tareComplete`,`Tare complete!`)}),E(3e3))},[e?.last_calibrated_at,S,s,E]);let D=e=>{e===`backspace`?f(e=>e.slice(0,-1)||``):e===`.`&&!d.includes(`.`)?f(e=>e+`.`):e>=`0`&&e<=`9`&&f(t=>t===`0`?e:t+e)};return l===`idle`?(0,g.jsxs)(`div`,{className:`flex flex-col h-full`,children:[(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3 mb-3`,children:[(0,g.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,g.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,g.jsx)(`div`,{className:`w-2 h-2 rounded-full ${n?`bg-green-500`:`bg-amber-500 animate-pulse`}`}),(0,g.jsx)(`span`,{className:`text-lg font-mono text-zinc-200`,children:t===null?`-- g`:`${t.toFixed(1)} g`})]}),(0,g.jsxs)(`div`,{className:`text-xs text-zinc-500 text-right`,children:[(0,g.jsxs)(`span`,{children:[s(`spoolbuddy.settings.tareOffset`,`Tare`),`: `,e.tare_offset]}),(0,g.jsx)(`span`,{className:`mx-1.5`,children:`·`}),(0,g.jsxs)(`span`,{children:[s(`spoolbuddy.settings.calFactor`,`Factor`),`: `,e.calibration_factor.toFixed(2)]})]})]}),e.last_calibrated_at&&(0,g.jsxs)(`div`,{className:`text-xs text-zinc-600 mt-1`,children:[s(`spoolbuddy.settings.lastCalibrated`,`Last calibrated`),`: `,y(e.last_calibrated_at)]})]}),b&&(0,g.jsx)(`div`,{className:`rounded-lg px-3 py-2 mb-3 text-sm ${b.type===`ok`?`bg-green-900/30 text-green-300 border border-green-800`:`bg-red-900/30 text-red-300 border border-red-800`}`,children:b.msg}),(0,g.jsxs)(`div`,{className:`flex gap-2`,children:[(0,g.jsxs)(`button`,{onClick:async()=>{v(!0),x(null),T.current&&=(clearTimeout(T.current),null);let t=e?.last_calibrated_at??null;try{await r.tare(e.device_id),x({type:`ok`,msg:s(`spoolbuddy.settings.tareSet`,`Tare command sent. Waiting for device...`)}),w({snapshot:t,startedAtMs:Date.now()})}catch{x({type:`error`,msg:s(`spoolbuddy.settings.tareFailed`,`Failed to send tare command`)}),E(5e3)}finally{v(!1)}},disabled:_,className:`flex-1 px-4 py-2.5 rounded-lg text-sm font-medium bg-zinc-700 text-zinc-200 hover:bg-zinc-600 disabled:opacity-40 transition-colors min-h-[44px] flex items-center justify-center gap-2`,children:[_&&(0,g.jsxs)(`svg`,{className:`w-4 h-4 animate-spin`,viewBox:`0 0 24 24`,fill:`none`,children:[(0,g.jsx)(`circle`,{className:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,strokeWidth:`4`}),(0,g.jsx)(`path`,{className:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z`})]}),s(`spoolbuddy.weight.tare`,`Tare`)]}),(0,g.jsx)(`button`,{onClick:()=>{u(`tare`),x(null)},className:`flex-1 px-4 py-2.5 rounded-lg text-sm font-medium bg-green-600 text-white hover:bg-green-700 transition-colors min-h-[44px]`,children:s(`spoolbuddy.weight.calibrate`,`Calibrate`)})]})]}):(0,g.jsxs)(`div`,{className:`flex gap-3`,children:[(0,g.jsx)(C,{step:l,labels:{tare:s(`spoolbuddy.weight.tare`,`Tare`),weight:s(`spoolbuddy.settings.knownWeight`,`Known weight`)}}),(0,g.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,g.jsxs)(`div`,{className:`flex items-center gap-2 bg-zinc-800 rounded-lg px-3 py-1.5 mb-1.5`,children:[(0,g.jsx)(`div`,{className:`w-2 h-2 rounded-full shrink-0 ${n?`bg-green-500`:`bg-amber-500 animate-pulse`}`}),(0,g.jsx)(`span`,{className:`text-sm font-mono text-zinc-200`,children:t===null?`-- g`:`${t.toFixed(1)} g`}),(0,g.jsx)(`span`,{className:`text-xs ml-auto ${n?`text-green-400`:`text-amber-400`}`,children:n?s(`spoolbuddy.settings.stable`,`Stable`):s(`spoolbuddy.settings.settling`,`Settling...`)})]}),b&&(0,g.jsx)(`div`,{className:`rounded-lg px-3 py-1.5 mb-1.5 text-xs ${b.type===`ok`?`bg-green-900/30 text-green-300 border border-green-800`:`bg-red-900/30 text-red-300 border border-red-800`}`,children:b.msg}),l===`tare`?(0,g.jsx)(`p`,{className:`text-sm text-zinc-300 mb-3`,children:s(`spoolbuddy.settings.calStep1`,`Remove all items from the scale and press Set Zero.`)}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsxs)(`div`,{className:`flex items-center gap-2 mb-1.5`,children:[(0,g.jsx)(`span`,{className:`text-xs text-zinc-400 shrink-0`,children:s(`spoolbuddy.settings.knownWeight`,`Known weight`)}),(0,g.jsxs)(`div`,{className:`flex-1 bg-zinc-900 border border-zinc-600 rounded px-3 py-1 text-right text-lg font-mono text-zinc-100`,children:[d||`0`,(0,g.jsx)(`span`,{className:`text-zinc-500 ml-1`,children:`g`})]})]}),(0,g.jsx)(`div`,{className:`grid grid-cols-4 gap-1 mb-1.5`,children:[`7`,`8`,`9`,`backspace`,`4`,`5`,`6`,`.`,`1`,`2`,`3`,`0`].map(e=>(0,g.jsx)(`button`,{onClick:()=>D(e),className:`rounded text-lg font-medium transition-colors h-[48px] active:scale-95 ${e===`backspace`?`bg-zinc-700 text-zinc-300 hover:bg-zinc-600`:`bg-zinc-800 text-zinc-100 hover:bg-zinc-700 border border-zinc-700`}`,children:e===`backspace`?`⌫`:e},e))})]}),(0,g.jsxs)(`div`,{className:`flex gap-2`,children:[(0,g.jsx)(`button`,{onClick:()=>{u(`idle`),x(null)},className:`flex-1 px-4 py-2 rounded-lg text-sm bg-zinc-700 text-zinc-300 hover:bg-zinc-600 transition-colors h-[40px]`,children:s(`common.cancel`,`Cancel`)}),(0,g.jsxs)(`button`,{onClick:async()=>{if(l===`tare`){v(!0),x(null);try{m(o),await r.tare(e.device_id),x({type:`ok`,msg:s(`spoolbuddy.settings.zeroSet`,`Zero point set. Place known weight on scale.`)}),u(`weight`)}catch{x({type:`error`,msg:s(`spoolbuddy.settings.tareFailed`,`Failed to send tare command`)})}finally{v(!1)}}else if(l===`weight`){let t=parseFloat(d);if(o===null||!t||t<=0)return;v(!0),x(null);try{await r.setCalibrationFactor(e.device_id,t,o,p??void 0),x({type:`ok`,msg:s(`spoolbuddy.settings.calibrationDone`,`Calibration complete!`)}),E(3e3),u(`idle`)}catch{x({type:`error`,msg:s(`spoolbuddy.settings.calibrationFailed`,`Calibration failed`)}),E(5e3)}finally{v(!1)}}},disabled:_,className:`flex-1 px-4 py-2 rounded-lg text-sm font-medium bg-green-600 text-white hover:bg-green-700 disabled:opacity-40 transition-colors h-[40px] flex items-center justify-center gap-2`,children:[_&&(0,g.jsxs)(`svg`,{className:`w-4 h-4 animate-spin`,viewBox:`0 0 24 24`,fill:`none`,children:[(0,g.jsx)(`circle`,{className:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,strokeWidth:`4`}),(0,g.jsx)(`path`,{className:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z`})]}),l===`tare`?s(`spoolbuddy.settings.setZero`,`Set Zero`):s(`spoolbuddy.settings.calibrateNow`,`Calibrate`)]})]})]})]})}function T({device:e}){let{t}=i(),[n,a]=(0,h.useState)(null),[s,c]=(0,h.useState)(null),[l,u]=(0,h.useState)(!1),[d,f]=(0,h.useState)(!1),p=e.update_status===`pending`||e.update_status===`updating`;(0,h.useEffect)(()=>{p&&n===`applying`&&a(null)},[p,n]),(0,h.useEffect)(()=>{let e=()=>{p&&setTimeout(()=>window.location.reload(),1e3)};return window.addEventListener(`spoolbuddy-online`,e),()=>window.removeEventListener(`spoolbuddy-online`,e)},[p]);let{data:m,refetch:_}=o({queryKey:[`spoolbuddy-update-check`,e.device_id],queryFn:()=>r.checkDaemonUpdate(e.device_id),staleTime:0}),{data:v}=o({queryKey:[`spoolbuddy-ssh-key`],queryFn:()=>r.getSSHPublicKey(),enabled:l,staleTime:1/0}),y=async()=>{a(`checking`),c(null);try{await _()}finally{a(null)}},b=async()=>{a(`applying`),c(null);try{await r.triggerUpdate(e.device_id)}catch(e){c(e instanceof Error?e.message:`Failed to trigger update`),a(null)}},x=n!=null||p,S=()=>{v?.public_key&&(navigator.clipboard.writeText(v.public_key),f(!0),setTimeout(()=>f(!1),2e3))},C=e.firmware_version||(m?.current_version&&m.current_version!==`0.0.0`?m.current_version:null);return(0,g.jsxs)(`div`,{className:`space-y-3`,children:[(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3 space-y-3`,children:[(0,g.jsxs)(`div`,{className:`flex justify-between items-center text-sm`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.currentVersion`,`Current Version`)}),(0,g.jsx)(`span`,{className:`text-zinc-200 font-mono`,children:C||(0,g.jsx)(`span`,{className:`text-zinc-500 italic text-xs`,children:t(`spoolbuddy.settings.versionPending`,`Waiting for daemon...`)})})]}),x?(0,g.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,g.jsxs)(`svg`,{className:`w-4 h-4 animate-spin text-green-400 flex-shrink-0`,viewBox:`0 0 24 24`,fill:`none`,children:[(0,g.jsx)(`circle`,{className:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,strokeWidth:`4`}),(0,g.jsx)(`path`,{className:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z`})]}),(0,g.jsx)(`span`,{className:`text-green-300 text-xs`,children:n===`checking`?t(`spoolbuddy.settings.checking`,`Checking for updates...`):e.update_message||t(`spoolbuddy.settings.updateWaiting`,`Updating...`)})]}):e.update_status===`error`?(0,g.jsx)(`p`,{className:`text-xs text-red-300`,children:e.update_message||t(`spoolbuddy.settings.updateFailed`,`Update failed`)}):s?(0,g.jsx)(`p`,{className:`text-xs text-red-300`,children:s}):m?.update_available?(0,g.jsxs)(`p`,{className:`text-xs text-green-300`,children:[t(`spoolbuddy.settings.updateAvailable`,`Update available`),`: `,C,` → `,m.latest_version]}):null,!x&&(m?.update_available?(0,g.jsx)(`button`,{onClick:b,disabled:!e.online,className:`w-full px-3 py-2 rounded-lg text-sm font-medium bg-green-600 text-white hover:bg-green-700 disabled:opacity-40 transition-colors`,children:e.online?t(`spoolbuddy.settings.applyUpdate`,`Apply Update`):t(`spoolbuddy.settings.deviceOffline`,`Device Offline`)}):(0,g.jsxs)(`div`,{className:`flex gap-2`,children:[(0,g.jsx)(`button`,{onClick:y,className:`flex-1 px-3 py-2 rounded-lg text-xs font-medium bg-zinc-700 text-zinc-300 hover:bg-zinc-600 transition-colors`,children:t(`spoolbuddy.settings.checkUpdates`,`Check for Updates`)}),(0,g.jsx)(`button`,{onClick:b,disabled:!e.online,className:`px-3 py-2 rounded-lg text-xs font-medium bg-zinc-700 text-zinc-400 hover:bg-zinc-600 hover:text-zinc-200 disabled:opacity-40 transition-colors`,children:t(`spoolbuddy.settings.forceUpdate`,`Force Update`)})]}))]}),(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3`,children:[(0,g.jsxs)(`button`,{onClick:()=>u(!l),className:`w-full flex justify-between items-center text-xs`,children:[(0,g.jsx)(`span`,{className:`font-medium text-zinc-400`,children:t(`spoolbuddy.settings.sshSetup`,`SSH Setup`)}),(0,g.jsx)(`svg`,{className:`w-3 h-3 text-zinc-500 transition-transform ${l?`rotate-180`:``}`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:(0,g.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M19 9l-7 7-7-7`})})]}),l&&(0,g.jsxs)(`div`,{className:`mt-2 space-y-2`,children:[(0,g.jsx)(`p`,{className:`text-xs text-zinc-500`,children:t(`spoolbuddy.settings.sshDescription`,`SSH key is deployed automatically. For manual setup, add this key to ~/.ssh/authorized_keys on the device.`)}),v?.public_key?(0,g.jsxs)(`div`,{className:`relative`,children:[(0,g.jsx)(`pre`,{className:`bg-zinc-900 rounded p-2 text-[10px] text-zinc-400 font-mono break-all whitespace-pre-wrap`,children:v.public_key}),(0,g.jsx)(`button`,{onClick:S,className:`absolute top-1 right-1 px-1.5 py-0.5 rounded text-[10px] bg-zinc-700 text-zinc-300 hover:bg-zinc-600 transition-colors`,children:d?t(`common.copied`,`Copied!`):t(`common.copy`,`Copy`)})]}):(0,g.jsx)(`span`,{className:`text-[10px] text-zinc-500 italic`,children:t(`spoolbuddy.settings.sshKeyLoading`,`Loading...`)})]})]})]})}function E({percent:e,color:t}){return(0,g.jsx)(`div`,{className:`w-full h-2 bg-zinc-700 rounded-full overflow-hidden`,children:(0,g.jsx)(`div`,{className:`h-full rounded-full transition-all ${t}`,style:{width:`${Math.min(100,Math.max(0,e))}%`}})})}function D(e){let t=Math.floor(e/86400),n=Math.floor(e%86400/3600),r=Math.floor(e%3600/60);return t>0?`${t}d ${n}h ${r}m`:n>0?`${n}h ${r}m`:`${r}m`}function O({device:e}){let{t}=i(),n=e.system_stats;if(!n)return(0,g.jsx)(`div`,{className:`flex items-center justify-center h-32`,children:(0,g.jsx)(`p`,{className:`text-sm text-zinc-500`,children:t(`spoolbuddy.settings.systemStatsWaiting`,`Waiting for system stats...`)})});let r=n.memory,a=n.disk,o=(n.cpu_temp_c??0)>=80?`text-red-400`:(n.cpu_temp_c??0)>=65?`text-amber-400`:`text-green-400`,s=(r?.percent??0)>=90?`bg-red-500`:(r?.percent??0)>=70?`bg-amber-500`:`bg-green-500`,c=(a?.percent??0)>=90?`bg-red-500`:(a?.percent??0)>=70?`bg-amber-500`:`bg-green-500`;return(0,g.jsxs)(`div`,{className:`space-y-2`,children:[(0,g.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-semibold text-zinc-300 mb-2`,children:`CPU`}),(0,g.jsxs)(`div`,{className:`space-y-1.5 text-xs`,children:[(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.cores`,`Cores`)}),(0,g.jsx)(`span`,{className:`text-zinc-300 font-mono`,children:n.cpu_count??`-`})]}),(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.loadAvg`,`Load Avg`)}),(0,g.jsx)(`span`,{className:`text-zinc-300 font-mono`,children:n.load_avg?n.load_avg.join(` / `):`-`})]}),(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.temp`,`Temp`)}),(0,g.jsx)(`span`,{className:`font-mono font-medium ${o}`,children:n.cpu_temp_c==null?`-`:`${n.cpu_temp_c}\u00B0C`})]})]})]}),(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-semibold text-zinc-300 mb-2`,children:t(`spoolbuddy.settings.memory`,`Memory`)}),r?(0,g.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,g.jsx)(E,{percent:r.percent??0,color:s}),(0,g.jsxs)(`div`,{className:`space-y-1 text-xs`,children:[(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.used`,`Used`)}),(0,g.jsxs)(`span`,{className:`text-zinc-300 font-mono`,children:[r.used_mb,` / `,r.total_mb,` MB`]})]}),(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.available`,`Free`)}),(0,g.jsxs)(`span`,{className:`text-zinc-300 font-mono`,children:[r.available_mb,` MB`]})]})]})]}):(0,g.jsx)(`span`,{className:`text-xs text-zinc-500`,children:`-`})]})]}),(0,g.jsx)(`div`,{className:`bg-zinc-800 rounded-lg px-3 py-2`,children:(0,g.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-semibold text-zinc-300 shrink-0`,children:t(`spoolbuddy.settings.disk`,`Disk`)}),a?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`div`,{className:`flex-1`,children:(0,g.jsx)(E,{percent:a.percent??0,color:c})}),(0,g.jsxs)(`span`,{className:`text-xs text-zinc-300 font-mono shrink-0`,children:[a.used_gb,` / `,a.total_gb,` GB`]})]}):(0,g.jsx)(`span`,{className:`text-xs text-zinc-500`,children:`-`})]})}),(0,g.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-semibold text-zinc-300 mb-1.5`,children:t(`spoolbuddy.settings.osInfo`,`OS`)}),(0,g.jsxs)(`div`,{className:`space-y-1 text-xs`,children:[n.os?.os&&(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.distro`,`Distro`)}),(0,g.jsx)(`span`,{className:`text-zinc-300 truncate ml-2`,children:n.os.os})]}),n.os?.kernel&&(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.kernel`,`Kernel`)}),(0,g.jsx)(`span`,{className:`text-zinc-300 font-mono truncate ml-2`,children:n.os.kernel})]}),n.os?.arch&&(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.arch`,`Arch`)}),(0,g.jsx)(`span`,{className:`text-zinc-300 font-mono`,children:n.os.arch})]})]})]}),(0,g.jsxs)(`div`,{className:`bg-zinc-800 rounded-lg p-3`,children:[(0,g.jsx)(`h3`,{className:`text-sm font-semibold text-zinc-300 mb-1.5`,children:t(`spoolbuddy.settings.runtime`,`Runtime`)}),(0,g.jsxs)(`div`,{className:`space-y-1 text-xs`,children:[n.os?.python&&(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:`Python`}),(0,g.jsx)(`span`,{className:`text-zinc-300 font-mono`,children:n.os.python})]}),n.system_uptime_s!=null&&(0,g.jsxs)(`div`,{className:`flex justify-between`,children:[(0,g.jsx)(`span`,{className:`text-zinc-500`,children:t(`spoolbuddy.settings.systemUptime`,`Uptime`)}),(0,g.jsx)(`span`,{className:`text-zinc-300`,children:D(n.system_uptime_s)})]})]})]})]})]})}function k(){let{sbState:e,setDisplayBrightness:t}=u(),{t:n}=i(),[a,s]=(0,h.useState)(`device`),{data:c=[]}=o({queryKey:[`spoolbuddy-devices`],queryFn:()=>r.getDevices(),refetchInterval:1e4}),l=e.deviceId?c.find(t=>t.device_id===e.deviceId)??c[0]:c[0],d=[{id:`device`,label:n(`spoolbuddy.settings.tabDevice`,`Device`)},{id:`display`,label:n(`spoolbuddy.settings.tabDisplay`,`Display`)},{id:`scale`,label:n(`spoolbuddy.settings.tabScale`,`Scale`)},{id:`updates`,label:n(`spoolbuddy.settings.tabUpdates`,`Updates`)},{id:`system`,label:n(`spoolbuddy.settings.tabSystem`,`System`)}];return(0,g.jsxs)(`div`,{className:`h-full flex flex-col p-4`,children:[(0,g.jsx)(`h1`,{className:`text-xl font-semibold text-zinc-100 mb-3`,children:n(`spoolbuddy.nav.settings`,`Settings`)}),(0,g.jsx)(`div`,{className:`flex gap-1 bg-zinc-800/50 rounded-lg p-1 mb-4`,children:d.map(e=>(0,g.jsx)(`button`,{onClick:()=>s(e.id),className:`flex-1 px-2 py-2 rounded-md text-sm font-medium transition-colors min-h-[36px] ${a===e.id?`bg-zinc-700 text-zinc-100`:`text-zinc-500 hover:text-zinc-300`}`,children:e.label},e.id))}),(0,g.jsx)(`div`,{className:`flex-1 min-h-0 overflow-y-auto`,children:l?(0,g.jsxs)(g.Fragment,{children:[a===`device`&&(0,g.jsx)(x,{device:l}),a===`display`&&(0,g.jsx)(S,{device:l,onBrightnessChange:t}),a===`scale`&&(0,g.jsx)(w,{device:l,weight:e.weight,weightStable:e.weightStable,rawAdc:e.rawAdc}),a===`updates`&&(0,g.jsx)(T,{device:l}),a===`system`&&(0,g.jsx)(O,{device:l})]}):(0,g.jsx)(`div`,{className:`flex items-center justify-center h-32`,children:(0,g.jsx)(`div`,{className:`text-center text-zinc-500`,children:(0,g.jsx)(`p`,{className:`text-sm`,children:n(`spoolbuddy.settings.noDevice`,`No SpoolBuddy device found`)})})})})]})}export{k as SpoolBuddySettingsPage};
|