@zonetrix/viewer 2.13.2 → 2.13.3

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 s=require("react/jsx-runtime"),n=require("react"),T=require("react-konva"),z=require("@zonetrix/shared");function Ce(i){const[f,t]=n.useState(null),[a,w]=n.useState(!1),[b,g]=n.useState(null),y=n.useCallback(async()=>{if(i){w(!0),g(null);try{const p=await fetch(i);if(!p.ok)throw new Error(`Failed to fetch config: ${p.statusText}`);const l=await p.json();t(l)}catch(p){const l=p instanceof Error?p:new Error("Unknown error occurred");g(l),console.error("Failed to fetch seat map config:",l)}finally{w(!1)}}},[i]);return n.useEffect(()=>{y()},[y]),{config:f,loading:a,error:b,refetch:y}}function je(i){const[f,t]=n.useState({width:0,height:0});return n.useEffect(()=>{const a=i.current;if(!a)return;const{width:w,height:b}=a.getBoundingClientRect();w>0&&b>0&&t({width:w,height:b});const g=new ResizeObserver(y=>{const p=y[0];if(!p)return;const{width:l,height:x}=p.contentRect;l>0&&x>0&&t(m=>m.width===l&&m.height===x?m:{width:l,height:x})});return g.observe(a),()=>{g.disconnect()}},[i]),f}function ve(i,f){return Math.sqrt(Math.pow(f.x-i.x,2)+Math.pow(f.y-i.y,2))}function we(i,f){return{x:(i.x+f.x)/2,y:(i.y+f.y)/2}}function Me(i,f){const t=n.useRef(null),a=n.useRef(null),w=n.useRef(1),{enabled:b,minScale:g,maxScale:y,currentScale:p,currentPosition:l,onScaleChange:x}=f;n.useEffect(()=>{const m=i.current;if(!m||!b)return;const d=m.container(),k=S=>{if(S.touches.length===2){S.preventDefault();const P={x:S.touches[0].clientX,y:S.touches[0].clientY},E={x:S.touches[1].clientX,y:S.touches[1].clientY};t.current=ve(P,E),a.current=we(P,E),w.current=p}},v=S=>{if(S.touches.length!==2)return;S.preventDefault();const P={x:S.touches[0].clientX,y:S.touches[0].clientY},E={x:S.touches[1].clientX,y:S.touches[1].clientY},O=ve(P,E),M=we(P,E);if(t.current!==null&&a.current!==null){const X=O/t.current,Y=Math.min(Math.max(p*X,g),y),G=d.getBoundingClientRect(),A=M.x-G.left,ne=M.y-G.top,ie=p,se={x:(A-l.x)/ie,y:(ne-l.y)/ie},oe=M.x-a.current.x,L=M.y-a.current.y,B={x:A-se.x*Y+oe,y:ne-se.y*Y+L};x(Y,B),t.current=O,a.current=M}},C=S=>{S.touches.length<2&&(t.current=null,a.current=null)};return d.addEventListener("touchstart",k,{passive:!1}),d.addEventListener("touchmove",v,{passive:!1}),d.addEventListener("touchend",C),()=>{d.removeEventListener("touchstart",k),d.removeEventListener("touchmove",v),d.removeEventListener("touchend",C)}},[i,b,g,y,p,l,x])}const ke={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},Fe=n.memo(({seat:i,state:f,colors:t,onClick:a,onMouseEnter:w,onMouseLeave:b})=>{const g=(i.size||24)/2,p={available:t.seatAvailable,reserved:t.seatReserved,selected:t.seatSelected,unavailable:t.seatUnavailable,hidden:t.seatHidden}[f],l=f==="available"||f==="selected",x=n.useCallback(()=>{l&&a(i)},[i,a,l]),m=n.useCallback(v=>{w(i,v);const C=v.target.getStage();C&&l&&(C.container().style.cursor="pointer")},[i,w,l]),d=n.useCallback(v=>{b();const C=v.target.getStage();C&&(C.container().style.cursor="grab")},[b]),k={x:i.position.x,y:i.position.y,fill:p,stroke:"#ffffff",strokeWidth:1,onClick:x,onTap:x,onMouseEnter:m,onMouseLeave:d};return i.shape==="circle"?s.jsx(T.Circle,{...k,radius:g}):s.jsx(T.Rect,{...k,width:g*2,height:g*2,offsetX:g,offsetY:g,cornerRadius:i.shape==="square"?0:4})});Fe.displayName="ViewerSeat";const Re=n.memo(({stage:i,stageColor:f})=>{const t=i.config,a=t.shape||"rectangle",w=t.showLabel!==!1,b=t.color||f,g=t.width/t.height,y=g<.5,p=g>2;let l;y?l=t.width*.25:p?l=t.height*.35:l=Math.min(t.width,t.height)*.25;const x=t.label?.length||6,k=t.width*.85/x*1.5,v=Math.max(10,Math.min(24,Math.min(l,k))),C=4,S=Math.max(20,t.width-C*2),P=(t.width-S)/2,E={fill:b+"80",stroke:"#ffffff",strokeWidth:2,perfectDrawEnabled:!1,hitStrokeWidth:0},O=()=>{switch(a){case"circle":{const M=Math.min(t.width,t.height)/2;return s.jsx(T.Circle,{x:t.width/2,y:t.height/2,radius:M,...E})}case"triangle":{const M=Math.min(t.width,t.height)/2;return s.jsx(T.RegularPolygon,{x:t.width/2,y:t.height/2,sides:3,radius:M,rotation:-90,...E})}case"arrow":{const M=t.width/24,X=t.height/24,Y=`M${9*M},${18*X} v${-8*X} H${5*M} l${7*M},${-7*X} l${7*M},${7*X} h${-4*M} v${8*X} Z`;return s.jsx(T.Path,{data:Y,...E})}default:return s.jsx(T.Rect,{width:t.width,height:t.height,cornerRadius:10,...E})}};return s.jsxs(T.Group,{x:i.position.x,y:i.position.y,rotation:t.rotation||0,children:[O(),w&&s.jsx(T.Text,{text:t.label,x:P,y:C,width:S,height:t.height-C*2,fontSize:v,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle",wrap:"word",ellipsis:!0})]})});Re.displayName="ViewerStage";const Ie=n.memo(({text:i})=>s.jsx(T.Text,{x:i.position.x,y:i.position.y,text:i.config.text,fontSize:i.config.fontSize,fill:i.config.color,rotation:i.config.rotation||0,scaleX:i.config.scaleX||1,scaleY:i.config.scaleY||1,listening:!1}));Ie.displayName="ViewerText";const Ee=n.memo(({floors:i,currentFloorId:f,onFloorChange:t,showAllOption:a,allLabel:w,position:b,className:g})=>{const y=n.useMemo(()=>[...i].sort((d,k)=>d.order-k.order),[i]),l={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}}[b]},x={padding:"10px 16px",fontSize:"14px",fontWeight:500,border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",transition:"all 0.2s ease",minHeight:"44px",touchAction:"manipulation"},m={...x,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return s.jsxs("div",{className:g,style:l,children:[a&&s.jsx("button",{type:"button",onClick:()=>t(null),style:f===null?m:x,children:w}),y.map(d=>s.jsx("button",{type:"button",onClick:()=>t(d.id),style:f===d.id?m:x,children:d.name},d.id))]})});Ee.displayName="FloorSelectorBar";const Te=n.memo(({scale:i,minScale:f,maxScale:t,fitScale:a,onZoomIn:w,onZoomOut:b,onFitToScreen:g,position:y,className:p})=>{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}}[y]},m={width:"44px",height:"44px",minWidth:"44px",minHeight:"44px",fontSize:"22px",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",touchAction:"manipulation"},d={...m,opacity:.4,cursor:"not-allowed"},k=i<t,v=i>f,C=Math.abs(i-a)<.01;return s.jsxs("div",{className:p,style:x,children:[s.jsx("button",{type:"button",onClick:w,disabled:!k,style:k?m:d,title:"Zoom In","aria-label":"Zoom In",children:"+"}),s.jsx("button",{type:"button",onClick:g,disabled:C,style:C?d:m,title:"Fit to Screen","aria-label":"Fit to Screen",children:"⤢"}),s.jsx("button",{type:"button",onClick:b,disabled:!v,style:v?m:d,title:"Zoom Out","aria-label":"Zoom Out",children:"−"})]})});Te.displayName="ZoomControls";const De=n.memo(({visible:i,x:f,y:t,seat:a,currency:w,state:b})=>{if(!i||!a)return null;const g=a.seatNumber||(a.rowLabel&&a.columnLabel?`${a.rowLabel}-${a.columnLabel}`:"N/A"),y={position:"fixed",left:`${f+15}px`,top:`${t+15}px`,zIndex:1e3,pointerEvents:"none"},p={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"},l={color:"#9ca3af",marginRight:"4px"},x={fontWeight:600},m={color:"#4ade80",fontWeight:600},d={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return s.jsx("div",{style:y,children:s.jsxs("div",{style:p,children:[a.sectionName&&s.jsxs("div",{style:{marginBottom:"4px"},children:[s.jsx("span",{style:l,children:"Section:"}),s.jsx("span",{style:{...x,color:"#3b82f6"},children:a.sectionName})]}),s.jsxs("div",{style:{marginBottom:"4px"},children:[s.jsx("span",{style:l,children:"Seat:"}),s.jsx("span",{style:x,children:g})]}),a.price!==void 0&&a.price>0&&b==="available"&&s.jsxs("div",{style:{marginBottom:"4px"},children:[s.jsx("span",{style:l,children:"Price:"}),s.jsxs("span",{style:m,children:[w," ",a.price.toFixed(2)]})]}),s.jsxs("div",{style:d,children:["Status: ",b]})]})})});De.displayName="SeatTooltip";const et=({config:i,configUrl:f,floorId:t,onFloorChange:a,reservedSeats:w=[],otherReservedSeats:b,unavailableSeats:g=[],selectedSeats:y,myReservedSeats:p=[],onSeatSelect:l,onSeatDeselect:x,onSelectionChange:m,colorOverrides:d,showTooltip:k=!0,zoomEnabled:v=!0,className:C="",onConfigLoad:S,onError:P,showFloorSelector:E,floorSelectorPosition:O="top-left",floorSelectorClassName:M,showAllFloorsOption:X=!0,allFloorsLabel:Y="All",fitToView:G=!0,fitPadding:A=40,showZoomControls:ne=!0,zoomControlsPosition:ie="bottom-right",zoomControlsClassName:se,minZoom:oe,maxZoom:L=3,zoomStep:B=.25,touchEnabled:Pe=!0})=>{const xe=b!==void 0?b:w,he=n.useRef(null),be=n.useRef(null),j=je(be),[H,ye]=n.useState(new Set),[R,U]=n.useState(1),[D,V]=n.useState({x:0,y:0}),[Le,Ne]=n.useState(null),[me,We]=n.useState(1),re=n.useRef({width:0,height:0}),[K,Se]=n.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Xe,loading:Ye,error:J}=Ce(f),c=i||Xe,de=t!==void 0,I=de?t||null:Le,ae=y!==void 0,$e=n.useCallback(e=>{de||Ne(e),a?.(e)},[de,a]),fe=c?.floors||[],ze=E!==void 0?E:fe.length>1,ce=n.useMemo(()=>c?{...c.colors,...d}:{...ke,...d},[c,d]),q=n.useMemo(()=>{if(!c)return[];let e=c.seats.filter(o=>o.state!=="hidden");return I&&(e=e.filter(o=>o.floorId===I||!o.floorId&&I==="floor_default")),e},[c,I]),le=n.useMemo(()=>c?.stages?I?c.stages.filter(e=>e.floorId===I||!e.floorId&&I==="floor_default"):c.stages:[],[c,I]),ue=n.useMemo(()=>c?.texts?I?c.texts.filter(e=>e.floorId===I||!e.floorId&&I==="floor_default"):c.texts:[],[c,I]),N=n.useMemo(()=>{if(!c||q.length===0&&le.length===0&&ue.length===0)return null;let e=1/0,o=1/0,u=-1/0,h=-1/0;return q.forEach(r=>{const F=(r.size||24)/2;e=Math.min(e,r.position.x-F),o=Math.min(o,r.position.y-F),u=Math.max(u,r.position.x+F),h=Math.max(h,r.position.y+F)}),le.forEach(r=>{e=Math.min(e,r.position.x),o=Math.min(o,r.position.y),u=Math.max(u,r.position.x+(r.config?.width||200)),h=Math.max(h,r.position.y+(r.config?.height||100))}),ue.forEach(r=>{const F=r.config.scaleX||1,W=r.config.scaleY||1,_=r.config.text.length*r.config.fontSize*.6*F,te=r.config.fontSize*W;e=Math.min(e,r.position.x),o=Math.min(o,r.position.y),u=Math.max(u,r.position.x+_),h=Math.max(h,r.position.y+te)}),{minX:e,minY:o,maxX:u,maxY:h,width:u-e,height:h-o}},[c,q,le,ue]),ge=n.useCallback(()=>{if(!c||!N||j.width===0||j.height===0)return;const e=j.width,o=j.height,u=e-A*2,h=o-A*2,r=u/N.width,F=h/N.height,W=Math.min(r,F,L),_=N.minX+N.width/2,te=N.minY+N.height/2,Ue=e/2,Ke=o/2,Je=Ue-_*W,Qe=Ke-te*W;U(W),V({x:Je,y:Qe}),We(W)},[c,N,j,A,L]);n.useEffect(()=>{if(!G||!c||!N||j.width===0||j.height===0)return;const e=Math.abs(j.width-re.current.width),o=Math.abs(j.height-re.current.height);!(re.current.width===0)&&e<10&&o<10||(re.current=j,ge())},[G,c,N,j,I,ge]);const $=n.useMemo(()=>{const e=new Set(xe),o=new Set(g),u=new Set(p);return{reserved:e,unavailable:o,myReserved:u}},[xe,g,p]),pe=n.useMemo(()=>y?new Set(y):null,[y]),Q=n.useCallback(e=>{const o=e.id,u=e.seatNumber||"";return $.unavailable.has(o)||$.unavailable.has(u)?"unavailable":$.reserved.has(o)||$.reserved.has(u)?"reserved":$.myReserved.has(o)||$.myReserved.has(u)||H.has(o)?"selected":e.state},[$,H]);n.useEffect(()=>{c&&S&&S(c)},[c,S]),n.useEffect(()=>{J&&P&&P(J)},[J,P]),n.useEffect(()=>{ae&&pe&&ye(pe)},[ae,pe]);const Oe=n.useCallback(e=>{const o=Q(e);if(o!=="available"&&o!=="selected")return;const u=H.has(e.id);ae||ye(h=>{const r=new Set(h);return u?r.delete(e.id):r.add(e.id),r}),u?x?.(e):(l?.(e),l||console.log("Seat selected:",e))},[Q,H,ae,l,x]),ee=n.useMemo(()=>c?q.filter(e=>H.has(e.id)):[],[c,q,H]);n.useEffect(()=>{m?.(ee)},[ee,m]);const Z=oe!==void 0?oe:me*.5,Ae=n.useCallback(()=>{if(!v)return;const e=Math.min(R+B,L);if(e!==R){const o=j.width||c?.canvas.width||800,u=j.height||c?.canvas.height||600,h=o/2,r=u/2,F={x:(h-D.x)/R,y:(r-D.y)/R};U(e),V({x:h-F.x*e,y:r-F.y*e})}},[v,R,B,L,j,c,D]),Be=n.useCallback(()=>{if(!v)return;const e=Math.max(R-B,Z);if(e!==R){const o=j.width||c?.canvas.width||800,u=j.height||c?.canvas.height||600,h=o/2,r=u/2,F={x:(h-D.x)/R,y:(r-D.y)/R};U(e),V({x:h-F.x*e,y:r-F.y*e})}},[v,R,B,Z,j,c,D]),He=n.useCallback(e=>{V({x:e.target.x(),y:e.target.y()})},[]),Ve=n.useCallback(e=>{if(!v)return;e.evt.preventDefault();const o=he.current;if(!o)return;const u=o.scaleX(),h=o.getPointerPosition();if(!h)return;const r=1.1,F=e.evt.deltaY>0?u/r:u*r,W=Math.min(Math.max(F,Z),L),_={x:(h.x-D.x)/u,y:(h.y-D.y)/u},te={x:h.x-_.x*W,y:h.y-_.y*W};U(W),V(te)},[v,D,Z,L]);Me(he,{enabled:Pe&&v,minScale:Z,maxScale:L,currentScale:R,currentPosition:D,onScaleChange:(e,o)=>{U(e),V(o)}});const qe=n.useCallback((e,o)=>{if(!k)return;const u=o.target.getStage();if(!u)return;const h=u.getPointerPosition();if(!h)return;const r=u.container().getBoundingClientRect();Se({visible:!0,x:r.left+h.x,y:r.top+h.y,seat:e,state:Q(e)})},[k,Q]),Ze=n.useCallback(()=>{Se(e=>({...e,visible:!1}))},[]);if(Ye)return s.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:s.jsx("p",{children:"Loading seat map..."})});if(J)return s.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:s.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",J.message]})});if(!c)return s.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:s.jsx("p",{children:"No configuration provided"})});const _e=j.width||c.canvas.width,Ge=j.height||c.canvas.height;return s.jsxs("div",{ref:be,className:`relative ${C}`,style:{width:"100%",height:"100%"},children:[ze&&fe.length>0&&s.jsx(Ee,{floors:fe,currentFloorId:I,onFloorChange:$e,showAllOption:X,allLabel:Y,position:O,className:M}),s.jsxs(T.Stage,{ref:he,width:_e,height:Ge,scaleX:R,scaleY:R,x:D.x,y:D.y,draggable:!0,onDragEnd:He,onWheel:Ve,style:{backgroundColor:c.canvas.backgroundColor,cursor:"grab"},children:[s.jsx(T.Layer,{listening:!1,children:le.map(e=>s.jsx(Re,{stage:e,stageColor:ce.stageColor},e.id))}),s.jsx(T.Layer,{listening:!1,children:ue.map(e=>s.jsx(Ie,{text:e},e.id))}),s.jsx(T.Layer,{children:q.map(e=>s.jsx(Fe,{seat:e,state:Q(e),colors:ce,onClick:Oe,onMouseEnter:qe,onMouseLeave:Ze},e.id))})]}),k&&s.jsx(De,{visible:K.visible,x:K.x,y:K.y,seat:K.seat,currency:ce.currency,state:K.state}),ne&&v&&s.jsx(Te,{scale:R,minScale:Z,maxScale:L,fitScale:me,onZoomIn:Ae,onZoomOut:Be,onFitToScreen:ge,position:ie,className:se}),ee.length>0&&s.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[s.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",ee.length,")"]}),s.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:ee.map(e=>s.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${ce.currency} ${e.price.toFixed(2)}`]},e.id))})]})]})};Object.defineProperty(exports,"clearFirebaseInstance",{enumerable:!0,get:()=>z.clearFirebaseInstance});Object.defineProperty(exports,"getFirebaseDatabase",{enumerable:!0,get:()=>z.getFirebaseDatabase});Object.defineProperty(exports,"initializeFirebaseForViewer",{enumerable:!0,get:()=>z.initializeFirebaseForViewer});Object.defineProperty(exports,"isFirebaseInitialized",{enumerable:!0,get:()=>z.isFirebaseInitialized});Object.defineProperty(exports,"useFirebaseConfig",{enumerable:!0,get:()=>z.useFirebaseConfig});Object.defineProperty(exports,"useFirebaseSeatStates",{enumerable:!0,get:()=>z.useFirebaseSeatStates});Object.defineProperty(exports,"useRealtimeSeatMap",{enumerable:!0,get:()=>z.useRealtimeSeatMap});exports.DEFAULT_COLORS=ke;exports.SeatMapViewer=et;exports.useConfigFetcher=Ce;exports.useContainerSize=je;exports.useTouchGestures=Me;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),n=require("react"),E=require("react-konva"),z=require("@zonetrix/shared");function je(i){const[f,t]=n.useState(null),[a,w]=n.useState(!1),[b,g]=n.useState(null),y=n.useCallback(async()=>{if(i){w(!0),g(null);try{const p=await fetch(i);if(!p.ok)throw new Error(`Failed to fetch config: ${p.statusText}`);const l=await p.json();t(l)}catch(p){const l=p instanceof Error?p:new Error("Unknown error occurred");g(l),console.error("Failed to fetch seat map config:",l)}finally{w(!1)}}},[i]);return n.useEffect(()=>{y()},[y]),{config:f,loading:a,error:b,refetch:y}}function Me(i){const[f,t]=n.useState({width:0,height:0});return n.useEffect(()=>{const a=i.current;if(!a)return;const{width:w,height:b}=a.getBoundingClientRect();w>0&&b>0&&t({width:w,height:b});const g=new ResizeObserver(y=>{const p=y[0];if(!p)return;const{width:l,height:x}=p.contentRect;l>0&&x>0&&t(m=>m.width===l&&m.height===x?m:{width:l,height:x})});return g.observe(a),()=>{g.disconnect()}},[i]),f}function we(i,f){return Math.sqrt(Math.pow(f.x-i.x,2)+Math.pow(f.y-i.y,2))}function Ce(i,f){return{x:(i.x+f.x)/2,y:(i.y+f.y)/2}}function ke(i,f){const t=n.useRef(null),a=n.useRef(null),w=n.useRef(1),{enabled:b,minScale:g,maxScale:y,currentScale:p,currentPosition:l,onScaleChange:x}=f;n.useEffect(()=>{const m=i.current;if(!m||!b)return;const h=m.container(),k=h.style.touchAction;h.style.touchAction="none";const S=v=>{if(v.touches.length===2){v.preventDefault();const T={x:v.touches[0].clientX,y:v.touches[0].clientY},Y={x:v.touches[1].clientX,y:v.touches[1].clientY};t.current=we(T,Y),a.current=Ce(T,Y),w.current=p}},C=v=>{if(v.touches.length!==2)return;v.preventDefault();const T={x:v.touches[0].clientX,y:v.touches[0].clientY},Y={x:v.touches[1].clientX,y:v.touches[1].clientY},F=we(T,Y),D=Ce(T,Y);if(t.current!==null&&a.current!==null){const G=F/t.current,A=Math.min(Math.max(p*G,g),y),O=h.getBoundingClientRect(),ie=D.x-O.left,oe=D.y-O.top,se=p,U={x:(ie-l.x)/se,y:(oe-l.y)/se},L=D.x-a.current.x,B=D.y-a.current.y,re={x:ie-U.x*A+L,y:oe-U.y*A+B};x(A,re),t.current=F,a.current=D}},X=v=>{v.touches.length<2&&(t.current=null,a.current=null)};return h.addEventListener("touchstart",S,{passive:!1}),h.addEventListener("touchmove",C,{passive:!1}),h.addEventListener("touchend",X),()=>{h.style.touchAction=k,h.removeEventListener("touchstart",S),h.removeEventListener("touchmove",C),h.removeEventListener("touchend",X)}},[i,b,g,y,p,l,x])}const Fe={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},Re=n.memo(({seat:i,state:f,colors:t,onClick:a,onMouseEnter:w,onMouseLeave:b})=>{const g=(i.size||24)/2,p={available:t.seatAvailable,reserved:t.seatReserved,selected:t.seatSelected,unavailable:t.seatUnavailable,hidden:t.seatHidden}[f],l=f==="available"||f==="selected",x=n.useCallback(()=>{l&&a(i)},[i,a,l]),m=n.useCallback(S=>{w(i,S);const C=S.target.getStage();C&&l&&(C.container().style.cursor="pointer")},[i,w,l]),h=n.useCallback(S=>{b();const C=S.target.getStage();C&&(C.container().style.cursor="grab")},[b]),k={x:i.position.x,y:i.position.y,rotation:i.rotation||0,fill:p,stroke:"#ffffff",strokeWidth:1,onClick:x,onTap:x,onMouseEnter:m,onMouseLeave:h};return i.shape==="circle"?o.jsx(E.Circle,{...k,radius:g}):o.jsx(E.Rect,{...k,width:g*2,height:g*2,offsetX:g,offsetY:g,cornerRadius:i.shape==="square"?0:4})});Re.displayName="ViewerSeat";const Ie=n.memo(({stage:i,stageColor:f})=>{const t=i.config,a=t.shape||"rectangle",w=t.showLabel!==!1,b=t.color||f,g=t.width/t.height,y=g<.5,p=g>2;let l;y?l=t.width*.25:p?l=t.height*.35:l=Math.min(t.width,t.height)*.25;const x=t.label?.length||6,k=t.width*.85/x*1.5,S=Math.max(10,Math.min(24,Math.min(l,k))),C=4,X=Math.max(20,t.width-C*2),v=(t.width-X)/2,T={fill:b+"80",stroke:"#ffffff",strokeWidth:2,perfectDrawEnabled:!1,hitStrokeWidth:0},Y=()=>{switch(a){case"circle":{const F=Math.min(t.width,t.height)/2;return o.jsx(E.Circle,{x:t.width/2,y:t.height/2,radius:F,...T})}case"triangle":{const F=Math.min(t.width,t.height)/2;return o.jsx(E.RegularPolygon,{x:t.width/2,y:t.height/2,sides:3,radius:F,rotation:-90,...T})}case"arrow":{const F=t.width/24,D=t.height/24,G=`M${9*F},${18*D} v${-8*D} H${5*F} l${7*F},${-7*D} l${7*F},${7*D} h${-4*F} v${8*D} Z`;return o.jsx(E.Path,{data:G,...T})}default:return o.jsx(E.Rect,{width:t.width,height:t.height,cornerRadius:10,...T})}};return o.jsxs(E.Group,{x:i.position.x,y:i.position.y,rotation:t.rotation||0,children:[Y(),w&&o.jsx(E.Text,{text:t.label,x:v,y:C,width:X,height:t.height-C*2,fontSize:S,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle",wrap:"word",ellipsis:!0})]})});Ie.displayName="ViewerStage";const Te=n.memo(({text:i})=>o.jsx(E.Text,{x:i.position.x,y:i.position.y,text:i.config.text,fontSize:i.config.fontSize,fill:i.config.color,rotation:i.config.rotation||0,scaleX:i.config.scaleX||1,scaleY:i.config.scaleY||1,listening:!1}));Te.displayName="ViewerText";const De=n.memo(({floors:i,currentFloorId:f,onFloorChange:t,showAllOption:a,allLabel:w,position:b,className:g})=>{const y=n.useMemo(()=>[...i].sort((h,k)=>h.order-k.order),[i]),l={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}}[b]},x={padding:"10px 16px",fontSize:"14px",fontWeight:500,border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",transition:"all 0.2s ease",minHeight:"44px",touchAction:"manipulation"},m={...x,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return o.jsxs("div",{className:g,style:l,children:[a&&o.jsx("button",{type:"button",onClick:()=>t(null),style:f===null?m:x,children:w}),y.map(h=>o.jsx("button",{type:"button",onClick:()=>t(h.id),style:f===h.id?m:x,children:h.name},h.id))]})});De.displayName="FloorSelectorBar";const Ee=n.memo(({scale:i,minScale:f,maxScale:t,fitScale:a,onZoomIn:w,onZoomOut:b,onFitToScreen:g,position:y,className:p})=>{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}}[y]},m={width:"44px",height:"44px",minWidth:"44px",minHeight:"44px",fontSize:"22px",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",touchAction:"manipulation"},h={...m,opacity:.4,cursor:"not-allowed"},k=i<t,S=i>f,C=Math.abs(i-a)<.01;return o.jsxs("div",{className:p,style:x,children:[o.jsx("button",{type:"button",onClick:w,disabled:!k,style:k?m:h,title:"Zoom In","aria-label":"Zoom In",children:"+"}),o.jsx("button",{type:"button",onClick:g,disabled:C,style:C?h:m,title:"Fit to Screen","aria-label":"Fit to Screen",children:"⤢"}),o.jsx("button",{type:"button",onClick:b,disabled:!S,style:S?m:h,title:"Zoom Out","aria-label":"Zoom Out",children:"−"})]})});Ee.displayName="ZoomControls";const Pe=n.memo(({visible:i,x:f,y:t,seat:a,currency:w,state:b})=>{if(!i||!a)return null;const g=a.seatNumber||(a.rowLabel&&a.columnLabel?`${a.rowLabel}-${a.columnLabel}`:"N/A"),y={position:"fixed",left:`${f+15}px`,top:`${t+15}px`,zIndex:1e3,pointerEvents:"none"},p={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"},l={color:"#9ca3af",marginRight:"4px"},x={fontWeight:600},m={color:"#4ade80",fontWeight:600},h={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return o.jsx("div",{style:y,children:o.jsxs("div",{style:p,children:[a.sectionName&&o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:l,children:"Section:"}),o.jsx("span",{style:{...x,color:"#3b82f6"},children:a.sectionName})]}),o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:l,children:"Seat:"}),o.jsx("span",{style:x,children:g})]}),a.price!==void 0&&a.price>0&&b==="available"&&o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:l,children:"Price:"}),o.jsxs("span",{style:m,children:[w," ",a.price.toFixed(2)]})]}),o.jsxs("div",{style:h,children:["Status: ",b]})]})})});Pe.displayName="SeatTooltip";const et=({config:i,configUrl:f,floorId:t,onFloorChange:a,reservedSeats:w=[],otherReservedSeats:b,unavailableSeats:g=[],selectedSeats:y,myReservedSeats:p=[],onSeatSelect:l,onSeatDeselect:x,onSelectionChange:m,colorOverrides:h,showTooltip:k=!0,zoomEnabled:S=!0,className:C="",onConfigLoad:X,onError:v,showFloorSelector:T,floorSelectorPosition:Y="top-left",floorSelectorClassName:F,showAllFloorsOption:D=!0,allFloorsLabel:G="All",fitToView:A=!0,fitPadding:O=40,showZoomControls:ie=!0,zoomControlsPosition:oe="bottom-right",zoomControlsClassName:se,minZoom:U,maxZoom:L=3,zoomStep:B=.25,touchEnabled:re=!0})=>{const be=b!==void 0?b:w,de=n.useRef(null),ye=n.useRef(null),j=Me(ye),[H,me]=n.useState(new Set),[R,K]=n.useState(1),[P,V]=n.useState({x:0,y:0}),[Le,Ne]=n.useState(null),[Se,We]=n.useState(1),ae=n.useRef({width:0,height:0}),[J,ve]=n.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Xe,loading:Ye,error:Q}=je(f),c=i||Xe,fe=t!==void 0,I=fe?t||null:Le,ce=y!==void 0,$e=n.useCallback(e=>{fe||Ne(e),a?.(e)},[fe,a]),ge=c?.floors||[],ze=T!==void 0?T:ge.length>1,le=n.useMemo(()=>c?{...c.colors,...h}:{...Fe,...h},[c,h]),q=n.useMemo(()=>{if(!c)return[];let e=c.seats.filter(s=>s.state!=="hidden");return I&&(e=e.filter(s=>s.floorId===I||!s.floorId&&I==="floor_default")),e},[c,I]),ue=n.useMemo(()=>c?.stages?I?c.stages.filter(e=>e.floorId===I||!e.floorId&&I==="floor_default"):c.stages:[],[c,I]),he=n.useMemo(()=>c?.texts?I?c.texts.filter(e=>e.floorId===I||!e.floorId&&I==="floor_default"):c.texts:[],[c,I]),N=n.useMemo(()=>{if(!c||q.length===0&&ue.length===0&&he.length===0)return null;let e=1/0,s=1/0,u=-1/0,d=-1/0;return q.forEach(r=>{const M=(r.size||24)/2;e=Math.min(e,r.position.x-M),s=Math.min(s,r.position.y-M),u=Math.max(u,r.position.x+M),d=Math.max(d,r.position.y+M)}),ue.forEach(r=>{e=Math.min(e,r.position.x),s=Math.min(s,r.position.y),u=Math.max(u,r.position.x+(r.config?.width||200)),d=Math.max(d,r.position.y+(r.config?.height||100))}),he.forEach(r=>{const M=r.config.scaleX||1,W=r.config.scaleY||1,_=r.config.text.length*r.config.fontSize*.6*M,ne=r.config.fontSize*W;e=Math.min(e,r.position.x),s=Math.min(s,r.position.y),u=Math.max(u,r.position.x+_),d=Math.max(d,r.position.y+ne)}),{minX:e,minY:s,maxX:u,maxY:d,width:u-e,height:d-s}},[c,q,ue,he]),pe=n.useCallback(()=>{if(!c||!N||j.width===0||j.height===0)return;const e=j.width,s=j.height,u=e-O*2,d=s-O*2,r=u/N.width,M=d/N.height,W=Math.min(r,M,L),_=N.minX+N.width/2,ne=N.minY+N.height/2,Ue=e/2,Ke=s/2,Je=Ue-_*W,Qe=Ke-ne*W;K(W),V({x:Je,y:Qe}),We(W)},[c,N,j,O,L]);n.useEffect(()=>{if(!A||!c||!N||j.width===0||j.height===0)return;const e=Math.abs(j.width-ae.current.width),s=Math.abs(j.height-ae.current.height);!(ae.current.width===0)&&e<10&&s<10||(ae.current=j,pe())},[A,c,N,j,I,pe]);const $=n.useMemo(()=>{const e=new Set(be),s=new Set(g),u=new Set(p);return{reserved:e,unavailable:s,myReserved:u}},[be,g,p]),xe=n.useMemo(()=>y?new Set(y):null,[y]),ee=n.useCallback(e=>{const s=e.id,u=e.seatNumber||"";return $.unavailable.has(s)||$.unavailable.has(u)?"unavailable":$.reserved.has(s)||$.reserved.has(u)?"reserved":$.myReserved.has(s)||$.myReserved.has(u)||H.has(s)?"selected":e.state},[$,H]);n.useEffect(()=>{c&&X&&X(c)},[c,X]),n.useEffect(()=>{Q&&v&&v(Q)},[Q,v]),n.useEffect(()=>{ce&&xe&&me(xe)},[ce,xe]);const Ae=n.useCallback(e=>{const s=ee(e);if(s!=="available"&&s!=="selected")return;const u=H.has(e.id);ce||me(d=>{const r=new Set(d);return u?r.delete(e.id):r.add(e.id),r}),u?x?.(e):(l?.(e),l||console.log("Seat selected:",e))},[ee,H,ce,l,x]),te=n.useMemo(()=>c?q.filter(e=>H.has(e.id)):[],[c,q,H]);n.useEffect(()=>{m?.(te)},[te,m]);const Z=U!==void 0?U:Se*.5,Oe=n.useCallback(()=>{if(!S)return;const e=Math.min(R+B,L);if(e!==R){const s=j.width||c?.canvas.width||800,u=j.height||c?.canvas.height||600,d=s/2,r=u/2,M={x:(d-P.x)/R,y:(r-P.y)/R};K(e),V({x:d-M.x*e,y:r-M.y*e})}},[S,R,B,L,j,c,P]),Be=n.useCallback(()=>{if(!S)return;const e=Math.max(R-B,Z);if(e!==R){const s=j.width||c?.canvas.width||800,u=j.height||c?.canvas.height||600,d=s/2,r=u/2,M={x:(d-P.x)/R,y:(r-P.y)/R};K(e),V({x:d-M.x*e,y:r-M.y*e})}},[S,R,B,Z,j,c,P]),He=n.useCallback(e=>{V({x:e.target.x(),y:e.target.y()})},[]),Ve=n.useCallback(e=>{if(!S)return;e.evt.preventDefault();const s=de.current;if(!s)return;const u=s.scaleX(),d=s.getPointerPosition();if(!d)return;const r=1.1,M=e.evt.deltaY>0?u/r:u*r,W=Math.min(Math.max(M,Z),L),_={x:(d.x-P.x)/u,y:(d.y-P.y)/u},ne={x:d.x-_.x*W,y:d.y-_.y*W};K(W),V(ne)},[S,P,Z,L]);ke(de,{enabled:re&&S,minScale:Z,maxScale:L,currentScale:R,currentPosition:P,onScaleChange:(e,s)=>{K(e),V(s)}});const qe=n.useCallback((e,s)=>{if(!k)return;const u=s.target.getStage();if(!u)return;const d=u.getPointerPosition();if(!d)return;const r=u.container().getBoundingClientRect();ve({visible:!0,x:r.left+d.x,y:r.top+d.y,seat:e,state:ee(e)})},[k,ee]),Ze=n.useCallback(()=>{ve(e=>({...e,visible:!1}))},[]);if(Ye)return o.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:o.jsx("p",{children:"Loading seat map..."})});if(Q)return o.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:o.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",Q.message]})});if(!c)return o.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:o.jsx("p",{children:"No configuration provided"})});const _e=j.width||c.canvas.width,Ge=j.height||c.canvas.height;return o.jsxs("div",{ref:ye,className:`relative ${C}`,style:{width:"100%",height:"100%",touchAction:re&&S?"none":"auto"},children:[ze&&ge.length>0&&o.jsx(De,{floors:ge,currentFloorId:I,onFloorChange:$e,showAllOption:D,allLabel:G,position:Y,className:F}),o.jsxs(E.Stage,{ref:de,width:_e,height:Ge,scaleX:R,scaleY:R,x:P.x,y:P.y,draggable:!0,onDragEnd:He,onWheel:Ve,style:{backgroundColor:c.canvas.backgroundColor,cursor:"grab"},children:[o.jsx(E.Layer,{listening:!1,children:ue.map(e=>o.jsx(Ie,{stage:e,stageColor:le.stageColor},e.id))}),o.jsx(E.Layer,{listening:!1,children:he.map(e=>o.jsx(Te,{text:e},e.id))}),o.jsx(E.Layer,{children:q.map(e=>o.jsx(Re,{seat:e,state:ee(e),colors:le,onClick:Ae,onMouseEnter:qe,onMouseLeave:Ze},e.id))})]}),k&&o.jsx(Pe,{visible:J.visible,x:J.x,y:J.y,seat:J.seat,currency:le.currency,state:J.state}),ie&&S&&o.jsx(Ee,{scale:R,minScale:Z,maxScale:L,fitScale:Se,onZoomIn:Oe,onZoomOut:Be,onFitToScreen:pe,position:oe,className:se}),te.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 (",te.length,")"]}),o.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:te.map(e=>o.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${le.currency} ${e.price.toFixed(2)}`]},e.id))})]})]})};Object.defineProperty(exports,"clearFirebaseInstance",{enumerable:!0,get:()=>z.clearFirebaseInstance});Object.defineProperty(exports,"getFirebaseDatabase",{enumerable:!0,get:()=>z.getFirebaseDatabase});Object.defineProperty(exports,"initializeFirebaseForViewer",{enumerable:!0,get:()=>z.initializeFirebaseForViewer});Object.defineProperty(exports,"isFirebaseInitialized",{enumerable:!0,get:()=>z.isFirebaseInitialized});Object.defineProperty(exports,"useFirebaseConfig",{enumerable:!0,get:()=>z.useFirebaseConfig});Object.defineProperty(exports,"useFirebaseSeatStates",{enumerable:!0,get:()=>z.useFirebaseSeatStates});Object.defineProperty(exports,"useRealtimeSeatMap",{enumerable:!0,get:()=>z.useRealtimeSeatMap});exports.DEFAULT_COLORS=Fe;exports.SeatMapViewer=et;exports.useConfigFetcher=je;exports.useContainerSize=Me;exports.useTouchGestures=ke;
package/dist/index.mjs CHANGED
@@ -1,20 +1,20 @@
1
- import { jsx as a, jsxs as k } from "react/jsx-runtime";
2
- import { useState as E, useCallback as N, useEffect as B, useRef as K, useMemo as z, memo as J } from "react";
3
- import { Stage as oe, Layer as vt, Group as re, Text as Rt, Circle as Dt, Rect as Nt, Path as se, RegularPolygon as ae } from "react-konva";
4
- import { clearFirebaseInstance as be, getFirebaseDatabase as me, initializeFirebaseForViewer as ve, isFirebaseInitialized as Se, useFirebaseConfig as we, useFirebaseSeatStates as Ce, useRealtimeSeatMap as Me } from "@zonetrix/shared";
5
- function ce(n) {
6
- const [u, e] = E(null), [r, S] = E(!1), [y, f] = E(null), x = N(async () => {
1
+ import { jsx as c, jsxs as k } from "react/jsx-runtime";
2
+ import { useState as A, useCallback as N, useEffect as B, useRef as K, useMemo as z, memo as J } from "react";
3
+ import { Stage as oe, Layer as St, Group as re, Text as Dt, Circle as Nt, Rect as Tt, Path as se, RegularPolygon as ce } from "react-konva";
4
+ import { clearFirebaseInstance as me, getFirebaseDatabase as be, initializeFirebaseForViewer as ve, isFirebaseInitialized as Se, useFirebaseConfig as we, useFirebaseSeatStates as Ce, useRealtimeSeatMap as Me } from "@zonetrix/shared";
5
+ function ae(n) {
6
+ const [u, e] = A(null), [r, S] = A(!1), [y, f] = A(null), x = N(async () => {
7
7
  if (n) {
8
8
  S(!0), f(null);
9
9
  try {
10
10
  const g = await fetch(n);
11
11
  if (!g.ok)
12
12
  throw new Error(`Failed to fetch config: ${g.statusText}`);
13
- const c = await g.json();
14
- e(c);
13
+ const a = await g.json();
14
+ e(a);
15
15
  } catch (g) {
16
- const c = g instanceof Error ? g : new Error("Unknown error occurred");
17
- f(c), console.error("Failed to fetch seat map config:", c);
16
+ const a = g instanceof Error ? g : new Error("Unknown error occurred");
17
+ f(a), console.error("Failed to fetch seat map config:", a);
18
18
  } finally {
19
19
  S(!1);
20
20
  }
@@ -30,7 +30,7 @@ function ce(n) {
30
30
  };
31
31
  }
32
32
  function le(n) {
33
- const [u, e] = E({ width: 0, height: 0 });
33
+ const [u, e] = A({ width: 0, height: 0 });
34
34
  return B(() => {
35
35
  const r = n.current;
36
36
  if (!r) return;
@@ -39,18 +39,18 @@ function le(n) {
39
39
  const f = new ResizeObserver((x) => {
40
40
  const g = x[0];
41
41
  if (!g) return;
42
- const { width: c, height: p } = g.contentRect;
43
- c > 0 && p > 0 && e((b) => b.width === c && b.height === p ? b : { width: c, height: p });
42
+ const { width: a, height: p } = g.contentRect;
43
+ a > 0 && p > 0 && e((m) => m.width === a && m.height === p ? m : { width: a, height: p });
44
44
  });
45
45
  return f.observe(r), () => {
46
46
  f.disconnect();
47
47
  };
48
48
  }, [n]), u;
49
49
  }
50
- function Ft(n, u) {
50
+ function kt(n, u) {
51
51
  return Math.sqrt(Math.pow(u.x - n.x, 2) + Math.pow(u.y - n.y, 2));
52
52
  }
53
- function kt(n, u) {
53
+ function Rt(n, u) {
54
54
  return {
55
55
  x: (n.x + u.x) / 2,
56
56
  y: (n.y + u.y) / 2
@@ -62,44 +62,46 @@ function he(n, u) {
62
62
  minScale: f,
63
63
  maxScale: x,
64
64
  currentScale: g,
65
- currentPosition: c,
65
+ currentPosition: a,
66
66
  onScaleChange: p
67
67
  } = u;
68
68
  B(() => {
69
- const b = n.current;
70
- if (!b || !y) return;
71
- const d = b.container(), I = (m) => {
72
- if (m.touches.length === 2) {
73
- m.preventDefault();
74
- const X = { x: m.touches[0].clientX, y: m.touches[0].clientY }, W = { x: m.touches[1].clientX, y: m.touches[1].clientY };
75
- e.current = Ft(X, W), r.current = kt(X, W), S.current = g;
69
+ const m = n.current;
70
+ if (!m || !y) return;
71
+ const h = m.container(), I = h.style.touchAction;
72
+ h.style.touchAction = "none";
73
+ const b = (v) => {
74
+ if (v.touches.length === 2) {
75
+ v.preventDefault();
76
+ const T = { x: v.touches[0].clientX, y: v.touches[0].clientY }, P = { x: v.touches[1].clientX, y: v.touches[1].clientY };
77
+ e.current = kt(T, P), r.current = Rt(T, P), S.current = g;
76
78
  }
77
- }, v = (m) => {
78
- if (m.touches.length !== 2) return;
79
- m.preventDefault();
80
- const X = { x: m.touches[0].clientX, y: m.touches[0].clientY }, W = { x: m.touches[1].clientX, y: m.touches[1].clientY }, O = Ft(X, W), M = kt(X, W);
79
+ }, w = (v) => {
80
+ if (v.touches.length !== 2) return;
81
+ v.preventDefault();
82
+ const T = { x: v.touches[0].clientX, y: v.touches[0].clientY }, P = { x: v.touches[1].clientX, y: v.touches[1].clientY }, F = kt(T, P), W = Rt(T, P);
81
83
  if (e.current !== null && r.current !== null) {
82
- const P = O / e.current, A = Math.min(
83
- Math.max(g * P, f),
84
+ const Q = F / e.current, O = Math.min(
85
+ Math.max(g * Q, f),
84
86
  x
85
- ), Q = d.getBoundingClientRect(), j = M.x - Q.left, st = M.y - Q.top, at = g, ct = {
86
- x: (j - c.x) / at,
87
- y: (st - c.y) / at
88
- }, lt = M.x - r.current.x, Y = M.y - r.current.y, V = {
89
- x: j - ct.x * A + lt,
90
- y: st - ct.y * A + Y
87
+ ), j = h.getBoundingClientRect(), ct = W.x - j.left, at = W.y - j.top, lt = g, tt = {
88
+ x: (ct - a.x) / lt,
89
+ y: (at - a.y) / lt
90
+ }, Y = W.x - r.current.x, V = W.y - r.current.y, ht = {
91
+ x: ct - tt.x * O + Y,
92
+ y: at - tt.y * O + V
91
93
  };
92
- p(A, V), e.current = O, r.current = M;
94
+ p(O, ht), e.current = F, r.current = W;
93
95
  }
94
- }, w = (m) => {
95
- m.touches.length < 2 && (e.current = null, r.current = null);
96
+ }, E = (v) => {
97
+ v.touches.length < 2 && (e.current = null, r.current = null);
96
98
  };
97
- return d.addEventListener("touchstart", I, {
99
+ return h.addEventListener("touchstart", b, {
98
100
  passive: !1
99
- }), d.addEventListener("touchmove", v, {
101
+ }), h.addEventListener("touchmove", w, {
100
102
  passive: !1
101
- }), d.addEventListener("touchend", w), () => {
102
- d.removeEventListener("touchstart", I), d.removeEventListener("touchmove", v), d.removeEventListener("touchend", w);
103
+ }), h.addEventListener("touchend", E), () => {
104
+ h.style.touchAction = I, h.removeEventListener("touchstart", b), h.removeEventListener("touchmove", w), h.removeEventListener("touchend", E);
103
105
  };
104
106
  }, [
105
107
  n,
@@ -107,7 +109,7 @@ function he(n, u) {
107
109
  f,
108
110
  x,
109
111
  g,
110
- c,
112
+ a,
111
113
  p
112
114
  ]);
113
115
  }
@@ -130,35 +132,36 @@ const de = {
130
132
  unavailable: e.seatUnavailable,
131
133
  hidden: e.seatHidden
132
134
  // Hidden seats are filtered out, but included for type safety
133
- }[u], c = u === "available" || u === "selected", p = N(() => {
134
- c && r(n);
135
- }, [n, r, c]), b = N(
136
- (v) => {
137
- S(n, v);
138
- const w = v.target.getStage();
139
- w && c && (w.container().style.cursor = "pointer");
135
+ }[u], a = u === "available" || u === "selected", p = N(() => {
136
+ a && r(n);
137
+ }, [n, r, a]), m = N(
138
+ (b) => {
139
+ S(n, b);
140
+ const w = b.target.getStage();
141
+ w && a && (w.container().style.cursor = "pointer");
140
142
  },
141
- [n, S, c]
142
- ), d = N(
143
- (v) => {
143
+ [n, S, a]
144
+ ), h = N(
145
+ (b) => {
144
146
  y();
145
- const w = v.target.getStage();
147
+ const w = b.target.getStage();
146
148
  w && (w.container().style.cursor = "grab");
147
149
  },
148
150
  [y]
149
151
  ), I = {
150
152
  x: n.position.x,
151
153
  y: n.position.y,
154
+ rotation: n.rotation || 0,
152
155
  fill: g,
153
156
  stroke: "#ffffff",
154
157
  strokeWidth: 1,
155
158
  onClick: p,
156
159
  onTap: p,
157
- onMouseEnter: b,
158
- onMouseLeave: d
160
+ onMouseEnter: m,
161
+ onMouseLeave: h
159
162
  };
160
- return n.shape === "circle" ? /* @__PURE__ */ a(Dt, { ...I, radius: f }) : /* @__PURE__ */ a(
161
- Nt,
163
+ return n.shape === "circle" ? /* @__PURE__ */ c(Nt, { ...I, radius: f }) : /* @__PURE__ */ c(
164
+ Tt,
162
165
  {
163
166
  ...I,
164
167
  width: f * 2,
@@ -171,59 +174,59 @@ const de = {
171
174
  }
172
175
  );
173
176
  Wt.displayName = "ViewerSeat";
174
- const Tt = J(({ stage: n, stageColor: u }) => {
177
+ const Xt = J(({ stage: n, stageColor: u }) => {
175
178
  const e = n.config, r = e.shape || "rectangle", S = e.showLabel !== !1, y = e.color || u, f = e.width / e.height, x = f < 0.5, g = f > 2;
176
- let c;
177
- x ? c = e.width * 0.25 : g ? c = e.height * 0.35 : c = Math.min(e.width, e.height) * 0.25;
178
- const p = e.label?.length || 6, I = e.width * 0.85 / p * 1.5, v = Math.max(
179
+ let a;
180
+ x ? a = e.width * 0.25 : g ? a = e.height * 0.35 : a = Math.min(e.width, e.height) * 0.25;
181
+ const p = e.label?.length || 6, I = e.width * 0.85 / p * 1.5, b = Math.max(
179
182
  10,
180
- Math.min(24, Math.min(c, I))
181
- ), w = 4, m = Math.max(20, e.width - w * 2), X = (e.width - m) / 2, W = {
183
+ Math.min(24, Math.min(a, I))
184
+ ), w = 4, E = Math.max(20, e.width - w * 2), v = (e.width - E) / 2, T = {
182
185
  fill: y + "80",
183
186
  stroke: "#ffffff",
184
187
  strokeWidth: 2,
185
188
  perfectDrawEnabled: !1,
186
189
  hitStrokeWidth: 0
187
- }, O = () => {
190
+ }, P = () => {
188
191
  switch (r) {
189
192
  case "circle": {
190
- const M = Math.min(e.width, e.height) / 2;
191
- return /* @__PURE__ */ a(
192
- Dt,
193
+ const F = Math.min(e.width, e.height) / 2;
194
+ return /* @__PURE__ */ c(
195
+ Nt,
193
196
  {
194
197
  x: e.width / 2,
195
198
  y: e.height / 2,
196
- radius: M,
197
- ...W
199
+ radius: F,
200
+ ...T
198
201
  }
199
202
  );
200
203
  }
201
204
  case "triangle": {
202
- const M = Math.min(e.width, e.height) / 2;
203
- return /* @__PURE__ */ a(
204
- ae,
205
+ const F = Math.min(e.width, e.height) / 2;
206
+ return /* @__PURE__ */ c(
207
+ ce,
205
208
  {
206
209
  x: e.width / 2,
207
210
  y: e.height / 2,
208
211
  sides: 3,
209
- radius: M,
212
+ radius: F,
210
213
  rotation: -90,
211
- ...W
214
+ ...T
212
215
  }
213
216
  );
214
217
  }
215
218
  case "arrow": {
216
- const M = e.width / 24, P = e.height / 24, A = `M${9 * M},${18 * P} v${-8 * P} H${5 * M} l${7 * M},${-7 * P} l${7 * M},${7 * P} h${-4 * M} v${8 * P} Z`;
217
- return /* @__PURE__ */ a(se, { data: A, ...W });
219
+ const F = e.width / 24, W = e.height / 24, Q = `M${9 * F},${18 * W} v${-8 * W} H${5 * F} l${7 * F},${-7 * W} l${7 * F},${7 * W} h${-4 * F} v${8 * W} Z`;
220
+ return /* @__PURE__ */ c(se, { data: Q, ...T });
218
221
  }
219
222
  default:
220
- return /* @__PURE__ */ a(
221
- Nt,
223
+ return /* @__PURE__ */ c(
224
+ Tt,
222
225
  {
223
226
  width: e.width,
224
227
  height: e.height,
225
228
  cornerRadius: 10,
226
- ...W
229
+ ...T
227
230
  }
228
231
  );
229
232
  }
@@ -235,16 +238,16 @@ const Tt = J(({ stage: n, stageColor: u }) => {
235
238
  y: n.position.y,
236
239
  rotation: e.rotation || 0,
237
240
  children: [
238
- O(),
239
- S && /* @__PURE__ */ a(
240
- Rt,
241
+ P(),
242
+ S && /* @__PURE__ */ c(
243
+ Dt,
241
244
  {
242
245
  text: e.label,
243
- x: X,
246
+ x: v,
244
247
  y: w,
245
- width: m,
248
+ width: E,
246
249
  height: e.height - w * 2,
247
- fontSize: v,
250
+ fontSize: b,
248
251
  fontStyle: "bold",
249
252
  fill: "#ffffff",
250
253
  align: "center",
@@ -257,9 +260,9 @@ const Tt = J(({ stage: n, stageColor: u }) => {
257
260
  }
258
261
  );
259
262
  });
260
- Tt.displayName = "ViewerStage";
261
- const Xt = J(({ text: n }) => /* @__PURE__ */ a(
262
- Rt,
263
+ Xt.displayName = "ViewerStage";
264
+ const Yt = J(({ text: n }) => /* @__PURE__ */ c(
265
+ Dt,
263
266
  {
264
267
  x: n.position.x,
265
268
  y: n.position.y,
@@ -272,8 +275,8 @@ const Xt = J(({ text: n }) => /* @__PURE__ */ a(
272
275
  listening: !1
273
276
  }
274
277
  ));
275
- Xt.displayName = "ViewerText";
276
- const Yt = J(
278
+ Yt.displayName = "ViewerText";
279
+ const Lt = J(
277
280
  ({
278
281
  floors: n,
279
282
  currentFloorId: u,
@@ -284,9 +287,9 @@ const Yt = J(
284
287
  className: f
285
288
  }) => {
286
289
  const x = z(
287
- () => [...n].sort((d, I) => d.order - I.order),
290
+ () => [...n].sort((h, I) => h.order - I.order),
288
291
  [n]
289
- ), c = {
292
+ ), a = {
290
293
  position: "absolute",
291
294
  display: "flex",
292
295
  alignItems: "center",
@@ -314,36 +317,36 @@ const Yt = J(
314
317
  transition: "all 0.2s ease",
315
318
  minHeight: "44px",
316
319
  touchAction: "manipulation"
317
- }, b = {
320
+ }, m = {
318
321
  ...p,
319
322
  backgroundColor: "#3A7DE5",
320
323
  borderColor: "#3A7DE5"
321
324
  };
322
- return /* @__PURE__ */ k("div", { className: f, style: c, children: [
323
- r && /* @__PURE__ */ a(
325
+ return /* @__PURE__ */ k("div", { className: f, style: a, children: [
326
+ r && /* @__PURE__ */ c(
324
327
  "button",
325
328
  {
326
329
  type: "button",
327
330
  onClick: () => e(null),
328
- style: u === null ? b : p,
331
+ style: u === null ? m : p,
329
332
  children: S
330
333
  }
331
334
  ),
332
- x.map((d) => /* @__PURE__ */ a(
335
+ x.map((h) => /* @__PURE__ */ c(
333
336
  "button",
334
337
  {
335
338
  type: "button",
336
- onClick: () => e(d.id),
337
- style: u === d.id ? b : p,
338
- children: d.name
339
+ onClick: () => e(h.id),
340
+ style: u === h.id ? m : p,
341
+ children: h.name
339
342
  },
340
- d.id
343
+ h.id
341
344
  ))
342
345
  ] });
343
346
  }
344
347
  );
345
- Yt.displayName = "FloorSelectorBar";
346
- const Lt = J(
348
+ Lt.displayName = "FloorSelectorBar";
349
+ const $t = J(
347
350
  ({ scale: n, minScale: u, maxScale: e, fitScale: r, onZoomIn: S, onZoomOut: y, onFitToScreen: f, position: x, className: g }) => {
348
351
  const p = {
349
352
  position: "absolute",
@@ -361,7 +364,7 @@ const Lt = J(
361
364
  "bottom-left": { bottom: 0, left: 0 },
362
365
  "bottom-right": { bottom: 0, right: 0 }
363
366
  }[x]
364
- }, b = {
367
+ }, m = {
365
368
  width: "44px",
366
369
  height: "44px",
367
370
  minWidth: "44px",
@@ -378,43 +381,43 @@ const Lt = J(
378
381
  justifyContent: "center",
379
382
  transition: "all 0.2s ease",
380
383
  touchAction: "manipulation"
381
- }, d = {
382
- ...b,
384
+ }, h = {
385
+ ...m,
383
386
  opacity: 0.4,
384
387
  cursor: "not-allowed"
385
- }, I = n < e, v = n > u, w = Math.abs(n - r) < 0.01;
388
+ }, I = n < e, b = n > u, w = Math.abs(n - r) < 0.01;
386
389
  return /* @__PURE__ */ k("div", { className: g, style: p, children: [
387
- /* @__PURE__ */ a(
390
+ /* @__PURE__ */ c(
388
391
  "button",
389
392
  {
390
393
  type: "button",
391
394
  onClick: S,
392
395
  disabled: !I,
393
- style: I ? b : d,
396
+ style: I ? m : h,
394
397
  title: "Zoom In",
395
398
  "aria-label": "Zoom In",
396
399
  children: "+"
397
400
  }
398
401
  ),
399
- /* @__PURE__ */ a(
402
+ /* @__PURE__ */ c(
400
403
  "button",
401
404
  {
402
405
  type: "button",
403
406
  onClick: f,
404
407
  disabled: w,
405
- style: w ? d : b,
408
+ style: w ? h : m,
406
409
  title: "Fit to Screen",
407
410
  "aria-label": "Fit to Screen",
408
411
  children: "⤢"
409
412
  }
410
413
  ),
411
- /* @__PURE__ */ a(
414
+ /* @__PURE__ */ c(
412
415
  "button",
413
416
  {
414
417
  type: "button",
415
418
  onClick: y,
416
- disabled: !v,
417
- style: v ? b : d,
419
+ disabled: !b,
420
+ style: b ? m : h,
418
421
  title: "Zoom Out",
419
422
  "aria-label": "Zoom Out",
420
423
  children: "−"
@@ -423,8 +426,8 @@ const Lt = J(
423
426
  ] });
424
427
  }
425
428
  );
426
- Lt.displayName = "ZoomControls";
427
- const $t = J(
429
+ $t.displayName = "ZoomControls";
430
+ const At = J(
428
431
  ({ visible: n, x: u, y: e, seat: r, currency: S, state: y }) => {
429
432
  if (!n || !r) return null;
430
433
  const f = r.seatNumber || (r.rowLabel && r.columnLabel ? `${r.rowLabel}-${r.columnLabel}` : "N/A"), x = {
@@ -442,45 +445,45 @@ const $t = J(
442
445
  fontSize: "13px",
443
446
  boxShadow: "0 4px 12px rgba(0, 0, 0, 0.3)",
444
447
  minWidth: "140px"
445
- }, c = {
448
+ }, a = {
446
449
  color: "#9ca3af",
447
450
  marginRight: "4px"
448
451
  }, p = {
449
452
  fontWeight: 600
450
- }, b = {
453
+ }, m = {
451
454
  color: "#4ade80",
452
455
  fontWeight: 600
453
- }, d = {
456
+ }, h = {
454
457
  fontSize: "11px",
455
458
  color: "#6b7280",
456
459
  textTransform: "capitalize",
457
460
  marginTop: "4px"
458
461
  };
459
- return /* @__PURE__ */ a("div", { style: x, children: /* @__PURE__ */ k("div", { style: g, children: [
462
+ return /* @__PURE__ */ c("div", { style: x, children: /* @__PURE__ */ k("div", { style: g, children: [
460
463
  r.sectionName && /* @__PURE__ */ k("div", { style: { marginBottom: "4px" }, children: [
461
- /* @__PURE__ */ a("span", { style: c, children: "Section:" }),
462
- /* @__PURE__ */ a("span", { style: { ...p, color: "#3b82f6" }, children: r.sectionName })
464
+ /* @__PURE__ */ c("span", { style: a, children: "Section:" }),
465
+ /* @__PURE__ */ c("span", { style: { ...p, color: "#3b82f6" }, children: r.sectionName })
463
466
  ] }),
464
467
  /* @__PURE__ */ k("div", { style: { marginBottom: "4px" }, children: [
465
- /* @__PURE__ */ a("span", { style: c, children: "Seat:" }),
466
- /* @__PURE__ */ a("span", { style: p, children: f })
468
+ /* @__PURE__ */ c("span", { style: a, children: "Seat:" }),
469
+ /* @__PURE__ */ c("span", { style: p, children: f })
467
470
  ] }),
468
471
  r.price !== void 0 && r.price > 0 && y === "available" && /* @__PURE__ */ k("div", { style: { marginBottom: "4px" }, children: [
469
- /* @__PURE__ */ a("span", { style: c, children: "Price:" }),
470
- /* @__PURE__ */ k("span", { style: b, children: [
472
+ /* @__PURE__ */ c("span", { style: a, children: "Price:" }),
473
+ /* @__PURE__ */ k("span", { style: m, children: [
471
474
  S,
472
475
  " ",
473
476
  r.price.toFixed(2)
474
477
  ] })
475
478
  ] }),
476
- /* @__PURE__ */ k("div", { style: d, children: [
479
+ /* @__PURE__ */ k("div", { style: h, children: [
477
480
  "Status: ",
478
481
  y
479
482
  ] })
480
483
  ] }) });
481
484
  }
482
485
  );
483
- $t.displayName = "SeatTooltip";
486
+ At.displayName = "SeatTooltip";
484
487
  const pe = ({
485
488
  config: n,
486
489
  configUrl: u,
@@ -492,84 +495,84 @@ const pe = ({
492
495
  unavailableSeats: f = [],
493
496
  selectedSeats: x,
494
497
  myReservedSeats: g = [],
495
- onSeatSelect: c,
498
+ onSeatSelect: a,
496
499
  onSeatDeselect: p,
497
- onSelectionChange: b,
498
- colorOverrides: d,
500
+ onSelectionChange: m,
501
+ colorOverrides: h,
499
502
  showTooltip: I = !0,
500
- zoomEnabled: v = !0,
503
+ zoomEnabled: b = !0,
501
504
  className: w = "",
502
- onConfigLoad: m,
503
- onError: X,
505
+ onConfigLoad: E,
506
+ onError: v,
504
507
  // Floor selector props
505
- showFloorSelector: W,
506
- floorSelectorPosition: O = "top-left",
507
- floorSelectorClassName: M,
508
- showAllFloorsOption: P = !0,
509
- allFloorsLabel: A = "All",
510
- fitToView: Q = !0,
508
+ showFloorSelector: T,
509
+ floorSelectorPosition: P = "top-left",
510
+ floorSelectorClassName: F,
511
+ showAllFloorsOption: W = !0,
512
+ allFloorsLabel: Q = "All",
513
+ fitToView: O = !0,
511
514
  fitPadding: j = 40,
512
515
  // Zoom controls
513
- showZoomControls: st = !0,
516
+ showZoomControls: ct = !0,
514
517
  zoomControlsPosition: at = "bottom-right",
515
- zoomControlsClassName: ct,
516
- minZoom: lt,
518
+ zoomControlsClassName: lt,
519
+ minZoom: tt,
517
520
  maxZoom: Y = 3,
518
521
  zoomStep: V = 0.25,
519
522
  // Touch gestures
520
- touchEnabled: Et = !0
523
+ touchEnabled: ht = !0
521
524
  }) => {
522
- const St = y !== void 0 ? y : S, pt = K(null), wt = K(null), C = le(wt), [Z, Ct] = E(
525
+ const wt = y !== void 0 ? y : S, yt = K(null), Ct = K(null), C = le(Ct), [Z, Mt] = A(
523
526
  /* @__PURE__ */ new Set()
524
- ), [R, tt] = E(1), [T, _] = E({ x: 0, y: 0 }), [Pt, zt] = E(null), [Mt, Bt] = E(1), ht = K({ width: 0, height: 0 }), [et, It] = E({ visible: !1, x: 0, y: 0, seat: null, state: "available" }), { config: At, loading: Ht, error: nt } = ce(u), s = n || At, yt = e !== void 0, D = yt ? e || null : Pt, dt = x !== void 0, Ot = N(
527
+ ), [R, et] = A(1), [X, _] = A({ x: 0, y: 0 }), [Et, Pt] = A(null), [It, zt] = A(1), dt = K({ width: 0, height: 0 }), [nt, Ft] = A({ visible: !1, x: 0, y: 0, seat: null, state: "available" }), { config: Bt, loading: Ht, error: it } = ae(u), s = n || Bt, xt = e !== void 0, D = xt ? e || null : Et, ut = x !== void 0, Ot = N(
525
528
  (t) => {
526
- yt || zt(t), r?.(t);
529
+ xt || Pt(t), r?.(t);
527
530
  },
528
- [yt, r]
529
- ), xt = s?.floors || [], jt = W !== void 0 ? W : xt.length > 1, ut = z(
530
- () => s ? { ...s.colors, ...d } : { ...de, ...d },
531
- [s, d]
531
+ [xt, r]
532
+ ), mt = s?.floors || [], jt = T !== void 0 ? T : mt.length > 1, ft = z(
533
+ () => s ? { ...s.colors, ...h } : { ...de, ...h },
534
+ [s, h]
532
535
  ), q = z(() => {
533
536
  if (!s) return [];
534
537
  let t = s.seats.filter((i) => i.state !== "hidden");
535
538
  return D && (t = t.filter(
536
539
  (i) => i.floorId === D || !i.floorId && D === "floor_default"
537
540
  )), t;
538
- }, [s, D]), ft = z(() => s?.stages ? D ? s.stages.filter(
541
+ }, [s, D]), gt = z(() => s?.stages ? D ? s.stages.filter(
539
542
  (t) => t.floorId === D || !t.floorId && D === "floor_default"
540
- ) : s.stages : [], [s, D]), gt = z(() => s?.texts ? D ? s.texts.filter(
543
+ ) : s.stages : [], [s, D]), pt = z(() => s?.texts ? D ? s.texts.filter(
541
544
  (t) => t.floorId === D || !t.floorId && D === "floor_default"
542
545
  ) : s.texts : [], [s, D]), L = z(() => {
543
- if (!s || q.length === 0 && ft.length === 0 && gt.length === 0)
546
+ if (!s || q.length === 0 && gt.length === 0 && pt.length === 0)
544
547
  return null;
545
- let t = 1 / 0, i = 1 / 0, l = -1 / 0, h = -1 / 0;
548
+ let t = 1 / 0, i = 1 / 0, l = -1 / 0, d = -1 / 0;
546
549
  return q.forEach((o) => {
547
- const F = (o.size || 24) / 2;
548
- t = Math.min(t, o.position.x - F), i = Math.min(i, o.position.y - F), l = Math.max(l, o.position.x + F), h = Math.max(h, o.position.y + F);
549
- }), ft.forEach((o) => {
550
- t = Math.min(t, o.position.x), i = Math.min(i, o.position.y), l = Math.max(l, o.position.x + (o.config?.width || 200)), h = Math.max(h, o.position.y + (o.config?.height || 100));
550
+ const M = (o.size || 24) / 2;
551
+ t = Math.min(t, o.position.x - M), i = Math.min(i, o.position.y - M), l = Math.max(l, o.position.x + M), d = Math.max(d, o.position.y + M);
551
552
  }), gt.forEach((o) => {
552
- const F = o.config.scaleX || 1, $ = o.config.scaleY || 1, U = o.config.text.length * o.config.fontSize * 0.6 * F, rt = o.config.fontSize * $;
553
- t = Math.min(t, o.position.x), i = Math.min(i, o.position.y), l = Math.max(l, o.position.x + U), h = Math.max(h, o.position.y + rt);
554
- }), { minX: t, minY: i, maxX: l, maxY: h, width: l - t, height: h - i };
555
- }, [s, q, ft, gt]), bt = N(() => {
553
+ t = Math.min(t, o.position.x), i = Math.min(i, o.position.y), l = Math.max(l, o.position.x + (o.config?.width || 200)), d = Math.max(d, o.position.y + (o.config?.height || 100));
554
+ }), pt.forEach((o) => {
555
+ const M = o.config.scaleX || 1, $ = o.config.scaleY || 1, U = o.config.text.length * o.config.fontSize * 0.6 * M, st = o.config.fontSize * $;
556
+ t = Math.min(t, o.position.x), i = Math.min(i, o.position.y), l = Math.max(l, o.position.x + U), d = Math.max(d, o.position.y + st);
557
+ }), { minX: t, minY: i, maxX: l, maxY: d, width: l - t, height: d - i };
558
+ }, [s, q, gt, pt]), bt = N(() => {
556
559
  if (!s || !L || C.width === 0 || C.height === 0) return;
557
- const t = C.width, i = C.height, l = t - j * 2, h = i - j * 2, o = l / L.width, F = h / L.height, $ = Math.min(o, F, Y), U = L.minX + L.width / 2, rt = L.minY + L.height / 2, te = t / 2, ee = i / 2, ne = te - U * $, ie = ee - rt * $;
558
- tt($), _({ x: ne, y: ie }), Bt($);
560
+ const t = C.width, i = C.height, l = t - j * 2, d = i - j * 2, o = l / L.width, M = d / L.height, $ = Math.min(o, M, Y), U = L.minX + L.width / 2, st = L.minY + L.height / 2, te = t / 2, ee = i / 2, ne = te - U * $, ie = ee - st * $;
561
+ et($), _({ x: ne, y: ie }), zt($);
559
562
  }, [s, L, C, j, Y]);
560
563
  B(() => {
561
- if (!Q || !s || !L || C.width === 0 || C.height === 0) return;
564
+ if (!O || !s || !L || C.width === 0 || C.height === 0) return;
562
565
  const t = Math.abs(
563
- C.width - ht.current.width
566
+ C.width - dt.current.width
564
567
  ), i = Math.abs(
565
- C.height - ht.current.height
568
+ C.height - dt.current.height
566
569
  );
567
- !(ht.current.width === 0) && t < 10 && i < 10 || (ht.current = C, bt());
568
- }, [Q, s, L, C, D, bt]);
570
+ !(dt.current.width === 0) && t < 10 && i < 10 || (dt.current = C, bt());
571
+ }, [O, s, L, C, D, bt]);
569
572
  const H = z(() => {
570
- const t = new Set(St), i = new Set(f), l = new Set(g);
573
+ const t = new Set(wt), i = new Set(f), l = new Set(g);
571
574
  return { reserved: t, unavailable: i, myReserved: l };
572
- }, [St, f, g]), mt = z(() => x ? new Set(x) : null, [x]), it = N(
575
+ }, [wt, f, g]), vt = z(() => x ? new Set(x) : null, [x]), ot = N(
573
576
  (t) => {
574
577
  const i = t.id, l = t.seatNumber || "";
575
578
  return H.unavailable.has(i) || H.unavailable.has(l) ? "unavailable" : H.reserved.has(i) || H.reserved.has(l) ? "reserved" : H.myReserved.has(i) || H.myReserved.has(l) || Z.has(i) ? "selected" : t.state;
@@ -577,76 +580,76 @@ const pe = ({
577
580
  [H, Z]
578
581
  );
579
582
  B(() => {
580
- s && m && m(s);
581
- }, [s, m]), B(() => {
582
- nt && X && X(nt);
583
- }, [nt, X]), B(() => {
584
- dt && mt && Ct(mt);
585
- }, [dt, mt]);
583
+ s && E && E(s);
584
+ }, [s, E]), B(() => {
585
+ it && v && v(it);
586
+ }, [it, v]), B(() => {
587
+ ut && vt && Mt(vt);
588
+ }, [ut, vt]);
586
589
  const Vt = N(
587
590
  (t) => {
588
- const i = it(t);
591
+ const i = ot(t);
589
592
  if (i !== "available" && i !== "selected")
590
593
  return;
591
594
  const l = Z.has(t.id);
592
- dt || Ct((h) => {
593
- const o = new Set(h);
595
+ ut || Mt((d) => {
596
+ const o = new Set(d);
594
597
  return l ? o.delete(t.id) : o.add(t.id), o;
595
- }), l ? p?.(t) : (c?.(t), c || console.log("Seat selected:", t));
598
+ }), l ? p?.(t) : (a?.(t), a || console.log("Seat selected:", t));
596
599
  },
597
600
  [
598
- it,
601
+ ot,
599
602
  Z,
600
- dt,
601
- c,
603
+ ut,
604
+ a,
602
605
  p
603
606
  ]
604
- ), ot = z(() => s ? q.filter((t) => Z.has(t.id)) : [], [s, q, Z]);
607
+ ), rt = z(() => s ? q.filter((t) => Z.has(t.id)) : [], [s, q, Z]);
605
608
  B(() => {
606
- b?.(ot);
607
- }, [ot, b]);
608
- const G = lt !== void 0 ? lt : Mt * 0.5, Zt = N(() => {
609
- if (!v) return;
609
+ m?.(rt);
610
+ }, [rt, m]);
611
+ const G = tt !== void 0 ? tt : It * 0.5, Zt = N(() => {
612
+ if (!b) return;
610
613
  const t = Math.min(R + V, Y);
611
614
  if (t !== R) {
612
- const i = C.width || s?.canvas.width || 800, l = C.height || s?.canvas.height || 600, h = i / 2, o = l / 2, F = {
613
- x: (h - T.x) / R,
614
- y: (o - T.y) / R
615
+ const i = C.width || s?.canvas.width || 800, l = C.height || s?.canvas.height || 600, d = i / 2, o = l / 2, M = {
616
+ x: (d - X.x) / R,
617
+ y: (o - X.y) / R
615
618
  };
616
- tt(t), _({
617
- x: h - F.x * t,
618
- y: o - F.y * t
619
+ et(t), _({
620
+ x: d - M.x * t,
621
+ y: o - M.y * t
619
622
  });
620
623
  }
621
624
  }, [
622
- v,
625
+ b,
623
626
  R,
624
627
  V,
625
628
  Y,
626
629
  C,
627
630
  s,
628
- T
631
+ X
629
632
  ]), _t = N(() => {
630
- if (!v) return;
633
+ if (!b) return;
631
634
  const t = Math.max(R - V, G);
632
635
  if (t !== R) {
633
- const i = C.width || s?.canvas.width || 800, l = C.height || s?.canvas.height || 600, h = i / 2, o = l / 2, F = {
634
- x: (h - T.x) / R,
635
- y: (o - T.y) / R
636
+ const i = C.width || s?.canvas.width || 800, l = C.height || s?.canvas.height || 600, d = i / 2, o = l / 2, M = {
637
+ x: (d - X.x) / R,
638
+ y: (o - X.y) / R
636
639
  };
637
- tt(t), _({
638
- x: h - F.x * t,
639
- y: o - F.y * t
640
+ et(t), _({
641
+ x: d - M.x * t,
642
+ y: o - M.y * t
640
643
  });
641
644
  }
642
645
  }, [
643
- v,
646
+ b,
644
647
  R,
645
648
  V,
646
649
  G,
647
650
  C,
648
651
  s,
649
- T
652
+ X
650
653
  ]), qt = N((t) => {
651
654
  _({
652
655
  x: t.target.x(),
@@ -654,31 +657,31 @@ const pe = ({
654
657
  });
655
658
  }, []), Gt = N(
656
659
  (t) => {
657
- if (!v) return;
660
+ if (!b) return;
658
661
  t.evt.preventDefault();
659
- const i = pt.current;
662
+ const i = yt.current;
660
663
  if (!i) return;
661
- const l = i.scaleX(), h = i.getPointerPosition();
662
- if (!h) return;
663
- const o = 1.1, F = t.evt.deltaY > 0 ? l / o : l * o, $ = Math.min(Math.max(F, G), Y), U = {
664
- x: (h.x - T.x) / l,
665
- y: (h.y - T.y) / l
666
- }, rt = {
667
- x: h.x - U.x * $,
668
- y: h.y - U.y * $
664
+ const l = i.scaleX(), d = i.getPointerPosition();
665
+ if (!d) return;
666
+ const o = 1.1, M = t.evt.deltaY > 0 ? l / o : l * o, $ = Math.min(Math.max(M, G), Y), U = {
667
+ x: (d.x - X.x) / l,
668
+ y: (d.y - X.y) / l
669
+ }, st = {
670
+ x: d.x - U.x * $,
671
+ y: d.y - U.y * $
669
672
  };
670
- tt($), _(rt);
673
+ et($), _(st);
671
674
  },
672
- [v, T, G, Y]
675
+ [b, X, G, Y]
673
676
  );
674
- he(pt, {
675
- enabled: Et && v,
677
+ he(yt, {
678
+ enabled: ht && b,
676
679
  minScale: G,
677
680
  maxScale: Y,
678
681
  currentScale: R,
679
- currentPosition: T,
682
+ currentPosition: X,
680
683
  onScaleChange: (t, i) => {
681
- tt(t), _(i);
684
+ et(t), _(i);
682
685
  }
683
686
  });
684
687
  const Ut = N(
@@ -686,60 +689,60 @@ const pe = ({
686
689
  if (!I) return;
687
690
  const l = i.target.getStage();
688
691
  if (!l) return;
689
- const h = l.getPointerPosition();
690
- if (!h) return;
692
+ const d = l.getPointerPosition();
693
+ if (!d) return;
691
694
  const o = l.container().getBoundingClientRect();
692
- It({
695
+ Ft({
693
696
  visible: !0,
694
- x: o.left + h.x,
695
- y: o.top + h.y,
697
+ x: o.left + d.x,
698
+ y: o.top + d.y,
696
699
  seat: t,
697
- state: it(t)
700
+ state: ot(t)
698
701
  });
699
702
  },
700
- [I, it]
703
+ [I, ot]
701
704
  ), Kt = N(() => {
702
- It((t) => ({ ...t, visible: !1 }));
705
+ Ft((t) => ({ ...t, visible: !1 }));
703
706
  }, []);
704
707
  if (Ht)
705
- return /* @__PURE__ */ a("div", { className: `flex items-center justify-center h-full ${w}`, children: /* @__PURE__ */ a("p", { children: "Loading seat map..." }) });
706
- if (nt)
707
- return /* @__PURE__ */ a("div", { className: `flex items-center justify-center h-full ${w}`, children: /* @__PURE__ */ k("p", { className: "text-red-500", children: [
708
+ return /* @__PURE__ */ c("div", { className: `flex items-center justify-center h-full ${w}`, children: /* @__PURE__ */ c("p", { children: "Loading seat map..." }) });
709
+ if (it)
710
+ return /* @__PURE__ */ c("div", { className: `flex items-center justify-center h-full ${w}`, children: /* @__PURE__ */ k("p", { className: "text-red-500", children: [
708
711
  "Error loading seat map: ",
709
- nt.message
712
+ it.message
710
713
  ] }) });
711
714
  if (!s)
712
- return /* @__PURE__ */ a("div", { className: `flex items-center justify-center h-full ${w}`, children: /* @__PURE__ */ a("p", { children: "No configuration provided" }) });
715
+ return /* @__PURE__ */ c("div", { className: `flex items-center justify-center h-full ${w}`, children: /* @__PURE__ */ c("p", { children: "No configuration provided" }) });
713
716
  const Jt = C.width || s.canvas.width, Qt = C.height || s.canvas.height;
714
717
  return /* @__PURE__ */ k(
715
718
  "div",
716
719
  {
717
- ref: wt,
720
+ ref: Ct,
718
721
  className: `relative ${w}`,
719
- style: { width: "100%", height: "100%" },
722
+ style: { width: "100%", height: "100%", touchAction: ht && b ? "none" : "auto" },
720
723
  children: [
721
- jt && xt.length > 0 && /* @__PURE__ */ a(
722
- Yt,
724
+ jt && mt.length > 0 && /* @__PURE__ */ c(
725
+ Lt,
723
726
  {
724
- floors: xt,
727
+ floors: mt,
725
728
  currentFloorId: D,
726
729
  onFloorChange: Ot,
727
- showAllOption: P,
728
- allLabel: A,
729
- position: O,
730
- className: M
730
+ showAllOption: W,
731
+ allLabel: Q,
732
+ position: P,
733
+ className: F
731
734
  }
732
735
  ),
733
736
  /* @__PURE__ */ k(
734
737
  oe,
735
738
  {
736
- ref: pt,
739
+ ref: yt,
737
740
  width: Jt,
738
741
  height: Qt,
739
742
  scaleX: R,
740
743
  scaleY: R,
741
- x: T.x,
742
- y: T.y,
744
+ x: X.x,
745
+ y: X.y,
743
746
  draggable: !0,
744
747
  onDragEnd: qt,
745
748
  onWheel: Gt,
@@ -748,21 +751,21 @@ const pe = ({
748
751
  cursor: "grab"
749
752
  },
750
753
  children: [
751
- /* @__PURE__ */ a(vt, { listening: !1, children: ft.map((t) => /* @__PURE__ */ a(
752
- Tt,
754
+ /* @__PURE__ */ c(St, { listening: !1, children: gt.map((t) => /* @__PURE__ */ c(
755
+ Xt,
753
756
  {
754
757
  stage: t,
755
- stageColor: ut.stageColor
758
+ stageColor: ft.stageColor
756
759
  },
757
760
  t.id
758
761
  )) }),
759
- /* @__PURE__ */ a(vt, { listening: !1, children: gt.map((t) => /* @__PURE__ */ a(Xt, { text: t }, t.id)) }),
760
- /* @__PURE__ */ a(vt, { children: q.map((t) => /* @__PURE__ */ a(
762
+ /* @__PURE__ */ c(St, { listening: !1, children: pt.map((t) => /* @__PURE__ */ c(Yt, { text: t }, t.id)) }),
763
+ /* @__PURE__ */ c(St, { children: q.map((t) => /* @__PURE__ */ c(
761
764
  Wt,
762
765
  {
763
766
  seat: t,
764
- state: it(t),
765
- colors: ut,
767
+ state: ot(t),
768
+ colors: ft,
766
769
  onClick: Vt,
767
770
  onMouseEnter: Ut,
768
771
  onMouseLeave: Kt
@@ -772,40 +775,40 @@ const pe = ({
772
775
  ]
773
776
  }
774
777
  ),
775
- I && /* @__PURE__ */ a(
776
- $t,
778
+ I && /* @__PURE__ */ c(
779
+ At,
777
780
  {
778
- visible: et.visible,
779
- x: et.x,
780
- y: et.y,
781
- seat: et.seat,
782
- currency: ut.currency,
783
- state: et.state
781
+ visible: nt.visible,
782
+ x: nt.x,
783
+ y: nt.y,
784
+ seat: nt.seat,
785
+ currency: ft.currency,
786
+ state: nt.state
784
787
  }
785
788
  ),
786
- st && v && /* @__PURE__ */ a(
787
- Lt,
789
+ ct && b && /* @__PURE__ */ c(
790
+ $t,
788
791
  {
789
792
  scale: R,
790
793
  minScale: G,
791
794
  maxScale: Y,
792
- fitScale: Mt,
795
+ fitScale: It,
793
796
  onZoomIn: Zt,
794
797
  onZoomOut: _t,
795
798
  onFitToScreen: bt,
796
799
  position: at,
797
- className: ct
800
+ className: lt
798
801
  }
799
802
  ),
800
- ot.length > 0 && /* @__PURE__ */ k("div", { className: "absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg", children: [
803
+ rt.length > 0 && /* @__PURE__ */ k("div", { className: "absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg", children: [
801
804
  /* @__PURE__ */ k("h3", { className: "font-semibold mb-2", children: [
802
805
  "Selected Seats (",
803
- ot.length,
806
+ rt.length,
804
807
  ")"
805
808
  ] }),
806
- /* @__PURE__ */ a("div", { className: "max-h-48 overflow-y-auto space-y-1", children: ot.map((t) => /* @__PURE__ */ k("div", { className: "text-sm", children: [
809
+ /* @__PURE__ */ c("div", { className: "max-h-48 overflow-y-auto space-y-1", children: rt.map((t) => /* @__PURE__ */ k("div", { className: "text-sm", children: [
807
810
  t.seatNumber,
808
- t.price && ` - ${ut.currency} ${t.price.toFixed(2)}`
811
+ t.price && ` - ${ft.currency} ${t.price.toFixed(2)}`
809
812
  ] }, t.id)) })
810
813
  ] })
811
814
  ]
@@ -815,11 +818,11 @@ const pe = ({
815
818
  export {
816
819
  de as DEFAULT_COLORS,
817
820
  pe as SeatMapViewer,
818
- be as clearFirebaseInstance,
819
- me as getFirebaseDatabase,
821
+ me as clearFirebaseInstance,
822
+ be as getFirebaseDatabase,
820
823
  ve as initializeFirebaseForViewer,
821
824
  Se as isFirebaseInitialized,
822
- ce as useConfigFetcher,
825
+ ae as useConfigFetcher,
823
826
  le as useContainerSize,
824
827
  we as useFirebaseConfig,
825
828
  Ce as useFirebaseSeatStates,
@@ -26,6 +26,7 @@ export interface SerializedSeat {
26
26
  price?: number;
27
27
  floorId?: string;
28
28
  size?: number;
29
+ rotation?: number;
29
30
  }
30
31
  export interface SectionConfig {
31
32
  rows?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zonetrix/viewer",
3
- "version": "2.13.2",
3
+ "version": "2.13.3",
4
4
  "type": "module",
5
5
  "description": "Lightweight React component for rendering interactive seat maps",
6
6
  "main": "./dist/index.js",