@zonetrix/viewer 2.10.2 → 2.10.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.
@@ -31,6 +31,7 @@ export interface UseFirebaseSeatStatesResult {
31
31
  }
32
32
  /**
33
33
  * Subscribe to real-time seat state updates from Firebase
34
+ * Uses useSyncExternalStore for stable snapshot handling
34
35
  *
35
36
  * @example
36
37
  * ```tsx
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),e=require("react"),O=require("react-konva"),V=require("firebase/database"),it=require("@zonetrix/shared");function Me(n){const[s,o]=e.useState(null),[r,h]=e.useState(!1),[d,c]=e.useState(null),m=async()=>{if(n){h(!0),c(null);try{const p=await fetch(n);if(!p.ok)throw new Error(`Failed to fetch config: ${p.statusText}`);const a=await p.json();o(a)}catch(p){const a=p instanceof Error?p:new Error("Unknown error occurred");c(a),console.error("Failed to fetch seat map config:",a)}finally{h(!1)}}};return e.useEffect(()=>{m()},[n]),{config:s,loading:r,error:d,refetch:m}}function Ee(n){const[s,o]=e.useState({width:0,height:0});return e.useEffect(()=>{const r=n.current;if(!r)return;const{width:h,height:d}=r.getBoundingClientRect();h>0&&d>0&&o({width:h,height:d});const c=new ResizeObserver(m=>{const p=m[0];if(!p)return;const{width:a,height:l}=p.contentRect;a>0&&l>0&&o(f=>f.width===a&&f.height===l?f:{width:a,height:l})});return c.observe(r),()=>{c.disconnect()}},[n]),s}function we(n,s){return Math.sqrt(Math.pow(s.x-n.x,2)+Math.pow(s.y-n.y,2))}function Ce(n,s){return{x:(n.x+s.x)/2,y:(n.y+s.y)/2}}function Fe(n,s){const o=e.useRef(null),r=e.useRef(null),h=e.useRef(1);e.useEffect(()=>{const d=n.current;if(!d||!s.enabled)return;const c=d.container(),m=l=>{if(l.touches.length===2){l.preventDefault();const f={x:l.touches[0].clientX,y:l.touches[0].clientY},g={x:l.touches[1].clientX,y:l.touches[1].clientY};o.current=we(f,g),r.current=Ce(f,g),h.current=s.currentScale}},p=l=>{if(l.touches.length!==2)return;l.preventDefault();const f={x:l.touches[0].clientX,y:l.touches[0].clientY},g={x:l.touches[1].clientX,y:l.touches[1].clientY},v=we(f,g),w=Ce(f,g);if(o.current!==null&&r.current!==null){const R=v/o.current,E=Math.min(Math.max(s.currentScale*R,s.minScale),s.maxScale),F=c.getBoundingClientRect(),j=w.x-F.left,k=w.y-F.top,D=s.currentScale,T={x:(j-s.currentPosition.x)/D,y:(k-s.currentPosition.y)/D},U=w.x-r.current.x,z=w.y-r.current.y,_={x:j-T.x*E+U,y:k-T.y*E+z};s.onScaleChange(E,_),o.current=v,r.current=w}},a=l=>{l.touches.length<2&&(o.current=null,r.current=null)};return c.addEventListener("touchstart",m,{passive:!1}),c.addEventListener("touchmove",p,{passive:!1}),c.addEventListener("touchend",a),()=>{c.removeEventListener("touchstart",m),c.removeEventListener("touchmove",p),c.removeEventListener("touchend",a)}},[n,s])}const ke={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},Ie=e.memo(({seat:n,state:s,colors:o,onClick:r,onMouseEnter:h,onMouseLeave:d})=>{const p={available:o.seatAvailable,reserved:o.seatReserved,selected:o.seatSelected,unavailable:o.seatUnavailable,hidden:o.seatHidden}[s],a=s==="available"||s==="selected",l=e.useCallback(()=>{a&&r(n)},[n,r,a]),f=e.useCallback(w=>{h(n,w);const R=w.target.getStage();R&&a&&(R.container().style.cursor="pointer")},[n,h,a]),g=e.useCallback(w=>{d();const R=w.target.getStage();R&&(R.container().style.cursor="grab")},[d]),v={x:n.position.x,y:n.position.y,fill:p,stroke:"#ffffff",strokeWidth:1,onClick:l,onTap:l,onMouseEnter:f,onMouseLeave:g};return n.shape==="circle"?i.jsx(O.Circle,{...v,radius:12}):i.jsx(O.Rect,{...v,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:n.shape==="square"?0:4})});Ie.displayName="ViewerSeat";const De=e.memo(({stage:n,stageColor:s})=>{const o=d=>({stage:"🎭",table:"⬜",wall:"▬",barrier:"🛡️","dj-booth":"🎵",bar:"🍷","entry-exit":"🚪",custom:"➕"})[d||"stage"]||"🎭",r=n.config.color||s,h=o(n.config.objectType);return i.jsxs(O.Group,{x:n.position.x,y:n.position.y,rotation:n.config.rotation||0,children:[i.jsx(O.Rect,{width:n.config.width,height:n.config.height,fill:r+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),i.jsx(O.Text,{text:h,x:0,y:0,width:n.config.width,height:n.config.height*.4,fontSize:32,fill:"#ffffff",align:"center",verticalAlign:"middle"}),i.jsx(O.Text,{text:n.config.label,x:0,y:n.config.height*.4,width:n.config.width,height:n.config.height*.6,fontSize:20,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle"})]})});De.displayName="ViewerStage";const Le=e.memo(({floors:n,currentFloorId:s,onFloorChange:o,showAllOption:r,allLabel:h,position:d,className:c})=>{const m=e.useMemo(()=>[...n].sort((g,v)=>g.order-v.order),[n]),a={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}}[d]},l={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"},f={...l,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return i.jsxs("div",{className:c,style:a,children:[r&&i.jsx("button",{type:"button",onClick:()=>o(null),style:s===null?f:l,children:h}),m.map(g=>i.jsx("button",{type:"button",onClick:()=>o(g.id),style:s===g.id?f:l,children:g.name},g.id))]})});Le.displayName="FloorSelectorBar";const Te=e.memo(({scale:n,minScale:s,maxScale:o,onZoomIn:r,onZoomOut:h,position:d,className:c})=>{const p={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}}[d]},a={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"},l={...a,opacity:.4,cursor:"not-allowed"},f=n<o,g=n>s;return i.jsxs("div",{className:c,style:p,children:[i.jsx("button",{type:"button",onClick:r,disabled:!f,style:f?a:l,title:"Zoom In",children:"+"}),i.jsx("button",{type:"button",onClick:h,disabled:!g,style:g?a:l,title:"Zoom Out",children:"−"})]})});Te.displayName="ZoomControls";const ze=e.memo(({visible:n,x:s,y:o,seat:r,currency:h,state:d})=>{if(!n||!r)return null;const c=r.seatNumber||(r.rowLabel&&r.columnLabel?`${r.rowLabel}-${r.columnLabel}`:"N/A"),m={position:"fixed",left:`${s+15}px`,top:`${o+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"},a={color:"#9ca3af",marginRight:"4px"},l={fontWeight:600},f={color:"#4ade80",fontWeight:600},g={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return i.jsx("div",{style:m,children:i.jsxs("div",{style:p,children:[r.sectionName&&i.jsxs("div",{style:{marginBottom:"4px"},children:[i.jsx("span",{style:a,children:"Section:"}),i.jsx("span",{style:{...l,color:"#3b82f6"},children:r.sectionName})]}),i.jsxs("div",{style:{marginBottom:"4px"},children:[i.jsx("span",{style:a,children:"Seat:"}),i.jsx("span",{style:l,children:c})]}),r.price!==void 0&&r.price>0&&d==="available"&&i.jsxs("div",{style:{marginBottom:"4px"},children:[i.jsx("span",{style:a,children:"Price:"}),i.jsxs("span",{style:f,children:[h," ",r.price.toFixed(2)]})]}),i.jsxs("div",{style:g,children:["Status: ",d]})]})})});ze.displayName="SeatTooltip";const at=({config:n,configUrl:s,floorId:o,onFloorChange:r,reservedSeats:h=[],unavailableSeats:d=[],selectedSeats:c,myReservedSeats:m=[],onSeatSelect:p,onSeatDeselect:a,onSelectionChange:l,colorOverrides:f,showTooltip:g=!0,zoomEnabled:v=!0,className:w="",onConfigLoad:R,onError:E,showFloorSelector:F,floorSelectorPosition:j="top-left",floorSelectorClassName:k,showAllFloorsOption:D=!0,allFloorsLabel:T="All",fitToView:U=!0,fitPadding:z=40,showZoomControls:_=!0,zoomControlsPosition:X="bottom-right",zoomControlsClassName:G,minZoom:Z,maxZoom:N=3,zoomStep:Y=.25,touchEnabled:ve=!0})=>{const P=e.useRef(null),$=e.useRef(null),M=Ee($),[W,he]=e.useState(new Set),[I,Q]=e.useState(1),[L,H]=e.useState({x:0,y:0}),[Xe,Ye]=e.useState(null),[Pe,We]=e.useState(1),ie=e.useRef({width:0,height:0}),[ee,me]=e.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Oe,loading:$e,error:te}=Me(s),b=n||Oe,ge=o!==void 0,A=ge?o||null:Xe,ae=c!==void 0,Be=e.useCallback(t=>{ge||Ye(t),r?.(t)},[ge,r]),pe=b?.floors||[],Ve=F!==void 0?F:pe.length>1,ce=e.useMemo(()=>b?{...b.colors,...f}:{...ke,...f},[b,f]),J=e.useMemo(()=>{if(!b)return[];let t=b.seats.filter(u=>u.state!=="hidden");return A&&(t=t.filter(u=>u.floorId===A||!u.floorId&&A==="floor_default")),t},[b,A]),le=e.useMemo(()=>b?.stages?A?b.stages.filter(t=>t.floorId===A||!t.floorId&&A==="floor_default"):b.stages:[],[b,A]),B=e.useMemo(()=>{if(!b||J.length===0&&le.length===0)return null;const t=12;let u=1/0,x=1/0,y=-1/0,S=-1/0;return J.forEach(C=>{u=Math.min(u,C.position.x-t),x=Math.min(x,C.position.y-t),y=Math.max(y,C.position.x+t),S=Math.max(S,C.position.y+t)}),le.forEach(C=>{u=Math.min(u,C.position.x),x=Math.min(x,C.position.y),y=Math.max(y,C.position.x+(C.config?.width||200)),S=Math.max(S,C.position.y+(C.config?.height||100))}),{minX:u,minY:x,maxX:y,maxY:S,width:y-u,height:S-x}},[b,J,le]);e.useEffect(()=>{if(!U||!b||!B||M.width===0||M.height===0)return;const t=Math.abs(M.width-ie.current.width),u=Math.abs(M.height-ie.current.height);if(!(ie.current.width===0)&&t<10&&u<10)return;ie.current=M;const y=M.width,S=M.height,C=y-z*2,re=S-z*2,ue=C/B.width,xe=re/B.height,de=Math.min(ue,xe,N),et=B.minX+B.width/2,tt=B.minY+B.height/2,nt=y/2,st=S/2,rt=nt-et*de,ot=st-tt*de;Q(de),H({x:rt,y:ot}),We(de)},[U,b,B,z,N,M,A]);const q=e.useMemo(()=>{const t=new Set(h),u=new Set(d),x=new Set(m);return{reserved:t,unavailable:u,myReserved:x}},[h,d,m]),be=e.useMemo(()=>c?new Set(c):null,[c]),ne=e.useCallback(t=>{const u=t.id,x=t.seatNumber||"";return q.unavailable.has(u)||q.unavailable.has(x)?"unavailable":q.reserved.has(u)||q.reserved.has(x)?"reserved":q.myReserved.has(u)||q.myReserved.has(x)||W.has(u)?"selected":t.state},[q,W]);e.useEffect(()=>{b&&R&&R(b)},[b,R]),e.useEffect(()=>{te&&E&&E(te)},[te,E]),e.useEffect(()=>{ae&&be&&he(be)},[ae,be]);const Ue=e.useCallback(t=>{const u=ne(t);if(u!=="available"&&u!=="selected")return;const x=W.has(t.id);ae||he(y=>{const S=new Set(y);return x?S.delete(t.id):S.add(t.id),S}),x?a?.(t):(p?.(t),p||console.log("Seat selected:",t))},[ne,W,ae,p,a]),se=e.useMemo(()=>b?J.filter(t=>W.has(t.id)):[],[J,W]);e.useEffect(()=>{l?.(se)},[se,l]);const K=Z!==void 0?Z:Pe,He=e.useCallback(()=>{if(!v)return;const t=Math.min(I+Y,N);if(t!==I){const u=M.width||b?.canvas.width||800,x=M.height||b?.canvas.height||600,y=u/2,S=x/2,C={x:(y-L.x)/I,y:(S-L.y)/I};Q(t),H({x:y-C.x*t,y:S-C.y*t})}},[v,I,Y,N,M,b,L]),qe=e.useCallback(()=>{if(!v)return;const t=Math.max(I-Y,K);if(t!==I){const u=M.width||b?.canvas.width||800,x=M.height||b?.canvas.height||600,y=u/2,S=x/2,C={x:(y-L.x)/I,y:(S-L.y)/I};Q(t),H({x:y-C.x*t,y:S-C.y*t})}},[v,I,Y,K,M,b,L]),_e=e.useCallback(t=>{H({x:t.target.x(),y:t.target.y()})},[]),Ge=e.useCallback(t=>{if(!v)return;t.evt.preventDefault();const u=P.current;if(!u)return;const x=u.scaleX(),y=u.getPointerPosition();if(!y)return;const S=1.1,C=t.evt.deltaY>0?x/S:x*S,re=Math.min(Math.max(C,K),N),ue={x:(y.x-L.x)/x,y:(y.y-L.y)/x},xe={x:y.x-ue.x*re,y:y.y-ue.y*re};Q(re),H(xe)},[v,L,K,N]);Fe(P,{enabled:ve&&v,minScale:K,maxScale:N,currentScale:I,currentPosition:L,onScaleChange:(t,u)=>{Q(t),H(u)},onPositionChange:t=>{H(t)}});const Je=e.useCallback((t,u)=>{if(!g)return;const x=u.target.getStage();if(!x)return;const y=x.getPointerPosition();if(!y)return;const S=x.container().getBoundingClientRect();me({visible:!0,x:S.left+y.x,y:S.top+y.y,seat:t,state:ne(t)})},[g,ne]),Ke=e.useCallback(()=>{me(t=>({...t,visible:!1}))},[]);if($e)return i.jsx("div",{className:`flex items-center justify-center h-full ${w}`,children:i.jsx("p",{children:"Loading seat map..."})});if(te)return i.jsx("div",{className:`flex items-center justify-center h-full ${w}`,children:i.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",te.message]})});if(!b)return i.jsx("div",{className:`flex items-center justify-center h-full ${w}`,children:i.jsx("p",{children:"No configuration provided"})});const Ze=M.width||b.canvas.width,Qe=M.height||b.canvas.height;return i.jsxs("div",{ref:$,className:`relative ${w}`,style:{width:"100%",height:"100%"},children:[Ve&&pe.length>0&&i.jsx(Le,{floors:pe,currentFloorId:A,onFloorChange:Be,showAllOption:D,allLabel:T,position:j,className:k}),i.jsxs(O.Stage,{ref:P,width:Ze,height:Qe,scaleX:I,scaleY:I,x:L.x,y:L.y,draggable:!0,onDragEnd:_e,onWheel:Ge,style:{backgroundColor:b.canvas.backgroundColor,cursor:"grab"},children:[i.jsx(O.Layer,{listening:!1,children:le.map(t=>i.jsx(De,{stage:t,stageColor:ce.stageColor},t.id))}),i.jsx(O.Layer,{children:J.map(t=>i.jsx(Ie,{seat:t,state:ne(t),colors:ce,onClick:Ue,onMouseEnter:Je,onMouseLeave:Ke},t.id))})]}),g&&i.jsx(ze,{visible:ee.visible,x:ee.x,y:ee.y,seat:ee.seat,currency:ce.currency,state:ee.state}),_&&v&&i.jsx(Te,{scale:I,minScale:K,maxScale:N,onZoomIn:He,onZoomOut:qe,position:X,className:G}),se.length>0&&i.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[i.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",se.length,")"]}),i.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:se.map(t=>i.jsxs("div",{className:"text-sm",children:[t.seatNumber,t.price&&` - ${ce.currency} ${t.price.toFixed(2)}`]},t.id))})]})]})};let oe=null;function ct(n){oe=n}function Se(){if(!oe)throw new Error("Firebase database not initialized. Call initializeFirebaseForViewer(db) first.");return oe}function fe(){return oe!==null}function lt(){oe=null}function ye(n,s){if(n.length!==s.length)return!1;for(let o=0;o<n.length;o++)if(n[o]!==s[o])return!1;return!0}function Re(n,s){return ye(n.myReserved,s.myReserved)&&ye(n.otherReserved,s.otherReserved)&&ye(n.unavailable,s.unavailable)}function je(n,s){const o=[],r=[],h=[];return Object.entries(n).forEach(([d,c])=>{c&&typeof c=="object"&&c.state&&(c.state==="unavailable"?h.push(d):c.state==="reserved"&&(s&&c.userId===s?o.push(d):r.push(d)))}),{myReserved:o,otherReserved:r,unavailable:h}}function Ne(n){const{seatMapId:s,currentUserId:o,enabled:r=!0,onStateChange:h,onError:d}=n,[c,m]=e.useState(null),[p,a]=e.useState(!0),[l,f]=e.useState(null),[g,v]=e.useState(null),[w,R]=e.useState([]),[E,F]=e.useState([]),[j,k]=e.useState([]),D=e.useRef(h),T=e.useRef(d),U=e.useRef(o);D.current=h,T.current=d,U.current=o;const z=e.useRef({myReserved:[],otherReserved:[],unavailable:[]}),_=e.useRef(null);return e.useEffect(()=>{if(!r||!s){a(!1);return}if(!fe()){a(!1),f(new Error("Firebase not initialized. Call initializeFirebaseForViewer first."));return}const X=Se(),G=V.ref(X,`seat_states/${s}`);a(!0),f(null);const Z=Y=>{const P=Y.val()||{},$=je(P,U.current),M=z.current,W=JSON.stringify(_.current)!==JSON.stringify(P);W&&(m(P),_.current=P),a(!1),!Re(M,$)&&(v(Date.now()),R($.myReserved),F($.otherReserved),k($.unavailable),z.current=$),W&&D.current?.(P)},N=Y=>{f(Y),a(!1),T.current?.(Y)};return V.onValue(G,Z,N),()=>{V.off(G)}},[s,r]),e.useEffect(()=>{if(c){const X=je(c,o),G=z.current;!Re(G,X)&&(R(X.myReserved),F(X.otherReserved),k(X.unavailable),z.current=X,v(Date.now()))}},[o]),{states:c,loading:p,error:l,lastUpdated:g,myReservedSeats:w,otherReservedSeats:E,unavailableSeats:j,reservedSeats:E}}function Ae(n){const{seatMapId:s,enabled:o=!0,subscribeToChanges:r=!1,onConfigLoad:h,onError:d}=n,[c,m]=e.useState(null),[p,a]=e.useState(!0),[l,f]=e.useState(null),g=e.useRef(h),v=e.useRef(d);g.current=h,v.current=d;const w=e.useCallback(async()=>{if(!s)return;if(!fe()){f(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")),a(!1);return}const R=Se(),E=V.ref(R,`seatmaps/${s}`);try{a(!0),f(null);const j=(await V.get(E)).val();if(j){const k=it.fromFirebaseSeatMap(j);m(k),g.current?.(k)}else f(new Error(`Seat map ${s} not found in Firebase`))}catch(F){const j=F instanceof Error?F:new Error("Unknown error");f(j),v.current?.(j)}finally{a(!1)}},[s]);return e.useEffect(()=>{if(!o||!s){a(!1);return}if(w(),r&&fe()){const R=Se(),E=V.ref(R,`seatmaps/${s}/meta/updated_at`);let F=!0,j=null;const k=D=>{if(F){F=!1,j=D.val();return}const T=D.val();D.exists()&&T!==j&&(j=T,w())};return V.onValue(E,k),()=>{V.off(E)}}},[s,o,r]),{config:c,loading:p,error:l,refetch:w}}function ut(n){const{seatMapId:s,userId:o,enabled:r=!0,subscribeToDesignChanges:h=!1,onConfigLoad:d,onStateChange:c,onError:m}=n,{config:p,loading:a,error:l,refetch:f}=Ae({seatMapId:s,enabled:r,subscribeToChanges:h,onConfigLoad:d,onError:m}),{states:g,loading:v,error:w,lastUpdated:R,myReservedSeats:E,otherReservedSeats:F,unavailableSeats:j,reservedSeats:k}=Ne({seatMapId:s,currentUserId:o,enabled:r,onStateChange:c,onError:m});return{config:p,loading:a||v,error:l||w,myReservedSeats:E,otherReservedSeats:F,unavailableSeats:j,reservedSeats:k,seatStates:g,lastUpdated:R,refetch:f}}exports.DEFAULT_COLORS=ke;exports.SeatMapViewer=at;exports.clearFirebaseInstance=lt;exports.initializeFirebaseForViewer=ct;exports.isFirebaseInitialized=fe;exports.useConfigFetcher=Me;exports.useContainerSize=Ee;exports.useFirebaseConfig=Ae;exports.useFirebaseSeatStates=Ne;exports.useRealtimeSeatMap=ut;exports.useTouchGestures=Fe;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),t=require("react"),X=require("react-konva"),W=require("firebase/database"),it=require("@zonetrix/shared");function Ce(n){const[s,i]=t.useState(null),[r,h]=t.useState(!1),[u,o]=t.useState(null),w=async()=>{if(n){h(!0),o(null);try{const p=await fetch(n);if(!p.ok)throw new Error(`Failed to fetch config: ${p.statusText}`);const l=await p.json();i(l)}catch(p){const l=p instanceof Error?p:new Error("Unknown error occurred");o(l),console.error("Failed to fetch seat map config:",l)}finally{h(!1)}}};return t.useEffect(()=>{w()},[n]),{config:s,loading:r,error:u,refetch:w}}function Re(n){const[s,i]=t.useState({width:0,height:0});return t.useEffect(()=>{const r=n.current;if(!r)return;const{width:h,height:u}=r.getBoundingClientRect();h>0&&u>0&&i({width:h,height:u});const o=new ResizeObserver(w=>{const p=w[0];if(!p)return;const{width:l,height:c}=p.contentRect;l>0&&c>0&&i(f=>f.width===l&&f.height===c?f:{width:l,height:c})});return o.observe(r),()=>{o.disconnect()}},[n]),s}function ye(n,s){return Math.sqrt(Math.pow(s.x-n.x,2)+Math.pow(s.y-n.y,2))}function me(n,s){return{x:(n.x+s.x)/2,y:(n.y+s.y)/2}}function je(n,s){const i=t.useRef(null),r=t.useRef(null),h=t.useRef(1);t.useEffect(()=>{const u=n.current;if(!u||!s.enabled)return;const o=u.container(),w=c=>{if(c.touches.length===2){c.preventDefault();const f={x:c.touches[0].clientX,y:c.touches[0].clientY},b={x:c.touches[1].clientX,y:c.touches[1].clientY};i.current=ye(f,b),r.current=me(f,b),h.current=s.currentScale}},p=c=>{if(c.touches.length!==2)return;c.preventDefault();const f={x:c.touches[0].clientX,y:c.touches[0].clientY},b={x:c.touches[1].clientX,y:c.touches[1].clientY},g=ye(f,b),x=me(f,b);if(i.current!==null&&r.current!==null){const C=g/i.current,j=Math.min(Math.max(s.currentScale*C,s.minScale),s.maxScale),E=o.getBoundingClientRect(),M=x.x-E.left,F=x.y-E.top,z=s.currentScale,L={x:(M-s.currentPosition.x)/z,y:(F-s.currentPosition.y)/z},D=x.x-r.current.x,N=x.y-r.current.y,ee={x:M-L.x*j+D,y:F-L.y*j+N};s.onScaleChange(j,ee),i.current=g,r.current=x}},l=c=>{c.touches.length<2&&(i.current=null,r.current=null)};return o.addEventListener("touchstart",w,{passive:!1}),o.addEventListener("touchmove",p,{passive:!1}),o.addEventListener("touchend",l),()=>{o.removeEventListener("touchstart",w),o.removeEventListener("touchmove",p),o.removeEventListener("touchend",l)}},[n,s])}const Me={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},Ee=t.memo(({seat:n,state:s,colors:i,onClick:r,onMouseEnter:h,onMouseLeave:u})=>{const p={available:i.seatAvailable,reserved:i.seatReserved,selected:i.seatSelected,unavailable:i.seatUnavailable,hidden:i.seatHidden}[s],l=s==="available"||s==="selected",c=t.useCallback(()=>{l&&r(n)},[n,r,l]),f=t.useCallback(x=>{h(n,x);const C=x.target.getStage();C&&l&&(C.container().style.cursor="pointer")},[n,h,l]),b=t.useCallback(x=>{u();const C=x.target.getStage();C&&(C.container().style.cursor="grab")},[u]),g={x:n.position.x,y:n.position.y,fill:p,stroke:"#ffffff",strokeWidth:1,onClick:c,onTap:c,onMouseEnter:f,onMouseLeave:b};return n.shape==="circle"?a.jsx(X.Circle,{...g,radius:12}):a.jsx(X.Rect,{...g,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:n.shape==="square"?0:4})});Ee.displayName="ViewerSeat";const Fe=t.memo(({stage:n,stageColor:s})=>{const i=u=>({stage:"🎭",table:"⬜",wall:"▬",barrier:"🛡️","dj-booth":"🎵",bar:"🍷","entry-exit":"🚪",custom:"➕"})[u||"stage"]||"🎭",r=n.config.color||s,h=i(n.config.objectType);return a.jsxs(X.Group,{x:n.position.x,y:n.position.y,rotation:n.config.rotation||0,children:[a.jsx(X.Rect,{width:n.config.width,height:n.config.height,fill:r+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),a.jsx(X.Text,{text:h,x:0,y:0,width:n.config.width,height:n.config.height*.4,fontSize:32,fill:"#ffffff",align:"center",verticalAlign:"middle"}),a.jsx(X.Text,{text:n.config.label,x:0,y:n.config.height*.4,width:n.config.width,height:n.config.height*.6,fontSize:20,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle"})]})});Fe.displayName="ViewerStage";const ke=t.memo(({floors:n,currentFloorId:s,onFloorChange:i,showAllOption:r,allLabel:h,position:u,className:o})=>{const w=t.useMemo(()=>[...n].sort((b,g)=>b.order-g.order),[n]),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}}[u]},c={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"},f={...c,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return a.jsxs("div",{className:o,style:l,children:[r&&a.jsx("button",{type:"button",onClick:()=>i(null),style:s===null?f:c,children:h}),w.map(b=>a.jsx("button",{type:"button",onClick:()=>i(b.id),style:s===b.id?f:c,children:b.name},b.id))]})});ke.displayName="FloorSelectorBar";const Ie=t.memo(({scale:n,minScale:s,maxScale:i,onZoomIn:r,onZoomOut:h,position:u,className:o})=>{const p={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}}[u]},l={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"},c={...l,opacity:.4,cursor:"not-allowed"},f=n<i,b=n>s;return a.jsxs("div",{className:o,style:p,children:[a.jsx("button",{type:"button",onClick:r,disabled:!f,style:f?l:c,title:"Zoom In",children:"+"}),a.jsx("button",{type:"button",onClick:h,disabled:!b,style:b?l:c,title:"Zoom Out",children:"−"})]})});Ie.displayName="ZoomControls";const Le=t.memo(({visible:n,x:s,y:i,seat:r,currency:h,state:u})=>{if(!n||!r)return null;const o=r.seatNumber||(r.rowLabel&&r.columnLabel?`${r.rowLabel}-${r.columnLabel}`:"N/A"),w={position:"fixed",left:`${s+15}px`,top:`${i+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"},c={fontWeight:600},f={color:"#4ade80",fontWeight:600},b={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return a.jsx("div",{style:w,children:a.jsxs("div",{style:p,children:[r.sectionName&&a.jsxs("div",{style:{marginBottom:"4px"},children:[a.jsx("span",{style:l,children:"Section:"}),a.jsx("span",{style:{...c,color:"#3b82f6"},children:r.sectionName})]}),a.jsxs("div",{style:{marginBottom:"4px"},children:[a.jsx("span",{style:l,children:"Seat:"}),a.jsx("span",{style:c,children:o})]}),r.price!==void 0&&r.price>0&&u==="available"&&a.jsxs("div",{style:{marginBottom:"4px"},children:[a.jsx("span",{style:l,children:"Price:"}),a.jsxs("span",{style:f,children:[h," ",r.price.toFixed(2)]})]}),a.jsxs("div",{style:b,children:["Status: ",u]})]})})});Le.displayName="SeatTooltip";const at=({config:n,configUrl:s,floorId:i,onFloorChange:r,reservedSeats:h=[],unavailableSeats:u=[],selectedSeats:o,myReservedSeats:w=[],onSeatSelect:p,onSeatDeselect:l,onSelectionChange:c,colorOverrides:f,showTooltip:b=!0,zoomEnabled:g=!0,className:x="",onConfigLoad:C,onError:j,showFloorSelector:E,floorSelectorPosition:M="top-left",floorSelectorClassName:F,showAllFloorsOption:z=!0,allFloorsLabel:L="All",fitToView:D=!0,fitPadding:N=40,showZoomControls:ee=!0,zoomControlsPosition:ze="bottom-right",zoomControlsClassName:Ne,minZoom:be,maxZoom:Y=3,zoomStep:te=.25,touchEnabled:Ae=!0})=>{const ue=t.useRef(null),xe=t.useRef(null),k=Re(xe),[$,Se]=t.useState(new Set),[I,H]=t.useState(1),[T,B]=t.useState({x:0,y:0}),[Xe,Ye]=t.useState(null),[Pe,We]=t.useState(1),ne=t.useRef({width:0,height:0}),[q,ve]=t.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Be,loading:Ue,error:_}=Ce(s),S=n||Be,de=i!==void 0,A=de?i||null:Xe,se=o!==void 0,$e=t.useCallback(e=>{de||Ye(e),r?.(e)},[de,r]),he=S?.floors||[],Oe=E!==void 0?E:he.length>1,re=t.useMemo(()=>S?{...S.colors,...f}:{...Me,...f},[S,f]),O=t.useMemo(()=>{if(!S)return[];let e=S.seats.filter(d=>d.state!=="hidden");return A&&(e=e.filter(d=>d.floorId===A||!d.floorId&&A==="floor_default")),e},[S,A]),oe=t.useMemo(()=>S?.stages?A?S.stages.filter(e=>e.floorId===A||!e.floorId&&A==="floor_default"):S.stages:[],[S,A]),P=t.useMemo(()=>{if(!S||O.length===0&&oe.length===0)return null;const e=12;let d=1/0,v=1/0,y=-1/0,m=-1/0;return O.forEach(R=>{d=Math.min(d,R.position.x-e),v=Math.min(v,R.position.y-e),y=Math.max(y,R.position.x+e),m=Math.max(m,R.position.y+e)}),oe.forEach(R=>{d=Math.min(d,R.position.x),v=Math.min(v,R.position.y),y=Math.max(y,R.position.x+(R.config?.width||200)),m=Math.max(m,R.position.y+(R.config?.height||100))}),{minX:d,minY:v,maxX:y,maxY:m,width:y-d,height:m-v}},[S,O,oe]);t.useEffect(()=>{if(!D||!S||!P||k.width===0||k.height===0)return;const e=Math.abs(k.width-ne.current.width),d=Math.abs(k.height-ne.current.height);if(!(ne.current.width===0)&&e<10&&d<10)return;ne.current=k;const y=k.width,m=k.height,R=y-N*2,Z=m-N*2,ie=R/P.width,ge=Z/P.height,ae=Math.min(ie,ge,Y),et=P.minX+P.width/2,tt=P.minY+P.height/2,nt=y/2,st=m/2,rt=nt-et*ae,ot=st-tt*ae;H(ae),B({x:rt,y:ot}),We(ae)},[D,S,P,N,Y,k,A]);const U=t.useMemo(()=>{const e=new Set(h),d=new Set(u),v=new Set(w);return{reserved:e,unavailable:d,myReserved:v}},[h,u,w]),fe=t.useMemo(()=>o?new Set(o):null,[o]),G=t.useCallback(e=>{const d=e.id,v=e.seatNumber||"";return U.unavailable.has(d)||U.unavailable.has(v)?"unavailable":U.reserved.has(d)||U.reserved.has(v)?"reserved":U.myReserved.has(d)||U.myReserved.has(v)||$.has(d)?"selected":e.state},[U,$]);t.useEffect(()=>{S&&C&&C(S)},[S,C]),t.useEffect(()=>{_&&j&&j(_)},[_,j]),t.useEffect(()=>{se&&fe&&Se(fe)},[se,fe]);const Ve=t.useCallback(e=>{const d=G(e);if(d!=="available"&&d!=="selected")return;const v=$.has(e.id);se||Se(y=>{const m=new Set(y);return v?m.delete(e.id):m.add(e.id),m}),v?l?.(e):(p?.(e),p||console.log("Seat selected:",e))},[G,$,se,p,l]),K=t.useMemo(()=>S?O.filter(e=>$.has(e.id)):[],[O,$]);t.useEffect(()=>{c?.(K)},[K,c]);const V=be!==void 0?be:Pe,He=t.useCallback(()=>{if(!g)return;const e=Math.min(I+te,Y);if(e!==I){const d=k.width||S?.canvas.width||800,v=k.height||S?.canvas.height||600,y=d/2,m=v/2,R={x:(y-T.x)/I,y:(m-T.y)/I};H(e),B({x:y-R.x*e,y:m-R.y*e})}},[g,I,te,Y,k,S,T]),qe=t.useCallback(()=>{if(!g)return;const e=Math.max(I-te,V);if(e!==I){const d=k.width||S?.canvas.width||800,v=k.height||S?.canvas.height||600,y=d/2,m=v/2,R={x:(y-T.x)/I,y:(m-T.y)/I};H(e),B({x:y-R.x*e,y:m-R.y*e})}},[g,I,te,V,k,S,T]),_e=t.useCallback(e=>{B({x:e.target.x(),y:e.target.y()})},[]),Ge=t.useCallback(e=>{if(!g)return;e.evt.preventDefault();const d=ue.current;if(!d)return;const v=d.scaleX(),y=d.getPointerPosition();if(!y)return;const m=1.1,R=e.evt.deltaY>0?v/m:v*m,Z=Math.min(Math.max(R,V),Y),ie={x:(y.x-T.x)/v,y:(y.y-T.y)/v},ge={x:y.x-ie.x*Z,y:y.y-ie.y*Z};H(Z),B(ge)},[g,T,V,Y]);je(ue,{enabled:Ae&&g,minScale:V,maxScale:Y,currentScale:I,currentPosition:T,onScaleChange:(e,d)=>{H(e),B(d)},onPositionChange:e=>{B(e)}});const Ke=t.useCallback((e,d)=>{if(!b)return;const v=d.target.getStage();if(!v)return;const y=v.getPointerPosition();if(!y)return;const m=v.container().getBoundingClientRect();ve({visible:!0,x:m.left+y.x,y:m.top+y.y,seat:e,state:G(e)})},[b,G]),Ze=t.useCallback(()=>{ve(e=>({...e,visible:!1}))},[]);if(Ue)return a.jsx("div",{className:`flex items-center justify-center h-full ${x}`,children:a.jsx("p",{children:"Loading seat map..."})});if(_)return a.jsx("div",{className:`flex items-center justify-center h-full ${x}`,children:a.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",_.message]})});if(!S)return a.jsx("div",{className:`flex items-center justify-center h-full ${x}`,children:a.jsx("p",{children:"No configuration provided"})});const Je=k.width||S.canvas.width,Qe=k.height||S.canvas.height;return a.jsxs("div",{ref:xe,className:`relative ${x}`,style:{width:"100%",height:"100%"},children:[Oe&&he.length>0&&a.jsx(ke,{floors:he,currentFloorId:A,onFloorChange:$e,showAllOption:z,allLabel:L,position:M,className:F}),a.jsxs(X.Stage,{ref:ue,width:Je,height:Qe,scaleX:I,scaleY:I,x:T.x,y:T.y,draggable:!0,onDragEnd:_e,onWheel:Ge,style:{backgroundColor:S.canvas.backgroundColor,cursor:"grab"},children:[a.jsx(X.Layer,{listening:!1,children:oe.map(e=>a.jsx(Fe,{stage:e,stageColor:re.stageColor},e.id))}),a.jsx(X.Layer,{children:O.map(e=>a.jsx(Ee,{seat:e,state:G(e),colors:re,onClick:Ve,onMouseEnter:Ke,onMouseLeave:Ze},e.id))})]}),b&&a.jsx(Le,{visible:q.visible,x:q.x,y:q.y,seat:q.seat,currency:re.currency,state:q.state}),ee&&g&&a.jsx(Ie,{scale:I,minScale:V,maxScale:Y,onZoomIn:He,onZoomOut:qe,position:ze,className:Ne}),K.length>0&&a.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[a.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",K.length,")"]}),a.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:K.map(e=>a.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${re.currency} ${e.price.toFixed(2)}`]},e.id))})]})]})};let Q=null;function ct(n){Q=n}function pe(){if(!Q)throw new Error("Firebase database not initialized. Call initializeFirebaseForViewer(db) first.");return Q}function le(){return Q!==null}function lt(){Q=null}function J(n,s){if(n.length!==s.length)return!1;const i=[...n].sort(),r=[...s].sort();return i.every((h,u)=>h===r[u])}function we(n,s){const i=[],r=[],h=[];return Object.entries(n).forEach(([u,o])=>{o&&typeof o=="object"&&o.state&&(o.state==="unavailable"?h.push(u):o.state==="reserved"&&(s&&o.userId===s?i.push(u):r.push(u)))}),{myReserved:i.sort(),otherReserved:r.sort(),unavailable:h.sort()}}const ce={states:null,loading:!0,error:null,lastUpdated:null,myReservedSeats:[],otherReservedSeats:[],unavailableSeats:[]};function Te(n){const{seatMapId:s,currentUserId:i,enabled:r=!0,onStateChange:h,onError:u}=n,o=t.useRef({...ce}),w=t.useRef(h),p=t.useRef(u),l=t.useRef(i);w.current=h,p.current=u,l.current=i;const c=t.useCallback(x=>{if(!r||!s)return o.current={...ce,loading:!1},()=>{};if(!le())return o.current={...ce,loading:!1,error:new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")},()=>{};const C=pe(),j=W.ref(C,`seat_states/${s}`),E=F=>{const L=F.val()||{},D=we(L,l.current),N=o.current;(N.loading||!J(N.myReservedSeats,D.myReserved)||!J(N.otherReservedSeats,D.otherReserved)||!J(N.unavailableSeats,D.unavailable))&&(o.current={states:L,loading:!1,error:null,lastUpdated:Date.now(),myReservedSeats:D.myReserved,otherReservedSeats:D.otherReserved,unavailableSeats:D.unavailable},w.current?.(L),x())},M=F=>{o.current={...o.current,loading:!1,error:F},p.current?.(F),x()};return W.onValue(j,E,M),()=>{W.off(j)}},[s,r]),f=t.useCallback(()=>o.current,[]),b=t.useCallback(()=>ce,[]),g=t.useSyncExternalStore(c,f,b);return t.useEffect(()=>{if(g.states&&i!==void 0){const x=we(g.states,i),C=o.current;(!J(C.myReservedSeats,x.myReserved)||!J(C.otherReservedSeats,x.otherReserved))&&(o.current={...C,myReservedSeats:x.myReserved,otherReservedSeats:x.otherReserved,unavailableSeats:x.unavailable,lastUpdated:Date.now()})}},[i]),{states:g.states,loading:g.loading,error:g.error,lastUpdated:g.lastUpdated,myReservedSeats:g.myReservedSeats,otherReservedSeats:g.otherReservedSeats,unavailableSeats:g.unavailableSeats,reservedSeats:g.otherReservedSeats}}function De(n){const{seatMapId:s,enabled:i=!0,subscribeToChanges:r=!1,onConfigLoad:h,onError:u}=n,[o,w]=t.useState(null),[p,l]=t.useState(!0),[c,f]=t.useState(null),b=t.useRef(h),g=t.useRef(u);b.current=h,g.current=u;const x=t.useCallback(async()=>{if(!s)return;if(!le()){f(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")),l(!1);return}const C=pe(),j=W.ref(C,`seatmaps/${s}`);try{l(!0),f(null);const M=(await W.get(j)).val();if(M){const F=it.fromFirebaseSeatMap(M);w(F),b.current?.(F)}else f(new Error(`Seat map ${s} not found in Firebase`))}catch(E){const M=E instanceof Error?E:new Error("Unknown error");f(M),g.current?.(M)}finally{l(!1)}},[s]);return t.useEffect(()=>{if(!i||!s){l(!1);return}if(x(),r&&le()){const C=pe(),j=W.ref(C,`seatmaps/${s}/meta/updated_at`);let E=!0,M=null;const F=z=>{if(E){E=!1,M=z.val();return}const L=z.val();z.exists()&&L!==M&&(M=L,x())};return W.onValue(j,F),()=>{W.off(j)}}},[s,i,r]),{config:o,loading:p,error:c,refetch:x}}function ut(n){const{seatMapId:s,userId:i,enabled:r=!0,subscribeToDesignChanges:h=!1,onConfigLoad:u,onStateChange:o,onError:w}=n,{config:p,loading:l,error:c,refetch:f}=De({seatMapId:s,enabled:r,subscribeToChanges:h,onConfigLoad:u,onError:w}),{states:b,loading:g,error:x,lastUpdated:C,myReservedSeats:j,otherReservedSeats:E,unavailableSeats:M,reservedSeats:F}=Te({seatMapId:s,currentUserId:i,enabled:r,onStateChange:o,onError:w});return{config:p,loading:l||g,error:c||x,myReservedSeats:j,otherReservedSeats:E,unavailableSeats:M,reservedSeats:F,seatStates:b,lastUpdated:C,refetch:f}}exports.DEFAULT_COLORS=Me;exports.SeatMapViewer=at;exports.clearFirebaseInstance=lt;exports.initializeFirebaseForViewer=ct;exports.isFirebaseInitialized=le;exports.useConfigFetcher=Ce;exports.useContainerSize=Re;exports.useFirebaseConfig=De;exports.useFirebaseSeatStates=Te;exports.useRealtimeSeatMap=ut;exports.useTouchGestures=je;