1import{f as b,j as e,M as q,F as m,u as fe,c as ke,p as _e,G as Ne,b as O,z as Ce,e as Se,m as z,L as ae,i as L,C as se,x as C,B as K,h as we,g as Pe,N as Be,r as $e,E as Ie,w as ne,P as Ee}from"./index-ChuvAvcO.js";import{I as Me}from"./ImportModal-COO3rJ4n.js";function Re({products:t,onClose:a}){const[r,h]=b.useState(()=>Object.fromEntries(t.map(g=>[g.id,1]))),[o,v]=b.useState(()=>new Set),[p,u]=b.useState(""),s=t.filter(g=>!o.has(g.id)),d=s.reduce((g,l)=>g+(Number(r[l.id])||0),0),j=(g,l)=>h(i=>({...i,[g]:Math.max(0,Math.min(999,Number(l)||0))})),k=g=>v(l=>new Set(l).add(g)),N=()=>{const g=Math.max(0,Math.min(999,Number(p)||0));h(Object.fromEntries(s.map(l=>[l.id,g])))},$=()=>{const g=s.filter(l=>(r[l.id]||0)>0).map(l=>`${l.id}:${r[l.id]}`).join(",");g&&(window.open(`/admin/print/labels?items=${encodeURIComponent(g)}&auto=1`,"_blank"),a())};return e.jsxs(q,{title:"Print barcode labels",onClose:a,wide:!0,footer:e.jsxs(e.Fragment,{children:[e.jsx("button",{onClick:a,children:"Cancel"}),e.jsxs("button",{className:"primary",disabled:!d,onClick:$,children:["Print ",d," label",d===1?"":"s"]})]}),children:[e.jsxs("div",{className:"flex",style:{gap:10,alignItems:"flex-end",marginBottom:12},children:[e.jsx(m,{label:"Set quantity for all",style:{width:160},children:e.jsx("input",{type:"number",min:"0",max:"999",value:p,onChange:g=>u(g.target.value),placeholder:"e.g. 5"})}),e.jsx("button",{className:"sm",onClick:N,children:"Apply to all"}),e.jsx("span",{className:"muted",style:{fontSize:12},children:"Or set on-hand stock as the qty by typing it in per row below."})]}),e.jsxs("table",{className:"tbl",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Product"}),e.jsx("th",{children:"SKU"}),e.jsx("th",{className:"num",style:{width:90},children:"On hand"}),e.jsx("th",{className:"num",style:{width:100},children:"Qty"}),e.jsx("th",{style:{width:34}})]})}),e.jsx("tbody",{children:s.map(g=>e.jsxs("tr",{children:[e.jsx("td",{children:g.title}),e.jsx("td",{className:"mono muted",children:g.sku||g.upc||"â"}),e.jsx("td",{className:"num muted",children:g.on_hand??"â"}),e.jsx("td",{className:"num",children:e.jsx("input",{type:"number",min:"0",max:"999",className:"sm",value:r[g.id]??0,onChange:l=>j(g.id,l.target.value),style:{width:64,textAlign:"right"}})}),e.jsx("td",{children:e.jsx("button",{className:"ghost",title:"Remove from this batch",onClick:()=>k(g.id),children:"Ã"})})]},g.id))})]}),!s.length&&e.jsx("div",{className:"muted",style:{fontSize:13},children:"Nothing left to print."})]})}function De(){var ee,te;const t=fe(),a=ke(),[r,h]=_e(),[o,v]=b.useState(r.get("q")||""),[p,u]=b.useState(r.get("manufacturer")||""),[s,d]=b.useState(r.get("category")||""),[j,k]=b.useState(r.get("vendor")||""),[N,$]=b.useState(r.get("stock")||""),[g,l]=b.useState(r.get("status")||"active"),[i,_]=b.useState(r.get("sort")||"newest"),[f,I]=b.useState(r.get("visibility")||""),[S,y]=b.useState(r.get("photos")||""),[x,w]=b.useState(r.get("loaner")==="1"),[c,E]=b.useState(r.get("onSale")==="1"),[B,H]=b.useState(r.get("rentalStatus")||""),[R,Q]=b.useState(r.get("missing")||""),[oe,Y]=b.useState(!1),[D,F]=b.useState(new Set),[ce,G]=b.useState(!1),[de,V]=b.useState(!1),[he,J]=b.useState(!1),T=Ne(o,250),X=O(),[me,ue]=Ce();b.useEffect(()=>{const n=new URLSearchParams;T&&n.set("q",T),p&&n.set("manufacturer",p),s&&n.set("category",s),j&&n.set("vendor",j),N&&n.set("stock",N),g!=="active"&&n.set("status",g),i!=="newest"&&n.set("sort",i),f&&n.set("visibility",f),S&&n.set("photos",S),x&&n.set("loaner","1"),c&&n.set("onSale","1"),B&&n.set("rentalStatus",B),R&&n.set("missing",R),h(n,{replace:!0})},[T,p,s,j,N,g,i,f,S,x,c,B,R]);const M=Se(()=>L.products({q:T,manufacturer:p,category:s,vendor:j,stock:N,status:g,sort:i,limit:200,visibility:f,photos:S,loaner:x?"1":"",onSale:c?"1":"",rentalStatus:B,missing:R}),[T,p,s,j,N,g,i,f,S,x,c,B,R]),A=((ee=M.data)==null?void 0:ee.rows)||[],ge=A.reduce((n,P)=>n+(P.on_hand||0)*(P.default_cost||0),0);b.useEffect(()=>{F(new Set)},[T,p,s,j,N,g,i,f,S,x,c,B,R]);const xe=(g!=="active"?1:0)+(p?1:0)+(j?1:0)+(f?1:0)+(S?1:0)+(x?1:0)+(c?1:0)+(B?1:0)+(R?1:0),pe=()=>{l("active"),u(""),k(""),I(""),y(""),w(!1),E(!1),H(""),Q("")},be=n=>F(P=>{const U=new Set(P);return U.has(n)?U.delete(n):U.add(n),U}),Z=A.length>0&&A.every(n=>D.has(n.id)),je=()=>F(Z?new Set:new Set(A.map(n=>n.id))),ye=A.filter(n=>D.has(n.id)),W=`/admin/inventory${r.toString()?`?${r.toString()}`:""}`,ve=async()=>{const n=D.size;if(await me(`Delete ${n} product${n===1?"":"s"}? They're removed from Inventory, Register, and the storefront, but their sales and stock history are kept, and you can restore any of them later from that product's own page.`,{danger:!0,confirmLabel:`Delete ${n} product${n===1?"":"s"}`})){J(!0);try{const P=await L.bulkDeleteProducts(Array.from(D));X(`Deleted ${P.disabled} product${P.disabled===1?"":"s"}`),F(new Set),M.reload()}catch(P){X(P.message,"err")}finally{J(!1)}}};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"page-head",children:[e.jsxs("div",{children:[e.jsx("h1",{children:"Inventory"}),e.jsx("div",{className:"sub",children:M.data?`${M.data.total}
1 products · ${z(ge)} at cost on this page`:" "})]}),e.jsxs("div",{className:"actions",children:[e.jsx(ae,{className:"btn",to:"/admin/settings?tab=labels",children:"Label settings"}),e.jsx("button",{className:"btn",onClick:()=>Y(!0),children:"Import CSV"}),e.jsx("a",{className:"btn",href:"/api/reports/export/products",children:"Export CSV"}),e.jsx("button",{className:"primary",onClick:()=>a("/admin/inventory/new",{state:{from:W}}),children:"+ New product"})]})]}),oe&&e.jsx(Me,{title:"Import products",templateHref:"/api/products/import/template",onImport:L.importProducts,onClose:()=>Y(!1),onImported:()=>M.reload()}),e.jsx(se,{children:e.jsxs("div",{className:"filters",children:[e.jsx(m,{label:"Filter by title, SKU or UPC",style:{flex:1,minWidth:250},children:e.jsx("input",{type:"search",value:o,onChange:n=>v(n.target.value),autoFocus:!0,placeholder:"Yamaha YTR-2330, VD-CR103, 008576100308â¦"})}),e.jsx(m,{label:"Category",children:e.jsx(C,{value:s,onChange:n=>d(n.target.value),placeholder:"All",options:t.categories.map(n=>({value:String(n.id),label:n.name}))})}),e.jsx(m,{label:"Stock",children:e.jsx(C,{value:N,onChange:n=>$(n.target.value),placeholder:"Any",options:[{value:"in",label:"In stock"},{value:"out",label:"Out of stock"},{value:"low",label:"At or below reorder point"}]})}),e.jsx(m,{label:"Sort",children:e.jsx(C,{value:i,onChange:n=>_(n.target.value),options:[{value:"title",label:"Title"},{value:"sku",label:"SKU"},{value:"price",label:"Price (high â low)"},{value:"stock",label:"On hand (high â low)"},{value:"newest",label:"Newest"}]})}),e.jsx(K,{label:" ",children:e.jsx(Ae,{count:xe,shop:t,status:g,setStatus:l,manufacturer:p,setManufacturer:u,vendor:j,setVendor:k,visibility:f,setVisibility:I,photos:S,setPhotos:y,loaner:x,setLoaner:w,onSale:c,setOnSale:E,rentalStatus:B,setRentalStatus:H,missing:R,setMissing:Q,onClear:pe})})]})}),e.jsxs(se,{title:`Products (${((te=M.data)==null?void 0:te.total)??0})`,tight:!0,right:D.size>0&&e.jsxs("div",{className:"flex",style:{gap:8,alignItems:"center"},children:[e.jsxs("span",{className:"muted",style:{fontSize:12.5},children:[D.size," selected"]}),e.jsx("button",{className:"sm",onClick:()=>V(!0),children:"â Edit"}),e.jsx("button",{className:"sm",onClick:()=>G(!0),children:"ð· Print labels"}),e.jsx("button",{className:"sm danger",disabled:he,onClick:ve,children:"ð Delete"}),e.jsx("button",{className:"sm ghost",onClick:()=>F(new Set),children:"Clear"})]}),children:[e.jsx(we,{error:M.error}),M.loading?e.jsx(Pe,{}):A.length?e.jsx("div",{className:"table-wrap",children:e.jsxs("table",{className:"tbl",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{style:{width:30},children:e.jsx("input",{type:"checkbox",checked:Z,onChange:je,"aria-label":"Select all"})}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"SKU"}),e.jsx("th",{children:"UPC"}),e.jsx("th",{children:"Manufacturer"}),e.jsx("th",{children:"Bin"}),e.jsx("th",{className:"num",children:"Cost"}),e.jsx("th",{className:"num",children:"Price"}),e.jsx("th",{children:"Stock"})]})}),e.jsx("tbody",{children:A.map(n=>e.jsxs("tr",{...$e(()=>a(`/admin/inventory/${n.id}`,{state:{from:W}})),children:[e.jsx("td",{onClick:P=>P.stopPropagation(),children:e.jsx("input",{type:"checkbox",checked:D.has(n.id),onChange:()=>be(n.id),"aria-label":`Select ${n.title}`})}),e.jsxs("td",{children:[e.jsx(ae,{to:`/admin/inventory/${n.id}`,state:{from:W},onClick:P=>P.stopPropagation(),children:n.title}),n.variant_count>0&&e.jsxs("span",{className:"badge grey",style:{marginLeft:6},children:[n.variant_count," variants"]}),n.status==="disabled"&&e.jsx("span",{className:"badge red",style:{marginLeft:6},children:"disabled"})]}),e.jsx("td",{className:"mono",children:n.sku||e.jsx("span",{className:"muted",children:"â"})}),e.jsx("td",{className:"mono muted",children:n.upc||"â"}),e.jsx("td",{className:"truncate",style:{maxWidth:150},children:n.manufacturer||e.jsx("span",{className:"muted",children:"â"})}),e.jsx("td",{className:"muted",children:n.bin_location||"â"}),e.jsx("td",{className:"num muted",children:n.default_cost?z(n.default_cost):"â"}),e.jsx("td",{className:"num",children:n.sale_price>0?e.jsxs(e.Fragment,{children:[z(n.sale_price)," ",e.jsx("span",{className:"muted",style:{textDecoration:"line-through",fontSize:12},children:z(n.price)})]}):z(n.price)}),e.jsx("td",{children:e.jsx(Be,{qty:n.on_hand,reorder:n.reorder_point,unlimited:n.unlimited_inventory})})]},n.id))})]})}):e.jsxs(Ie,{icon:"â¤",children:["No products match.",e.jsx("div",{style:{marginTop:10},children:e.jsx("button",{className:"primary",onClick:()=>a("/admin/inventory/new",{state:{from:W}}),children:"+ New product"})})]})]}),ce&&e.jsx(Re,{products:ye,onClose:()=>G(!1)}),de&&e.jsx(Le,{ids:Array.from(D),shop:t,onClose:()=>V(!1),onDone:()=>{V(!1),F(new Set),M.reload()}}),ue]})}function Le({ids:t,shop:a,onClose:r,onDone:h}){const o=O(),[v,p]=b.useState(!1),[u,s]=b.useState({category_ids:!1,availability:!1,status:!1,manufacturer:!1,primary_vendor:!1,price:!1,sale_price:!1}),[d,j]=b.useState({category_ids:[],availability:"both",status:"active",manufacturer:"",primary_vendor:"",price:"",sale_price:""}),k=l=>s(i=>({...i,[l]:!i[l]})),N=l=>j(i=>{const _=String(l),f=new Set(i.category_ids.map(String));return f.has(_)?f.delete(_):f.add(_),{...i,category_ids:Array.from(f)}}),$=Object.values(u).some(Boolean),g=async()=>{const l={};if(u.category_ids&&(l.category_ids=d.category_ids.join(",")),u.availability&&(l.availability=d.availability),u.status&&(l.status=d.status),u.manufacturer&&(l.manufacturer=d.manufacturer.trim()),u.primary_vendor&&(l.primary_vendor=d.primary_vendor),u.price){const i=Number(d.price);if(!(i>=0)){o("Enter a valid price","err");return}l.price=i}u.sale_price&&(l.sale_price=d.sale_price===""?null:Number(d.sale_price)),p(!0);try{const i=await L.bulkUpdateProducts(t,l);o(`Updated ${i.updated} product${i.updated===1?"":"s"}`),h()}catch(i){o(i.message,"err")}finally{p(!1)}};return e.jsxs(q,{title:`Edit ${t.length} product${t.length===1?"":"s"}`,onClose:r,wide:!0,footer:e.jsxs(e.Fragment,{children:[e.jsx("button",{onClick:r,children:"Cancel"}),e.jsx("button",{className:"primary",disabled:!$||v,onClick:g,children:v?"Savingâ¦":`Update ${t.length} product${t.length===1?"":"s"}`})]}),children:[e.jsx("div",{className:"hint",style:{marginBottom:14},children:"Check a field to change it on every selected product â anything left unchecked stays as-is."}),e.jsxs("label",{className:"check",style:{marginBottom:4},children:[e.jsx("input",{type:"checkbox",checked:u.category_ids,onChange:()=>k("category_ids")}),"Category"]}),u.category_ids&&(a.categories.length?e.jsx("div",{className:"grid k3",style:{gap:4,marginLeft:26,marginBottom:14},children:a.categories.map(l=>e.jsxs("label",{className:"check",children:[e.jsx("input",{type:"checkbox",checked:d.category_ids.map(String).includes(String(l.id)),onChange:()=>N(l.id)}),l.name]},l.id))}):e.jsx("div",{className:"hint",style:{marginLeft:26,marginBottom:14},children:"No categories set up yet."})),e.jsxs("label",{className:"check",style:{marginBottom:4},children:[e.jsx("input",{type:"checkbox",checked:u.availability,onChange:()=>k("availability")}),"Website visibility"]}),u.availability&&e.jsx("div",{style:{marginLeft:26,marginBottom:14,maxWidth:260},children:e.jsx(C,{value:d.availability,onChange:l=>j(i=>({...i,availability:l.target.value})),options:[{value:"both",label:"Store + website"},{value:"store",label:"Store only"},{value:"web",label:"Website only"}]})}),e.jsxs("label",{className:"check",style:{marginBottom:4},children:[e.jsx("input",{type:"checkbox",checked:u.status,onChange:()=>k("status")}),"Status"]}),u.status&&e.jsx("div",{style:{marginLeft:26,marginBottom:14,maxWidth:260},children:e.jsx(C,{value:d.status,onChange:l=>j(i=>({...i,status:l.target.value})),options:[{value:"active",label:"Active"},{value:"disabled",label:"Disabled"}]})}),e.jsxs("label",{className:"check",style:{marginBottom:4},children:[e.jsx("input",{type:"checkbox",checked:u.manufacturer,onChange:()=>k("manufacturer")}),"Manufacturer"]}),u.manufacturer&&e.jsxs("div",{style:{marginLeft:26,marginBottom:14,maxWidth:260},children:[e.jsx("input",{value:d.manufacturer,list:"bulk-mfr-list",onCh
1ange:l=>j(i=>({...i,manufacturer:l.target.value}))}),e.jsx("datalist",{id:"bulk-mfr-list",children:a.manufacturers.map(l=>e.jsx("option",{value:l},l))})]}),e.jsxs("label",{className:"check",style:{marginBottom:4},children:[e.jsx("input",{type:"checkbox",checked:u.primary_vendor,onChange:()=>k("primary_vendor")}),"Vendor"]}),u.primary_vendor&&e.jsx("div",{style:{marginLeft:26,marginBottom:14,maxWidth:260},children:e.jsx(C,{value:d.primary_vendor,onChange:l=>j(i=>({...i,primary_vendor:l.target.value})),placeholder:"â",options:a.vendors.map(l=>({value:l.name,label:l.name}))})}),e.jsxs("label",{className:"check",style:{marginBottom:4},children:[e.jsx("input",{type:"checkbox",checked:u.price,onChange:()=>k("price")}),"Price"]}),u.price&&e.jsx("div",{style:{marginLeft:26,marginBottom:14,maxWidth:160},children:e.jsx(ne,{value:d.price,onChange:l=>j(i=>({...i,price:l.target.value}))})}),e.jsxs("label",{className:"check",style:{marginBottom:4},children:[e.jsx("input",{type:"checkbox",checked:u.sale_price,onChange:()=>k("sale_price")}),"Sale price"]}),u.sale_price&&e.jsx("div",{style:{marginLeft:26,maxWidth:160},children:e.jsx(ne,{value:d.sale_price,placeholder:"blank clears it",onChange:l=>j(i=>({...i,sale_price:l.target.value}))})})]})}function Ae({count:t,shop:a,status:r,setStatus:h,manufacturer:o,setManufacturer:v,vendor:p,setVendor:u,visibility:s,setVisibility:d,photos:j,setPhotos:k,loaner:N,setLoaner:$,onSale:g,setOnSale:l,rentalStatus:i,setRentalStatus:_,missing:f,setMissing:I,onClear:S}){const[y,x]=b.useState(!1),w=b.useRef(null);return b.useEffect(()=>{if(!y)return;const c=B=>{w.current&&!w.current.contains(B.target)&&x(!1)},E=B=>{B.key==="Escape"&&x(!1)};return document.addEventListener("mousedown",c),document.addEventListener("keydown",E),()=>{document.removeEventListener("mousedown",c),document.removeEventListener("keydown",E)}},[y]),e.jsxs("div",{className:"dropdown-anchor",ref:w,children:[e.jsxs("button",{type:"button",className:"sm",onClick:()=>x(c=>!c),children:["More filters",t?` (${t})`:""," â¾"]}),y&&e.jsxs("div",{className:"dropdown-panel",style:{width:260,maxHeight:"70vh",overflowY:"auto"},children:[e.jsx(m,{label:"Status",style:{marginBottom:14},children:e.jsx(C,{value:r,onChange:c=>h(c.target.value),placeholder:"All",options:[{value:"active",label:"Active"},{value:"disabled",label:"Disabled"}]})}),e.jsx(m,{label:"Manufacturer",style:{marginBottom:14},children:e.jsx(C,{value:o,onChange:c=>v(c.target.value),placeholder:"All",options:a.manufacturers})}),e.jsx(m,{label:"Vendor",style:{marginBottom:14},children:e.jsx(C,{value:p,onChange:c=>u(c.target.value),placeholder:"All",options:a.vendors.map(c=>({value:c.name,label:c.name}))})}),e.jsx(m,{label:"Website visibility",style:{marginBottom:14},children:e.jsx(C,{value:s,onChange:c=>d(c.target.value),placeholder:"Any",options:[{value:"web",label:"Visible on website"},{value:"store",label:"Store only (hidden online)"}]})}),e.jsx(m,{label:"Photos",style:{marginBottom:14},children:e.jsx(C,{value:j,onChange:c=>k(c.target.value),placeholder:"Any",options:[{value:"yes",label:"Has photos"},{value:"no",label:"No photos"}]})}),e.jsx(m,{label:"Rental status",style:{marginBottom:14},children:e.jsx(C,{value:i,onChange:c=>_(c.target.value),placeholder:"Any",options:[{value:"available",label:"Available for rental"},{value:"rented",label:"Currently rented"}]})}),e.jsxs("label",{className:"check",style:{marginTop:4},children:[e.jsx("input",{type:"checkbox",checked:N,onChange:c=>$(c.target.checked)}),"Loaner available"]}),e.jsxs("label",{className:"check",children:[e.jsx("input",{type:"checkbox",checked:g,onChange:c=>l(c.target.checked)}),"On sale"]}),e.jsx(m,{label:"Missing info",hint:"find products that need cleanup",style:{marginTop:8,marginBottom:0},children:e.jsx(C,{value:f,onChange:c=>I(c.target.value),placeholder:"Any",options:[{value:"price",label:"No price set"},{value:"sku",label:"No SKU"},{value:"bin",label:"No bin location"}]})}),t>0&&e.jsx("button",{type:"button",className:"ghost sm",style:{marginTop:8},onClick:S,children:"Clear these filters"})]})]})}const Fe=t=>
1({title:(t==null?void 0:t.title)||"",sku:(t==null?void 0:t.sku)||"",upc:(t==null?void 0:t.upc)||"",manufacturer:(t==null?void 0:t.manufacturer)||"",primary_vendor:(t==null?void 0:t.primary_vendor)||"",price:(t==null?void 0:t.price)??"",sale_price:(t==null?void 0:t.sale_price)??"",default_cost:(t==null?void 0:t.default_cost)??"",map_price:(t==null?void 0:t.map_price)??"",reorder_point:(t==null?void 0:t.reorder_point)??0,desired_stock_level:(t==null?void 0:t.desired_stock_level)??0,bin_location:(t==null?void 0:t.bin_location)||"",weight:(t==null?void 0:t.weight)??"",length:(t==null?void 0:t.length)??"",width:(t==null?void 0:t.width)??"",height:(t==null?void 0:t.height)??"",availability:(t==null?void 0:t.availability)||"both",unit_of_measure:(t==null?void 0:t.unit_of_measure)||"each",taxable:(t==null?void 0:t.taxable)??1,tax_profile_id:(t==null?void 0:t.tax_profile_id)||"",unlimited_inventory:(t==null?void 0:t.unlimited_inventory)??0,is_loaner:(t==null?void 0:t.is_loaner)??0,rental_status:(t==null?void 0:t.rental_status)||"",rental_plan_id:(t==null?void 0:t.rental_plan_id)||"",serialized:(t==null?void 0:t.serialized)??0,condition:(t==null?void 0:t.condition)||"",description:(t==null?void 0:t.description)||"",short_description:(t==null?void 0:t.short_description)||"",meta_title:(t==null?void 0:t.meta_title)||"",meta_description:(t==null?void 0:t.meta_description)||"",category_ids:(t==null?void 0:t.category_ids)||"",website_price:(t==null?void 0:t.website_price)??"",website_sale_price:(t==null?void 0:t.website_sale_price)??"",initial_qty:"",initial_cost:""}),Te=["price","sale_price","default_cost","map_price","reorder_point","desired_stock_level","weight","length","width","height","website_price","website_sale_price","initial_qty","initial_cost"];function ze({f:t,set:a,setForm:r,shop:h,isNew:o,hasVariants:v}){var p,u;return e.jsxs(e.Fragment,{children:[e.jsx(m,{label:"Product title",hint:"required",children:e.jsx("input",{value:t.title,onChange:a("title"),placeholder:"Yamaha YTR-2330 Standard Bb Trumpet"})}),e.jsxs("div",{className:"grid k2",style:{gap:12},children:[e.jsx(m,{label:"SKU",children:e.jsx("input",{value:t.sku,onChange:a("sku"),className:"mono"})}),e.jsx(m,{label:"UPC",hint:"leave blank to auto-generate",children:e.jsx("input",{value:t.upc,onChange:a("upc"),className:"mono"})})]}),e.jsxs("div",{className:"grid k2",style:{gap:12},children:[e.jsx(m,{label:"Manufacturer",children:e.jsx("input",{value:t.manufacturer,onChange:a("manufacturer"),list:"mfr-list"})}),e.jsx(m,{label:"Primary vendor",children:e.jsx(C,{value:t.primary_vendor,onChange:a("primary_vendor"),placeholder:"â",options:h.vendors.map(s=>({value:s.name,label:s.name}))})})]}),e.jsx("datalist",{id:"mfr-list",children:h.manufacturers.map(s=>e.jsx("option",{value:s},s))}),e.jsx("h3",{className:"section",children:"Pricing"}),e.jsxs("div",{className:"grid k4",style:{gap:12},children:[e.jsx(m,{label:"Price",hint:v?"priced per variant below":void 0,children:e.jsx("input",{type:"number",step:"0.01",value:t.price,onChange:a("price"),disabled:v})}),e.jsx(m,{label:"Sale price",children:e.jsx("input",{type:"number",step:"0.01",value:t.sale_price,onChange:a("sale_price")})}),e.jsx(m,{label:"Cost",children:e.jsx("input",{type:"number",step:"0.01",value:t.default_cost,onChange:a("default_cost")})}),e.jsx(m,{label:"MAP",children:e.jsx("input",{type:"number",step:"0.01",value:t.map_price,onChange:a("map_price")})})]}),e.jsx("h3",{className:"section",children:"Stock"}),e.jsxs("div",{className:"grid k3",style:{gap:12},children:[e.jsx(m,{label:"Reorder point",children:e.jsx("input",{type:"number",value:t.reorder_point,onChange:a("reorder_point")})}),e.jsx(m,{label:"Desired level",children:e.jsx("input",{type:"number",value:t.desired_stock_level,onChange:a("desired_stock_level")})}),e.jsx(m,{label:"Bin location",children:e.jsx(C,{value:t.bin_location,onChange:a("bin_location"),placeholder:"â",options:h.bin_locations.map(s=>({value:s.name,label:s.name}))})})]}),o&&!v&&e.jsxs("div",{className:"grid k2",style:{gap:12},children:[e.jsx(m,{label:"Opening quantity",hint:"creates the first inventory lot",children:e.jsx("input",{type:"number",value:t.initial_qty,onChange:a("initial_qty"),placeholder:"0"})}),e.jsx(m,{label:"Cost per item on that lot",children:e.jsx("input",{type:"number",step:"0.01",value:t.initial_cost!==""?t.initial_cost:t.default_cost,onChange:a("initial_cost")})})]}),e.jsxs("div",{className:"flex",style:{gap:12,alignItems:"center",flexWrap:"wrap",marginBottom:8},children:[e.jsxs("label",{className:"check",style:{marginBottom:0},children:[e.jsx("input",{type:"checkbox",checked:!!t.taxable,onChange:a("taxable")})," Taxable"]}),!!t.taxable&&e.jsx(C,{value:t.tax_profile_id,onChange:a("tax_profile_id"),placeholder:"Shop default",options:h.tax_profiles.map(s=>({value:s.id,label:`${s.name} (${(s.rate*100).toFixed(2)}%)`})),style:{minWidth:220}})]}),e.jsxs("label",{className:"check",children:[e.jsx("input",{type:"checkbox",checked:!!t.is_loaner,onChange:a("is_loaner")}),"Available as a loaner (displays first in the work order loaner dropdown)"]}),e.jsx("h3",{className:"section",children:"Rental"}),e.jsxs("label",{className:"check",title:t.rental_status==="rented"?"Currently out on a contract â ends automatically when it's returned":void 0,children:[e.jsx("input",{type:"checkbox",checked:t.rental_status==="available",disabled:t.rental_status==="rented",onChange:s=>r(d=>({...d,rental_status:s.target.checked?"available":null}))}),(p=h==null?void 0:h.features)!=null&&p.website?"List this item for online rental":"Mark this item as a rental",t.rental_status==="rented"?" (currently out on a contract)":""]}),t.rental_status==="available"&&e.jsx(m,{label:"Rental profile",hint:(u=h==null?void 0:h.features)!=null&&u.website?"sets the rate and billing terms â manage these in Settings â Rental Profiles":"sets the rate and billing terms, and surfaces this item first when searching in New Rental Contract â manage profiles in Settings â Rental Profiles. Add the Website add-on to al
1so list it for online rental.",style:{marginTop:8,maxWidth:360},children:e.jsx(C,{value:t.rental_plan_id,onChange:a("rental_plan_id"),placeholder:"â choose a profile â",options:h.rental_plans.map(s=>({value:s.id,label:`${s.name} ($${s.flat_rate}/${s.billing_frequency==="weekly"?"wk":"mo"})`}))})}),e.jsxs("label",{className:"check",style:{marginTop:8},children:[e.jsx("input",{type:"checkbox",checked:!!t.serialized,onChange:a("serialized")}),"Track individual units (serial numbers)"]}),e.jsx("div",{className:"hint",style:{marginTop:-4,marginBottom:8},children:"For instruments where it matters which exact one a customer has â on-hand becomes a list of units instead of a count. Manage units from this product's own page after saving."}),e.jsx("h3",{className:"section",children:"Shipping dimensions"}),e.jsxs("div",{className:"grid k4",style:{gap:12},children:[e.jsx(m,{label:"Weight (lb)",children:e.jsx("input",{type:"number",step:"0.1",value:t.weight,onChange:a("weight")})}),e.jsx(m,{label:"Length (in)",children:e.jsx("input",{type:"number",step:"0.1",value:t.length,onChange:a("length")})}),e.jsx(m,{label:"Width (in)",children:e.jsx("input",{type:"number",step:"0.1",value:t.width,onChange:a("width")})}),e.jsx(m,{label:"Height (in)",children:e.jsx("input",{type:"number",step:"0.1",value:t.height,onChange:a("height")})})]})]})}function We({product:t,onChanged:a}){const r=O(),h=b.useRef(null),[o,v]=b.useState(0),[p,u]=b.useState(null),[s,d]=b.useState(t.images||[]),[j,k]=b.useState(null);b.useEffect(()=>d(t.images||[]),[t.images]);const N=()=>{var i;return(i=h.current)==null?void 0:i.click()},$=async i=>{const _=Array.from(i.target.files||[]);if(i.target.value="",!!_.length){v(_.length);try{for(const f of _)await L.uploadProductImage(t.id,f),v(I=>I-1)}catch(f){r(f.message,"err")}finally{v(0),a()}}},g=async i=>{try{await L.deleteProductImage(t.id,i.id),a()}catch(_){r(_.message,"err")}},l=async i=>{const _=p;if(u(null),_===null||_===i)return;const f=s.findIndex(x=>x.id===_),I=s.findIndex(x=>x.id===i);if(f===-1||I===-1)return;const S=[...s],[y]=S.splice(f,1);S.splice(I,0,y),d(S);try{await L.reorderProductImages(t.id,S.map(x=>x.id))}catch(x){r(x.message,"err"),d(s)}};return e.jsxs("div",{children:[s.length>0&&e.jsx("div",{className:"photo-grid",children:s.map((i,_)=>e.jsxs("div",{className:`photo-tile${p===i.id?" dragging":""}`,draggable:!0,onDragStart:()=>u(i.id),onDragOver:f=>f.preventDefault(),onDrop:()=>l(i.id),onDragEnd:()=>u(null),onClick:()=>k(i),children:[e.jsx("img",{src:`/uploads/${i.filename}`,alt:""}),_===0&&e.jsx("span",{className:"photo-cover-badge",children:"Cover"}),e.jsx("button",{type:"button",className:"photo-remove","aria-label":"Remove photo",onClick:f=>{f.stopPropagation(),g(i)},children:"Ã"})]},i.id))}),e.jsxs("div",{className:"flex",style:{alignItems:"center",gap:10,marginTop:s.length?10:0},children:[e.jsx("button",{type:"button",className:"sm",disabled:!!o,onClick:N,children:o?`Uploading ${o}â¦`:s.length?"+ Add photos":"Upload photos"}),s.length>1&&e.jsx("span",{className:"muted",style:{fontSize:12},children:"Drag a photo to reorder â the first is the cover."})]}),e.jsx("input",{ref:h,type:"file",accept:"image/jpeg,image/png,image/gif,image/webp",multiple:!0,style:{display:"none"},onChange:$}),j&&e.jsx(q,{title:j.original_filename||"Photo",onClose:()=>k(null),children:e.jsx("img",{src:`/uploads/${j.filename}`,alt:"",style:{display:"block",maxWidth:"100%",maxHeight:"75vh",width:"auto",height:"auto",objectFit:"contain",margin:"0 auto",borderRadius:8}})})]})}function Ue({variant:t,images:a,onSave:r}){const h=O(),o=async v=>{try{await r({image_url:v})}catch(p){h(p.message,"err")}};return e.jsx(K,{label:Ee(t),style:{marginBottom:14},children:a!=null&&a.length?e.jsxs("div",{className:"flex",style:{gap:8,flexWrap:"wrap"},children:[e.jsx("button",{type:"button",className:`variant-photo-pick${t.image_url?"":" on"}`,onClick:()=>o(null),title:"Use the product's own photo",children:e.jsx("span",{className:"muted",style:{fontSize:9.5},children:"Default"})}),a.map(v=>{const p=`/uploads/${v.filename}`;return e.jsx("button",{type:"button",className:`variant-photo-pick${t.image_url===p?" on":""}`,onClick:()=>o(p),title:"Use this photo for this variant",children:e.jsx("img",{src:p,alt:""})},v.id)})]}):e.jsx("span",{className:"muted",style:{fontSize:13},children:"Upload a photo above first."})})}function Oe({f:t,set:a,setDirect:r,shop:h,product:o,onImagesChanged:v}){var s;const p=String(t.category_ids||"").split(",").map(d=>
1d.trim()).filter(Boolean),u=d=>{const j=String(d),k=p.includes(j)?p.filter(N=>N!==j):[...p,j];r("category_ids",k.join(","))};return e.jsxs(e.Fragment,{children:[e.jsx("h3",{className:"section",children:"Photos"}),e.jsx(K,{label:"Product photos",hint:"shown on the shop page and the product's own page",children:o!=null&&o.id?e.jsx(We,{product:o,onChanged:v}):e.jsx("span",{className:"muted",style:{fontSize:13},children:"Save the product first to add photos."})}),(o==null?void 0:o.id)&&((s=o.variants)==null?void 0:s.length)>0&&e.jsxs(e.Fragment,{children:[e.jsx("h3",{className:"section",children:"Variant photos"}),e.jsx("div",{className:"hint",style:{marginBottom:12},children:"Shown instead of the photos above when a shopper picks that option."}),o.variants.map(d=>e.jsx(Ue,{variant:d,images:o.images,onSave:j=>L.put(`/products/${o.id}/variants/${d.id}`,j).then(v)},d.id))]}),e.jsx("h3",{className:"section",children:"Listing copy"}),e.jsx(m,{label:"Short description",hint:"shows on the shop grid, and doubles as the search-engine summary for this page",children:e.jsx("textarea",{rows:2,value:t.short_description,onChange:a("short_description")})}),e.jsx(m,{label:"Full description",hint:"shows on the product's own page",children:e.jsx("textarea",{rows:5,value:t.description,onChange:a("description")})}),e.jsx("h3",{className:"section",children:"Search engine (SEO)"}),e.jsx(m,{label:"Meta title",hint:"shown in the browser tab and search results â blank uses the product title",children:e.jsx("input",{value:t.meta_title,onChange:a("meta_title"),placeholder:t.title})}),e.jsx(m,{label:"Meta description",hint:"blank uses the short description above",children:e.jsx("textarea",{rows:2,value:t.meta_description,onChange:a("meta_description")})}),e.jsx("h3",{className:"section",children:"Visibility"}),e.jsx(m,{label:"Show this product on",children:e.jsx(C,{value:t.availability,onChange:a("availability"),options:[{value:"both",label:"Store + website"},{value:"store",label:"Store only"},{value:"web",label:"Website only"}]})}),e.jsxs("label",{className:"check",children:[e.jsx("input",{type:"checkbox",checked:!!t.unlimited_inventory,onChange:a("unlimited_inventory")}),"Unlimited inventory (always shows in stock online â skips stock tracking everywhere, not just on the website)"]}),e.jsx(m,{label:"Categories",hint:"controls which shop-page filters find it",children:h.categories.length?e.jsx("div",{className:"grid k3",style:{gap:4},children:h.categories.map(d=>e.jsxs("label",{className:"check",children:[e.jsx("input",{type:"checkbox",checked:p.includes(String(d.id)),onChange:()=>u(d.id)}),d.name]},d.id))}):e.jsx("span",{className:"muted",style:{fontSize:13},children:"No categories set up yet."})}),e.jsx("h3",{className:"section",children:"Website pricing"}),e.jsxs("div",{className:"grid k2",style:{gap:12},children:[e.jsx(m,{label:"Website price",hint:"leave blank to use the regular price",children:e.jsx("input",{type:"number",step:"0.01",value:t.website_price,onChange:a("website_price")})}),e.jsx(m,{label:"Website sale price",hint:"leave blank for no online sale price",children:e.jsx("input",{type:"number",step:"0.01",value:t.website_sale_price,onChange:a("website_sale_price")})})]})]})}const le=t=>t.filter(a=>a.name.trim()&&a.values.length),Ve=t=>t===0?"option_name":`option${t+1}_name`,qe=t=>t===0?"option_value":`option${t+1}_value`;function ie(t){return le(t).reduce((a,r)=>a.length?a.flatMap(h=>r.values.map(o=>[...h,o])):r.values.map(h=>[h]),[])}function re({values:t,setValues:a,placeholder:r,autoFocus:h}){const[o,v]=b.useState(""),p=()=>{const s=o.trim();s&&!t.includes(s)&&a([...t,s]),v("")},u=s=>a(t.filter(d=>d!==s));return e.jsxs(e.Fragment,{children:[e.jsx("input",{value:o,onChange:s=>v(s.target.value),autoFocus:h,onKeyDown:s=>{(s.key==="Enter"||s.key===",")&&(s.preventDefault(),p())},onBlur:p,placeholder:r}),t.length>0&&e.jsx("div",{className:"pill-row",children:t.map(s=>e.jsxs("span",{className:"badge grey",style:{display:"inline-flex",gap:5,alignItems:"center"},children:[s,e.jsx("button",{type:"button",onClick:()=>u(s),style:{border:0,background:"none",cursor:"pointer",padding:0,lineHeight:1,color:"inherit"},children:"Ã"})]},s))})]})}function Ke({axis:t,onChange:a,onRemove:r}){const h=t.name.trim()&&t.values.length>0;return t.collapsed&&h?e.jsxs("div",{className:"flex",style:{gap:12,alignItems:"center",padding:"10px 0",borderBottom:"1px solid var(--line)"},children:[e.jsxs("div",{style:{flex:1},children:[e.jsx("strong",{children:t.name}),e.jsxs("span",{className:"muted",children:[" â ",t.values.join(", ")
1]})]}),e.jsx("button",{type:"button",className:"ghost sm",onClick:()=>a({...t,collapsed:!1}),children:"Edit"}),e.jsx("button",{type:"button",className:"ghost sm",onClick:r,children:"Remove"})]}):e.jsxs("div",{style:{marginBottom:14,paddingBottom:14,borderBottom:"1px solid var(--line)"},children:[e.jsxs("div",{className:"grid k2",style:{gap:12},children:[e.jsx(m,{label:"Option name",hint:'e.g. "Size" or "Color"',children:e.jsx("input",{value:t.name,onChange:o=>a({...t,name:o.target.value}),placeholder:"Size"})}),e.jsx(m,{label:"Values",hint:"type a value and press Enter to add it",children:e.jsx(re,{values:t.values,setValues:o=>a({...t,values:o}),placeholder:"Small, Medium, Largeâ¦"})})]}),e.jsxs("div",{className:"flex",style:{gap:8,marginTop:8},children:[e.jsx("button",{type:"button",className:"ghost sm",onClick:r,children:"Remove"}),e.jsx("button",{type:"button",className:"sm primary",disabled:!h,onClick:()=>a({...t,collapsed:!0}),children:"Save"})]})]})}function He({row:t,onUpdate:a,onRemove:r}){const h=t.values.join(" / ");return e.jsxs("div",{style:{borderBottom:"1px solid var(--line)"},children:[e.jsxs("div",{className:"flex",style:{gap:10,alignItems:"center",padding:"10px 0",cursor:"pointer"},onClick:()=>a({collapsed:!t.collapsed}),children:[e.jsx("span",{className:"muted",style:{width:12,display:"inline-block"},children:t.collapsed?"â¸":"â¾"}),e.jsx("strong",{style:{flex:1},children:h}),e.jsx("span",{className:"muted",children:t.price!==""?z(Number(t.price)):"uses product price"}),e.jsx("button",{type:"button",className:"ghost sm",onClick:o=>{o.stopPropagation(),r()},children:"Ã"})]}),!t.collapsed&&e.jsxs("div",{className:"grid k3",style:{gap:12,padding:"0 0 14px 22px"},children:[e.jsx(m,{label:"SKU",children:e.jsx("input",{className:"sm mono",value:t.sku,onChange:o=>a({sku:o.target.value})})}),e.jsx(m,{label:"UPC",hint:"leave blank to auto-generate",children:e.jsx("input",{className:"sm mono",value:t.upc,placeholder:"auto",onChange:o=>a({upc:o.target.value})})}),e.jsx(m,{label:"Price",hint:"leave blank to use the product's price",children:e.jsx("input",{className:"sm",type:"number",step:"0.01",value:t.price,onChange:o=>a({price:o.target.value})})})]})]})}function Qe({hasVariants:t,setHasVariants:a,axes:r,setAxes:h,rows:o,setRows:v,showToggle:p=!0,title:u="Variants"}){const[s,d]=b.useState(()=>new Set),[j,k]=b.useState("");b.useEffect(()=>{const y=ie(r);v(x=>{const w=new Map(x.map(c=>[c.key,c]));return y.map(c=>{const E=JSON.stringify(c);return w.get(E)||{key:E,values:c,sku:"",upc:"",price:"",collapsed:!0}}).filter(c=>!s.has(c.key))})},[JSON.stringify(r),s]);const N=()=>h(y=>[...y,{name:"",values:[]}]),$=(y,x)=>h(w=>w.map((c,E)=>E===y?x:c)),g=y=>h(x=>x.filter((w,c)=>c!==y)),l=(y,x)=>v(w=>w.map(c=>c.key===y?{...c,...x}:c)),i=y=>d(x=>new Set(x).add(y)),_=()=>d(new Set),f=()=>v(y=>y.map(x=>({...x,price:j}))),I=y=>{const x=y.target.checked;a(x),x&&!r.length&&h([{name:"",values:[]}])},S=p?t:!0;return e.jsxs(e.Fragment,{children:[p&&e.jsxs(e.Fragment,{children:[e.jsx("h3",{className:"section",children:u}),e.jsxs("label",{className:"check",children:[e.jsx("input",{type:"checkbox",checked:t,onChange:I}),"This product comes in different options (size, color, conditionâ¦)"]})]}),S&&e.jsxs("div",{style:{marginTop:12},children:[r.map((y,x)=>e.jsx(Ke,{axis:y,onChange:w=>$(x,w),onRemove:()=>g(x)},x)),r.length<3&&e.jsx("button",{type:"button",className:"sm",onClick:N,children:"+ Add another option"}),o.length>0&&e.jsxs("div",{style:{marginTop:16},children:[e.jsxs("div",{className:"flex",style:{gap:8,alignItems:"center",marginBottom:4},children:[e.jsx("input",{type:"number",step:"0.01",className:"sm",placeholder:"Price",value:j,onChange:y=>k(y.target.value),style:{width:100}}),e.jsx("button",{type:"button",className:"sm",disabled:j==="",onClick:f,children:"Apply to all variants"})]}),o.map(y=>e.jsx(He,{row:y,onUpdate:x=>l(y.key,x),onRemove:()=>i(y.key)},y.key)),s.size>0&&e.jsxs("button",{type:"button",className:"ghost sm",style:{marginTop:8},onClick:_,children:["Restore ",s.size," removed combination",s.size===1?"":"s"]})]})]})]})}const Je=Object.freeze(Object.defineProperty({__proto__:null,PRODUCT_NUMERIC_FIELDS:Te,ProductFields:ze,ProductWebsiteFields:Oe,TagInput:re,VariantMatrixEditor:Qe,activeAxes:le,blankProductForm:Fe,cartesianRows:ie,default:De,optionNameKey:Ve,optionValueKey:qe},Symbol.toStringTag,{value:"Module"}));
1export{Je as I,ze as P,re as T,Qe as V,Oe as a,Fe as b,Re as c,Te as d,le as e,qe as f,Ve as o};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.