@zonetrix/viewer 2.4.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),t=require("react"),k=require("react-konva");function P(i){const[h,u]=t.useState(null),[m,S]=t.useState(!1),[C,x]=t.useState(null),b=async()=>{if(i){S(!0),x(null);try{const f=await fetch(i);if(!f.ok)throw new Error(`Failed to fetch config: ${f.statusText}`);const c=await f.json();u(c)}catch(f){const c=f instanceof Error?f:new Error("Unknown error occurred");x(c),console.error("Failed to fetch seat map config:",c)}finally{S(!1)}}};return t.useEffect(()=>{b()},[i]),{config:h,loading:m,error:C,refetch:b}}const G={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},J=t.memo(({seat:i,state:h,colors:u,onClick:m})=>{const x={available:u.seatAvailable,reserved:u.seatReserved,selected:u.seatSelected,unavailable:u.seatUnavailable,hidden:u.seatHidden}[h],b=h==="available"||h==="selected",f=t.useCallback(()=>{b&&m(i)},[i,m,b]),c={x:i.position.x,y:i.position.y,fill:x,stroke:"#ffffff",strokeWidth:1,onClick:f,onTap:f};return i.shape==="circle"?o.jsx(k.Circle,{...c,radius:12}):o.jsx(k.Rect,{...c,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:i.shape==="square"?0:4})});J.displayName="ViewerSeat";const Q=t.memo(({stage:i,stageColor:h})=>o.jsxs(k.Group,{x:i.position.x,y:i.position.y,children:[o.jsx(k.Rect,{width:i.config.width,height:i.config.height,fill:h+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),o.jsx(k.Text,{text:i.config.label,x:0,y:0,width:i.config.width,height:i.config.height,fontSize:24,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle"})]}));Q.displayName="ViewerStage";const ee=t.memo(({floors:i,currentFloorId:h,onFloorChange:u,showAllOption:m,allLabel:S,position:C,className:x})=>{const b=t.useMemo(()=>[...i].sort((p,E)=>p.order-E.order),[i]),c={position:"absolute",display:"flex",alignItems:"center",gap:"8px",padding:"8px 12px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[C]},M={padding:"6px 14px",fontSize:"14px",fontWeight:500,border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",transition:"all 0.2s ease"},y={...M,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return o.jsxs("div",{className:x,style:c,children:[m&&o.jsx("button",{type:"button",onClick:()=>u(null),style:h===null?y:M,children:S}),b.map(p=>o.jsx("button",{type:"button",onClick:()=>u(p.id),style:h===p.id?y:M,children:p.name},p.id))]})});ee.displayName="FloorSelectorBar";const te=t.memo(({scale:i,minScale:h,maxScale:u,onZoomIn:m,onZoomOut:S,position:C,className:x})=>{const f={position:"absolute",display:"flex",flexDirection:"column",gap:"4px",padding:"8px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[C]},c={width:"36px",height:"36px",fontSize:"20px",fontWeight:"bold",border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s ease"},M={...c,opacity:.4,cursor:"not-allowed"},y=i<u,p=i>h;return o.jsxs("div",{className:x,style:f,children:[o.jsx("button",{type:"button",onClick:m,disabled:!y,style:y?c:M,title:"Zoom In",children:"+"}),o.jsx("button",{type:"button",onClick:S,disabled:!p,style:p?c:M,title:"Zoom Out",children:"−"})]})});te.displayName="ZoomControls";const Ee=({config:i,configUrl:h,floorId:u,onFloorChange:m,reservedSeats:S=[],unavailableSeats:C=[],onSeatSelect:x,onSeatDeselect:b,onSelectionChange:f,colorOverrides:c,showTooltip:M=!0,zoomEnabled:y=!0,className:p="",onConfigLoad:E,onError:W,showFloorSelector:q,floorSelectorPosition:ne="top-left",floorSelectorClassName:oe,showAllFloorsOption:se=!0,allFloorsLabel:ie="All",fitToView:Y=!0,fitPadding:B=40,showZoomControls:ae=!0,zoomControlsPosition:re="bottom-right",zoomControlsClassName:le,maxZoom:F=3,zoomStep:O=.25})=>{const ce=t.useRef(null),[I,de]=t.useState(new Set),[g,H]=t.useState(1),[w,T]=t.useState({x:0,y:0}),[ue,fe]=t.useState(null),[U,K]=t.useState(!1),[he,pe]=t.useState(1),{config:ge,loading:xe,error:R}=P(h),n=i||ge,$=u!==void 0,v=$?u||null:ue,me=t.useCallback(e=>{$||fe(e),m?.(e)},[$,m]),Z=n?.floors||[],be=q!==void 0?q:Z.length>1,z=t.useMemo(()=>n?{...n.colors,...c}:{...G,...c},[n,c]),N=t.useMemo(()=>{if(!n)return[];let e=n.seats.filter(s=>s.state!=="hidden");return v&&(e=e.filter(s=>s.floorId===v||!s.floorId&&v==="floor_default")),e},[n,v]),D=t.useMemo(()=>n?.stages?v?n.stages.filter(e=>e.floorId===v||!e.floorId&&v==="floor_default"):n.stages:[],[n,v]),j=t.useMemo(()=>{if(!n||N.length===0&&D.length===0)return null;const e=12;let s=1/0,r=1/0,d=-1/0,l=-1/0;return N.forEach(a=>{s=Math.min(s,a.position.x-e),r=Math.min(r,a.position.y-e),d=Math.max(d,a.position.x+e),l=Math.max(l,a.position.y+e)}),D.forEach(a=>{s=Math.min(s,a.position.x),r=Math.min(r,a.position.y),d=Math.max(d,a.position.x+(a.config?.width||200)),l=Math.max(l,a.position.y+(a.config?.height||100))}),{minX:s,minY:r,maxX:d,maxY:l,width:d-s,height:l-r}},[n,N,D]);t.useEffect(()=>{if(!Y||U||!n||!j)return;const e=n.canvas.width,s=n.canvas.height,r=e-B*2,d=s-B*2,l=r/j.width,a=d/j.height,L=Math.min(l,a,F),we=j.minX+j.width/2,je=j.minY+j.height/2,ke=e/2,Me=s/2,Ie=ke-we*L,Ne=Me-je*L;H(L),T({x:Ie,y:Ne}),pe(L),K(!0)},[Y,U,n,j,B,F]),t.useEffect(()=>{Y&&K(!1)},[v,Y]);const A=t.useMemo(()=>{const e=new Set(S),s=new Set(C);return{reserved:e,unavailable:s}},[S,C]),V=t.useCallback(e=>{const s=e.id,r=e.seatNumber||"";return A.unavailable.has(s)||A.unavailable.has(r)?"unavailable":A.reserved.has(s)||A.reserved.has(r)?"reserved":I.has(s)?"selected":e.state},[A,I]);t.useEffect(()=>{n&&E&&E(n)},[n,E]),t.useEffect(()=>{R&&W&&W(R)},[R,W]);const ye=t.useCallback(e=>{const s=V(e);if(s!=="available"&&s!=="selected")return;const r=I.has(e.id);de(d=>{const l=new Set(d);return r?l.delete(e.id):l.add(e.id),l}),r?b?.(e):(x?.(e),x||console.log("Seat selected:",e))},[V,I,x,b]),X=t.useMemo(()=>n?N.filter(e=>I.has(e.id)):[],[N,I]);t.useEffect(()=>{f?.(X)},[X,f]);const _=he,Se=t.useCallback(()=>{if(!y)return;const e=Math.min(g+O,F);if(e!==g){const s=n?.canvas.width||800,r=n?.canvas.height||600,d=s/2,l=r/2,a={x:(d-w.x)/g,y:(l-w.y)/g};H(e),T({x:d-a.x*e,y:l-a.y*e})}},[y,g,O,F,n,w]),ve=t.useCallback(()=>{if(!y)return;const e=Math.max(g-O,_);if(e!==g){const s=n?.canvas.width||800,r=n?.canvas.height||600,d=s/2,l=r/2,a={x:(d-w.x)/g,y:(l-w.y)/g};H(e),T({x:d-a.x*e,y:l-a.y*e})}},[y,g,O,_,n,w]),Ce=t.useCallback(e=>{T({x:e.target.x(),y:e.target.y()})},[]);return xe?o.jsx("div",{className:`flex items-center justify-center h-full ${p}`,children:o.jsx("p",{children:"Loading seat map..."})}):R?o.jsx("div",{className:`flex items-center justify-center h-full ${p}`,children:o.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",R.message]})}):n?o.jsxs("div",{className:`relative ${p}`,children:[be&&Z.length>0&&o.jsx(ee,{floors:Z,currentFloorId:v,onFloorChange:me,showAllOption:se,allLabel:ie,position:ne,className:oe}),o.jsxs(k.Stage,{ref:ce,width:n.canvas.width,height:n.canvas.height,scaleX:g,scaleY:g,x:w.x,y:w.y,draggable:!0,onDragEnd:Ce,style:{backgroundColor:n.canvas.backgroundColor,cursor:"grab"},children:[o.jsx(k.Layer,{listening:!1,children:D.map(e=>o.jsx(Q,{stage:e,stageColor:z.stageColor},e.id))}),o.jsx(k.Layer,{children:N.map(e=>o.jsx(J,{seat:e,state:V(e),colors:z,onClick:ye},e.id))})]}),ae&&y&&o.jsx(te,{scale:g,minScale:_,maxScale:F,onZoomIn:Se,onZoomOut:ve,position:re,className:le}),X.length>0&&o.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[o.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",X.length,")"]}),o.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:X.map(e=>o.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${z.currency} ${e.price.toFixed(2)}`]},e.id))})]})]}):o.jsx("div",{className:`flex items-center justify-center h-full ${p}`,children:o.jsx("p",{children:"No configuration provided"})})};exports.DEFAULT_COLORS=G;exports.SeatMapViewer=Ee;exports.useConfigFetcher=P;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),n=require("react"),E=require("react-konva");function J(o){const[p,h]=n.useState(null),[a,y]=n.useState(!1),[m,S]=n.useState(null),j=async()=>{if(o){y(!0),S(null);try{const x=await fetch(o);if(!x.ok)throw new Error(`Failed to fetch config: ${x.statusText}`);const r=await x.json();h(r)}catch(x){const r=x instanceof Error?x:new Error("Unknown error occurred");S(r),console.error("Failed to fetch seat map config:",r)}finally{y(!1)}}};return n.useEffect(()=>{j()},[o]),{config:p,loading:a,error:m,refetch:j}}const Q={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},ee=n.memo(({seat:o,state:p,colors:h,onClick:a,onMouseEnter:y,onMouseLeave:m})=>{const x={available:h.seatAvailable,reserved:h.seatReserved,selected:h.seatSelected,unavailable:h.seatUnavailable,hidden:h.seatHidden}[p],r=p==="available"||p==="selected",g=n.useCallback(()=>{r&&a(o)},[o,a,r]),b=n.useCallback(k=>{y(o,k);const M=k.target.getStage();M&&r&&(M.container().style.cursor="pointer")},[o,y,r]),f=n.useCallback(k=>{m();const M=k.target.getStage();M&&(M.container().style.cursor="grab")},[m]),w={x:o.position.x,y:o.position.y,fill:x,stroke:"#ffffff",strokeWidth:1,onClick:g,onTap:g,onMouseEnter:b,onMouseLeave:f};return o.shape==="circle"?t.jsx(E.Circle,{...w,radius:12}):t.jsx(E.Rect,{...w,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:o.shape==="square"?0:4})});ee.displayName="ViewerSeat";const te=n.memo(({stage:o,stageColor:p})=>t.jsxs(E.Group,{x:o.position.x,y:o.position.y,children:[t.jsx(E.Rect,{width:o.config.width,height:o.config.height,fill:p+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),t.jsx(E.Text,{text:o.config.label,x:0,y:0,width:o.config.width,height:o.config.height,fontSize:24,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle"})]}));te.displayName="ViewerStage";const ne=n.memo(({floors:o,currentFloorId:p,onFloorChange:h,showAllOption:a,allLabel:y,position:m,className:S})=>{const j=n.useMemo(()=>[...o].sort((f,w)=>f.order-w.order),[o]),r={position:"absolute",display:"flex",alignItems:"center",gap:"8px",padding:"8px 12px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[m]},g={padding:"6px 14px",fontSize:"14px",fontWeight:500,border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",transition:"all 0.2s ease"},b={...g,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return t.jsxs("div",{className:S,style:r,children:[a&&t.jsx("button",{type:"button",onClick:()=>h(null),style:p===null?b:g,children:y}),j.map(f=>t.jsx("button",{type:"button",onClick:()=>h(f.id),style:p===f.id?b:g,children:f.name},f.id))]})});ne.displayName="FloorSelectorBar";const se=n.memo(({scale:o,minScale:p,maxScale:h,onZoomIn:a,onZoomOut:y,position:m,className:S})=>{const x={position:"absolute",display:"flex",flexDirection:"column",gap:"4px",padding:"8px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[m]},r={width:"36px",height:"36px",fontSize:"20px",fontWeight:"bold",border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s ease"},g={...r,opacity:.4,cursor:"not-allowed"},b=o<h,f=o>p;return t.jsxs("div",{className:S,style:x,children:[t.jsx("button",{type:"button",onClick:a,disabled:!b,style:b?r:g,title:"Zoom In",children:"+"}),t.jsx("button",{type:"button",onClick:y,disabled:!f,style:f?r:g,title:"Zoom Out",children:"−"})]})});se.displayName="ZoomControls";const oe=n.memo(({visible:o,x:p,y:h,seat:a,currency:y,state:m})=>{if(!o||!a)return null;const S=a.seatNumber||(a.rowLabel&&a.columnLabel?`${a.rowLabel}-${a.columnLabel}`:"N/A"),j={position:"fixed",left:`${p+15}px`,top:`${h+15}px`,zIndex:1e3,pointerEvents:"none"},x={backgroundColor:"rgba(26, 26, 26, 0.95)",color:"#fff",border:"1px solid #444",borderRadius:"8px",padding:"8px 12px",fontSize:"13px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.3)",minWidth:"140px"},r={color:"#9ca3af",marginRight:"4px"},g={fontWeight:600},b={color:"#4ade80",fontWeight:600},f={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return t.jsx("div",{style:j,children:t.jsxs("div",{style:x,children:[a.sectionName&&t.jsxs("div",{style:{marginBottom:"4px"},children:[t.jsx("span",{style:r,children:"Section:"}),t.jsx("span",{style:{...g,color:"#3b82f6"},children:a.sectionName})]}),t.jsxs("div",{style:{marginBottom:"4px"},children:[t.jsx("span",{style:r,children:"Seat:"}),t.jsx("span",{style:g,children:S})]}),a.price!==void 0&&a.price>0&&t.jsxs("div",{style:{marginBottom:"4px"},children:[t.jsx("span",{style:r,children:"Price:"}),t.jsxs("span",{style:b,children:[y," ",a.price.toFixed(2)]})]}),t.jsxs("div",{style:f,children:["Status: ",m]})]})})});oe.displayName="SeatTooltip";const Be=({config:o,configUrl:p,floorId:h,onFloorChange:a,reservedSeats:y=[],unavailableSeats:m=[],onSeatSelect:S,onSeatDeselect:j,onSelectionChange:x,colorOverrides:r,showTooltip:g=!0,zoomEnabled:b=!0,className:f="",onConfigLoad:w,onError:k,showFloorSelector:M,floorSelectorPosition:ie="top-left",floorSelectorClassName:ae,showAllFloorsOption:re=!0,allFloorsLabel:le="All",fitToView:$=!0,fitPadding:P=40,showZoomControls:ce=!0,zoomControlsPosition:de="bottom-right",zoomControlsClassName:ue,maxZoom:L=3,zoomStep:D=.25})=>{const fe=n.useRef(null),[R,he]=n.useState(new Set),[v,Z]=n.useState(1),[I,T]=n.useState({x:0,y:0}),[pe,xe]=n.useState(null),[U,K]=n.useState(!1),[ge,be]=n.useState(1),[A,G]=n.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:ye,loading:me,error:B}=J(p),s=o||ye,V=h!==void 0,C=V?h||null:pe,Se=n.useCallback(e=>{V||xe(e),a?.(e)},[V,a]),q=s?.floors||[],ve=M!==void 0?M:q.length>1,z=n.useMemo(()=>s?{...s.colors,...r}:{...Q,...r},[s,r]),F=n.useMemo(()=>{if(!s)return[];let e=s.seats.filter(i=>i.state!=="hidden");return C&&(e=e.filter(i=>i.floorId===C||!i.floorId&&C==="floor_default")),e},[s,C]),O=n.useMemo(()=>s?.stages?C?s.stages.filter(e=>e.floorId===C||!e.floorId&&C==="floor_default"):s.stages:[],[s,C]),N=n.useMemo(()=>{if(!s||F.length===0&&O.length===0)return null;const e=12;let i=1/0,l=1/0,d=-1/0,c=-1/0;return F.forEach(u=>{i=Math.min(i,u.position.x-e),l=Math.min(l,u.position.y-e),d=Math.max(d,u.position.x+e),c=Math.max(c,u.position.y+e)}),O.forEach(u=>{i=Math.min(i,u.position.x),l=Math.min(l,u.position.y),d=Math.max(d,u.position.x+(u.config?.width||200)),c=Math.max(c,u.position.y+(u.config?.height||100))}),{minX:i,minY:l,maxX:d,maxY:c,width:d-i,height:c-l}},[s,F,O]);n.useEffect(()=>{if(!$||U||!s||!N)return;const e=s.canvas.width,i=s.canvas.height,l=e-P*2,d=i-P*2,c=l/N.width,u=d/N.height,H=Math.min(c,u,L),Ne=N.minX+N.width/2,Ee=N.minY+N.height/2,Re=e/2,Fe=i/2,Le=Re-Ne*H,Ae=Fe-Ee*H;Z(H),T({x:Le,y:Ae}),be(H),K(!0)},[$,U,s,N,P,L]),n.useEffect(()=>{$&&K(!1)},[C,$]);const W=n.useMemo(()=>{const e=new Set(y),i=new Set(m);return{reserved:e,unavailable:i}},[y,m]),X=n.useCallback(e=>{const i=e.id,l=e.seatNumber||"";return W.unavailable.has(i)||W.unavailable.has(l)?"unavailable":W.reserved.has(i)||W.reserved.has(l)?"reserved":R.has(i)?"selected":e.state},[W,R]);n.useEffect(()=>{s&&w&&w(s)},[s,w]),n.useEffect(()=>{B&&k&&k(B)},[B,k]);const je=n.useCallback(e=>{const i=X(e);if(i!=="available"&&i!=="selected")return;const l=R.has(e.id);he(d=>{const c=new Set(d);return l?c.delete(e.id):c.add(e.id),c}),l?j?.(e):(S?.(e),S||console.log("Seat selected:",e))},[X,R,S,j]),Y=n.useMemo(()=>s?F.filter(e=>R.has(e.id)):[],[F,R]);n.useEffect(()=>{x?.(Y)},[Y,x]);const _=ge,Ce=n.useCallback(()=>{if(!b)return;const e=Math.min(v+D,L);if(e!==v){const i=s?.canvas.width||800,l=s?.canvas.height||600,d=i/2,c=l/2,u={x:(d-I.x)/v,y:(c-I.y)/v};Z(e),T({x:d-u.x*e,y:c-u.y*e})}},[b,v,D,L,s,I]),we=n.useCallback(()=>{if(!b)return;const e=Math.max(v-D,_);if(e!==v){const i=s?.canvas.width||800,l=s?.canvas.height||600,d=i/2,c=l/2,u={x:(d-I.x)/v,y:(c-I.y)/v};Z(e),T({x:d-u.x*e,y:c-u.y*e})}},[b,v,D,_,s,I]),ke=n.useCallback(e=>{T({x:e.target.x(),y:e.target.y()})},[]),Me=n.useCallback((e,i)=>{if(!g)return;const l=i.target.getStage();if(!l)return;const d=l.getPointerPosition();if(!d)return;const c=l.container().getBoundingClientRect();G({visible:!0,x:c.left+d.x,y:c.top+d.y,seat:e,state:X(e)})},[g,X]),Ie=n.useCallback(()=>{G(e=>({...e,visible:!1}))},[]);return me?t.jsx("div",{className:`flex items-center justify-center h-full ${f}`,children:t.jsx("p",{children:"Loading seat map..."})}):B?t.jsx("div",{className:`flex items-center justify-center h-full ${f}`,children:t.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",B.message]})}):s?t.jsxs("div",{className:`relative ${f}`,children:[ve&&q.length>0&&t.jsx(ne,{floors:q,currentFloorId:C,onFloorChange:Se,showAllOption:re,allLabel:le,position:ie,className:ae}),t.jsxs(E.Stage,{ref:fe,width:s.canvas.width,height:s.canvas.height,scaleX:v,scaleY:v,x:I.x,y:I.y,draggable:!0,onDragEnd:ke,style:{backgroundColor:s.canvas.backgroundColor,cursor:"grab"},children:[t.jsx(E.Layer,{listening:!1,children:O.map(e=>t.jsx(te,{stage:e,stageColor:z.stageColor},e.id))}),t.jsx(E.Layer,{children:F.map(e=>t.jsx(ee,{seat:e,state:X(e),colors:z,onClick:je,onMouseEnter:Me,onMouseLeave:Ie},e.id))})]}),g&&t.jsx(oe,{visible:A.visible,x:A.x,y:A.y,seat:A.seat,currency:z.currency,state:A.state}),ce&&b&&t.jsx(se,{scale:v,minScale:_,maxScale:L,onZoomIn:Ce,onZoomOut:we,position:de,className:ue}),Y.length>0&&t.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[t.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",Y.length,")"]}),t.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:Y.map(e=>t.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${z.currency} ${e.price.toFixed(2)}`]},e.id))})]})]}):t.jsx("div",{className:`flex items-center justify-center h-full ${f}`,children:t.jsx("p",{children:"No configuration provided"})})};exports.DEFAULT_COLORS=Q;exports.SeatMapViewer=Be;exports.useConfigFetcher=J;
package/dist/index.mjs CHANGED
@@ -1,34 +1,34 @@
1
- import { jsx as i, jsxs as w } from "react/jsx-runtime";
2
- import { useState as C, useEffect as Y, useRef as Et, useCallback as M, useMemo as F, memo as Z } from "react";
3
- import { Stage as Wt, Layer as tt, Group as jt, Rect as et, Text as Bt, Circle as Dt } from "react-konva";
4
- function Ht(o) {
5
- const [f, d] = C(null), [m, x] = C(!1), [S, g] = C(null), y = async () => {
6
- if (o) {
7
- x(!0), g(null);
1
+ import { jsx as i, jsxs as x } from "react/jsx-runtime";
2
+ import { useState as I, useEffect as W, useRef as zt, useCallback as C, useMemo as L, memo as j } from "react";
3
+ import { Stage as Dt, Layer as nt, Group as Tt, Rect as ot, Text as jt, Circle as Ht } from "react-konva";
4
+ function Ot(n) {
5
+ const [u, h] = I(null), [r, b] = I(!1), [m, v] = I(null), w = async () => {
6
+ if (n) {
7
+ b(!0), v(null);
8
8
  try {
9
- const h = await fetch(o);
10
- if (!h.ok)
11
- throw new Error(`Failed to fetch config: ${h.statusText}`);
12
- const l = await h.json();
13
- d(l);
14
- } catch (h) {
15
- const l = h instanceof Error ? h : new Error("Unknown error occurred");
16
- g(l), console.error("Failed to fetch seat map config:", l);
9
+ const p = await fetch(n);
10
+ if (!p.ok)
11
+ throw new Error(`Failed to fetch config: ${p.statusText}`);
12
+ const s = await p.json();
13
+ h(s);
14
+ } catch (p) {
15
+ const s = p instanceof Error ? p : new Error("Unknown error occurred");
16
+ v(s), console.error("Failed to fetch seat map config:", s);
17
17
  } finally {
18
- x(!1);
18
+ b(!1);
19
19
  }
20
20
  }
21
21
  };
22
- return Y(() => {
23
- y();
24
- }, [o]), {
25
- config: f,
26
- loading: m,
27
- error: S,
28
- refetch: y
22
+ return W(() => {
23
+ w();
24
+ }, [n]), {
25
+ config: u,
26
+ loading: r,
27
+ error: m,
28
+ refetch: w
29
29
  };
30
30
  }
31
- const Tt = {
31
+ const Zt = {
32
32
  canvasBackground: "#1a1a1a",
33
33
  stageColor: "#808080",
34
34
  seatAvailable: "#2C2B30",
@@ -38,64 +38,74 @@ const Tt = {
38
38
  seatHidden: "#4a4a4a",
39
39
  gridLines: "#404040",
40
40
  currency: "KD"
41
- }, nt = Z(({ seat: o, state: f, colors: d, onClick: m }) => {
42
- const g = {
43
- available: d.seatAvailable,
44
- reserved: d.seatReserved,
45
- selected: d.seatSelected,
46
- unavailable: d.seatUnavailable,
47
- hidden: d.seatHidden
41
+ }, it = j(({ seat: n, state: u, colors: h, onClick: r, onMouseEnter: b, onMouseLeave: m }) => {
42
+ const p = {
43
+ available: h.seatAvailable,
44
+ reserved: h.seatReserved,
45
+ selected: h.seatSelected,
46
+ unavailable: h.seatUnavailable,
47
+ hidden: h.seatHidden
48
48
  // Hidden seats are filtered out, but included for type safety
49
- }[f], y = f === "available" || f === "selected", h = M(() => {
50
- y && m(o);
51
- }, [o, m, y]), l = {
52
- x: o.position.x,
53
- y: o.position.y,
54
- fill: g,
49
+ }[u], s = u === "available" || u === "selected", g = C(() => {
50
+ s && r(n);
51
+ }, [n, r, s]), y = C((M) => {
52
+ b(n, M);
53
+ const R = M.target.getStage();
54
+ R && s && (R.container().style.cursor = "pointer");
55
+ }, [n, b, s]), f = C((M) => {
56
+ m();
57
+ const R = M.target.getStage();
58
+ R && (R.container().style.cursor = "grab");
59
+ }, [m]), N = {
60
+ x: n.position.x,
61
+ y: n.position.y,
62
+ fill: p,
55
63
  stroke: "#ffffff",
56
64
  strokeWidth: 1,
57
- onClick: h,
58
- onTap: h
65
+ onClick: g,
66
+ onTap: g,
67
+ onMouseEnter: y,
68
+ onMouseLeave: f
59
69
  };
60
- return o.shape === "circle" ? /* @__PURE__ */ i(
61
- Dt,
70
+ return n.shape === "circle" ? /* @__PURE__ */ i(
71
+ Ht,
62
72
  {
63
- ...l,
73
+ ...N,
64
74
  radius: 12
65
75
  }
66
76
  ) : /* @__PURE__ */ i(
67
- et,
77
+ ot,
68
78
  {
69
- ...l,
79
+ ...N,
70
80
  width: 24,
71
81
  height: 24,
72
82
  offsetX: 12,
73
83
  offsetY: 12,
74
- cornerRadius: o.shape === "square" ? 0 : 4
84
+ cornerRadius: n.shape === "square" ? 0 : 4
75
85
  }
76
86
  );
77
87
  });
78
- nt.displayName = "ViewerSeat";
79
- const ot = Z(({ stage: o, stageColor: f }) => /* @__PURE__ */ w(jt, { x: o.position.x, y: o.position.y, children: [
88
+ it.displayName = "ViewerSeat";
89
+ const rt = j(({ stage: n, stageColor: u }) => /* @__PURE__ */ x(Tt, { x: n.position.x, y: n.position.y, children: [
80
90
  /* @__PURE__ */ i(
81
- et,
91
+ ot,
82
92
  {
83
- width: o.config.width,
84
- height: o.config.height,
85
- fill: f + "80",
93
+ width: n.config.width,
94
+ height: n.config.height,
95
+ fill: u + "80",
86
96
  stroke: "#ffffff",
87
97
  strokeWidth: 2,
88
98
  cornerRadius: 10
89
99
  }
90
100
  ),
91
101
  /* @__PURE__ */ i(
92
- Bt,
102
+ jt,
93
103
  {
94
- text: o.config.label,
104
+ text: n.config.label,
95
105
  x: 0,
96
106
  y: 0,
97
- width: o.config.width,
98
- height: o.config.height,
107
+ width: n.config.width,
108
+ height: n.config.height,
99
109
  fontSize: 24,
100
110
  fontStyle: "bold",
101
111
  fill: "#ffffff",
@@ -104,20 +114,20 @@ const ot = Z(({ stage: o, stageColor: f }) => /* @__PURE__ */ w(jt, { x: o.posit
104
114
  }
105
115
  )
106
116
  ] }));
107
- ot.displayName = "ViewerStage";
108
- const it = Z(({
109
- floors: o,
110
- currentFloorId: f,
111
- onFloorChange: d,
112
- showAllOption: m,
113
- allLabel: x,
114
- position: S,
115
- className: g
117
+ rt.displayName = "ViewerStage";
118
+ const st = j(({
119
+ floors: n,
120
+ currentFloorId: u,
121
+ onFloorChange: h,
122
+ showAllOption: r,
123
+ allLabel: b,
124
+ position: m,
125
+ className: v
116
126
  }) => {
117
- const y = F(
118
- () => [...o].sort((u, A) => u.order - A.order),
119
- [o]
120
- ), l = {
127
+ const w = L(
128
+ () => [...n].sort((f, N) => f.order - N.order),
129
+ [n]
130
+ ), s = {
121
131
  position: "absolute",
122
132
  display: "flex",
123
133
  alignItems: "center",
@@ -132,8 +142,8 @@ const it = Z(({
132
142
  "top-right": { top: 0, right: 0 },
133
143
  "bottom-left": { bottom: 0, left: 0 },
134
144
  "bottom-right": { bottom: 0, right: 0 }
135
- }[S]
136
- }, N = {
145
+ }[m]
146
+ }, g = {
137
147
  padding: "6px 14px",
138
148
  fontSize: "14px",
139
149
  fontWeight: 500,
@@ -143,44 +153,44 @@ const it = Z(({
143
153
  color: "#fff",
144
154
  cursor: "pointer",
145
155
  transition: "all 0.2s ease"
146
- }, b = {
147
- ...N,
156
+ }, y = {
157
+ ...g,
148
158
  backgroundColor: "#3A7DE5",
149
159
  borderColor: "#3A7DE5"
150
160
  };
151
- return /* @__PURE__ */ w("div", { className: g, style: l, children: [
152
- m && /* @__PURE__ */ i(
161
+ return /* @__PURE__ */ x("div", { className: v, style: s, children: [
162
+ r && /* @__PURE__ */ i(
153
163
  "button",
154
164
  {
155
165
  type: "button",
156
- onClick: () => d(null),
157
- style: f === null ? b : N,
158
- children: x
166
+ onClick: () => h(null),
167
+ style: u === null ? y : g,
168
+ children: b
159
169
  }
160
170
  ),
161
- y.map((u) => /* @__PURE__ */ i(
171
+ w.map((f) => /* @__PURE__ */ i(
162
172
  "button",
163
173
  {
164
174
  type: "button",
165
- onClick: () => d(u.id),
166
- style: f === u.id ? b : N,
167
- children: u.name
175
+ onClick: () => h(f.id),
176
+ style: u === f.id ? y : g,
177
+ children: f.name
168
178
  },
169
- u.id
179
+ f.id
170
180
  ))
171
181
  ] });
172
182
  });
173
- it.displayName = "FloorSelectorBar";
174
- const st = Z(({
175
- scale: o,
176
- minScale: f,
177
- maxScale: d,
178
- onZoomIn: m,
179
- onZoomOut: x,
180
- position: S,
181
- className: g
183
+ st.displayName = "FloorSelectorBar";
184
+ const at = j(({
185
+ scale: n,
186
+ minScale: u,
187
+ maxScale: h,
188
+ onZoomIn: r,
189
+ onZoomOut: b,
190
+ position: m,
191
+ className: v
182
192
  }) => {
183
- const h = {
193
+ const p = {
184
194
  position: "absolute",
185
195
  display: "flex",
186
196
  flexDirection: "column",
@@ -195,8 +205,8 @@ const st = Z(({
195
205
  "top-right": { top: 0, right: 0 },
196
206
  "bottom-left": { bottom: 0, left: 0 },
197
207
  "bottom-right": { bottom: 0, right: 0 }
198
- }[S]
199
- }, l = {
208
+ }[m]
209
+ }, s = {
200
210
  width: "36px",
201
211
  height: "36px",
202
212
  fontSize: "20px",
@@ -210,19 +220,19 @@ const st = Z(({
210
220
  alignItems: "center",
211
221
  justifyContent: "center",
212
222
  transition: "all 0.2s ease"
213
- }, N = {
214
- ...l,
223
+ }, g = {
224
+ ...s,
215
225
  opacity: 0.4,
216
226
  cursor: "not-allowed"
217
- }, b = o < d, u = o > f;
218
- return /* @__PURE__ */ w("div", { className: g, style: h, children: [
227
+ }, y = n < h, f = n > u;
228
+ return /* @__PURE__ */ x("div", { className: v, style: p, children: [
219
229
  /* @__PURE__ */ i(
220
230
  "button",
221
231
  {
222
232
  type: "button",
223
- onClick: m,
224
- disabled: !b,
225
- style: b ? l : N,
233
+ onClick: r,
234
+ disabled: !y,
235
+ style: y ? s : g,
226
236
  title: "Zoom In",
227
237
  children: "+"
228
238
  }
@@ -231,213 +241,304 @@ const st = Z(({
231
241
  "button",
232
242
  {
233
243
  type: "button",
234
- onClick: x,
235
- disabled: !u,
236
- style: u ? l : N,
244
+ onClick: b,
245
+ disabled: !f,
246
+ style: f ? s : g,
237
247
  title: "Zoom Out",
238
248
  children: "−"
239
249
  }
240
250
  )
241
251
  ] });
242
252
  });
243
- st.displayName = "ZoomControls";
244
- const zt = ({
245
- config: o,
246
- configUrl: f,
247
- floorId: d,
248
- onFloorChange: m,
249
- reservedSeats: x = [],
250
- unavailableSeats: S = [],
251
- onSeatSelect: g,
252
- onSeatDeselect: y,
253
- onSelectionChange: h,
254
- colorOverrides: l,
255
- showTooltip: N = !0,
256
- zoomEnabled: b = !0,
257
- className: u = "",
258
- onConfigLoad: A,
259
- onError: z,
253
+ at.displayName = "ZoomControls";
254
+ const lt = j(({
255
+ visible: n,
256
+ x: u,
257
+ y: h,
258
+ seat: r,
259
+ currency: b,
260
+ state: m
261
+ }) => {
262
+ if (!n || !r) return null;
263
+ const v = r.seatNumber || (r.rowLabel && r.columnLabel ? `${r.rowLabel}-${r.columnLabel}` : "N/A"), w = {
264
+ position: "fixed",
265
+ left: `${u + 15}px`,
266
+ top: `${h + 15}px`,
267
+ zIndex: 1e3,
268
+ pointerEvents: "none"
269
+ }, p = {
270
+ backgroundColor: "rgba(26, 26, 26, 0.95)",
271
+ color: "#fff",
272
+ border: "1px solid #444",
273
+ borderRadius: "8px",
274
+ padding: "8px 12px",
275
+ fontSize: "13px",
276
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.3)",
277
+ minWidth: "140px"
278
+ }, s = {
279
+ color: "#9ca3af",
280
+ marginRight: "4px"
281
+ }, g = {
282
+ fontWeight: 600
283
+ }, y = {
284
+ color: "#4ade80",
285
+ fontWeight: 600
286
+ }, f = {
287
+ fontSize: "11px",
288
+ color: "#6b7280",
289
+ textTransform: "capitalize",
290
+ marginTop: "4px"
291
+ };
292
+ return /* @__PURE__ */ i("div", { style: w, children: /* @__PURE__ */ x("div", { style: p, children: [
293
+ r.sectionName && /* @__PURE__ */ x("div", { style: { marginBottom: "4px" }, children: [
294
+ /* @__PURE__ */ i("span", { style: s, children: "Section:" }),
295
+ /* @__PURE__ */ i("span", { style: { ...g, color: "#3b82f6" }, children: r.sectionName })
296
+ ] }),
297
+ /* @__PURE__ */ x("div", { style: { marginBottom: "4px" }, children: [
298
+ /* @__PURE__ */ i("span", { style: s, children: "Seat:" }),
299
+ /* @__PURE__ */ i("span", { style: g, children: v })
300
+ ] }),
301
+ r.price !== void 0 && r.price > 0 && /* @__PURE__ */ x("div", { style: { marginBottom: "4px" }, children: [
302
+ /* @__PURE__ */ i("span", { style: s, children: "Price:" }),
303
+ /* @__PURE__ */ x("span", { style: y, children: [
304
+ b,
305
+ " ",
306
+ r.price.toFixed(2)
307
+ ] })
308
+ ] }),
309
+ /* @__PURE__ */ x("div", { style: f, children: [
310
+ "Status: ",
311
+ m
312
+ ] })
313
+ ] }) });
314
+ });
315
+ lt.displayName = "SeatTooltip";
316
+ const Ut = ({
317
+ config: n,
318
+ configUrl: u,
319
+ floorId: h,
320
+ onFloorChange: r,
321
+ reservedSeats: b = [],
322
+ unavailableSeats: m = [],
323
+ onSeatSelect: v,
324
+ onSeatDeselect: w,
325
+ onSelectionChange: p,
326
+ colorOverrides: s,
327
+ showTooltip: g = !0,
328
+ zoomEnabled: y = !0,
329
+ className: f = "",
330
+ onConfigLoad: N,
331
+ onError: M,
260
332
  // Floor selector props
261
- showFloorSelector: P,
262
- floorSelectorPosition: rt = "top-left",
263
- floorSelectorClassName: at,
264
- showAllFloorsOption: lt = !0,
265
- allFloorsLabel: ct = "All",
266
- fitToView: D = !0,
267
- fitPadding: L = 40,
333
+ showFloorSelector: R,
334
+ floorSelectorPosition: ct = "top-left",
335
+ floorSelectorClassName: dt,
336
+ showAllFloorsOption: ft = !0,
337
+ allFloorsLabel: ht = "All",
338
+ fitToView: H = !0,
339
+ fitPadding: U = 40,
268
340
  // Zoom controls
269
- showZoomControls: dt = !0,
270
- zoomControlsPosition: ht = "bottom-right",
271
- zoomControlsClassName: ft,
272
- maxZoom: E = 3,
273
- zoomStep: H = 0.25
341
+ showZoomControls: ut = !0,
342
+ zoomControlsPosition: pt = "bottom-right",
343
+ zoomControlsClassName: gt,
344
+ maxZoom: X = 3,
345
+ zoomStep: O = 0.25
274
346
  }) => {
275
- const ut = Et(null), [R, pt] = C(/* @__PURE__ */ new Set()), [p, V] = C(1), [k, T] = C({ x: 0, y: 0 }), [gt, mt] = C(null), [J, Q] = C(!1), [yt, bt] = C(1), { config: xt, loading: vt, error: W } = Ht(f), e = o || xt, _ = d !== void 0, v = _ ? d || null : gt, St = M((t) => {
276
- _ || mt(t), m?.(t);
277
- }, [_, m]), U = e?.floors || [], wt = P !== void 0 ? P : U.length > 1, q = F(
278
- () => e ? { ...e.colors, ...l } : { ...Tt, ...l },
279
- [e, l]
280
- ), X = F(() => {
347
+ const yt = zt(null), [A, xt] = I(/* @__PURE__ */ new Set()), [S, q] = I(1), [F, Z] = I({ x: 0, y: 0 }), [bt, mt] = I(null), [Q, tt] = I(!1), [vt, St] = I(1), [Y, et] = I({ visible: !1, x: 0, y: 0, seat: null, state: "available" }), { config: wt, loading: Ct, error: $ } = Ot(u), e = n || wt, G = h !== void 0, k = G ? h || null : bt, kt = C((t) => {
348
+ G || mt(t), r?.(t);
349
+ }, [G, r]), K = e?.floors || [], It = R !== void 0 ? R : K.length > 1, P = L(
350
+ () => e ? { ...e.colors, ...s } : { ...Zt, ...s },
351
+ [e, s]
352
+ ), B = L(() => {
281
353
  if (!e) return [];
282
- let t = e.seats.filter((n) => n.state !== "hidden");
283
- return v && (t = t.filter(
284
- (n) => n.floorId === v || !n.floorId && v === "floor_default"
354
+ let t = e.seats.filter((o) => o.state !== "hidden");
355
+ return k && (t = t.filter(
356
+ (o) => o.floorId === k || !o.floorId && k === "floor_default"
285
357
  )), t;
286
- }, [e, v]), $ = F(() => e?.stages ? v ? e.stages.filter(
287
- (t) => t.floorId === v || !t.floorId && v === "floor_default"
288
- ) : e.stages : [], [e, v]), I = F(() => {
289
- if (!e || X.length === 0 && $.length === 0)
358
+ }, [e, k]), V = L(() => e?.stages ? k ? e.stages.filter(
359
+ (t) => t.floorId === k || !t.floorId && k === "floor_default"
360
+ ) : e.stages : [], [e, k]), E = L(() => {
361
+ if (!e || B.length === 0 && V.length === 0)
290
362
  return null;
291
363
  const t = 12;
292
- let n = 1 / 0, r = 1 / 0, c = -1 / 0, a = -1 / 0;
293
- return X.forEach((s) => {
294
- n = Math.min(n, s.position.x - t), r = Math.min(r, s.position.y - t), c = Math.max(c, s.position.x + t), a = Math.max(a, s.position.y + t);
295
- }), $.forEach((s) => {
296
- n = Math.min(n, s.position.x), r = Math.min(r, s.position.y), c = Math.max(c, s.position.x + (s.config?.width || 200)), a = Math.max(a, s.position.y + (s.config?.height || 100));
297
- }), { minX: n, minY: r, maxX: c, maxY: a, width: c - n, height: a - r };
298
- }, [e, X, $]);
299
- Y(() => {
300
- if (!D || J || !e || !I) return;
301
- const t = e.canvas.width, n = e.canvas.height, r = t - L * 2, c = n - L * 2, a = r / I.width, s = c / I.height, O = Math.min(a, s, E), Mt = I.minX + I.width / 2, Ft = I.minY + I.height / 2, Rt = t / 2, Xt = n / 2, Yt = Rt - Mt * O, At = Xt - Ft * O;
302
- V(O), T({ x: Yt, y: At }), bt(O), Q(!0);
303
- }, [D, J, e, I, L, E]), Y(() => {
304
- D && Q(!1);
305
- }, [v, D]);
306
- const j = F(() => {
307
- const t = new Set(x), n = new Set(S);
308
- return { reserved: t, unavailable: n };
309
- }, [x, S]), G = M((t) => {
310
- const n = t.id, r = t.seatNumber || "";
311
- return j.unavailable.has(n) || j.unavailable.has(r) ? "unavailable" : j.reserved.has(n) || j.reserved.has(r) ? "reserved" : R.has(n) ? "selected" : t.state;
312
- }, [j, R]);
313
- Y(() => {
314
- e && A && A(e);
315
- }, [e, A]), Y(() => {
316
- W && z && z(W);
317
- }, [W, z]);
318
- const Ct = M((t) => {
319
- const n = G(t);
320
- if (n !== "available" && n !== "selected")
364
+ let o = 1 / 0, a = 1 / 0, c = -1 / 0, l = -1 / 0;
365
+ return B.forEach((d) => {
366
+ o = Math.min(o, d.position.x - t), a = Math.min(a, d.position.y - t), c = Math.max(c, d.position.x + t), l = Math.max(l, d.position.y + t);
367
+ }), V.forEach((d) => {
368
+ o = Math.min(o, d.position.x), a = Math.min(a, d.position.y), c = Math.max(c, d.position.x + (d.config?.width || 200)), l = Math.max(l, d.position.y + (d.config?.height || 100));
369
+ }), { minX: o, minY: a, maxX: c, maxY: l, width: c - o, height: l - a };
370
+ }, [e, B, V]);
371
+ W(() => {
372
+ if (!H || Q || !e || !E) return;
373
+ const t = e.canvas.width, o = e.canvas.height, a = t - U * 2, c = o - U * 2, l = a / E.width, d = c / E.height, _ = Math.min(l, d, X), At = E.minX + E.width / 2, Bt = E.minY + E.height / 2, Wt = t / 2, Xt = o / 2, Yt = Wt - At * _, $t = Xt - Bt * _;
374
+ q(_), Z({ x: Yt, y: $t }), St(_), tt(!0);
375
+ }, [H, Q, e, E, U, X]), W(() => {
376
+ H && tt(!1);
377
+ }, [k, H]);
378
+ const z = L(() => {
379
+ const t = new Set(b), o = new Set(m);
380
+ return { reserved: t, unavailable: o };
381
+ }, [b, m]), D = C((t) => {
382
+ const o = t.id, a = t.seatNumber || "";
383
+ return z.unavailable.has(o) || z.unavailable.has(a) ? "unavailable" : z.reserved.has(o) || z.reserved.has(a) ? "reserved" : A.has(o) ? "selected" : t.state;
384
+ }, [z, A]);
385
+ W(() => {
386
+ e && N && N(e);
387
+ }, [e, N]), W(() => {
388
+ $ && M && M($);
389
+ }, [$, M]);
390
+ const Nt = C((t) => {
391
+ const o = D(t);
392
+ if (o !== "available" && o !== "selected")
321
393
  return;
322
- const r = R.has(t.id);
323
- pt((c) => {
324
- const a = new Set(c);
325
- return r ? a.delete(t.id) : a.add(t.id), a;
326
- }), r ? y?.(t) : (g?.(t), g || console.log("Seat selected:", t));
327
- }, [G, R, g, y]), B = F(() => e ? X.filter((t) => R.has(t.id)) : [], [X, R]);
328
- Y(() => {
329
- h?.(B);
330
- }, [B, h]);
331
- const K = yt, kt = M(() => {
332
- if (!b) return;
333
- const t = Math.min(p + H, E);
334
- if (t !== p) {
335
- const n = e?.canvas.width || 800, r = e?.canvas.height || 600, c = n / 2, a = r / 2, s = {
336
- x: (c - k.x) / p,
337
- y: (a - k.y) / p
394
+ const a = A.has(t.id);
395
+ xt((c) => {
396
+ const l = new Set(c);
397
+ return a ? l.delete(t.id) : l.add(t.id), l;
398
+ }), a ? w?.(t) : (v?.(t), v || console.log("Seat selected:", t));
399
+ }, [D, A, v, w]), T = L(() => e ? B.filter((t) => A.has(t.id)) : [], [B, A]);
400
+ W(() => {
401
+ p?.(T);
402
+ }, [T, p]);
403
+ const J = vt, Mt = C(() => {
404
+ if (!y) return;
405
+ const t = Math.min(S + O, X);
406
+ if (t !== S) {
407
+ const o = e?.canvas.width || 800, a = e?.canvas.height || 600, c = o / 2, l = a / 2, d = {
408
+ x: (c - F.x) / S,
409
+ y: (l - F.y) / S
338
410
  };
339
- V(t), T({
340
- x: c - s.x * t,
341
- y: a - s.y * t
411
+ q(t), Z({
412
+ x: c - d.x * t,
413
+ y: l - d.y * t
342
414
  });
343
415
  }
344
- }, [b, p, H, E, e, k]), It = M(() => {
345
- if (!b) return;
346
- const t = Math.max(p - H, K);
347
- if (t !== p) {
348
- const n = e?.canvas.width || 800, r = e?.canvas.height || 600, c = n / 2, a = r / 2, s = {
349
- x: (c - k.x) / p,
350
- y: (a - k.y) / p
416
+ }, [y, S, O, X, e, F]), Rt = C(() => {
417
+ if (!y) return;
418
+ const t = Math.max(S - O, J);
419
+ if (t !== S) {
420
+ const o = e?.canvas.width || 800, a = e?.canvas.height || 600, c = o / 2, l = a / 2, d = {
421
+ x: (c - F.x) / S,
422
+ y: (l - F.y) / S
351
423
  };
352
- V(t), T({
353
- x: c - s.x * t,
354
- y: a - s.y * t
424
+ q(t), Z({
425
+ x: c - d.x * t,
426
+ y: l - d.y * t
355
427
  });
356
428
  }
357
- }, [b, p, H, K, e, k]), Nt = M((t) => {
358
- T({
429
+ }, [y, S, O, J, e, F]), Ft = C((t) => {
430
+ Z({
359
431
  x: t.target.x(),
360
432
  y: t.target.y()
361
433
  });
434
+ }, []), Et = C((t, o) => {
435
+ if (!g) return;
436
+ const a = o.target.getStage();
437
+ if (!a) return;
438
+ const c = a.getPointerPosition();
439
+ if (!c) return;
440
+ const l = a.container().getBoundingClientRect();
441
+ et({
442
+ visible: !0,
443
+ x: l.left + c.x,
444
+ y: l.top + c.y,
445
+ seat: t,
446
+ state: D(t)
447
+ });
448
+ }, [g, D]), Lt = C(() => {
449
+ et((t) => ({ ...t, visible: !1 }));
362
450
  }, []);
363
- return vt ? /* @__PURE__ */ i("div", { className: `flex items-center justify-center h-full ${u}`, children: /* @__PURE__ */ i("p", { children: "Loading seat map..." }) }) : W ? /* @__PURE__ */ i("div", { className: `flex items-center justify-center h-full ${u}`, children: /* @__PURE__ */ w("p", { className: "text-red-500", children: [
451
+ return Ct ? /* @__PURE__ */ i("div", { className: `flex items-center justify-center h-full ${f}`, children: /* @__PURE__ */ i("p", { children: "Loading seat map..." }) }) : $ ? /* @__PURE__ */ i("div", { className: `flex items-center justify-center h-full ${f}`, children: /* @__PURE__ */ x("p", { className: "text-red-500", children: [
364
452
  "Error loading seat map: ",
365
- W.message
366
- ] }) }) : e ? /* @__PURE__ */ w("div", { className: `relative ${u}`, children: [
367
- wt && U.length > 0 && /* @__PURE__ */ i(
368
- it,
453
+ $.message
454
+ ] }) }) : e ? /* @__PURE__ */ x("div", { className: `relative ${f}`, children: [
455
+ It && K.length > 0 && /* @__PURE__ */ i(
456
+ st,
369
457
  {
370
- floors: U,
371
- currentFloorId: v,
372
- onFloorChange: St,
373
- showAllOption: lt,
374
- allLabel: ct,
375
- position: rt,
376
- className: at
458
+ floors: K,
459
+ currentFloorId: k,
460
+ onFloorChange: kt,
461
+ showAllOption: ft,
462
+ allLabel: ht,
463
+ position: ct,
464
+ className: dt
377
465
  }
378
466
  ),
379
- /* @__PURE__ */ w(
380
- Wt,
467
+ /* @__PURE__ */ x(
468
+ Dt,
381
469
  {
382
- ref: ut,
470
+ ref: yt,
383
471
  width: e.canvas.width,
384
472
  height: e.canvas.height,
385
- scaleX: p,
386
- scaleY: p,
387
- x: k.x,
388
- y: k.y,
473
+ scaleX: S,
474
+ scaleY: S,
475
+ x: F.x,
476
+ y: F.y,
389
477
  draggable: !0,
390
- onDragEnd: Nt,
478
+ onDragEnd: Ft,
391
479
  style: { backgroundColor: e.canvas.backgroundColor, cursor: "grab" },
392
480
  children: [
393
- /* @__PURE__ */ i(tt, { listening: !1, children: $.map((t) => /* @__PURE__ */ i(
394
- ot,
481
+ /* @__PURE__ */ i(nt, { listening: !1, children: V.map((t) => /* @__PURE__ */ i(
482
+ rt,
395
483
  {
396
484
  stage: t,
397
- stageColor: q.stageColor
485
+ stageColor: P.stageColor
398
486
  },
399
487
  t.id
400
488
  )) }),
401
- /* @__PURE__ */ i(tt, { children: X.map((t) => /* @__PURE__ */ i(
402
- nt,
489
+ /* @__PURE__ */ i(nt, { children: B.map((t) => /* @__PURE__ */ i(
490
+ it,
403
491
  {
404
492
  seat: t,
405
- state: G(t),
406
- colors: q,
407
- onClick: Ct
493
+ state: D(t),
494
+ colors: P,
495
+ onClick: Nt,
496
+ onMouseEnter: Et,
497
+ onMouseLeave: Lt
408
498
  },
409
499
  t.id
410
500
  )) })
411
501
  ]
412
502
  }
413
503
  ),
414
- dt && b && /* @__PURE__ */ i(
415
- st,
504
+ g && /* @__PURE__ */ i(
505
+ lt,
506
+ {
507
+ visible: Y.visible,
508
+ x: Y.x,
509
+ y: Y.y,
510
+ seat: Y.seat,
511
+ currency: P.currency,
512
+ state: Y.state
513
+ }
514
+ ),
515
+ ut && y && /* @__PURE__ */ i(
516
+ at,
416
517
  {
417
- scale: p,
418
- minScale: K,
419
- maxScale: E,
420
- onZoomIn: kt,
421
- onZoomOut: It,
422
- position: ht,
423
- className: ft
518
+ scale: S,
519
+ minScale: J,
520
+ maxScale: X,
521
+ onZoomIn: Mt,
522
+ onZoomOut: Rt,
523
+ position: pt,
524
+ className: gt
424
525
  }
425
526
  ),
426
- B.length > 0 && /* @__PURE__ */ w("div", { className: "absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg", children: [
427
- /* @__PURE__ */ w("h3", { className: "font-semibold mb-2", children: [
527
+ T.length > 0 && /* @__PURE__ */ x("div", { className: "absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg", children: [
528
+ /* @__PURE__ */ x("h3", { className: "font-semibold mb-2", children: [
428
529
  "Selected Seats (",
429
- B.length,
530
+ T.length,
430
531
  ")"
431
532
  ] }),
432
- /* @__PURE__ */ i("div", { className: "max-h-48 overflow-y-auto space-y-1", children: B.map((t) => /* @__PURE__ */ w("div", { className: "text-sm", children: [
533
+ /* @__PURE__ */ i("div", { className: "max-h-48 overflow-y-auto space-y-1", children: T.map((t) => /* @__PURE__ */ x("div", { className: "text-sm", children: [
433
534
  t.seatNumber,
434
- t.price && ` - ${q.currency} ${t.price.toFixed(2)}`
535
+ t.price && ` - ${P.currency} ${t.price.toFixed(2)}`
435
536
  ] }, t.id)) })
436
537
  ] })
437
- ] }) : /* @__PURE__ */ i("div", { className: `flex items-center justify-center h-full ${u}`, children: /* @__PURE__ */ i("p", { children: "No configuration provided" }) });
538
+ ] }) : /* @__PURE__ */ i("div", { className: `flex items-center justify-center h-full ${f}`, children: /* @__PURE__ */ i("p", { children: "No configuration provided" }) });
438
539
  };
439
540
  export {
440
- Tt as DEFAULT_COLORS,
441
- zt as SeatMapViewer,
442
- Ht as useConfigFetcher
541
+ Zt as DEFAULT_COLORS,
542
+ Ut as SeatMapViewer,
543
+ Ot as useConfigFetcher
443
544
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zonetrix/viewer",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "type": "module",
5
5
  "description": "Lightweight React component for rendering interactive seat maps",
6
6
  "main": "./dist/index.js",