| 1 |
- import{i as e}from"./chunk-aKtaBQYM.js";import{C as t,D as n,a as r,w as i}from"./client-BdOyoZJz.js";import{t as a}from"./react-dom-xhkz5--P.js";import{n as o}from"./QueryClientProvider-Clbyr4Jg.js";import{t as s}from"./useQuery-CCy0EwsM.js";import{t as c}from"./useMutation-qh3Iyscy.js";import{t as l}from"./createLucideIcon-Yo2YoYjm.js";import{a as u}from"./info-DcT0QU8O.js";import{n as d}from"./ToastContext-VFOrCCoA.js";import{t as f}from"./ellipsis-vertical-So0E77JK.js";import{t as p}from"./loader-circle-CB4leTZa.js";import{t as m}from"./package-D9xR0eOt.js";import{t as h}from"./pen-line-DYnjxVtS.js";import{t as g}from"./triangle-alert-gIik0G2C.js";import{t as _}from"./x-Dctff5l9.js";import{t as v}from"./Button-pwVKPiYn.js";import{An as y,At as b,Cn as x,I as S,Ln as C,Mn as w,On as T,Vn as E,Zt as D,_t as O,at as k,cn as A,kt as j,un as ee,wn as M,yn as N,yt as P}from"./index-BoVbGTav.js";var F=l(`folder-tree`,[[`path`,{d:`M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z`,key:`hod4my`}],[`path`,{d:`M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z`,key:`w4yl2u`}],[`path`,{d:`M3 5a2 2 0 0 0 2 2h3`,key:`f2jnh7`}],[`path`,{d:`M3 3v13a2 2 0 0 0 2 2h3`,key:`k8epm1`}]]),I=l(`list-todo`,[[`path`,{d:`M13 5h8`,key:`a7qcls`}],[`path`,{d:`M13 12h8`,key:`h98zly`}],[`path`,{d:`M13 19h8`,key:`c3s6r1`}],[`path`,{d:`m3 17 2 2 4-4`,key:`1jhpwq`}],[`rect`,{x:`3`,y:`4`,width:`6`,height:`6`,rx:`1`,key:`cif1o7`}]]),L=e(n(),1),R=e(a(),1),z=t(),B=[`#ef4444`,`#f97316`,`#eab308`,`#22c55e`,`#06b6d4`,`#3b82f6`,`#8b5cf6`,`#ec4899`,`#6b7280`];function V({project:e,onClose:t,onSave:n,isLoading:i,currencySymbol:a,t:c}){let[l,u]=(0,L.useState)(e?.name||``),[d,f]=(0,L.useState)(e?.description||``),[m,h]=(0,L.useState)(e?.color||B[0]),[g,y]=(0,L.useState)(e?.target_count?.toString()||``),[b,x]=(0,L.useState)(e?.target_parts_count?.toString()||``),[C,w]=(0,L.useState)(e?.target_sets?.toString()||``),[T,E]=(0,L.useState)(e?.status||`active`),[D,O]=(0,L.useState)(e?.tags||``),[k,A]=(0,L.useState)(e?.due_date?.split(`T`)[0]||``),[M,N]=(0,L.useState)(e?.priority||`normal`),[P,F]=(0,L.useState)(e?.budget?.toString()||``),[I,R]=(0,L.useState)(e?.url||``),[V,H]=(0,L.useState)(null),[U,W]=(0,L.useState)(e?.parent_id??null),G=o(),{data:te}=s({queryKey:[`projects`,void 0],queryFn:()=>r.getProjects()}),K=S(te||[],e?.id),[q,J]=(0,L.useState)(e?.cover_image_filename||null),Y=(0,L.useRef)(null),[X,Z]=(0,L.useState)(!1),[Q,$]=(0,L.useState)(0);return(0,z.jsx)(`div`,{className:`fixed inset-0 bg-black/70 flex items-center justify-center z-50 p-4`,children:(0,z.jsxs)(`div`,{className:`bg-bambu-dark-secondary rounded-lg w-full max-w-md border border-bambu-dark-tertiary flex flex-col max-h-[calc(100vh-2rem)]`,children:[(0,z.jsx)(`div`,{className:`p-4 border-b border-bambu-dark-tertiary flex-shrink-0`,children:(0,z.jsx)(`h2`,{className:`text-lg font-semibold text-white`,children:c(e?`projects.editProject`:`projects.newProject`)})}),(0,z.jsxs)(`form`,{onSubmit:t=>{t.preventDefault();let r=I.trim();if(r&&!/^https?:\/\//i.test(r)){H(c(`projects.urlInvalid`));return}H(null),n({name:l.trim(),description:d.trim()||void 0,color:m,target_count:g?parseInt(g,10):void 0,target_parts_count:b?parseInt(b,10):void 0,target_sets:e?C?parseInt(C,10):null:C?parseInt(C,10):void 0,tags:e?D.trim()||null:D.trim()||void 0,due_date:e?k||null:k||void 0,priority:M,budget:P.trim()?parseFloat(P):null,url:e?r||null:r||void 0,parent_id:e?U??0:U??void 0,...e&&{status:T}})},className:`flex flex-col flex-1 min-h-0`,children:[(0,z.jsxs)(`div`,{className:`p-4 space-y-4 overflow-y-auto flex-1`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`common.name`)}),(0,z.jsx)(`input`,{type:`text`,value:l,onChange:e=>u(e.target.value),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white placeholder-bambu-gray focus:outline-none focus:border-bambu-green`,placeholder:c(`projects.namePlaceholder`),required:!0})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`common.description`)}),(0,z.jsx)(`textarea`,{value:d,onChange:e=>f(e.target.value),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white placeholder-bambu-gray focus:outline-none focus:border-bambu-green resize-none`,placeholder:c(`projects.descriptionPlaceholder`),rows:2})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projects.urlLabel`)}),(0,z.jsx)(`input`,{type:`url`,value:I,onChange:e=>{R(e.target.value),V&&H(null)},className:`w-full bg-bambu-dark border rounded px-3 py-2 text-white placeholder-bambu-gray focus:outline-none ${V?`border-red-500 focus:border-red-500`:`border-bambu-dark-tertiary focus:border-bambu-green`}`,placeholder:c(`projects.urlPlaceholder`),maxLength:2048}),V&&(0,z.jsx)(`p`,{className:`text-xs text-red-600 dark:text-red-400 mt-1`,children:V})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projects.parentLabel`)}),(0,z.jsxs)(`select`,{value:U??``,onChange:e=>W(e.target.value?parseInt(e.target.value,10):null),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white focus:outline-none focus:border-bambu-green`,children:[(0,z.jsx)(`option`,{value:``,children:c(`projects.parentNone`)}),K.map(e=>(0,z.jsx)(`option`,{value:e.id,children:e.name},e.id))]}),(0,z.jsx)(`p`,{className:`text-xs text-bambu-gray mt-1`,children:c(`projects.parentHint`)})]}),e&&(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projects.coverImageLabel`)}),(0,z.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,z.jsx)(`div`,{className:`w-20 h-20 rounded bg-bambu-dark border border-bambu-dark-tertiary overflow-hidden flex items-center justify-center flex-shrink-0`,children:q?(0,z.jsx)(`img`,{src:r.getProjectCoverImageUrl(e.id,Q),alt:c(`projects.coverImageAlt`),className:`w-full h-full object-cover`}):(0,z.jsx)(ee,{className:`w-6 h-6 text-bambu-gray`})}),(0,z.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,z.jsx)(`input`,{ref:Y,type:`file`,accept:`image/jpeg,image/png,image/gif,image/webp`,onChange:async t=>{let n=t.target.files?.[0];if(!(!n||!e)){Z(!0);try{J((await r.uploadProjectCoverImage(e.id,n)).filename),$(e=>e+1),G.invalidateQueries({queryKey:[`projects`]})}catch{}finally{Z(!1),Y.current&&(Y.current.value=``)}}},className:`hidden`}),(0,z.jsxs)(v,{type:`button`,variant:`secondary`,onClick:()=>Y.current?.click(),disabled:X,children:[X?(0,z.jsx)(p,{className:`w-4 h-4 animate-spin`}):(0,z.jsx)(j,{className:`w-4 h-4 mr-1`}),c(q?`projects.coverImageReplace`:`projects.coverImageUpload`)]}),q&&(0,z.jsxs)(v,{type:`button`,variant:`secondary`,onClick:async()=>{if(e){Z(!0);try{await r.deleteProjectCoverImage(e.id),J(null),$(e=>e+1),G.invalidateQueries({queryKey:[`projects`]})}finally{Z(!1)}}},disabled:X,children:[(0,z.jsx)(_,{className:`w-4 h-4 mr-1`}),c(`projects.coverImageRemove`)]})]})]})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projects.color`)}),(0,z.jsx)(`div`,{className:`flex gap-2 flex-wrap`,children:B.map(e=>(0,z.jsx)(`button`,{type:`button`,onClick:()=>h(e),className:`w-8 h-8 rounded-full transition-transform ${m===e?`ring-2 ring-white ring-offset-2 ring-offset-bambu-dark-secondary scale-110`:``}`,style:{backgroundColor:e}},e))})]}),(0,z.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projects.targetPlates`)}),(0,z.jsx)(`input`,{type:`number`,value:g,onChange:e=>y(e.target.value),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white placeholder-bambu-gray focus:outline-none focus:border-bambu-green`,placeholder:c(`projects.targetPlatesPlaceholder`),min:`1`}),(0,z.jsx)(`p`,{className:`text-xs text-bambu-gray mt-1`,children:c(`projects.targetPlatesHelp`)})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projects.targetParts`)}),(0,z.jsx)(`input`,{type:`number`,value:b,onChange:e=>x(e.target.value),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white placeholder-bambu-gray focus:outline-none focus:border-bambu-green`,placeholder:c(`projects.targetPartsPlaceholder`),min:`1`}),(0,z.jsx)(`p`,{className:`text-xs text-bambu-gray mt-1`,children:c(`projects.targetPartsHelp`)})]})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projects.targetSets`)}),(0,z.jsx)(`input`,{type:`number`,value:C,onChange:e=>w(e.target.value),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white placeholder-bambu-gray focus:outline-none focus:border-bambu-green`,placeholder:c(`projects.targetSetsPlaceholder`),min:`1`}),(0,z.jsx)(`p`,{className:`text-xs text-bambu-gray mt-1`,children:c(`projects.targetSetsHelp`)})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projects.tagsLabel`)}),(0,z.jsx)(`input`,{type:`text`,value:D,onChange:e=>O(e.target.value),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white placeholder-bambu-gray focus:outline-none focus:border-bambu-green`,placeholder:c(`projects.tagsPlaceholder`)})]}),(0,z.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projects.dueDate`)}),(0,z.jsx)(`input`,{type:`date`,value:k,onChange:e=>A(e.target.value),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white focus:outline-none focus:border-bambu-green`})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projects.priority`)}),(0,z.jsxs)(`select`,{value:M,onChange:e=>N(e.target.value),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white focus:outline-none focus:border-bambu-green`,children:[(0,z.jsx)(`option`,{value:`low`,children:c(`projects.priorityLow`)}),(0,z.jsx)(`option`,{value:`normal`,children:c(`projects.priorityNormal`)}),(0,z.jsx)(`option`,{value:`high`,children:c(`projects.priorityHigh`)}),(0,z.jsx)(`option`,{value:`urgent`,children:c(`projects.priorityUrgent`)})]})]})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`projectDetail.cost.budget`)}),(0,z.jsxs)(`div`,{className:`relative`,children:[(0,z.jsx)(`span`,{className:`absolute left-3 top-1/2 -translate-y-1/2 text-bambu-gray pointer-events-none`,children:a}),(0,z.jsx)(`input`,{type:`number`,step:`0.01`,min:`0`,value:P,onChange:e=>F(e.target.value),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded pl-8 pr-3 py-2 text-white placeholder-bambu-gray focus:outline-none focus:border-bambu-green`,placeholder:`0.00`})]})]}),e&&(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`label`,{className:`block text-sm font-medium text-white mb-1`,children:c(`common.status`)}),(0,z.jsxs)(`select`,{value:T,onChange:e=>E(e.target.value),className:`w-full bg-bambu-dark border border-bambu-dark-tertiary rounded px-3 py-2 text-white focus:outline-none focus:border-bambu-green`,children:[(0,z.jsx)(`option`,{value:`active`,children:c(`projects.statusActive`)}),(0,z.jsx)(`option`,{value:`completed`,children:c(`projects.statusCompleted`)}),(0,z.jsx)(`option`,{value:`archived`,children:c(`projects.statusArchived`)})]})]})]}),(0,z.jsxs)(`div`,{className:`flex justify-end gap-2 p-4 border-t border-bambu-dark-tertiary flex-shrink-0`,children:[(0,z.jsx)(v,{type:`button`,variant:`secondary`,onClick:t,children:c(`common.cancel`)}),(0,z.jsx)(v,{type:`submit`,disabled:!l.trim()||i,children:i?(0,z.jsx)(p,{className:`w-4 h-4 animate-spin`}):c(e?`common.save`:`projects.create`)})]})]})]})})}function H({projectId:e,altText:t}){let n=(0,L.useRef)(null),[i,a]=(0,L.useState)(!1),[o,s]=(0,L.useState)(null);return(0,z.jsxs)(`div`,{ref:n,className:`relative flex-shrink-0`,onMouseEnter:()=>{if(!n.current)return;let e=n.current.getBoundingClientRect(),t=window.innerWidth,r=window.innerHeight,i=e.right+8;i+384>t-8&&(i=e.left-384-8);let o=e.top;o+384>r-8&&(o=r-384-8),o<8&&(o=8),s({left:i,top:o}),a(!0)},onMouseLeave:()=>a(!1),onClick:e=>e.stopPropagation(),children:[(0,z.jsx)(`div`,{className:`w-10 h-10 rounded-lg overflow-hidden bg-bambu-dark border border-bambu-dark-tertiary`,children:(0,z.jsx)(`img`,{src:r.getProjectCoverImageUrl(e),alt:t,className:`w-full h-full object-cover`,loading:`lazy`})}),i&&o&&(0,R.createPortal)((0,z.jsx)(`div`,{className:`fixed z-[100] w-96 h-96 rounded-lg overflow-hidden border border-bambu-dark-tertiary shadow-2xl bg-bambu-dark pointer-events-none`,style:{left:o.left,top:o.top},"aria-hidden":`true`,children:(0,z.jsx)(`img`,{src:r.getProjectCoverImageUrl(e),alt:``,className:`w-full h-full object-contain`,loading:`lazy`})}),document.body)]})}function U({project:e,parentName:t,onClick:n,onEdit:i,onDelete:a,hasPermission:o,t:s}){let c=e.target_count?Math.round(e.archive_count/e.target_count*100):0,l=e.target_parts_count?Math.round(e.completed_count/e.target_parts_count*100):0,u=e.status===`completed`,d=e.status===`archived`,[p,_]=(0,L.useState)(!1),v=u?{icon:y,color:`text-bambu-green`,bg:`bg-bambu-green/10`}:d?{icon:C,color:`text-bambu-gray`,bg:`bg-bambu-gray/10`}:e.queue_count>0?{icon:T,color:`text-blue-600 dark:text-blue-400`,bg:`bg-blue-50 dark:bg-blue-400/10`}:{icon:N,color:`text-bambu-gray`,bg:`bg-bambu-gray/10`};return(0,z.jsxs)(`div`,{className:`group relative bg-gradient-to-br from-bambu-card to-bambu-dark-secondary rounded-xl border border-bambu-dark-tertiary hover:border-bambu-green/50 hover:shadow-lg hover:shadow-bambu-green/5 transition-all duration-300 cursor-pointer overflow-hidden`,onClick:n,children:[(0,z.jsx)(`div`,{className:`absolute top-0 left-0 w-1.5 h-full`,style:{backgroundColor:e.color||`#6b7280`,boxShadow:`0 0 12px ${e.color||`#6b7280`}40`}}),(0,z.jsxs)(`div`,{className:`p-5 pl-6`,children:[(0,z.jsxs)(`div`,{className:`flex items-start justify-between mb-4`,children:[(0,z.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0 flex-1`,children:[e.cover_image_filename?(0,z.jsx)(H,{projectId:e.id,altText:s(`projects.coverImageAlt`)}):(0,z.jsx)(`div`,{className:`p-2 rounded-lg ${v.bg} flex-shrink-0`,children:(0,z.jsx)(v.icon,{className:`w-5 h-5 ${v.color}`})}),(0,z.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,z.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,z.jsx)(`h3`,{className:`font-semibold text-white truncate`,children:e.name}),e.url&&(0,z.jsx)(`a`,{href:e.url,target:`_blank`,rel:`noopener noreferrer`,onClick:e=>e.stopPropagation(),title:e.url,"aria-label":s(`projects.openExternalUrl`),className:`inline-flex items-center justify-center w-6 h-6 rounded bg-bambu-dark border border-bambu-dark-tertiary text-bambu-green hover:bg-bambu-green/10 hover:border-bambu-green transition-colors flex-shrink-0`,children:(0,z.jsx)(x,{className:`w-3.5 h-3.5`})}),e.target_parts_count?(0,z.jsxs)(`span`,{className:`text-xs px-2 py-0.5 rounded-full whitespace-nowrap font-medium ${l>=100?`bg-bambu-green/20 text-bambu-green`:`bg-bambu-dark text-bambu-gray`}`,children:[e.completed_count,`/`,e.target_parts_count,` `,s(`projects.parts`)]}):e.target_count?(0,z.jsxs)(`span`,{className:`text-xs px-2 py-0.5 rounded-full whitespace-nowrap font-medium ${c>=100?`bg-bambu-green/20 text-bambu-green`:`bg-bambu-dark text-bambu-gray`}`,children:[e.archive_count,`/`,e.target_count,` `,s(`projects.plates`)]}):e.completed_count>0?(0,z.jsxs)(`span`,{className:`text-xs px-2 py-0.5 rounded-full whitespace-nowrap font-medium bg-bambu-dark text-bambu-gray`,children:[e.completed_count,` `,s(`projects.parts`)]}):null,u&&(0,z.jsx)(`span`,{className:`text-xs bg-bambu-green/20 text-bambu-green px-2 py-0.5 rounded-full whitespace-nowrap`,children:s(`projects.done`)}),d&&(0,z.jsx)(`span`,{className:`text-xs bg-bambu-gray/20 text-bambu-gray px-2 py-0.5 rounded-full whitespace-nowrap`,children:s(`projects.statusArchived`)}),e.child_count>0&&(0,z.jsxs)(`span`,{className:`text-xs bg-bambu-dark text-bambu-gray px-2 py-0.5 rounded-full whitespace-nowrap inline-flex items-center gap-1`,title:s(`projects.subProjectCount`,{count:e.child_count}),children:[(0,z.jsx)(F,{className:`w-3 h-3`}),e.child_count]})]}),t&&(0,z.jsxs)(`p`,{className:`text-xs text-bambu-gray mt-1 flex items-center gap-1`,children:[(0,z.jsx)(A,{className:`w-3 h-3 flex-shrink-0`}),(0,z.jsx)(`span`,{className:`truncate`,children:s(`projects.partOf`,{name:t})})]}),e.description&&(0,z.jsx)(`p`,{className:`text-sm text-bambu-gray/70 mt-1 line-clamp-1`,children:e.description}),e.archives&&e.archives.length>0&&(()=>{let t=e.archives.map(e=>e.filament_type).filter(Boolean).flatMap(e=>e.split(`,`).map(e=>e.trim())).filter(Boolean),n=[...new Set(t)],r=e.archives.map(e=>e.filament_color).filter(Boolean).flatMap(e=>e.split(`,`).map(e=>e.trim())).filter(e=>e.startsWith(`#`)||/^[0-9A-Fa-f]{6}$/.test(e)),i=[...new Set(r)];return n.length===0&&i.length===0?null:(0,z.jsxs)(`div`,{className:`flex items-center gap-2 mt-1.5`,children:[n.slice(0,3).map(e=>(0,z.jsx)(`span`,{className:`text-[10px] px-1.5 py-0.5 bg-bambu-dark text-bambu-gray rounded`,children:e},e)),i.length>0&&(0,z.jsxs)(`div`,{className:`flex items-center gap-0.5`,children:[i.slice(0,5).map(e=>(0,z.jsx)(`div`,{className:`w-3 h-3 rounded-full border border-black/20`,style:{backgroundColor:e.startsWith(`#`)?e:`#${e}`},title:e},e)),i.length>5&&(0,z.jsxs)(`span`,{className:`text-[10px] text-bambu-gray ml-0.5`,children:[`+`,i.length-5]})]})]})})()]})]}),(0,z.jsxs)(`div`,{className:`relative`,onClick:e=>e.stopPropagation(),children:[(0,z.jsx)(`button`,{className:`p-1.5 rounded-lg hover:bg-bambu-dark text-bambu-gray hover:text-white transition-colors can-hover:opacity-0 group-hover:opacity-100 focus-visible:opacity-100`,onClick:()=>_(!p),children:(0,z.jsx)(f,{className:`w-4 h-4`})}),p&&(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`div`,{className:`fixed inset-0 z-10`,onClick:()=>_(!1)}),(0,z.jsxs)(`div`,{className:`absolute right-0 top-8 z-20 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg shadow-xl py-1 min-w-[120px]`,children:[(0,z.jsxs)(`button`,{className:`w-full px-3 py-2 text-left text-sm flex items-center gap-2 ${o(`projects:update`)?`text-white hover:bg-bambu-dark`:`text-bambu-gray cursor-not-allowed`}`,onClick:()=>{o(`projects:update`)&&(i(),_(!1))},disabled:!o(`projects:update`),title:o(`projects:update`)?void 0:s(`projects.noEditPermission`),children:[(0,z.jsx)(h,{className:`w-4 h-4`}),s(`common.edit`)]}),(0,z.jsxs)(`button`,{className:`w-full px-3 py-2 text-left text-sm flex items-center gap-2 ${o(`projects:delete`)?`text-red-600 dark:text-red-400 hover:bg-bambu-dark`:`text-bambu-gray cursor-not-allowed`}`,onClick:()=>{o(`projects:delete`)&&(a(),_(!1))},disabled:!o(`projects:delete`),title:o(`projects:delete`)?void 0:s(`projects.noDeletePermission`),children:[(0,z.jsx)(b,{className:`w-4 h-4`}),s(`common.delete`)]})]})]})]})]}),(0,z.jsx)(`div`,{className:`mb-4`,children:e.target_count||e.target_parts_count?(0,z.jsxs)(`div`,{className:`space-y-3`,children:[e.target_count&&(0,z.jsxs)(`div`,{children:[(0,z.jsxs)(`div`,{className:`flex items-center justify-between text-xs mb-1`,children:[(0,z.jsx)(`span`,{className:`text-bambu-gray`,children:s(`projects.plates`)}),(0,z.jsxs)(`span`,{className:c>=100?`text-bambu-green font-medium`:`text-white`,children:[e.archive_count,` / `,e.target_count]})]}),(0,z.jsx)(`div`,{className:`h-2 bg-bambu-dark/80 rounded-full overflow-hidden backdrop-blur-sm`,children:(0,z.jsx)(`div`,{className:`h-full transition-all duration-500 ease-out rounded-full relative`,style:{width:`${Math.min(c,100)}%`,background:c>=100?`linear-gradient(90deg, #22c55e, #4ade80)`:`linear-gradient(90deg, ${e.color||`#6b7280`}, ${e.color||`#6b7280`}cc)`,boxShadow:`0 0 8px ${c>=100?`#22c55e`:e.color||`#6b7280`}60`}})})]}),e.target_parts_count&&(0,z.jsxs)(`div`,{children:[(0,z.jsxs)(`div`,{className:`flex items-center justify-between text-xs mb-1`,children:[(0,z.jsx)(`span`,{className:`text-bambu-gray`,children:s(`projects.parts`)}),(0,z.jsxs)(`span`,{className:l>=100?`text-bambu-green font-medium`:`text-white`,children:[e.completed_count,` / `,e.target_parts_count]})]}),(0,z.jsx)(`div`,{className:`h-2 bg-bambu-dark/80 rounded-full overflow-hidden backdrop-blur-sm`,children:(0,z.jsx)(`div`,{className:`h-full transition-all duration-500 ease-out rounded-full relative`,style:{width:`${Math.min(l,100)}%`,background:l>=100?`linear-gradient(90deg, #22c55e, #4ade80)`:`linear-gradient(90deg, ${e.color||`#6b7280`}, ${e.color||`#6b7280`}cc)`,boxShadow:`0 0 8px ${l>=100?`#22c55e`:e.color||`#6b7280`}60`}})})]}),e.failed_count>0&&(0,z.jsxs)(`div`,{className:`text-xs text-red-600 dark:text-red-400`,children:[e.failed_count,` `,s(`projects.failed`)]})]}):e.completed_count>0||e.failed_count>0?(0,z.jsxs)(`div`,{className:`flex items-center gap-4 text-xs`,children:[e.completed_count>0&&(0,z.jsxs)(`div`,{className:`flex items-center gap-1.5 text-bambu-gray`,children:[(0,z.jsx)(C,{className:`w-3.5 h-3.5`}),(0,z.jsxs)(`span`,{children:[e.completed_count,` `,s(`projects.completed`)]})]}),e.failed_count>0&&(0,z.jsxs)(`div`,{className:`flex items-center gap-1.5 text-red-600 dark:text-red-400`,children:[(0,z.jsx)(g,{className:`w-3.5 h-3.5`}),(0,z.jsxs)(`span`,{children:[e.failed_count,` `,s(`projects.failed`)]})]}),e.queue_count>0&&(0,z.jsxs)(`div`,{className:`flex items-center gap-1.5 text-blue-600 dark:text-blue-400`,children:[(0,z.jsx)(T,{className:`w-3.5 h-3.5`}),(0,z.jsxs)(`span`,{children:[e.queue_count,` `,s(`projects.inQueue`)]})]})]}):(0,z.jsx)(`div`,{className:`text-xs text-bambu-gray/60 italic`,children:s(`projects.noPrintsYet`)})}),e.archives&&e.archives.length>0&&(0,z.jsxs)(`div`,{className:`mb-4`,children:[(0,z.jsx)(`div`,{className:`grid grid-cols-4 gap-1.5`,children:e.archives.slice(0,4).map(e=>(0,z.jsxs)(`div`,{className:`relative aspect-square rounded-lg bg-bambu-dark overflow-hidden border border-bambu-dark-tertiary`,title:e.print_name||`Unknown`,children:[e.thumbnail_path?(0,z.jsx)(`img`,{src:r.getArchiveThumbnail(e.id),alt:e.print_name||``,className:`w-full h-full object-cover`}):(0,z.jsx)(`div`,{className:`w-full h-full flex items-center justify-center text-bambu-gray/50`,children:(0,z.jsx)(m,{className:`w-6 h-6`})}),e.status===`failed`&&(0,z.jsx)(`div`,{className:`absolute inset-0 bg-red-500/40 flex items-center justify-center`,children:(0,z.jsx)(g,{className:`w-4 h-4 text-white`})})]},e.id))}),e.archive_count>4&&(0,z.jsx)(`p`,{className:`text-xs text-bambu-gray mt-1.5 text-center`,children:s(`common.more`,{count:e.archive_count-4})})]}),(0,z.jsxs)(`div`,{className:`flex items-center justify-between pt-3 border-t border-bambu-dark-tertiary`,children:[(0,z.jsxs)(`div`,{className:`flex items-center gap-4 text-xs text-bambu-gray`,children:[(0,z.jsxs)(`div`,{className:`flex items-center gap-1.5`,title:s(`projects.printJobs`),children:[(0,z.jsx)(A,{className:`w-3.5 h-3.5 text-blue-600 dark:text-blue-400`}),(0,z.jsxs)(`span`,{children:[e.archive_count,` `,s(`projects.plates`)]})]}),(0,z.jsxs)(`div`,{className:`flex items-center gap-1.5`,title:s(`projects.partsPrinted`),children:[(0,z.jsx)(m,{className:`w-3.5 h-3.5 text-bambu-green`}),(0,z.jsxs)(`span`,{children:[e.completed_count,` `,s(`projects.parts`)]})]}),e.failed_count>0&&(0,z.jsxs)(`div`,{className:`flex items-center gap-1.5 text-red-600 dark:text-red-400`,title:s(`projects.failedParts`),children:[(0,z.jsx)(g,{className:`w-3.5 h-3.5`}),(0,z.jsx)(`span`,{children:e.failed_count})]}),e.queue_count>0&&(0,z.jsxs)(`div`,{className:`flex items-center gap-1.5 text-yellow-600 dark:text-yellow-400`,title:s(`projects.inQueue`),children:[(0,z.jsx)(I,{className:`w-3.5 h-3.5`}),(0,z.jsx)(`span`,{children:e.queue_count})]})]}),(0,z.jsx)(w,{className:`w-4 h-4 text-bambu-gray/50 group-hover:text-bambu-gray transition-colors`})]})]})]})}function W(){let{t:e}=i(),t=E(),n=o(),{showToast:a}=d(),{hasPermission:l}=P(),[f,m]=(0,L.useState)(!1),[h,g]=(0,L.useState)(),[_,b]=(0,L.useState)(`active`),[x,S]=(0,L.useState)(null),[A,ee]=(0,L.useState)(()=>localStorage.getItem(`projects-collapse-subprojects`)===`true`),[I,R]=(0,L.useState)({}),B=()=>{let e=!A;ee(e),R({}),localStorage.setItem(`projects-collapse-subprojects`,String(e))},{data:H}=s({queryKey:[`settings`],queryFn:r.getSettings}),W=k(H?.currency||`USD`),{data:G,isLoading:te}=s({queryKey:[`projects`,_===`all`?void 0:_],queryFn:()=>r.getProjects(_===`all`?void 0:_)}),{data:K}=s({queryKey:[`projects`,void 0],queryFn:()=>r.getProjects()}),q=new Map((K||[]).map(e=>[e.id,e.name])),J=G||[],Y=new Set(J.map(e=>e.id)),X=new Map;for(let e of J)if(e.parent_id!==null&&Y.has(e.parent_id)){let t=X.get(e.parent_id)||[];t.push(e),X.set(e.parent_id,t)}let Z=new Set,Q=e=>{if(!Z.has(e)){Z.add(e);for(let t of X.get(e)||[])Q(t.id)}},$=[];for(let e of J)e.parent_id!==null&&Y.has(e.parent_id)||($.push(e),Q(e.id));for(let e of J)Z.has(e.id)||($.push(e),Q(e.id));let ne=(t,n,r)=>{let i=(0,z.jsx)(U,{project:t,parentName:n===0&&t.parent_id!==null?q.get(t.parent_id):void 0,onClick:()=>pe(t),onEdit:()=>fe(t),onDelete:()=>me(t.id),hasPermission:l,t:e}),a=new Set(r).add(t.id),o=(X.get(t.id)||[]).filter(e=>!a.has(e.id));if(o.length===0)return(0,z.jsx)(`div`,{children:i},t.id);let s=I[t.id]??!A;return(0,z.jsxs)(`div`,{className:s?`col-span-full space-y-4`:`space-y-4`,children:[i,(0,z.jsxs)(`div`,{className:`ml-4 md:ml-8 pl-4 md:pl-6 border-l-2 rounded-l space-y-4`,style:{borderColor:t.color||`#6b7280`},children:[(0,z.jsxs)(`button`,{type:`button`,onClick:()=>R(e=>({...e,[t.id]:!s})),"aria-expanded":s,title:e(s?`projects.collapseSubProjects`:`projects.expandSubProjects`),className:`text-xs uppercase tracking-wide text-bambu-gray hover:text-white transition-colors flex items-center gap-1.5 max-w-full min-w-0`,children:[s?(0,z.jsx)(u,{className:`w-3.5 h-3.5 flex-shrink-0`}):(0,z.jsx)(w,{className:`w-3.5 h-3.5 flex-shrink-0`}),(0,z.jsx)(F,{className:`w-3.5 h-3.5 flex-shrink-0`}),(0,z.jsx)(`span`,{className:`truncate`,children:e(`projects.subProjectsOf`,{name:t.name})}),(0,z.jsx)(`span`,{className:`px-1.5 py-0.5 rounded-full bg-bambu-dark normal-case tracking-normal flex-shrink-0`,children:o.length})]}),s&&(0,z.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-8`,children:o.map(e=>ne(e,n+1,a))})]})]},t.id)},re=c({mutationFn:e=>r.createProject(e),onSuccess:()=>{n.invalidateQueries({queryKey:[`projects`]}),m(!1),a(e(`projects.toast.created`),`success`)},onError:e=>{a(e.message,`error`)}}),ie=c({mutationFn:({id:e,data:t})=>r.updateProject(e,t),onSuccess:()=>{n.invalidateQueries({queryKey:[`projects`]}),m(!1),g(void 0),a(e(`projects.toast.updated`),`success`)},onError:e=>{a(e.message,`error`)}}),ae=c({mutationFn:e=>r.deleteProject(e),onSuccess:()=>{S(null),a(e(`projects.toast.deleted`),`success`),setTimeout(()=>window.location.reload(),100)},onError:e=>{S(null),a(e.message,`error`)}}),oe=c({mutationFn:e=>r.importProject(e),onSuccess:()=>{n.invalidateQueries({queryKey:[`projects`]}),a(e(`projects.toast.imported`),`success`)},onError:e=>{a(e.message,`error`)}}),se=(0,L.useRef)(null),ce=async()=>{try{let t=await r.getProjects(),n=await Promise.all(t.map(async e=>await r.exportProjectJson(e.id))),i=new Blob([JSON.stringify(n,null,2)],{type:`application/json`}),o=URL.createObjectURL(i),s=document.createElement(`a`);s.href=o,s.download=`bambuddy_projects_${new Date().toISOString().split(`T`)[0]}.json`,s.click(),URL.revokeObjectURL(o),a(e(`projects.toast.exported`),`success`)}catch(e){a(e.message,`error`)}},le=()=>{se.current?.click()},ue=async t=>{let i=t.target.files?.[0];if(i){try{if(i.name.toLowerCase().endsWith(`.zip`))await r.importProjectFile(i),n.invalidateQueries({queryKey:[`projects`]}),a(e(`projects.toast.imported`),`success`);else{let t=await i.text(),n=JSON.parse(t),r=Array.isArray(n)?n:[n];for(let e of r)await oe.mutateAsync(e);r.length>1&&a(e(`projects.toast.multipleImported`,{count:r.length}),`success`)}}catch(t){a(`${e(`projects.toast.importFailed`)}: ${t.message}`,`error`)}t.target.value=``}},de=e=>{h?ie.mutate({id:h.id,data:e}):re.mutate(e)},fe=e=>{g(e),m(!0)},pe=e=>{t(`/projects/${e.id}`)},me=e=>{S(e)},he=()=>{x!==null&&ae.mutate(x)},ge=K?.reduce((e,t)=>(e[t.status]=(e[t.status]||0)+1,e.all=(e.all||0)+1,e),{})||{};return(0,z.jsxs)(`div`,{className:`p-4 md:p-8 space-y-8`,children:[(0,z.jsx)(`input`,{ref:se,type:`file`,accept:`.json,.zip`,onChange:ue,className:`hidden`}),(0,z.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-4`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsxs)(`h1`,{className:`text-2xl font-bold text-white flex items-center gap-3`,children:[(0,z.jsx)(N,{className:`w-7 h-7 text-bambu-green`}),e(`projects.title`)]}),(0,z.jsx)(`p`,{className:`text-bambu-gray mt-1`,children:e(`projects.subtitle`)})]}),(0,z.jsxs)(`div`,{className:`flex gap-2`,children:[(0,z.jsxs)(v,{variant:`secondary`,onClick:le,disabled:!l(`projects:create`),title:l(`projects:create`)?e(`projects.importProject`):e(`projects.noImportPermission`),children:[(0,z.jsx)(j,{className:`w-4 h-4 mr-2`}),e(`projects.import`)]}),(0,z.jsxs)(v,{variant:`secondary`,onClick:ce,disabled:!l(`projects:read`),title:l(`projects:read`)?e(`projects.exportAll`):e(`projects.noExportPermission`),children:[(0,z.jsx)(M,{className:`w-4 h-4 mr-2`}),e(`projects.export`)]}),(0,z.jsxs)(v,{onClick:()=>m(!0),className:`sm:w-auto w-full`,disabled:!l(`projects:create`),title:l(`projects:create`)?void 0:e(`projects.noCreatePermission`),children:[(0,z.jsx)(D,{className:`w-4 h-4 mr-2`}),e(`projects.newProject`)]})]})]}),(0,z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,z.jsx)(`div`,{className:`flex gap-1 p-1 bg-bambu-dark rounded-xl w-fit`,children:[{key:`active`,label:e(`projects.statusActive`),icon:T},{key:`completed`,label:e(`projects.statusCompleted`),icon:y},{key:`archived`,label:e(`projects.statusArchived`),icon:C},{key:`all`,label:e(`common.all`),icon:N}].map(({key:e,label:t,icon:n})=>(0,z.jsxs)(`button`,{onClick:()=>b(e),className:`flex items-center gap-2 px-4 py-2 text-sm rounded-lg transition-all ${_===e?`bg-bambu-card text-white shadow-sm`:`text-bambu-gray hover:text-white`}`,children:[(0,z.jsx)(n,{className:`w-4 h-4`}),(0,z.jsx)(`span`,{children:t}),ge[e]>0&&(0,z.jsx)(`span`,{className:`text-xs px-1.5 py-0.5 rounded-full ${_===e?`bg-bambu-green/20 text-bambu-green`:`bg-bambu-dark-tertiary`}`,children:ge[e]})]},e))}),X.size>0&&(0,z.jsxs)(`button`,{type:`button`,onClick:B,"aria-pressed":A,title:e(A?`projects.expandSubProjects`:`projects.collapseSubProjects`),className:`flex items-center gap-2 px-3 py-1.5 text-sm rounded-lg transition-colors ${A?`bg-bambu-green/20 text-bambu-green`:`text-bambu-gray hover:text-white hover:bg-bambu-dark`}`,children:[(0,z.jsx)(F,{className:`w-4 h-4`}),e(`common.collapse`)]})]}),te?(0,z.jsx)(`div`,{className:`flex items-center justify-center py-20`,children:(0,z.jsxs)(`div`,{className:`flex flex-col items-center gap-3`,children:[(0,z.jsx)(p,{className:`w-8 h-8 animate-spin text-bambu-green`}),(0,z.jsx)(`p`,{className:`text-sm text-bambu-gray`,children:e(`projects.loading`)})]})}):G?.length===0?(0,z.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-20 px-4`,children:[(0,z.jsx)(`div`,{className:`p-4 bg-bambu-dark rounded-2xl mb-4`,children:(0,z.jsx)(N,{className:`w-12 h-12 text-bambu-gray/50`})}),(0,z.jsx)(`h3`,{className:`text-lg font-medium text-white mb-2`,children:_===`all`?e(`projects.noProjects`):e(`projects.noProjectsFiltered`,{status:_})}),(0,z.jsx)(`p`,{className:`text-bambu-gray text-center max-w-md mb-6`,children:_===`all`?e(`projects.createFirst`):e(`projects.noProjectsFilteredHelp`,{status:_})}),_===`all`&&(0,z.jsxs)(v,{onClick:()=>m(!0),disabled:!l(`projects:create`),title:l(`projects:create`)?void 0:e(`projects.noCreatePermission`),children:[(0,z.jsx)(D,{className:`w-4 h-4 mr-2`}),e(`projects.createFirstButton`)]})]}):(0,z.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-8`,children:$.map(e=>ne(e,0,new Set))}),x!==null&&(0,z.jsx)(O,{title:e(`projects.deleteProject`),message:e(`projects.deleteConfirm`),confirmText:e(`projects.deleteProject`),variant:`danger`,onConfirm:he,onCancel:()=>S(null)}),f&&(0,z.jsx)(V,{project:h,onClose:()=>{m(!1),g(void 0)},onSave:de,isLoading:re.isPending||ie.isPending,currencySymbol:W,t:e})]})}export{V as ProjectModal,W as ProjectsPage,F as n,I as t};
|