SpoolBuddyDashboard-B6TlU7-K.js 31 KB

1
  1. import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{T as t,a as n,k as r,t as i,v as a,w as o}from"./client-Bw3urp1w.js";import{u as s}from"./chunk-62JRHF6Z-BW23DMlx.js";import{n as c}from"./QueryClientProvider-C3eWKLmF.js";import{t as l}from"./useQuery-BTfjV-1Z.js";import{t as u}from"./useMutation-CGk77Rd2.js";import{t as d}from"./useQueries-Xuq6LLzc.js";import{t as f}from"./check-Pg_IdFns.js";import{n as p}from"./ToastContext-lCIPyrWa.js";import{t as m}from"./refresh-cw-LKkW6pKU.js";import{t as h}from"./triangle-alert-DxTC_wVZ.js";import{t as g}from"./unlink-_txqGyT9.js";import{t as _}from"./x-D4CM9tS6.js";import{c as v,u as y}from"./colors-BBBvvSKR.js";import{t as ee}from"./AssignToAmsModal-C421iyiz.js";import{t as b}from"./SpoolIcon-CI8KDVpv.js";var x=e(r(),1),S=o();function te({spool:e,scaleWeight:n,onClose:r,onSyncWeight:i,onAssignToAms:o,isAssigned:s,onUnassignFromAms:c}){let{t:l}=t(),[u,d]=(0,x.useState)(!1),[p,_]=(0,x.useState)(!1),ee=y(e.rgba),te=v(e.color_name,e.rgba,e.color_name_is_synthesized),C=e.core_weight&&e.core_weight>0?e.core_weight:250,w=n===null?null:Math.round(Math.max(0,n)),T=w===null?null:Math.round(Math.max(0,w-C)),E=Math.round(e.label_weight||1e3),D=T===null?null:Math.min(100,Math.round(T/E*100)),O=D===null?`#808080`:D>50?`#22c55e`:D>20?`#eab308`:`#ef4444`,ne=Math.max(0,(e.label_weight||0)-(e.weight_used||0))+C,k=w===null?null:w-ne,A=k===null?null:Math.abs(k)<=50,j=async()=>{if(n!==null){d(!0);try{await a.updateSpoolWeight(e.id,Math.round(n)),_(!0),i?.(),setTimeout(()=>_(!1),3e3)}catch(e){console.error(`Failed to sync weight:`,e)}finally{d(!1)}}};return(0,S.jsxs)(`div`,{className:`flex flex-col items-center space-y-4 max-w-md`,children:[(0,S.jsxs)(`div`,{className:`flex items-start gap-5`,children:[(0,S.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,S.jsx)(b,{color:ee,isEmpty:!1,size:100,spool:e}),D!==null&&(0,S.jsxs)(`div`,{className:`absolute -bottom-2 -right-2 px-2 py-0.5 rounded-full text-xs font-bold text-white shadow-lg`,style:{backgroundColor:O},children:[D,`%`]})]}),(0,S.jsxs)(`div`,{className:`flex-1 min-w-0 pt-1`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(`h3`,{className:`text-lg font-semibold text-zinc-100`,children:te||l(`spoolbuddy.spool.unknownColor`)}),(0,S.jsxs)(`span`,{className:`text-xs font-mono text-zinc-500 shrink-0`,children:[`#`,e.id]})]}),(0,S.jsxs)(`p`,{className:`text-sm text-zinc-400`,children:[e.brand,` • `,e.material,e.subtype&&` ${e.subtype}`]}),T!==null&&(0,S.jsxs)(`div`,{className:`mt-3`,children:[(0,S.jsxs)(`div`,{className:`flex items-baseline gap-2`,children:[(0,S.jsxs)(`span`,{className:`text-3xl font-bold font-mono text-zinc-100`,children:[T,`g`]}),(0,S.jsxs)(`span`,{className:`text-sm text-zinc-500`,children:[`/ `,E,`g`]})]}),(0,S.jsx)(`p`,{className:`text-xs text-zinc-500 mt-0.5`,children:l(`spoolbuddy.spool.remaining`,`Remaining`)}),(0,S.jsx)(`div`,{className:`mt-2 max-w-xs`,children:(0,S.jsx)(`div`,{className:`h-2 bg-zinc-700 rounded-full overflow-hidden`,children:(0,S.jsx)(`div`,{className:`h-full rounded-full transition-all duration-500`,style:{width:`${D}%`,backgroundColor:O}})})})]})]})]}),(0,S.jsxs)(`div`,{className:`grid grid-cols-2 gap-x-6 gap-y-2 text-sm bg-zinc-800 rounded-lg p-4 w-full`,children:[(0,S.jsxs)(`div`,{className:`flex justify-between`,children:[(0,S.jsx)(`span`,{className:`text-zinc-500`,children:l(`spoolbuddy.dashboard.grossWeight`,`Gross weight`)}),(0,S.jsx)(`span`,{className:`font-mono text-zinc-300`,children:w===null?`—`:`${w}g`})]}),(0,S.jsxs)(`div`,{className:`flex justify-between`,children:[(0,S.jsx)(`span`,{className:`text-zinc-500`,children:l(`spoolbuddy.spool.coreWeight`,`Core`)}),(0,S.jsxs)(`span`,{className:`font-mono text-zinc-300`,children:[C,`g`]})]}),(0,S.jsxs)(`div`,{className:`flex justify-between`,children:[(0,S.jsx)(`span`,{className:`text-zinc-500`,children:l(`spoolbuddy.dashboard.spoolSize`,`Spool size`)}),(0,S.jsxs)(`span`,{className:`font-mono text-zinc-300`,children:[E,`g`]})]}),(0,S.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,S.jsx)(`span`,{className:`text-zinc-500`,children:l(`spoolbuddy.spool.scaleWeight`,`Scale`)}),w===null?(0,S.jsx)(`span`,{className:`text-zinc-500`,children:`—`}):(0,S.jsxs)(`span`,{className:`flex items-center gap-1 font-mono ${A?`text-green-500`:`text-yellow-500`}`,children:[w,`g`,A?(0,S.jsx)(f,{className:`w-3.5 h-3.5`}):(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(h,{className:`w-3.5 h-3.5`}),(0,S.jsx)(`button`,{onClick:j,className:`p-1 hover:bg-green-500/20 rounded transition-colors text-green-500`,title:l(`spoolbuddy.dashboard.syncWeight`,`Sync Weight`),children:(0,S.jsx)(m,{className:`w-4 h-4`})})]})]})]}),(0,S.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,S.jsx)(`span`,{className:`text-zinc-500`,children:l(`spoolbuddy.dashboard.tagId`,`Tag`)}),(0,S.jsx)(`span`,{className:`font-mono text-xs text-zinc-400 truncate max-w-[120px]`,title:e.tag_uid||``,children:e.tag_uid?e.tag_uid.slice(-8):`—`})]})]}),(0,S.jsxs)(`div`,{className:`flex gap-2 justify-center`,children:[o&&(0,S.jsx)(`button`,{onClick:s?void 0:o,disabled:!!s,className:`px-5 py-2.5 rounded-lg text-sm font-medium bg-green-600 text-white hover:bg-green-700 transition-colors min-h-[44px] disabled:opacity-50 disabled:cursor-not-allowed`,children:l(`spoolbuddy.modal.assignToAms`,`Assign to AMS`)}),c&&(0,S.jsxs)(`button`,{onClick:c,className:`px-5 py-2.5 rounded-lg text-sm font-medium bg-red-600/20 text-red-400 hover:bg-red-600/30 transition-colors min-h-[44px]`,children:[(0,S.jsx)(g,{className:`w-4 h-4 inline mr-1`}),l(`inventory.unassignSpool`)]}),(0,S.jsx)(`button`,{onClick:j,disabled:n===null||u,className:`px-5 py-2.5 rounded-lg text-sm font-medium transition-colors min-h-[44px] ${p?`bg-green-600/20 text-green-400`:o?`bg-zinc-700 text-zinc-300 hover:bg-zinc-600 disabled:opacity-40 disabled:cursor-not-allowed`:`bg-green-600 text-white hover:bg-green-700 disabled:opacity-40 disabled:cursor-not-allowed`}`,children:u?`...`:p?l(`spoolbuddy.dashboard.weightSynced`,`Synced!`):l(`spoolbuddy.dashboard.syncWeight`,`Sync Weight`)}),r&&(0,S.jsx)(`button`,{onClick:r,className:`px-5 py-2.5 rounded-lg text-sm font-medium bg-zinc-700 text-zinc-300 hover:bg-zinc-600 transition-colors min-h-[44px]`,children:l(`spoolbuddy.dashboard.close`,`Close`)})]})]})}function C({tagUid:e,scaleWeight:n,coreWeight:r,tagData:i,onLinkSpool:a,onAddToInventory:o,onClose:s}){let{t:c}=t(),l=r??i?.core_weight??250,u=n===null?null:Math.round(Math.max(0,n)),d=u===null?null:Math.round(Math.max(0,u-l));return(0,S.jsxs)(`div`,{className:`flex flex-col items-center text-center space-y-5`,children:[i?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(b,{color:y(i.rgba),isEmpty:!1,size:80,spool:i}),(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{className:`text-lg font-semibold text-zinc-100`,children:[i.brand,i.material,i.subtype].filter(Boolean).join(` `)}),i.color_name&&(0,S.jsx)(`p`,{className:`text-sm text-zinc-300 mt-0.5`,children:i.color_name}),(0,S.jsxs)(`p`,{className:`text-xs text-zinc-500 mt-1`,children:[c(`spoolbuddy.dashboard.newTag`,`New Tag Detected`),` · `,(0,S.jsx)(`span`,{className:`font-mono`,children:e})]})]})]}):(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`div`,{className:`w-20 h-20 rounded-2xl bg-green-500/15 flex items-center justify-center`,children:(0,S.jsx)(`svg`,{className:`w-10 h-10 text-green-500`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,children:(0,S.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,d:`M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A2 2 0 013 12V7a4 4 0 014-4z`})})}),(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h3`,{className:`text-lg font-semibold text-zinc-100`,children:c(`spoolbuddy.dashboard.newTag`,`New Tag Detected`)}),(0,S.jsx)(`p`,{className:`text-sm text-zinc-500 font-mono mt-1`,children:e})]})]}),u!==null&&(0,S.jsxs)(`div`,{className:`text-sm text-zinc-400`,children:[(0,S.jsxs)(`span`,{className:`font-mono font-semibold`,children:[u,`g`]}),` `,c(`spoolbuddy.dashboard.onScale`,`on scale`),d!==null&&d>0&&(0,S.jsxs)(`span`,{className:`text-zinc-500`,children:[` • ~`,d,`g filament`]})]}),(0,S.jsxs)(`div`,{className:`flex flex-wrap gap-2 justify-center`,children:[o&&(0,S.jsx)(`button`,{onClick:o,className:`px-5 py-2.5 rounded-lg text-sm font-medium bg-green-600 text-white hover:bg-green-700 transition-colors min-h-[44px]`,children:c(`spoolbuddy.modal.addToInventory`,`Add to Inventory`)}),a&&(0,S.jsxs)(`button`,{onClick:a,className:`px-5 py-2.5 rounded-lg text-sm font-medium bg-zinc-700 text-zinc-300 hover:bg-zinc-600 transition-colors min-h-[44px]`,children:[(0,S.jsx)(`svg`,{className:`w-4 h-4 inline-block mr-1.5 -mt-0.5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,children:(0,S.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,d:`M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1`})}),c(`inventory.assignSpool`,`Assign Spool`)]}),s&&(0,S.jsx)(`button`,{onClick:s,className:`px-5 py-2.5 rounded-lg text-sm font-medium bg-zinc-700 text-zinc-300 hover:bg-zinc-600 transition-colors min-h-[44px]`,children:c(`spoolbuddy.dashboard.close`,`Close`)})]})]})}function w({isOpen:e,onClose:n,tagId:r,untaggedSpools:i,onLink:a}){let{t:o}=t(),[s,c]=(0,x.useState)(null),l=(0,x.useCallback)(()=>{c(null),n()},[n]),u=(0,x.useCallback)(e=>{e.key===`Escape`&&l()},[l]);return(0,x.useEffect)(()=>(e&&(document.addEventListener(`keydown`,u),document.body.style.overflow=`hidden`),()=>{document.removeEventListener(`keydown`,u),document.body.style.overflow=``}),[e,u]),e?(0,S.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/70 animate-fade-in`,onClick:l,children:(0,S.jsxs)(`div`,{className:`bg-zinc-800 rounded-xl shadow-2xl w-full max-w-lg mx-4 animate-slide-up`,onClick:e=>e.stopPropagation(),children:[(0,S.jsxs)(`div`,{className:`flex items-center justify-between px-5 py-4 border-b border-zinc-700`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`h2`,{className:`text-base font-semibold text-zinc-100`,children:o(`spoolbuddy.dashboard.linkTagTitle`,`Link Tag to Spool`)}),(0,S.jsx)(`p`,{className:`text-sm text-zinc-500 font-mono`,children:r})]}),(0,S.jsx)(`button`,{onClick:l,className:`p-2 rounded-lg text-zinc-500 hover:text-zinc-300 hover:bg-zinc-700 transition-colors`,children:(0,S.jsx)(_,{className:`w-5 h-5`})})]}),(0,S.jsxs)(`div`,{className:`px-5 py-4 space-y-3 max-h-[400px] overflow-y-auto`,children:[(0,S.jsx)(`p`,{className:`text-sm text-zinc-400`,children:o(`spoolbuddy.dashboard.selectSpool`,`Select a spool to link this tag to:`)}),i.length===0?(0,S.jsx)(`div`,{className:`text-center py-8 text-zinc-500`,children:o(`spoolbuddy.dashboard.noUntagged`,`No spools without tags found`)}):(0,S.jsx)(`div`,{className:`space-y-2`,children:i.map(e=>(0,S.jsxs)(`button`,{type:`button`,onClick:()=>c(e),className:`w-full flex items-center gap-3 p-3 rounded-lg border-2 transition-all text-left ${s?.id===e.id?`border-green-500 bg-green-500/10`:`border-zinc-700 hover:border-green-500/50 hover:bg-zinc-700/50`}`,children:[(0,S.jsx)(b,{color:y(e.rgba),spool:e,isEmpty:!1,size:40}),(0,S.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(`div`,{className:`font-medium text-zinc-100 truncate`,children:v(e.color_name,e.rgba,e.color_name_is_synthesized)||o(`spoolbuddy.spool.unknownColor`)}),(0,S.jsxs)(`span`,{className:`text-[10px] font-mono text-zinc-500 shrink-0`,children:[`#`,e.id]})]}),(0,S.jsxs)(`div`,{className:`text-sm text-zinc-400 truncate`,children:[e.brand,` • `,e.material,e.subtype&&` ${e.subtype}`]})]}),(0,S.jsxs)(`div`,{className:`text-sm font-mono text-zinc-500`,children:[Math.max(0,e.label_weight-e.weight_used),`g`]})]},e.id))})]}),(0,S.jsxs)(`div`,{className:`flex justify-end gap-2 px-5 py-4 border-t border-zinc-700`,children:[(0,S.jsx)(`button`,{onClick:l,className:`px-4 py-2.5 rounded-lg text-sm font-medium bg-zinc-700 text-zinc-300 hover:bg-zinc-600 transition-colors min-h-[44px]`,children:o(`common.cancel`,`Cancel`)}),(0,S.jsx)(`button`,{onClick:()=>{s&&(a(s),c(null))},disabled:!s,className:`px-4 py-2.5 rounded-lg text-sm font-medium bg-green-600 text-white hover:bg-green-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors min-h-[44px]`,children:o(`spoolbuddy.dashboard.linkTag`,`Link Tag`)})]})]})}):null}function T(e){return e?e.replace(/[^0-9a-f]/gi,``).toUpperCase():``}function E(e,t){let n=T(e),r=T(t);return!n||!r?!1:n===r||n.endsWith(r)||r.endsWith(n)}var D=[`#00AE42`,`#FF6B35`,`#3B82F6`,`#EF4444`,`#A855F7`,`#FBBF24`,`#14B8A6`,`#EC4899`,`#F97316`,`#22C55E`];function O(){let{t:e}=t(),[n,r]=(0,x.useState)(0);(0,x.useEffect)(()=>{let e=setInterval(()=>{r(e=>(e+1)%D.length)},5e3);return()=>clearInterval(e)},[]);let i=D[n];return(0,S.jsxs)(`div`,{className:`flex flex-col items-center text-center`,children:[(0,S.jsxs)(`div`,{className:`relative mb-6 flex items-center justify-center`,style:{width:160,height:160},children:[(0,S.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center pointer-events-none`,children:[0,1].map(e=>(0,S.jsx)(`div`,{className:`absolute rounded-full border spoolbuddy-optimized-ping`,style:{width:80,height:80,borderColor:`${i}4D`,transition:`border-color 140ms linear`,animationDelay:`${e*.8}s`}},e))}),(0,S.jsxs)(`div`,{className:`relative overflow-hidden rounded-full`,children:[(0,S.jsx)(`div`,{className:`absolute inset-0 rounded-full opacity-30 spoolbuddy-spool-glow`,style:{background:`radial-gradient(circle, ${i} 0%, transparent 70%)`}}),(0,S.jsx)(`div`,{className:`relative`,style:{transition:`opacity 140ms linear`},children:(0,S.jsx)(b,{color:i,isEmpty:!1,size:100})})]})]}),(0,S.jsxs)(`div`,{className:`space-y-2`,children:[(0,S.jsx)(`p`,{className:`text-xl font-medium text-zinc-300`,children:e(`spoolbuddy.dashboard.readyToScan`,`Ready to scan`)}),(0,S.jsx)(`p`,{className:`text-sm text-zinc-500`,children:e(`spoolbuddy.dashboard.idleMessage`,`Place a spool on the scale to identify it`)})]}),(0,S.jsxs)(`div`,{className:`mt-6 flex items-center gap-2 text-sm text-zinc-600`,children:[(0,S.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,children:(0,S.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,d:`M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})}),(0,S.jsx)(`span`,{children:e(`spoolbuddy.dashboard.nfcHint`,`NFC tag will be read automatically`)})]})]})}function ne(){let{t:e}=t();return(0,S.jsxs)(`div`,{className:`flex flex-col items-center text-center`,children:[(0,S.jsx)(`div`,{className:`relative mb-6 flex items-center justify-center`,style:{width:160,height:160},children:(0,S.jsx)(`div`,{className:`w-24 h-24 rounded-full bg-zinc-800 flex items-center justify-center`,children:(0,S.jsx)(`svg`,{className:`w-12 h-12 text-zinc-600`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,children:(0,S.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`1.5`,d:`M18.364 5.636a9 9 0 010 12.728m0 0l-12.728-12.728m12.728 12.728L5.636 5.636m12.728 0a9 9 0 00-12.728 0m0 12.728a9 9 0 010-12.728`})})})}),(0,S.jsxs)(`div`,{className:`space-y-2`,children:[(0,S.jsx)(`p`,{className:`text-lg font-medium text-zinc-500`,children:e(`spoolbuddy.status.deviceOffline`,`Device Offline`)}),(0,S.jsx)(`p`,{className:`text-sm text-zinc-600`,children:e(`spoolbuddy.status.connectDisplay`,`Connect the SpoolBuddy display to scan spools`)})]}),(0,S.jsxs)(`div`,{className:`mt-6 flex items-center gap-2 text-xs text-zinc-600`,children:[(0,S.jsx)(`svg`,{className:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,children:(0,S.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,d:`M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.14 0M1.394 9.393c5.857-5.857 15.355-5.857 21.213 0`})}),(0,S.jsx)(`span`,{children:e(`spoolbuddy.status.waitingConnection`,`Waiting for device connection...`)})]})]})}function k(){let{sbState:e,selectedPrinterId:r}=s(),{t:a}=t(),{showToast:o}=p(),{data:f}=l({queryKey:[`spoolman-settings`],queryFn:n.getSpoolmanSettings,staleTime:300*1e3}),m=f?.spoolman_enabled===`true`&&!!f?.spoolman_url,{data:h=[],refetch:g}=l({queryKey:m?[`spoolman-inventory-spools`]:[`inventory-spools`],queryFn:()=>m?n.getSpoolmanInventorySpools(!1):n.getSpools(!1),enabled:f!==void 0}),{data:_=[]}=l({queryKey:[`spoolman-slot-assignments`],queryFn:()=>n.getSpoolmanSlotAssignments(),enabled:m,staleTime:3*1e3,refetchInterval:3*1e3,refetchIntervalInBackground:!1}),{data:v=[]}=l({queryKey:[`printers`],queryFn:()=>n.getPrinters()}),T=d({queries:v.map(e=>({queryKey:[`printerStatus`,e.id],queryFn:()=>n.getPrinterStatus(e.id),refetchInterval:1e4,select:e=>({connected:e?.connected,awaiting_plate_clear:e?.awaiting_plate_clear===!0})}))}),D=v.map((e,t)=>({printer:e,pending:T[t]?.data?.awaiting_plate_clear===!0})).filter(e=>e.pending),k=c(),A=u({mutationFn:e=>n.clearPlate(e),onSuccess:(e,t)=>{k.setQueryData([`printerStatus`,t],e=>e&&{...e,awaiting_plate_clear:!1}),o(a(`spoolbuddy.dashboard.plateClearedToast`,`Plate marked as cleared`),`success`)},onError:()=>{o(a(`spoolbuddy.dashboard.plateClearFailed`,`Could not mark plate as cleared`),`error`)}}),j=u({mutationFn:e=>n.unassignSpoolmanSlot(e),onSuccess:()=>{k.invalidateQueries({queryKey:[`spoolman-slot-assignments`]}),k.invalidateQueries({queryKey:[`spoolman-inventory-spools`]})},onError:()=>o(a(`inventory.unassignFailed`,`Failed to unassign spool`),`error`)}),[M,re]=(0,x.useState)(null),[N,P]=(0,x.useState)(null),[F,I]=(0,x.useState)(null),[L,R]=(0,x.useState)(null),[z,B]=(0,x.useState)(null),[ie,V]=(0,x.useState)(!1),[ae,oe]=(0,x.useState)(!1),[se,H]=(0,x.useState)(!1),[ce,le]=(0,x.useState)(!1),[U,W]=(0,x.useState)(null),G=e.matchedSpool?.tag_uid??e.unknownTagUid??null,K=e.unknownTagUid?e.unknownTrayUuid:null,q=e.unknownTagUid?e.unknownTagData:null,J=e.weight,Y=e.weightStable,X=(0,x.useRef)(null);J===null?X.current=null:(X.current===null||Math.abs(J-X.current)>=3||Y)&&(X.current=J);let Z=X.current,Q=(0,x.useMemo)(()=>{if(e.matchedSpool?.id){let t=h.find(t=>t.id===e.matchedSpool?.id);if(t)return t}if(!M)return null;let t=h.find(e=>E(e.tag_uid,M));if(t)return t;if(N){let e=h.find(e=>e.tray_uuid?.toUpperCase()===N);if(e)return e}return U||null},[M,N,e.matchedSpool,h,U]),$=(0,x.useMemo)(()=>{if(Q&&!U)return Q;let t=e.matchedSpool;return t?{id:t.id,tag_uid:t.tag_uid,material:t.material,subtype:t.subtype,color_name:t.color_name,color_name_is_synthesized:t.color_name_is_synthesized,rgba:t.rgba,brand:t.brand,label_weight:t.label_weight,core_weight:t.core_weight,weight_used:t.weight_used}:null},[Q,U,e.matchedSpool]),ue=m&&$!=null?_.some(e=>e.spoolman_spool_id===$.id):!1,de=(0,x.useMemo)(()=>m?h.filter(e=>!e.tag_uid&&!e.tray_uuid&&!e.archived_at):h.filter(e=>!e.tag_uid&&!e.archived_at),[h,m]);(0,x.useEffect)(()=>{if(G){let e=z===G;M!==null&&M!==G||!e&&M!==G?(re(G),P(K),I(q),R(null),B(null),W(null)):M===G&&(q&&I(q),K&&P(K)),!e&&J!==null&&Y&&R(Math.round(Math.max(0,J)))}else z&&(re(null),P(null),I(null),B(null),R(null),W(null))},[G,K,q,J,Y,M,z]);let fe=()=>{B(M)},pe=async e=>{if(M)try{if(m){let t=await n.linkTagToSpoolmanSpool(e.id,{tag_uid:M,tray_uuid:N||void 0});if(!t){o(a(`spoolman.linkFailed`),`error`);return}let{id:r,material:i,subtype:s,color_name:c,color_name_is_synthesized:l,rgba:u,brand:d,label_weight:f,core_weight:p,weight_used:m}=t;W({id:r,material:i,subtype:s,color_name:c,color_name_is_synthesized:l,rgba:u,brand:d,label_weight:f,core_weight:p,weight_used:m}),o(a(`spoolman.linkSuccess`),`success`)}else await n.linkTagToSpool(e.id,{tag_uid:M,...N?{tray_uuid:N}:{},tag_type:N?`bambulab`:`generic`,data_origin:`nfc_link`});g()}catch(e){console.error(`Failed to link tag:`,e);let t=e instanceof i&&e.status===409&&e.code===`tag_already_linked`?e.detail?.spool_id:void 0;o(typeof t==`number`?a(`inventory.tagAlreadyLinked`,{id:t}):a(`spoolman.linkFailed`),`error`)}finally{V(!1)}},me=async()=>{if(M){le(!0);try{let e=he??L,t=F,r={material:t?.material??`PLA`,subtype:t?.subtype??null,color_name:t?.color_name??null,rgba:t?.rgba??null,extra_colors:t?.extra_colors??null,effect_type:t?.effect_type??null,brand:t?.brand??null,label_weight:t?.label_weight??1e3,slicer_filament:t?.slicer_filament??null,slicer_filament_name:t?.slicer_filament_name??null,nozzle_temp_min:t?.nozzle_temp_min??null,nozzle_temp_max:t?.nozzle_temp_max??null};if(m){let t=await n.createSpoolmanInventorySpool({...r,weight_used:0,note:null,added_full:null,last_used:null,encode_time:null,tag_uid:null,tray_uuid:null,data_origin:null,tag_type:null,cost_per_kg:null,last_scale_weight:e===null?null:Math.round(e),last_weighed_at:e===null?null:new Date().toISOString(),category:null,low_stock_threshold_pct:null});await n.linkTagToSpoolmanSpool(t.id,{tag_uid:M,tray_uuid:N||void 0})}else await n.createSpool({...r,core_weight:t?.core_weight??250,core_weight_catalog_id:t?.core_weight_catalog_id??null,weight_used:0,note:null,added_full:null,last_used:null,encode_time:null,tag_uid:M,tray_uuid:N,data_origin:`spoolbuddy`,tag_type:N?`bambulab`:`generic`,cost_per_kg:null,last_scale_weight:e===null?null:Math.round(e),last_weighed_at:e===null?null:new Date().toISOString(),category:null,low_stock_threshold_pct:null,material_number:null})}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`Failed to quick-add spool:`,t),o(t||a(`spoolbuddy.errors.quickAddFailed`,`Failed to add spool`),`error`)}finally{H(!1),le(!1),g()}}},he=J!==null&&(G===M||G===null&&M!==null)?J:null,ge=h.length,_e=new Set(h.map(e=>e.material)).size,ve=new Set(h.filter(e=>e.brand).map(e=>e.brand)).size;return(0,S.jsxs)(`div`,{className:`h-full flex flex-col p-4`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-6 px-4 py-1.5 bg-zinc-800/50 rounded-xl border border-zinc-700/50 mb-3 shrink-0`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(`span`,{className:`text-xl font-bold text-zinc-100`,children:ge}),(0,S.jsx)(`span`,{className:`text-sm text-zinc-500`,children:a(`spoolbuddy.inventory.spools`,`Spools`)})]}),(0,S.jsx)(`div`,{className:`w-px h-5 bg-zinc-700`}),(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(`span`,{className:`text-xl font-bold text-zinc-100`,children:_e}),(0,S.jsx)(`span`,{className:`text-sm text-zinc-500`,children:a(`spoolbuddy.spool.material`,`Materials`)})]}),(0,S.jsx)(`div`,{className:`w-px h-5 bg-zinc-700`}),(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(`span`,{className:`text-xl font-bold text-zinc-100`,children:ve}),(0,S.jsx)(`span`,{className:`text-sm text-zinc-500`,children:a(`spoolbuddy.spool.brand`,`Brands`)})]})]}),(0,S.jsxs)(`div`,{className:`flex-1 flex gap-4 min-h-0`,children:[(0,S.jsxs)(`div`,{className:`w-5/12 flex flex-col min-h-0`,children:[(0,S.jsxs)(`div`,{className:`border border-dashed border-zinc-700/50 rounded-xl p-4`,children:[(0,S.jsx)(`h2`,{className:`text-sm font-semibold text-zinc-400 uppercase tracking-wide mb-3`,children:a(`spoolbuddy.dashboard.device`,`Device`)}),(0,S.jsxs)(`div`,{className:`space-y-2.5`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,S.jsx)(`div`,{className:`w-2.5 h-2.5 rounded-full ${e.deviceOnline?`bg-green-500`:`bg-red-500`}`}),(0,S.jsx)(`span`,{className:`text-base text-zinc-400`,children:e.deviceOnline?a(`spoolbuddy.status.online`,`Online`):a(`spoolbuddy.status.offline`,`Disconnected`)})]}),(0,S.jsxs)(`div`,{className:`flex items-center justify-between p-3 bg-zinc-800/50 rounded-lg`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(`svg`,{className:`w-4 h-4 ${e.deviceOnline?`text-green-500`:`text-zinc-500`}`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,children:(0,S.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,d:`M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3`})}),(0,S.jsx)(`span`,{className:`text-sm text-zinc-500`,children:a(`spoolbuddy.spool.scaleWeight`,`Scale`)})]}),(0,S.jsx)(`span`,{className:`text-lg font-mono font-semibold text-zinc-100`,children:Z===null?`—`:`${Math.abs(Z)<=20?0:Math.round(Math.max(0,Z))}g`})]}),(0,S.jsxs)(`div`,{className:`flex items-center justify-between p-3 bg-zinc-800/50 rounded-lg`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(`svg`,{className:`w-4 h-4 ${e.deviceOnline?`text-green-500`:`text-zinc-500`}`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,children:(0,S.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,d:`M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A2 2 0 013 12V7a4 4 0 014-4z`})}),(0,S.jsx)(`span`,{className:`text-sm text-zinc-500`,children:`NFC`})]}),(0,S.jsx)(`span`,{className:`text-sm font-medium ${G?`text-green-500`:`text-zinc-500`}`,children:G?a(`spoolbuddy.dashboard.tagDetected`,`Tag detected`):a(`spoolbuddy.dashboard.noTag`,`No tag`)})]})]})]}),v.length>0&&(0,S.jsxs)(`div`,{className:`mt-3 border border-dashed border-zinc-700/50 rounded-xl p-4`,children:[(0,S.jsx)(`h2`,{className:`text-sm font-semibold text-zinc-400 uppercase tracking-wide mb-2.5`,children:a(`spoolbuddy.dashboard.printers`,`Printers`)}),(0,S.jsx)(`div`,{className:`flex flex-wrap gap-2 overflow-hidden`,children:v.map((e,t)=>{let n=T[t]?.data?.connected??!1;return(0,S.jsxs)(`div`,{className:`flex items-center gap-1.5 px-2.5 py-1 bg-zinc-800/50 rounded-lg`,title:`${e.name} — ${n?`Online`:`Offline`}`,children:[(0,S.jsx)(`div`,{className:`w-2 h-2 rounded-full shrink-0 ${n?`bg-green-500`:`bg-zinc-600`}`}),(0,S.jsx)(`span`,{className:`text-xs text-zinc-400 truncate max-w-[100px]`,children:e.name})]},e.id)})}),D.length>0&&(0,S.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-2`,"data-testid":`plate-clear-section`,"aria-label":a(`spoolbuddy.dashboard.plateReadyLabel`,`Plates ready to clear`),children:D.map(({printer:e})=>(0,S.jsxs)(`button`,{type:`button`,onClick:()=>A.mutate(e.id),disabled:A.isPending,"data-testid":`plate-clear-button-${e.id}`,title:a(`spoolbuddy.dashboard.plateReady`,`Plate ready: {{name}}`,{name:e.name}),className:`flex items-center gap-1.5 px-2.5 py-1 rounded-lg bg-amber-500/10 hover:bg-amber-500/20 active:bg-amber-500/30 border border-amber-500/30 text-amber-200 transition-colors disabled:opacity-60 disabled:cursor-wait`,children:[(0,S.jsxs)(`svg`,{className:`w-3 h-3 shrink-0`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:[(0,S.jsx)(`path`,{d:`M12 9v4`}),(0,S.jsx)(`path`,{d:`M12 17h.01`}),(0,S.jsx)(`path`,{d:`M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z`})]}),(0,S.jsx)(`span`,{className:`text-xs truncate max-w-[100px]`,children:e.name}),(0,S.jsx)(`span`,{className:`text-xs opacity-70`,"aria-hidden":`true`,children:`·`}),(0,S.jsx)(`span`,{className:`text-xs font-medium`,children:a(`spoolbuddy.dashboard.plateClearAction`,`Clear`)})]},e.id))})]})]}),(0,S.jsx)(`div`,{className:`w-7/12 min-h-0`,children:(0,S.jsxs)(`div`,{className:`border border-dashed border-zinc-700/50 rounded-xl p-6 h-full flex flex-col`,children:[(0,S.jsx)(`h2`,{className:`text-sm font-semibold text-zinc-400 uppercase tracking-wide mb-4 shrink-0`,children:a(`spoolbuddy.dashboard.currentSpool`,`Current Spool`)}),(0,S.jsx)(`div`,{className:`flex-1 flex items-center justify-center min-h-0`,children:e.deviceOnline?(Q||e.matchedSpool)&&M&&z!==M?(0,S.jsx)(te,{spool:(()=>{let t=Q??e.matchedSpool;return{id:t.id,tag_uid:M,material:t.material,subtype:t.subtype,color_name:t.color_name,color_name_is_synthesized:t.color_name_is_synthesized,rgba:t.rgba,brand:t.brand,label_weight:t.label_weight,core_weight:t.core_weight,weight_used:t.weight_used}})(),scaleWeight:he??L,onSyncWeight:()=>g(),onAssignToAms:()=>oe(!0),isAssigned:ue,onUnassignFromAms:ue&&Q?.id!=null?()=>j.mutate(Q.id):void 0,onClose:fe}):G&&M&&!Q&&!e.matchedSpool&&z!==M?(0,S.jsx)(C,{tagUid:M,scaleWeight:he??L,tagData:F,onLinkSpool:de.length>0?()=>V(!0):void 0,onAddToInventory:()=>H(!0),onClose:fe}):(0,S.jsx)(O,{}):(0,S.jsx)(ne,{})})]})})]}),$&&!U&&M&&(0,S.jsx)(ee,{isOpen:ae,onClose:()=>oe(!1),spool:$,printerId:r,variant:`kiosk`,spoolmanMode:m}),M&&(0,S.jsx)(w,{isOpen:ie,onClose:()=>V(!1),tagId:M,untaggedSpools:de,onLink:pe}),se&&M&&(0,S.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/60`,children:(0,S.jsxs)(`div`,{className:`bg-zinc-800 rounded-2xl p-6 mx-4 max-w-sm w-full border border-zinc-700`,children:[(0,S.jsx)(`h3`,{className:`text-lg font-semibold text-zinc-100 mb-3`,children:a(`spoolbuddy.modal.addToInventory`,`Add to Inventory`)}),F?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`p`,{className:`text-sm text-zinc-400 mb-3`,children:a(`spoolbuddy.modal.quickAddFromTag`,`Adds this spool with the details read from its Bambu tag. You can edit them later in Bambuddy.`)}),(0,S.jsxs)(`div`,{className:`flex items-center gap-3 p-3 bg-zinc-900/60 border border-zinc-700 rounded-lg mb-1`,children:[(0,S.jsx)(b,{color:y(F.rgba),isEmpty:!1,size:40,spool:F}),(0,S.jsxs)(`div`,{className:`min-w-0`,children:[(0,S.jsx)(`p`,{className:`text-sm font-medium text-zinc-100 truncate`,children:[F.brand,F.material,F.subtype].filter(Boolean).join(` `)}),(0,S.jsx)(`p`,{className:`text-xs text-zinc-400 truncate`,children:[F.color_name,`${F.label_weight} g`,F.diameter?`${F.diameter} mm`:null].filter(Boolean).join(` · `)})]})]})]}):(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`div`,{className:`flex gap-2.5 p-3 bg-amber-500/10 border border-amber-500/20 rounded-lg mb-4`,children:[(0,S.jsx)(`svg`,{className:`w-5 h-5 text-amber-500 shrink-0 mt-0.5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,children:(0,S.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,d:`M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})}),(0,S.jsx)(`p`,{className:`text-sm text-amber-200/80`,children:a(`spoolbuddy.modal.quickAddHint`,`For best results, add the spool in the Bambuddy web interface first (with material, color, brand), then use "Assign Spool" here to assign the NFC tag.`)})]}),(0,S.jsx)(`p`,{className:`text-sm text-zinc-400 mb-1`,children:a(`spoolbuddy.modal.quickAddDesc`,`This will create a basic PLA spool entry with this NFC tag. You can edit the details later in Bambuddy.`)})]}),(0,S.jsx)(`p`,{className:`text-xs text-zinc-500 font-mono mb-5`,children:M}),(0,S.jsxs)(`div`,{className:`flex gap-3`,children:[(0,S.jsx)(`button`,{onClick:()=>H(!1),className:`flex-1 px-4 py-2.5 rounded-lg text-sm font-medium bg-zinc-700 text-zinc-300 hover:bg-zinc-600 transition-colors min-h-[44px]`,children:a(`common.cancel`,`Cancel`)}),(0,S.jsx)(`button`,{onClick:me,disabled:ce,className:`flex-1 px-4 py-2.5 rounded-lg text-sm font-medium bg-green-600 text-white hover:bg-green-700 disabled:opacity-50 transition-colors min-h-[44px]`,children:ce?a(`common.saving`,`Saving...`):F?a(`common.add`,`Add`):a(`spoolbuddy.modal.addAnyway`,`Add Anyway`)})]})]})})]})}export{k as SpoolBuddyDashboard};