@zonetrix/viewer 2.10.4 → 2.10.5

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 i=require("react/jsx-runtime"),t=require("react"),X=require("react-konva"),W=require("firebase/database"),ot=require("@zonetrix/shared");function we(n){const[s,a]=t.useState(null),[r,h]=t.useState(!1),[u,o]=t.useState(null),m=async()=>{if(n){h(!0),o(null);try{const g=await fetch(n);if(!g.ok)throw new Error(`Failed to fetch config: ${g.statusText}`);const l=await g.json();a(l)}catch(g){const l=g instanceof Error?g:new Error("Unknown error occurred");o(l),console.error("Failed to fetch seat map config:",l)}finally{h(!1)}}};return t.useEffect(()=>{m()},[n]),{config:s,loading:r,error:u,refetch:m}}function Ce(n){const[s,a]=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&&a({width:h,height:u});const o=new ResizeObserver(m=>{const g=m[0];if(!g)return;const{width:l,height:c}=g.contentRect;l>0&&c>0&&a(f=>f.width===l&&f.height===c?f:{width:l,height:c})});return o.observe(r),()=>{o.disconnect()}},[n]),s}function ve(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 Re(n,s){const a=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(),m=c=>{if(c.touches.length===2){c.preventDefault();const f={x:c.touches[0].clientX,y:c.touches[0].clientY},p={x:c.touches[1].clientX,y:c.touches[1].clientY};a.current=ve(f,p),r.current=me(f,p),h.current=s.currentScale}},g=c=>{if(c.touches.length!==2)return;c.preventDefault();const f={x:c.touches[0].clientX,y:c.touches[0].clientY},p={x:c.touches[1].clientX,y:c.touches[1].clientY},b=ve(f,p),w=me(f,p);if(a.current!==null&&r.current!==null){const R=b/a.current,M=Math.min(Math.max(s.currentScale*R,s.minScale),s.maxScale),E=o.getBoundingClientRect(),j=w.x-E.left,F=w.y-E.top,z=s.currentScale,L={x:(j-s.currentPosition.x)/z,y:(F-s.currentPosition.y)/z},D=w.x-r.current.x,N=w.y-r.current.y,Q={x:j-L.x*M+D,y:F-L.y*M+N};s.onScaleChange(M,Q),a.current=b,r.current=w}},l=c=>{c.touches.length<2&&(a.current=null,r.current=null)};return o.addEventListener("touchstart",m,{passive:!1}),o.addEventListener("touchmove",g,{passive:!1}),o.addEventListener("touchend",l),()=>{o.removeEventListener("touchstart",m),o.removeEventListener("touchmove",g),o.removeEventListener("touchend",l)}},[n,s])}const je={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},Me=t.memo(({seat:n,state:s,colors:a,onClick:r,onMouseEnter:h,onMouseLeave:u})=>{const g={available:a.seatAvailable,reserved:a.seatReserved,selected:a.seatSelected,unavailable:a.seatUnavailable,hidden:a.seatHidden}[s],l=s==="available"||s==="selected",c=t.useCallback(()=>{l&&r(n)},[n,r,l]),f=t.useCallback(w=>{h(n,w);const R=w.target.getStage();R&&l&&(R.container().style.cursor="pointer")},[n,h,l]),p=t.useCallback(w=>{u();const R=w.target.getStage();R&&(R.container().style.cursor="grab")},[u]),b={x:n.position.x,y:n.position.y,fill:g,stroke:"#ffffff",strokeWidth:1,onClick:c,onTap:c,onMouseEnter:f,onMouseLeave:p};return n.shape==="circle"?i.jsx(X.Circle,{...b,radius:12}):i.jsx(X.Rect,{...b,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:n.shape==="square"?0:4})});Me.displayName="ViewerSeat";const Ee=t.memo(({stage:n,stageColor:s})=>{const a=u=>({stage:"🎭",table:"⬜",wall:"▬",barrier:"🛡️","dj-booth":"🎵",bar:"🍷","entry-exit":"🚪",custom:"➕"})[u||"stage"]||"🎭",r=n.config.color||s,h=a(n.config.objectType);return i.jsxs(X.Group,{x:n.position.x,y:n.position.y,rotation:n.config.rotation||0,children:[i.jsx(X.Rect,{width:n.config.width,height:n.config.height,fill:r+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),i.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"}),i.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"})]})});Ee.displayName="ViewerStage";const Fe=t.memo(({floors:n,currentFloorId:s,onFloorChange:a,showAllOption:r,allLabel:h,position:u,className:o})=>{const m=t.useMemo(()=>[...n].sort((p,b)=>p.order-b.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 i.jsxs("div",{className:o,style:l,children:[r&&i.jsx("button",{type:"button",onClick:()=>a(null),style:s===null?f:c,children:h}),m.map(p=>i.jsx("button",{type:"button",onClick:()=>a(p.id),style:s===p.id?f:c,children:p.name},p.id))]})});Fe.displayName="FloorSelectorBar";const ke=t.memo(({scale:n,minScale:s,maxScale:a,onZoomIn:r,onZoomOut:h,position:u,className:o})=>{const g={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<a,p=n>s;return i.jsxs("div",{className:o,style:g,children:[i.jsx("button",{type:"button",onClick:r,disabled:!f,style:f?l:c,title:"Zoom In",children:"+"}),i.jsx("button",{type:"button",onClick:h,disabled:!p,style:p?l:c,title:"Zoom Out",children:"−"})]})});ke.displayName="ZoomControls";const Ie=t.memo(({visible:n,x:s,y:a,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"),m={position:"fixed",left:`${s+15}px`,top:`${a+15}px`,zIndex:1e3,pointerEvents:"none"},g={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},p={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return i.jsx("div",{style:m,children:i.jsxs("div",{style:g,children:[r.sectionName&&i.jsxs("div",{style:{marginBottom:"4px"},children:[i.jsx("span",{style:l,children:"Section:"}),i.jsx("span",{style:{...c,color:"#3b82f6"},children:r.sectionName})]}),i.jsxs("div",{style:{marginBottom:"4px"},children:[i.jsx("span",{style:l,children:"Seat:"}),i.jsx("span",{style:c,children:o})]}),r.price!==void 0&&r.price>0&&u==="available"&&i.jsxs("div",{style:{marginBottom:"4px"},children:[i.jsx("span",{style:l,children:"Price:"}),i.jsxs("span",{style:f,children:[h," ",r.price.toFixed(2)]})]}),i.jsxs("div",{style:p,children:["Status: ",u]})]})})});Ie.displayName="SeatTooltip";const it=({config:n,configUrl:s,floorId:a,onFloorChange:r,reservedSeats:h=[],unavailableSeats:u=[],selectedSeats:o,myReservedSeats:m=[],onSeatSelect:g,onSeatDeselect:l,onSelectionChange:c,colorOverrides:f,showTooltip:p=!0,zoomEnabled:b=!0,className:w="",onConfigLoad:R,onError:M,showFloorSelector:E,floorSelectorPosition:j="top-left",floorSelectorClassName:F,showAllFloorsOption:z=!0,allFloorsLabel:L="All",fitToView:D=!0,fitPadding:N=40,showZoomControls:Q=!0,zoomControlsPosition:De="bottom-right",zoomControlsClassName:ze,minZoom:be,maxZoom:Y=3,zoomStep:ee=.25,touchEnabled:Ne=!0})=>{const le=t.useRef(null),xe=t.useRef(null),k=Ce(xe),[U,Se]=t.useState(new Set),[I,H]=t.useState(1),[T,B]=t.useState({x:0,y:0}),[Ae,Xe]=t.useState(null),[Ye,Pe]=t.useState(1),te=t.useRef({width:0,height:0}),[q,ye]=t.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:We,loading:Be,error:_}=we(s),x=n||We,ue=a!==void 0,A=ue?a||null:Ae,ne=o!==void 0,$e=t.useCallback(e=>{ue||Xe(e),r?.(e)},[ue,r]),de=x?.floors||[],Ue=E!==void 0?E:de.length>1,se=t.useMemo(()=>x?{...x.colors,...f}:{...je,...f},[x,f]),O=t.useMemo(()=>{if(!x)return[];let e=x.seats.filter(d=>d.state!=="hidden");return A&&(e=e.filter(d=>d.floorId===A||!d.floorId&&A==="floor_default")),e},[x,A]),re=t.useMemo(()=>x?.stages?A?x.stages.filter(e=>e.floorId===A||!e.floorId&&A==="floor_default"):x.stages:[],[x,A]),P=t.useMemo(()=>{if(!x||O.length===0&&re.length===0)return null;const e=12;let d=1/0,S=1/0,y=-1/0,v=-1/0;return O.forEach(C=>{d=Math.min(d,C.position.x-e),S=Math.min(S,C.position.y-e),y=Math.max(y,C.position.x+e),v=Math.max(v,C.position.y+e)}),re.forEach(C=>{d=Math.min(d,C.position.x),S=Math.min(S,C.position.y),y=Math.max(y,C.position.x+(C.config?.width||200)),v=Math.max(v,C.position.y+(C.config?.height||100))}),{minX:d,minY:S,maxX:y,maxY:v,width:y-d,height:v-S}},[x,O,re]);t.useEffect(()=>{if(!D||!x||!P||k.width===0||k.height===0)return;const e=Math.abs(k.width-te.current.width),d=Math.abs(k.height-te.current.height);if(!(te.current.width===0)&&e<10&&d<10)return;te.current=k;const y=k.width,v=k.height,C=y-N*2,Z=v-N*2,oe=C/P.width,fe=Z/P.height,ie=Math.min(oe,fe,Y),Qe=P.minX+P.width/2,et=P.minY+P.height/2,tt=y/2,nt=v/2,st=tt-Qe*ie,rt=nt-et*ie;H(ie),B({x:st,y:rt}),Pe(ie)},[D,x,P,N,Y,k,A]);const $=t.useMemo(()=>{const e=new Set(h),d=new Set(u),S=new Set(m);return{reserved:e,unavailable:d,myReserved:S}},[h,u,m]),he=t.useMemo(()=>o?new Set(o):null,[o]),G=t.useCallback(e=>{const d=e.id,S=e.seatNumber||"";return $.unavailable.has(d)||$.unavailable.has(S)?"unavailable":$.reserved.has(d)||$.reserved.has(S)?"reserved":$.myReserved.has(d)||$.myReserved.has(S)||U.has(d)?"selected":e.state},[$,U]);t.useEffect(()=>{x&&R&&R(x)},[x,R]),t.useEffect(()=>{_&&M&&M(_)},[_,M]),t.useEffect(()=>{ne&&he&&Se(he)},[ne,he]);const Oe=t.useCallback(e=>{const d=G(e);if(d!=="available"&&d!=="selected")return;const S=U.has(e.id);ne||Se(y=>{const v=new Set(y);return S?v.delete(e.id):v.add(e.id),v}),S?l?.(e):(g?.(e),g||console.log("Seat selected:",e))},[G,U,ne,g,l]),K=t.useMemo(()=>x?O.filter(e=>U.has(e.id)):[],[O,U]);t.useEffect(()=>{c?.(K)},[K,c]);const V=be!==void 0?be:Ye,Ve=t.useCallback(()=>{if(!b)return;const e=Math.min(I+ee,Y);if(e!==I){const d=k.width||x?.canvas.width||800,S=k.height||x?.canvas.height||600,y=d/2,v=S/2,C={x:(y-T.x)/I,y:(v-T.y)/I};H(e),B({x:y-C.x*e,y:v-C.y*e})}},[b,I,ee,Y,k,x,T]),He=t.useCallback(()=>{if(!b)return;const e=Math.max(I-ee,V);if(e!==I){const d=k.width||x?.canvas.width||800,S=k.height||x?.canvas.height||600,y=d/2,v=S/2,C={x:(y-T.x)/I,y:(v-T.y)/I};H(e),B({x:y-C.x*e,y:v-C.y*e})}},[b,I,ee,V,k,x,T]),qe=t.useCallback(e=>{B({x:e.target.x(),y:e.target.y()})},[]),_e=t.useCallback(e=>{if(!b)return;e.evt.preventDefault();const d=le.current;if(!d)return;const S=d.scaleX(),y=d.getPointerPosition();if(!y)return;const v=1.1,C=e.evt.deltaY>0?S/v:S*v,Z=Math.min(Math.max(C,V),Y),oe={x:(y.x-T.x)/S,y:(y.y-T.y)/S},fe={x:y.x-oe.x*Z,y:y.y-oe.y*Z};H(Z),B(fe)},[b,T,V,Y]);Re(le,{enabled:Ne&&b,minScale:V,maxScale:Y,currentScale:I,currentPosition:T,onScaleChange:(e,d)=>{H(e),B(d)},onPositionChange:e=>{B(e)}});const Ge=t.useCallback((e,d)=>{if(!p)return;const S=d.target.getStage();if(!S)return;const y=S.getPointerPosition();if(!y)return;const v=S.container().getBoundingClientRect();ye({visible:!0,x:v.left+y.x,y:v.top+y.y,seat:e,state:G(e)})},[p,G]),Ke=t.useCallback(()=>{ye(e=>({...e,visible:!1}))},[]);if(Be)return i.jsx("div",{className:`flex items-center justify-center h-full ${w}`,children:i.jsx("p",{children:"Loading seat map..."})});if(_)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: ",_.message]})});if(!x)return i.jsx("div",{className:`flex items-center justify-center h-full ${w}`,children:i.jsx("p",{children:"No configuration provided"})});const Ze=k.width||x.canvas.width,Je=k.height||x.canvas.height;return i.jsxs("div",{ref:xe,className:`relative ${w}`,style:{width:"100%",height:"100%"},children:[Ue&&de.length>0&&i.jsx(Fe,{floors:de,currentFloorId:A,onFloorChange:$e,showAllOption:z,allLabel:L,position:j,className:F}),i.jsxs(X.Stage,{ref:le,width:Ze,height:Je,scaleX:I,scaleY:I,x:T.x,y:T.y,draggable:!0,onDragEnd:qe,onWheel:_e,style:{backgroundColor:x.canvas.backgroundColor,cursor:"grab"},children:[i.jsx(X.Layer,{listening:!1,children:re.map(e=>i.jsx(Ee,{stage:e,stageColor:se.stageColor},e.id))}),i.jsx(X.Layer,{children:O.map(e=>i.jsx(Me,{seat:e,state:G(e),colors:se,onClick:Oe,onMouseEnter:Ge,onMouseLeave:Ke},e.id))})]}),p&&i.jsx(Ie,{visible:q.visible,x:q.x,y:q.y,seat:q.seat,currency:se.currency,state:q.state}),Q&&b&&i.jsx(ke,{scale:I,minScale:V,maxScale:Y,onZoomIn:Ve,onZoomOut:He,position:De,className:ze}),K.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 (",K.length,")"]}),i.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:K.map(e=>i.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${se.currency} ${e.price.toFixed(2)}`]},e.id))})]})]})};let J=null;function at(n){J=n}function pe(){if(!J)throw new Error("Firebase database not initialized. Call initializeFirebaseForViewer(db) first.");return J}function ce(){return J!==null}function ct(){J=null}function ge(n,s){if(n.length!==s.length)return!1;const a=[...n].sort(),r=[...s].sort();return a.every((h,u)=>h===r[u])}function lt(n,s){const a=[],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?a.push(u):r.push(u)))}),{myReserved:a.sort(),otherReserved:r.sort(),unavailable:h.sort()}}const ae={states:null,loading:!0,error:null,lastUpdated:null,myReservedSeats:[],otherReservedSeats:[],unavailableSeats:[]};function Le(n){const{seatMapId:s,currentUserId:a,enabled:r=!0,onStateChange:h,onError:u}=n,o=t.useRef({...ae}),m=t.useRef(h),g=t.useRef(u),l=t.useRef(a);m.current=h,g.current=u,l.current=a;const c=t.useCallback(w=>{if(!r||!s)return o.current={...ae,loading:!1},()=>{};if(!ce())return o.current={...ae,loading:!1,error:new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")},()=>{};const R=pe(),M=W.ref(R,`seatmaps/${s}/seat_states`),E=F=>{const L=F.val()||{},D=lt(L,l.current),N=o.current;(N.loading||!ge(N.myReservedSeats,D.myReserved)||!ge(N.otherReservedSeats,D.otherReserved)||!ge(N.unavailableSeats,D.unavailable))&&(o.current={states:L,loading:!1,error:null,lastUpdated:Date.now(),myReservedSeats:D.myReserved,otherReservedSeats:D.otherReserved,unavailableSeats:D.unavailable},m.current?.(L),w())},j=F=>{o.current={...o.current,loading:!1,error:F},g.current?.(F),w()};return W.onValue(M,E,j),()=>{W.off(M)}},[s,r,a]),f=t.useCallback(()=>o.current,[]),p=t.useCallback(()=>ae,[]),b=t.useSyncExternalStore(c,f,p);return{states:b.states,loading:b.loading,error:b.error,lastUpdated:b.lastUpdated,myReservedSeats:b.myReservedSeats,otherReservedSeats:b.otherReservedSeats,unavailableSeats:b.unavailableSeats,reservedSeats:b.otherReservedSeats}}function Te(n){const{seatMapId:s,enabled:a=!0,subscribeToChanges:r=!1,onConfigLoad:h,onError:u}=n,[o,m]=t.useState(null),[g,l]=t.useState(!0),[c,f]=t.useState(null),p=t.useRef(h),b=t.useRef(u);p.current=h,b.current=u;const w=t.useCallback(async()=>{if(!s)return;if(!ce()){f(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")),l(!1);return}const R=pe(),M=W.ref(R,`seatmaps/${s}`);try{l(!0),f(null);const j=(await W.get(M)).val();if(j){const F=ot.fromFirebaseSeatMap(j);m(F),p.current?.(F)}else f(new Error(`Seat map ${s} not found in Firebase`))}catch(E){const j=E instanceof Error?E:new Error("Unknown error");f(j),b.current?.(j)}finally{l(!1)}},[s]);return t.useEffect(()=>{if(!a||!s){l(!1);return}if(w(),r&&ce()){const R=pe(),M=W.ref(R,`seatmaps/${s}/meta/updated_at`);let E=!0,j=null;const F=z=>{if(E){E=!1,j=z.val();return}const L=z.val();z.exists()&&L!==j&&(j=L,w())};return W.onValue(M,F),()=>{W.off(M)}}},[s,a,r]),{config:o,loading:g,error:c,refetch:w}}function ut(n){const{seatMapId:s,userId:a,enabled:r=!0,subscribeToDesignChanges:h=!1,onConfigLoad:u,onStateChange:o,onError:m}=n,{config:g,loading:l,error:c,refetch:f}=Te({seatMapId:s,enabled:r,subscribeToChanges:h,onConfigLoad:u,onError:m}),{states:p,loading:b,error:w,lastUpdated:R,myReservedSeats:M,otherReservedSeats:E,unavailableSeats:j,reservedSeats:F}=Le({seatMapId:s,currentUserId:a,enabled:r,onStateChange:o,onError:m});return{config:g,loading:l||b,error:c||w,myReservedSeats:M,otherReservedSeats:E,unavailableSeats:j,reservedSeats:F,seatStates:p,lastUpdated:R,refetch:f}}exports.DEFAULT_COLORS=je;exports.SeatMapViewer=it;exports.clearFirebaseInstance=ct;exports.initializeFirebaseForViewer=at;exports.isFirebaseInitialized=ce;exports.useConfigFetcher=we;exports.useContainerSize=Ce;exports.useFirebaseConfig=Te;exports.useFirebaseSeatStates=Le;exports.useRealtimeSeatMap=ut;exports.useTouchGestures=Re;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),t=require("react"),X=require("react-konva"),W=require("firebase/database"),ot=require("@zonetrix/shared");function we(n){const[s,a]=t.useState(null),[r,h]=t.useState(!1),[u,o]=t.useState(null),w=async()=>{if(n){h(!0),o(null);try{const g=await fetch(n);if(!g.ok)throw new Error(`Failed to fetch config: ${g.statusText}`);const l=await g.json();a(l)}catch(g){const l=g instanceof Error?g: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 Ce(n){const[s,a]=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&&a({width:h,height:u});const o=new ResizeObserver(w=>{const g=w[0];if(!g)return;const{width:l,height:c}=g.contentRect;l>0&&c>0&&a(f=>f.width===l&&f.height===c?f:{width:l,height:c})});return o.observe(r),()=>{o.disconnect()}},[n]),s}function ve(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 Re(n,s){const a=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},p={x:c.touches[1].clientX,y:c.touches[1].clientY};a.current=ve(f,p),r.current=me(f,p),h.current=s.currentScale}},g=c=>{if(c.touches.length!==2)return;c.preventDefault();const f={x:c.touches[0].clientX,y:c.touches[0].clientY},p={x:c.touches[1].clientX,y:c.touches[1].clientY},b=ve(f,p),v=me(f,p);if(a.current!==null&&r.current!==null){const R=b/a.current,E=Math.min(Math.max(s.currentScale*R,s.minScale),s.maxScale),F=o.getBoundingClientRect(),M=v.x-F.left,j=v.y-F.top,z=s.currentScale,L={x:(M-s.currentPosition.x)/z,y:(j-s.currentPosition.y)/z},D=v.x-r.current.x,N=v.y-r.current.y,Q={x:M-L.x*E+D,y:j-L.y*E+N};s.onScaleChange(E,Q),a.current=b,r.current=v}},l=c=>{c.touches.length<2&&(a.current=null,r.current=null)};return o.addEventListener("touchstart",w,{passive:!1}),o.addEventListener("touchmove",g,{passive:!1}),o.addEventListener("touchend",l),()=>{o.removeEventListener("touchstart",w),o.removeEventListener("touchmove",g),o.removeEventListener("touchend",l)}},[n,s])}const je={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},Me=t.memo(({seat:n,state:s,colors:a,onClick:r,onMouseEnter:h,onMouseLeave:u})=>{const g={available:a.seatAvailable,reserved:a.seatReserved,selected:a.seatSelected,unavailable:a.seatUnavailable,hidden:a.seatHidden}[s],l=s==="available"||s==="selected",c=t.useCallback(()=>{l&&r(n)},[n,r,l]),f=t.useCallback(v=>{h(n,v);const R=v.target.getStage();R&&l&&(R.container().style.cursor="pointer")},[n,h,l]),p=t.useCallback(v=>{u();const R=v.target.getStage();R&&(R.container().style.cursor="grab")},[u]),b={x:n.position.x,y:n.position.y,fill:g,stroke:"#ffffff",strokeWidth:1,onClick:c,onTap:c,onMouseEnter:f,onMouseLeave:p};return n.shape==="circle"?i.jsx(X.Circle,{...b,radius:12}):i.jsx(X.Rect,{...b,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:n.shape==="square"?0:4})});Me.displayName="ViewerSeat";const Ee=t.memo(({stage:n,stageColor:s})=>{const a=u=>({stage:"🎭",table:"⬜",wall:"▬",barrier:"🛡️","dj-booth":"🎵",bar:"🍷","entry-exit":"🚪",custom:"➕"})[u||"stage"]||"🎭",r=n.config.color||s,h=a(n.config.objectType);return i.jsxs(X.Group,{x:n.position.x,y:n.position.y,rotation:n.config.rotation||0,children:[i.jsx(X.Rect,{width:n.config.width,height:n.config.height,fill:r+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),i.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"}),i.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"})]})});Ee.displayName="ViewerStage";const Fe=t.memo(({floors:n,currentFloorId:s,onFloorChange:a,showAllOption:r,allLabel:h,position:u,className:o})=>{const w=t.useMemo(()=>[...n].sort((p,b)=>p.order-b.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 i.jsxs("div",{className:o,style:l,children:[r&&i.jsx("button",{type:"button",onClick:()=>a(null),style:s===null?f:c,children:h}),w.map(p=>i.jsx("button",{type:"button",onClick:()=>a(p.id),style:s===p.id?f:c,children:p.name},p.id))]})});Fe.displayName="FloorSelectorBar";const ke=t.memo(({scale:n,minScale:s,maxScale:a,onZoomIn:r,onZoomOut:h,position:u,className:o})=>{const g={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<a,p=n>s;return i.jsxs("div",{className:o,style:g,children:[i.jsx("button",{type:"button",onClick:r,disabled:!f,style:f?l:c,title:"Zoom In",children:"+"}),i.jsx("button",{type:"button",onClick:h,disabled:!p,style:p?l:c,title:"Zoom Out",children:"−"})]})});ke.displayName="ZoomControls";const Ie=t.memo(({visible:n,x:s,y:a,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:`${a+15}px`,zIndex:1e3,pointerEvents:"none"},g={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},p={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return i.jsx("div",{style:w,children:i.jsxs("div",{style:g,children:[r.sectionName&&i.jsxs("div",{style:{marginBottom:"4px"},children:[i.jsx("span",{style:l,children:"Section:"}),i.jsx("span",{style:{...c,color:"#3b82f6"},children:r.sectionName})]}),i.jsxs("div",{style:{marginBottom:"4px"},children:[i.jsx("span",{style:l,children:"Seat:"}),i.jsx("span",{style:c,children:o})]}),r.price!==void 0&&r.price>0&&u==="available"&&i.jsxs("div",{style:{marginBottom:"4px"},children:[i.jsx("span",{style:l,children:"Price:"}),i.jsxs("span",{style:f,children:[h," ",r.price.toFixed(2)]})]}),i.jsxs("div",{style:p,children:["Status: ",u]})]})})});Ie.displayName="SeatTooltip";const it=({config:n,configUrl:s,floorId:a,onFloorChange:r,reservedSeats:h=[],unavailableSeats:u=[],selectedSeats:o,myReservedSeats:w=[],onSeatSelect:g,onSeatDeselect:l,onSelectionChange:c,colorOverrides:f,showTooltip:p=!0,zoomEnabled:b=!0,className:v="",onConfigLoad:R,onError:E,showFloorSelector:F,floorSelectorPosition:M="top-left",floorSelectorClassName:j,showAllFloorsOption:z=!0,allFloorsLabel:L="All",fitToView:D=!0,fitPadding:N=40,showZoomControls:Q=!0,zoomControlsPosition:De="bottom-right",zoomControlsClassName:ze,minZoom:be,maxZoom:Y=3,zoomStep:ee=.25,touchEnabled:Ne=!0})=>{const le=t.useRef(null),xe=t.useRef(null),k=Ce(xe),[U,Se]=t.useState(new Set),[I,H]=t.useState(1),[T,B]=t.useState({x:0,y:0}),[Ae,Xe]=t.useState(null),[Ye,Pe]=t.useState(1),te=t.useRef({width:0,height:0}),[q,ye]=t.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:We,loading:Be,error:_}=we(s),x=n||We,ue=a!==void 0,A=ue?a||null:Ae,ne=o!==void 0,$e=t.useCallback(e=>{ue||Xe(e),r?.(e)},[ue,r]),de=x?.floors||[],Ue=F!==void 0?F:de.length>1,se=t.useMemo(()=>x?{...x.colors,...f}:{...je,...f},[x,f]),O=t.useMemo(()=>{if(!x)return[];let e=x.seats.filter(d=>d.state!=="hidden");return A&&(e=e.filter(d=>d.floorId===A||!d.floorId&&A==="floor_default")),e},[x,A]),re=t.useMemo(()=>x?.stages?A?x.stages.filter(e=>e.floorId===A||!e.floorId&&A==="floor_default"):x.stages:[],[x,A]),P=t.useMemo(()=>{if(!x||O.length===0&&re.length===0)return null;const e=12;let d=1/0,S=1/0,y=-1/0,m=-1/0;return O.forEach(C=>{d=Math.min(d,C.position.x-e),S=Math.min(S,C.position.y-e),y=Math.max(y,C.position.x+e),m=Math.max(m,C.position.y+e)}),re.forEach(C=>{d=Math.min(d,C.position.x),S=Math.min(S,C.position.y),y=Math.max(y,C.position.x+(C.config?.width||200)),m=Math.max(m,C.position.y+(C.config?.height||100))}),{minX:d,minY:S,maxX:y,maxY:m,width:y-d,height:m-S}},[x,O,re]);t.useEffect(()=>{if(!D||!x||!P||k.width===0||k.height===0)return;const e=Math.abs(k.width-te.current.width),d=Math.abs(k.height-te.current.height);if(!(te.current.width===0)&&e<10&&d<10)return;te.current=k;const y=k.width,m=k.height,C=y-N*2,Z=m-N*2,oe=C/P.width,fe=Z/P.height,ie=Math.min(oe,fe,Y),Qe=P.minX+P.width/2,et=P.minY+P.height/2,tt=y/2,nt=m/2,st=tt-Qe*ie,rt=nt-et*ie;H(ie),B({x:st,y:rt}),Pe(ie)},[D,x,P,N,Y,k,A]);const $=t.useMemo(()=>{const e=new Set(h),d=new Set(u),S=new Set(w);return{reserved:e,unavailable:d,myReserved:S}},[h,u,w]),he=t.useMemo(()=>o?new Set(o):null,[o]),G=t.useCallback(e=>{const d=e.id,S=e.seatNumber||"";return $.unavailable.has(d)||$.unavailable.has(S)?"unavailable":$.reserved.has(d)||$.reserved.has(S)?"reserved":$.myReserved.has(d)||$.myReserved.has(S)||U.has(d)?"selected":e.state},[$,U]);t.useEffect(()=>{x&&R&&R(x)},[x,R]),t.useEffect(()=>{_&&E&&E(_)},[_,E]),t.useEffect(()=>{ne&&he&&Se(he)},[ne,he]);const Oe=t.useCallback(e=>{const d=G(e);if(d!=="available"&&d!=="selected")return;const S=U.has(e.id);ne||Se(y=>{const m=new Set(y);return S?m.delete(e.id):m.add(e.id),m}),S?l?.(e):(g?.(e),g||console.log("Seat selected:",e))},[G,U,ne,g,l]),K=t.useMemo(()=>x?O.filter(e=>U.has(e.id)):[],[O,U]);t.useEffect(()=>{c?.(K)},[K,c]);const V=be!==void 0?be:Ye,Ve=t.useCallback(()=>{if(!b)return;const e=Math.min(I+ee,Y);if(e!==I){const d=k.width||x?.canvas.width||800,S=k.height||x?.canvas.height||600,y=d/2,m=S/2,C={x:(y-T.x)/I,y:(m-T.y)/I};H(e),B({x:y-C.x*e,y:m-C.y*e})}},[b,I,ee,Y,k,x,T]),He=t.useCallback(()=>{if(!b)return;const e=Math.max(I-ee,V);if(e!==I){const d=k.width||x?.canvas.width||800,S=k.height||x?.canvas.height||600,y=d/2,m=S/2,C={x:(y-T.x)/I,y:(m-T.y)/I};H(e),B({x:y-C.x*e,y:m-C.y*e})}},[b,I,ee,V,k,x,T]),qe=t.useCallback(e=>{B({x:e.target.x(),y:e.target.y()})},[]),_e=t.useCallback(e=>{if(!b)return;e.evt.preventDefault();const d=le.current;if(!d)return;const S=d.scaleX(),y=d.getPointerPosition();if(!y)return;const m=1.1,C=e.evt.deltaY>0?S/m:S*m,Z=Math.min(Math.max(C,V),Y),oe={x:(y.x-T.x)/S,y:(y.y-T.y)/S},fe={x:y.x-oe.x*Z,y:y.y-oe.y*Z};H(Z),B(fe)},[b,T,V,Y]);Re(le,{enabled:Ne&&b,minScale:V,maxScale:Y,currentScale:I,currentPosition:T,onScaleChange:(e,d)=>{H(e),B(d)},onPositionChange:e=>{B(e)}});const Ge=t.useCallback((e,d)=>{if(!p)return;const S=d.target.getStage();if(!S)return;const y=S.getPointerPosition();if(!y)return;const m=S.container().getBoundingClientRect();ye({visible:!0,x:m.left+y.x,y:m.top+y.y,seat:e,state:G(e)})},[p,G]),Ke=t.useCallback(()=>{ye(e=>({...e,visible:!1}))},[]);if(Be)return i.jsx("div",{className:`flex items-center justify-center h-full ${v}`,children:i.jsx("p",{children:"Loading seat map..."})});if(_)return i.jsx("div",{className:`flex items-center justify-center h-full ${v}`,children:i.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",_.message]})});if(!x)return i.jsx("div",{className:`flex items-center justify-center h-full ${v}`,children:i.jsx("p",{children:"No configuration provided"})});const Ze=k.width||x.canvas.width,Je=k.height||x.canvas.height;return i.jsxs("div",{ref:xe,className:`relative ${v}`,style:{width:"100%",height:"100%"},children:[Ue&&de.length>0&&i.jsx(Fe,{floors:de,currentFloorId:A,onFloorChange:$e,showAllOption:z,allLabel:L,position:M,className:j}),i.jsxs(X.Stage,{ref:le,width:Ze,height:Je,scaleX:I,scaleY:I,x:T.x,y:T.y,draggable:!0,onDragEnd:qe,onWheel:_e,style:{backgroundColor:x.canvas.backgroundColor,cursor:"grab"},children:[i.jsx(X.Layer,{listening:!1,children:re.map(e=>i.jsx(Ee,{stage:e,stageColor:se.stageColor},e.id))}),i.jsx(X.Layer,{children:O.map(e=>i.jsx(Me,{seat:e,state:G(e),colors:se,onClick:Oe,onMouseEnter:Ge,onMouseLeave:Ke},e.id))})]}),p&&i.jsx(Ie,{visible:q.visible,x:q.x,y:q.y,seat:q.seat,currency:se.currency,state:q.state}),Q&&b&&i.jsx(ke,{scale:I,minScale:V,maxScale:Y,onZoomIn:Ve,onZoomOut:He,position:De,className:ze}),K.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 (",K.length,")"]}),i.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:K.map(e=>i.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${se.currency} ${e.price.toFixed(2)}`]},e.id))})]})]})};let J=null;function at(n){J=n}function pe(){if(!J)throw new Error("Firebase database not initialized. Call initializeFirebaseForViewer(db) first.");return J}function ce(){return J!==null}function ct(){J=null}function ge(n,s){if(n.length!==s.length)return!1;const a=[...n].sort(),r=[...s].sort();return a.every((h,u)=>h===r[u])}function lt(n,s){const a=[],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?a.push(u):r.push(u)))}),{myReserved:a.sort(),otherReserved:r.sort(),unavailable:h.sort()}}const ae={states:null,loading:!0,error:null,lastUpdated:null,myReservedSeats:[],otherReservedSeats:[],unavailableSeats:[]};function Le(n){const{seatMapId:s,currentUserId:a,enabled:r=!0,onStateChange:h,onError:u}=n,o=t.useRef({...ae}),w=t.useRef(h),g=t.useRef(u),l=t.useRef(a);w.current=h,g.current=u,l.current=a;const c=t.useCallback(v=>{if(!r||!s)return(o.current.loading!==!1||o.current.states!==null)&&(o.current={...ae,loading:!1},v()),()=>{};if(!ce()){const j="Firebase not initialized. Call initializeFirebaseForViewer first.";return o.current.error?.message!==j&&(o.current={...ae,loading:!1,error:new Error(j)},v()),()=>{}}const R=pe(),E=W.ref(R,`seatmaps/${s}/seat_states`),F=j=>{const L=j.val()||{},D=lt(L,l.current),N=o.current;(N.loading||!ge(N.myReservedSeats,D.myReserved)||!ge(N.otherReservedSeats,D.otherReserved)||!ge(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),v())},M=j=>{o.current={...o.current,loading:!1,error:j},g.current?.(j),v()};return W.onValue(E,F,M),()=>{W.off(E)}},[s,r,a]),f=t.useCallback(()=>o.current,[]),p=t.useCallback(()=>ae,[]),b=t.useSyncExternalStore(c,f,p);return{states:b.states,loading:b.loading,error:b.error,lastUpdated:b.lastUpdated,myReservedSeats:b.myReservedSeats,otherReservedSeats:b.otherReservedSeats,unavailableSeats:b.unavailableSeats,reservedSeats:b.otherReservedSeats}}function Te(n){const{seatMapId:s,enabled:a=!0,subscribeToChanges:r=!1,onConfigLoad:h,onError:u}=n,[o,w]=t.useState(null),[g,l]=t.useState(!0),[c,f]=t.useState(null),p=t.useRef(h),b=t.useRef(u);p.current=h,b.current=u;const v=t.useCallback(async()=>{if(!s)return;if(!ce()){f(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")),l(!1);return}const R=pe(),E=W.ref(R,`seatmaps/${s}`);try{l(!0),f(null);const M=(await W.get(E)).val();if(M){const j=ot.fromFirebaseSeatMap(M);w(j),p.current?.(j)}else f(new Error(`Seat map ${s} not found in Firebase`))}catch(F){const M=F instanceof Error?F:new Error("Unknown error");f(M),b.current?.(M)}finally{l(!1)}},[s]);return t.useEffect(()=>{if(!a||!s){l(!1);return}if(v(),r&&ce()){const R=pe(),E=W.ref(R,`seatmaps/${s}/meta/updated_at`);let F=!0,M=null;const j=z=>{if(F){F=!1,M=z.val();return}const L=z.val();z.exists()&&L!==M&&(M=L,v())};return W.onValue(E,j),()=>{W.off(E)}}},[s,a,r]),{config:o,loading:g,error:c,refetch:v}}function ut(n){const{seatMapId:s,userId:a,enabled:r=!0,subscribeToDesignChanges:h=!1,onConfigLoad:u,onStateChange:o,onError:w}=n,{config:g,loading:l,error:c,refetch:f}=Te({seatMapId:s,enabled:r,subscribeToChanges:h,onConfigLoad:u,onError:w}),{states:p,loading:b,error:v,lastUpdated:R,myReservedSeats:E,otherReservedSeats:F,unavailableSeats:M,reservedSeats:j}=Le({seatMapId:s,currentUserId:a,enabled:r,onStateChange:o,onError:w});return{config:g,loading:l||b,error:c||v,myReservedSeats:E,otherReservedSeats:F,unavailableSeats:M,reservedSeats:j,seatStates:p,lastUpdated:R,refetch:f}}exports.DEFAULT_COLORS=je;exports.SeatMapViewer=it;exports.clearFirebaseInstance=ct;exports.initializeFirebaseForViewer=at;exports.isFirebaseInitialized=ce;exports.useConfigFetcher=we;exports.useContainerSize=Ce;exports.useFirebaseConfig=Te;exports.useFirebaseSeatStates=Le;exports.useRealtimeSeatMap=ut;exports.useTouchGestures=Re;
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { jsx as y, jsxs as L } from "react/jsx-runtime";
2
- import { useState as N, useEffect as W, useRef as A, useCallback as I, useMemo as U, memo as ne, useSyncExternalStore as lt } from "react";
3
- import { Stage as dt, Layer as Me, Group as ut, Rect as ke, Text as Ee, Circle as ht } from "react-konva";
4
- import { ref as ve, onValue as Le, off as De, get as ft } from "firebase/database";
1
+ import { jsx as y, jsxs as D } from "react/jsx-runtime";
2
+ import { useState as T, useEffect as W, useRef as A, useCallback as F, useMemo as U, memo as ne, useSyncExternalStore as lt } from "react";
3
+ import { Stage as dt, Layer as Me, Group as ut, Rect as Le, Text as Ee, Circle as ht } from "react-konva";
4
+ import { ref as ve, onValue as De, off as Ne, get as ft } from "firebase/database";
5
5
  import { fromFirebaseSeatMap as gt } from "@zonetrix/shared";
6
6
  function pt(t) {
7
- const [n, i] = N(null), [r, d] = N(!1), [c, o] = N(null), S = async () => {
7
+ const [n, i] = T(null), [r, d] = T(!1), [c, o] = T(null), x = async () => {
8
8
  if (t) {
9
9
  d(!0), o(null);
10
10
  try {
@@ -22,23 +22,23 @@ function pt(t) {
22
22
  }
23
23
  };
24
24
  return W(() => {
25
- S();
25
+ x();
26
26
  }, [t]), {
27
27
  config: n,
28
28
  loading: r,
29
29
  error: c,
30
- refetch: S
30
+ refetch: x
31
31
  };
32
32
  }
33
33
  function bt(t) {
34
- const [n, i] = N({ width: 0, height: 0 });
34
+ const [n, i] = T({ width: 0, height: 0 });
35
35
  return W(() => {
36
36
  const r = t.current;
37
37
  if (!r) return;
38
38
  const { width: d, height: c } = r.getBoundingClientRect();
39
39
  d > 0 && c > 0 && i({ width: d, height: c });
40
- const o = new ResizeObserver((S) => {
41
- const h = S[0];
40
+ const o = new ResizeObserver((x) => {
41
+ const h = x[0];
42
42
  if (!h) return;
43
43
  const { width: a, height: s } = h.contentRect;
44
44
  a > 0 && s > 0 && i((u) => u.width === a && u.height === s ? u : { width: a, height: s });
@@ -62,7 +62,7 @@ function yt(t, n) {
62
62
  W(() => {
63
63
  const c = t.current;
64
64
  if (!c || !n.enabled) return;
65
- const o = c.container(), S = (s) => {
65
+ const o = c.container(), x = (s) => {
66
66
  if (s.touches.length === 2) {
67
67
  s.preventDefault();
68
68
  const u = { x: s.touches[0].clientX, y: s.touches[0].clientY }, f = { x: s.touches[1].clientX, y: s.touches[1].clientY };
@@ -71,25 +71,25 @@ function yt(t, n) {
71
71
  }, h = (s) => {
72
72
  if (s.touches.length !== 2) return;
73
73
  s.preventDefault();
74
- const u = { x: s.touches[0].clientX, y: s.touches[0].clientY }, f = { x: s.touches[1].clientX, y: s.touches[1].clientY }, g = Ie(u, f), x = Fe(u, f);
74
+ const u = { x: s.touches[0].clientX, y: s.touches[0].clientY }, f = { x: s.touches[1].clientX, y: s.touches[1].clientY }, g = Ie(u, f), m = Fe(u, f);
75
75
  if (i.current !== null && r.current !== null) {
76
- const C = g / i.current, R = Math.min(
76
+ const C = g / i.current, M = Math.min(
77
77
  Math.max(n.currentScale * C, n.minScale),
78
78
  n.maxScale
79
- ), F = o.getBoundingClientRect(), M = x.x - F.left, k = x.y - F.top, Y = n.currentScale, T = {
80
- x: (M - n.currentPosition.x) / Y,
81
- y: (k - n.currentPosition.y) / Y
82
- }, X = x.x - r.current.x, j = x.y - r.current.y, re = {
83
- x: M - T.x * R + X,
84
- y: k - T.y * R + j
79
+ ), L = o.getBoundingClientRect(), E = m.x - L.left, R = m.y - L.top, Y = n.currentScale, k = {
80
+ x: (E - n.currentPosition.x) / Y,
81
+ y: (R - n.currentPosition.y) / Y
82
+ }, X = m.x - r.current.x, j = m.y - r.current.y, re = {
83
+ x: E - k.x * M + X,
84
+ y: R - k.y * M + j
85
85
  };
86
- n.onScaleChange(R, re), i.current = g, r.current = x;
86
+ n.onScaleChange(M, re), i.current = g, r.current = m;
87
87
  }
88
88
  }, a = (s) => {
89
89
  s.touches.length < 2 && (i.current = null, r.current = null);
90
90
  };
91
- return o.addEventListener("touchstart", S, { passive: !1 }), o.addEventListener("touchmove", h, { passive: !1 }), o.addEventListener("touchend", a), () => {
92
- o.removeEventListener("touchstart", S), o.removeEventListener("touchmove", h), o.removeEventListener("touchend", a);
91
+ return o.addEventListener("touchstart", x, { passive: !1 }), o.addEventListener("touchmove", h, { passive: !1 }), o.addEventListener("touchend", a), () => {
92
+ o.removeEventListener("touchstart", x), o.removeEventListener("touchmove", h), o.removeEventListener("touchend", a);
93
93
  };
94
94
  }, [t, n]);
95
95
  }
@@ -103,7 +103,7 @@ const vt = {
103
103
  seatHidden: "#4a4a4a",
104
104
  gridLines: "#404040",
105
105
  currency: "KD"
106
- }, Ne = ne(({ seat: t, state: n, colors: i, onClick: r, onMouseEnter: d, onMouseLeave: c }) => {
106
+ }, Te = ne(({ seat: t, state: n, colors: i, onClick: r, onMouseEnter: d, onMouseLeave: c }) => {
107
107
  const h = {
108
108
  available: i.seatAvailable,
109
109
  reserved: i.seatReserved,
@@ -111,15 +111,15 @@ const vt = {
111
111
  unavailable: i.seatUnavailable,
112
112
  hidden: i.seatHidden
113
113
  // Hidden seats are filtered out, but included for type safety
114
- }[n], a = n === "available" || n === "selected", s = I(() => {
114
+ }[n], a = n === "available" || n === "selected", s = F(() => {
115
115
  a && r(t);
116
- }, [t, r, a]), u = I((x) => {
117
- d(t, x);
118
- const C = x.target.getStage();
116
+ }, [t, r, a]), u = F((m) => {
117
+ d(t, m);
118
+ const C = m.target.getStage();
119
119
  C && a && (C.container().style.cursor = "pointer");
120
- }, [t, d, a]), f = I((x) => {
120
+ }, [t, d, a]), f = F((m) => {
121
121
  c();
122
- const C = x.target.getStage();
122
+ const C = m.target.getStage();
123
123
  C && (C.container().style.cursor = "grab");
124
124
  }, [c]), g = {
125
125
  x: t.position.x,
@@ -139,7 +139,7 @@ const vt = {
139
139
  radius: 12
140
140
  }
141
141
  ) : /* @__PURE__ */ y(
142
- ke,
142
+ Le,
143
143
  {
144
144
  ...g,
145
145
  width: 24,
@@ -150,8 +150,8 @@ const vt = {
150
150
  }
151
151
  );
152
152
  });
153
- Ne.displayName = "ViewerSeat";
154
- const Te = ne(({ stage: t, stageColor: n }) => {
153
+ Te.displayName = "ViewerSeat";
154
+ const ke = ne(({ stage: t, stageColor: n }) => {
155
155
  const i = (c) => ({
156
156
  stage: "🎭",
157
157
  table: "⬜",
@@ -162,9 +162,9 @@ const Te = ne(({ stage: t, stageColor: n }) => {
162
162
  "entry-exit": "🚪",
163
163
  custom: "➕"
164
164
  })[c || "stage"] || "🎭", r = t.config.color || n, d = i(t.config.objectType);
165
- return /* @__PURE__ */ L(ut, { x: t.position.x, y: t.position.y, rotation: t.config.rotation || 0, children: [
165
+ return /* @__PURE__ */ D(ut, { x: t.position.x, y: t.position.y, rotation: t.config.rotation || 0, children: [
166
166
  /* @__PURE__ */ y(
167
- ke,
167
+ Le,
168
168
  {
169
169
  width: t.config.width,
170
170
  height: t.config.height,
@@ -205,7 +205,7 @@ const Te = ne(({ stage: t, stageColor: n }) => {
205
205
  )
206
206
  ] });
207
207
  });
208
- Te.displayName = "ViewerStage";
208
+ ke.displayName = "ViewerStage";
209
209
  const ze = ne(({
210
210
  floors: t,
211
211
  currentFloorId: n,
@@ -215,7 +215,7 @@ const ze = ne(({
215
215
  position: c,
216
216
  className: o
217
217
  }) => {
218
- const S = U(
218
+ const x = U(
219
219
  () => [...t].sort((f, g) => f.order - g.order),
220
220
  [t]
221
221
  ), a = {
@@ -251,7 +251,7 @@ const ze = ne(({
251
251
  backgroundColor: "#3A7DE5",
252
252
  borderColor: "#3A7DE5"
253
253
  };
254
- return /* @__PURE__ */ L("div", { className: o, style: a, children: [
254
+ return /* @__PURE__ */ D("div", { className: o, style: a, children: [
255
255
  r && /* @__PURE__ */ y(
256
256
  "button",
257
257
  {
@@ -261,7 +261,7 @@ const ze = ne(({
261
261
  children: d
262
262
  }
263
263
  ),
264
- S.map((f) => /* @__PURE__ */ y(
264
+ x.map((f) => /* @__PURE__ */ y(
265
265
  "button",
266
266
  {
267
267
  type: "button",
@@ -321,7 +321,7 @@ const Ae = ne(({
321
321
  opacity: 0.4,
322
322
  cursor: "not-allowed"
323
323
  }, u = t < i, f = t > n;
324
- return /* @__PURE__ */ L("div", { className: o, style: h, children: [
324
+ return /* @__PURE__ */ D("div", { className: o, style: h, children: [
325
325
  /* @__PURE__ */ y(
326
326
  "button",
327
327
  {
@@ -356,7 +356,7 @@ const Xe = ne(({
356
356
  state: c
357
357
  }) => {
358
358
  if (!t || !r) return null;
359
- const o = r.seatNumber || (r.rowLabel && r.columnLabel ? `${r.rowLabel}-${r.columnLabel}` : "N/A"), S = {
359
+ const o = r.seatNumber || (r.rowLabel && r.columnLabel ? `${r.rowLabel}-${r.columnLabel}` : "N/A"), x = {
360
360
  position: "fixed",
361
361
  left: `${n + 15}px`,
362
362
  top: `${i + 15}px`,
@@ -385,24 +385,24 @@ const Xe = ne(({
385
385
  textTransform: "capitalize",
386
386
  marginTop: "4px"
387
387
  };
388
- return /* @__PURE__ */ y("div", { style: S, children: /* @__PURE__ */ L("div", { style: h, children: [
389
- r.sectionName && /* @__PURE__ */ L("div", { style: { marginBottom: "4px" }, children: [
388
+ return /* @__PURE__ */ y("div", { style: x, children: /* @__PURE__ */ D("div", { style: h, children: [
389
+ r.sectionName && /* @__PURE__ */ D("div", { style: { marginBottom: "4px" }, children: [
390
390
  /* @__PURE__ */ y("span", { style: a, children: "Section:" }),
391
391
  /* @__PURE__ */ y("span", { style: { ...s, color: "#3b82f6" }, children: r.sectionName })
392
392
  ] }),
393
- /* @__PURE__ */ L("div", { style: { marginBottom: "4px" }, children: [
393
+ /* @__PURE__ */ D("div", { style: { marginBottom: "4px" }, children: [
394
394
  /* @__PURE__ */ y("span", { style: a, children: "Seat:" }),
395
395
  /* @__PURE__ */ y("span", { style: s, children: o })
396
396
  ] }),
397
- r.price !== void 0 && r.price > 0 && c === "available" && /* @__PURE__ */ L("div", { style: { marginBottom: "4px" }, children: [
397
+ r.price !== void 0 && r.price > 0 && c === "available" && /* @__PURE__ */ D("div", { style: { marginBottom: "4px" }, children: [
398
398
  /* @__PURE__ */ y("span", { style: a, children: "Price:" }),
399
- /* @__PURE__ */ L("span", { style: u, children: [
399
+ /* @__PURE__ */ D("span", { style: u, children: [
400
400
  d,
401
401
  " ",
402
402
  r.price.toFixed(2)
403
403
  ] })
404
404
  ] }),
405
- /* @__PURE__ */ L("div", { style: f, children: [
405
+ /* @__PURE__ */ D("div", { style: f, children: [
406
406
  "Status: ",
407
407
  c
408
408
  ] })
@@ -417,22 +417,22 @@ const It = ({
417
417
  reservedSeats: d = [],
418
418
  unavailableSeats: c = [],
419
419
  selectedSeats: o,
420
- myReservedSeats: S = [],
420
+ myReservedSeats: x = [],
421
421
  onSeatSelect: h,
422
422
  onSeatDeselect: a,
423
423
  onSelectionChange: s,
424
424
  colorOverrides: u,
425
425
  showTooltip: f = !0,
426
426
  zoomEnabled: g = !0,
427
- className: x = "",
427
+ className: m = "",
428
428
  onConfigLoad: C,
429
- onError: R,
429
+ onError: M,
430
430
  // Floor selector props
431
- showFloorSelector: F,
432
- floorSelectorPosition: M = "top-left",
433
- floorSelectorClassName: k,
431
+ showFloorSelector: L,
432
+ floorSelectorPosition: E = "top-left",
433
+ floorSelectorClassName: R,
434
434
  showAllFloorsOption: Y = !0,
435
- allFloorsLabel: T = "All",
435
+ allFloorsLabel: k = "All",
436
436
  fitToView: X = !0,
437
437
  fitPadding: j = 40,
438
438
  // Zoom controls
@@ -445,9 +445,9 @@ const It = ({
445
445
  // Touch gestures
446
446
  touchEnabled: Pe = !0
447
447
  }) => {
448
- const he = A(null), we = A(null), E = bt(we), [O, Ce] = N(/* @__PURE__ */ new Set()), [D, G] = N(1), [z, H] = N({ x: 0, y: 0 }), [We, Be] = N(null), [$e, Ue] = N(1), ie = A({ width: 0, height: 0 }), [Z, Re] = N({ visible: !1, x: 0, y: 0, seat: null, state: "available" }), { config: He, loading: Ve, error: K } = pt(n), p = t || He, fe = i !== void 0, P = fe ? i || null : We, se = o !== void 0, Oe = I((e) => {
448
+ const he = A(null), we = A(null), I = bt(we), [O, Ce] = T(/* @__PURE__ */ new Set()), [N, G] = T(1), [z, H] = T({ x: 0, y: 0 }), [We, Be] = T(null), [$e, Ue] = T(1), ie = A({ width: 0, height: 0 }), [Z, Re] = T({ visible: !1, x: 0, y: 0, seat: null, state: "available" }), { config: He, loading: Ve, error: K } = pt(n), p = t || He, fe = i !== void 0, P = fe ? i || null : We, se = o !== void 0, Oe = F((e) => {
449
449
  fe || Be(e), r?.(e);
450
- }, [fe, r]), ge = p?.floors || [], _e = F !== void 0 ? F : ge.length > 1, ae = U(
450
+ }, [fe, r]), ge = p?.floors || [], _e = L !== void 0 ? L : ge.length > 1, ae = U(
451
451
  () => p ? { ...p.colors, ...u } : { ...vt, ...u },
452
452
  [p, u]
453
453
  ), _ = U(() => {
@@ -462,87 +462,87 @@ const It = ({
462
462
  if (!p || _.length === 0 && ce.length === 0)
463
463
  return null;
464
464
  const e = 12;
465
- let l = 1 / 0, b = 1 / 0, v = -1 / 0, m = -1 / 0;
465
+ let l = 1 / 0, b = 1 / 0, v = -1 / 0, S = -1 / 0;
466
466
  return _.forEach((w) => {
467
- l = Math.min(l, w.position.x - e), b = Math.min(b, w.position.y - e), v = Math.max(v, w.position.x + e), m = Math.max(m, w.position.y + e);
467
+ l = Math.min(l, w.position.x - e), b = Math.min(b, w.position.y - e), v = Math.max(v, w.position.x + e), S = Math.max(S, w.position.y + e);
468
468
  }), ce.forEach((w) => {
469
- l = Math.min(l, w.position.x), b = Math.min(b, w.position.y), v = Math.max(v, w.position.x + (w.config?.width || 200)), m = Math.max(m, w.position.y + (w.config?.height || 100));
470
- }), { minX: l, minY: b, maxX: v, maxY: m, width: v - l, height: m - b };
469
+ l = Math.min(l, w.position.x), b = Math.min(b, w.position.y), v = Math.max(v, w.position.x + (w.config?.width || 200)), S = Math.max(S, w.position.y + (w.config?.height || 100));
470
+ }), { minX: l, minY: b, maxX: v, maxY: S, width: v - l, height: S - b };
471
471
  }, [p, _, ce]);
472
472
  W(() => {
473
- if (!X || !p || !$ || E.width === 0 || E.height === 0) return;
474
- const e = Math.abs(E.width - ie.current.width), l = Math.abs(E.height - ie.current.height);
473
+ if (!X || !p || !$ || I.width === 0 || I.height === 0) return;
474
+ const e = Math.abs(I.width - ie.current.width), l = Math.abs(I.height - ie.current.height);
475
475
  if (!(ie.current.width === 0) && e < 10 && l < 10) return;
476
- ie.current = E;
477
- const v = E.width, m = E.height, w = v - j * 2, ee = m - j * 2, le = w / $.width, be = ee / $.height, de = Math.min(le, be, B), rt = $.minX + $.width / 2, ot = $.minY + $.height / 2, it = v / 2, st = m / 2, at = it - rt * de, ct = st - ot * de;
476
+ ie.current = I;
477
+ const v = I.width, S = I.height, w = v - j * 2, ee = S - j * 2, le = w / $.width, be = ee / $.height, de = Math.min(le, be, B), rt = $.minX + $.width / 2, ot = $.minY + $.height / 2, it = v / 2, st = S / 2, at = it - rt * de, ct = st - ot * de;
478
478
  G(de), H({ x: at, y: ct }), Ue(de);
479
- }, [X, p, $, j, B, E, P]);
479
+ }, [X, p, $, j, B, I, P]);
480
480
  const V = U(() => {
481
- const e = new Set(d), l = new Set(c), b = new Set(S);
481
+ const e = new Set(d), l = new Set(c), b = new Set(x);
482
482
  return { reserved: e, unavailable: l, myReserved: b };
483
- }, [d, c, S]), pe = U(() => o ? new Set(o) : null, [o]), J = I((e) => {
483
+ }, [d, c, x]), pe = U(() => o ? new Set(o) : null, [o]), J = F((e) => {
484
484
  const l = e.id, b = e.seatNumber || "";
485
485
  return V.unavailable.has(l) || V.unavailable.has(b) ? "unavailable" : V.reserved.has(l) || V.reserved.has(b) ? "reserved" : V.myReserved.has(l) || V.myReserved.has(b) || O.has(l) ? "selected" : e.state;
486
486
  }, [V, O]);
487
487
  W(() => {
488
488
  p && C && C(p);
489
489
  }, [p, C]), W(() => {
490
- K && R && R(K);
491
- }, [K, R]), W(() => {
490
+ K && M && M(K);
491
+ }, [K, M]), W(() => {
492
492
  se && pe && Ce(pe);
493
493
  }, [se, pe]);
494
- const qe = I((e) => {
494
+ const qe = F((e) => {
495
495
  const l = J(e);
496
496
  if (l !== "available" && l !== "selected")
497
497
  return;
498
498
  const b = O.has(e.id);
499
499
  se || Ce((v) => {
500
- const m = new Set(v);
501
- return b ? m.delete(e.id) : m.add(e.id), m;
500
+ const S = new Set(v);
501
+ return b ? S.delete(e.id) : S.add(e.id), S;
502
502
  }), b ? a?.(e) : (h?.(e), h || console.log("Seat selected:", e));
503
503
  }, [J, O, se, h, a]), Q = U(() => p ? _.filter((e) => O.has(e.id)) : [], [_, O]);
504
504
  W(() => {
505
505
  s?.(Q);
506
506
  }, [Q, s]);
507
- const q = xe !== void 0 ? xe : $e, Ge = I(() => {
507
+ const q = xe !== void 0 ? xe : $e, Ge = F(() => {
508
508
  if (!g) return;
509
- const e = Math.min(D + oe, B);
510
- if (e !== D) {
511
- const l = E.width || p?.canvas.width || 800, b = E.height || p?.canvas.height || 600, v = l / 2, m = b / 2, w = {
512
- x: (v - z.x) / D,
513
- y: (m - z.y) / D
509
+ const e = Math.min(N + oe, B);
510
+ if (e !== N) {
511
+ const l = I.width || p?.canvas.width || 800, b = I.height || p?.canvas.height || 600, v = l / 2, S = b / 2, w = {
512
+ x: (v - z.x) / N,
513
+ y: (S - z.y) / N
514
514
  };
515
515
  G(e), H({
516
516
  x: v - w.x * e,
517
- y: m - w.y * e
517
+ y: S - w.y * e
518
518
  });
519
519
  }
520
- }, [g, D, oe, B, E, p, z]), Ze = I(() => {
520
+ }, [g, N, oe, B, I, p, z]), Ze = F(() => {
521
521
  if (!g) return;
522
- const e = Math.max(D - oe, q);
523
- if (e !== D) {
524
- const l = E.width || p?.canvas.width || 800, b = E.height || p?.canvas.height || 600, v = l / 2, m = b / 2, w = {
525
- x: (v - z.x) / D,
526
- y: (m - z.y) / D
522
+ const e = Math.max(N - oe, q);
523
+ if (e !== N) {
524
+ const l = I.width || p?.canvas.width || 800, b = I.height || p?.canvas.height || 600, v = l / 2, S = b / 2, w = {
525
+ x: (v - z.x) / N,
526
+ y: (S - z.y) / N
527
527
  };
528
528
  G(e), H({
529
529
  x: v - w.x * e,
530
- y: m - w.y * e
530
+ y: S - w.y * e
531
531
  });
532
532
  }
533
- }, [g, D, oe, q, E, p, z]), Ke = I((e) => {
533
+ }, [g, N, oe, q, I, p, z]), Ke = F((e) => {
534
534
  H({
535
535
  x: e.target.x(),
536
536
  y: e.target.y()
537
537
  });
538
- }, []), Je = I((e) => {
538
+ }, []), Je = F((e) => {
539
539
  if (!g) return;
540
540
  e.evt.preventDefault();
541
541
  const l = he.current;
542
542
  if (!l) return;
543
543
  const b = l.scaleX(), v = l.getPointerPosition();
544
544
  if (!v) return;
545
- const m = 1.1, w = e.evt.deltaY > 0 ? b / m : b * m, ee = Math.min(Math.max(w, q), B), le = {
545
+ const S = 1.1, w = e.evt.deltaY > 0 ? b / S : b * S, ee = Math.min(Math.max(w, q), B), le = {
546
546
  x: (v.x - z.x) / b,
547
547
  y: (v.y - z.y) / b
548
548
  }, be = {
@@ -555,7 +555,7 @@ const It = ({
555
555
  enabled: Pe && g,
556
556
  minScale: q,
557
557
  maxScale: B,
558
- currentScale: D,
558
+ currentScale: N,
559
559
  currentPosition: z,
560
560
  onScaleChange: (e, l) => {
561
561
  G(e), H(l);
@@ -564,38 +564,38 @@ const It = ({
564
564
  H(e);
565
565
  }
566
566
  });
567
- const Qe = I((e, l) => {
567
+ const Qe = F((e, l) => {
568
568
  if (!f) return;
569
569
  const b = l.target.getStage();
570
570
  if (!b) return;
571
571
  const v = b.getPointerPosition();
572
572
  if (!v) return;
573
- const m = b.container().getBoundingClientRect();
573
+ const S = b.container().getBoundingClientRect();
574
574
  Re({
575
575
  visible: !0,
576
- x: m.left + v.x,
577
- y: m.top + v.y,
576
+ x: S.left + v.x,
577
+ y: S.top + v.y,
578
578
  seat: e,
579
579
  state: J(e)
580
580
  });
581
- }, [f, J]), et = I(() => {
581
+ }, [f, J]), et = F(() => {
582
582
  Re((e) => ({ ...e, visible: !1 }));
583
583
  }, []);
584
584
  if (Ve)
585
- return /* @__PURE__ */ y("div", { className: `flex items-center justify-center h-full ${x}`, children: /* @__PURE__ */ y("p", { children: "Loading seat map..." }) });
585
+ return /* @__PURE__ */ y("div", { className: `flex items-center justify-center h-full ${m}`, children: /* @__PURE__ */ y("p", { children: "Loading seat map..." }) });
586
586
  if (K)
587
- return /* @__PURE__ */ y("div", { className: `flex items-center justify-center h-full ${x}`, children: /* @__PURE__ */ L("p", { className: "text-red-500", children: [
587
+ return /* @__PURE__ */ y("div", { className: `flex items-center justify-center h-full ${m}`, children: /* @__PURE__ */ D("p", { className: "text-red-500", children: [
588
588
  "Error loading seat map: ",
589
589
  K.message
590
590
  ] }) });
591
591
  if (!p)
592
- return /* @__PURE__ */ y("div", { className: `flex items-center justify-center h-full ${x}`, children: /* @__PURE__ */ y("p", { children: "No configuration provided" }) });
593
- const tt = E.width || p.canvas.width, nt = E.height || p.canvas.height;
594
- return /* @__PURE__ */ L(
592
+ return /* @__PURE__ */ y("div", { className: `flex items-center justify-center h-full ${m}`, children: /* @__PURE__ */ y("p", { children: "No configuration provided" }) });
593
+ const tt = I.width || p.canvas.width, nt = I.height || p.canvas.height;
594
+ return /* @__PURE__ */ D(
595
595
  "div",
596
596
  {
597
597
  ref: we,
598
- className: `relative ${x}`,
598
+ className: `relative ${m}`,
599
599
  style: { width: "100%", height: "100%" },
600
600
  children: [
601
601
  _e && ge.length > 0 && /* @__PURE__ */ y(
@@ -605,19 +605,19 @@ const It = ({
605
605
  currentFloorId: P,
606
606
  onFloorChange: Oe,
607
607
  showAllOption: Y,
608
- allLabel: T,
609
- position: M,
610
- className: k
608
+ allLabel: k,
609
+ position: E,
610
+ className: R
611
611
  }
612
612
  ),
613
- /* @__PURE__ */ L(
613
+ /* @__PURE__ */ D(
614
614
  dt,
615
615
  {
616
616
  ref: he,
617
617
  width: tt,
618
618
  height: nt,
619
- scaleX: D,
620
- scaleY: D,
619
+ scaleX: N,
620
+ scaleY: N,
621
621
  x: z.x,
622
622
  y: z.y,
623
623
  draggable: !0,
@@ -626,7 +626,7 @@ const It = ({
626
626
  style: { backgroundColor: p.canvas.backgroundColor, cursor: "grab" },
627
627
  children: [
628
628
  /* @__PURE__ */ y(Me, { listening: !1, children: ce.map((e) => /* @__PURE__ */ y(
629
- Te,
629
+ ke,
630
630
  {
631
631
  stage: e,
632
632
  stageColor: ae.stageColor
@@ -634,7 +634,7 @@ const It = ({
634
634
  e.id
635
635
  )) }),
636
636
  /* @__PURE__ */ y(Me, { children: _.map((e) => /* @__PURE__ */ y(
637
- Ne,
637
+ Te,
638
638
  {
639
639
  seat: e,
640
640
  state: J(e),
@@ -662,7 +662,7 @@ const It = ({
662
662
  re && g && /* @__PURE__ */ y(
663
663
  Ae,
664
664
  {
665
- scale: D,
665
+ scale: N,
666
666
  minScale: q,
667
667
  maxScale: B,
668
668
  onZoomIn: Ge,
@@ -671,13 +671,13 @@ const It = ({
671
671
  className: je
672
672
  }
673
673
  ),
674
- Q.length > 0 && /* @__PURE__ */ L("div", { className: "absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg", children: [
675
- /* @__PURE__ */ L("h3", { className: "font-semibold mb-2", children: [
674
+ Q.length > 0 && /* @__PURE__ */ D("div", { className: "absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg", children: [
675
+ /* @__PURE__ */ D("h3", { className: "font-semibold mb-2", children: [
676
676
  "Selected Seats (",
677
677
  Q.length,
678
678
  ")"
679
679
  ] }),
680
- /* @__PURE__ */ y("div", { className: "max-h-48 overflow-y-auto space-y-1", children: Q.map((e) => /* @__PURE__ */ L("div", { className: "text-sm", children: [
680
+ /* @__PURE__ */ y("div", { className: "max-h-48 overflow-y-auto space-y-1", children: Q.map((e) => /* @__PURE__ */ D("div", { className: "text-sm", children: [
681
681
  e.seatNumber,
682
682
  e.price && ` - ${ae.currency} ${e.price.toFixed(2)}`
683
683
  ] }, e.id)) })
@@ -700,7 +700,7 @@ function me() {
700
700
  function Se() {
701
701
  return te !== null;
702
702
  }
703
- function kt() {
703
+ function Lt() {
704
704
  te = null;
705
705
  }
706
706
  function ye(t, n) {
@@ -728,45 +728,47 @@ const ue = {
728
728
  unavailableSeats: []
729
729
  };
730
730
  function St(t) {
731
- const { seatMapId: n, currentUserId: i, enabled: r = !0, onStateChange: d, onError: c } = t, o = A({ ...ue }), S = A(d), h = A(c), a = A(i);
732
- S.current = d, h.current = c, a.current = i;
733
- const s = I(
734
- (x) => {
731
+ const { seatMapId: n, currentUserId: i, enabled: r = !0, onStateChange: d, onError: c } = t, o = A({ ...ue }), x = A(d), h = A(c), a = A(i);
732
+ x.current = d, h.current = c, a.current = i;
733
+ const s = F(
734
+ (m) => {
735
735
  if (!r || !n)
736
- return o.current = { ...ue, loading: !1 }, () => {
736
+ return (o.current.loading !== !1 || o.current.states !== null) && (o.current = { ...ue, loading: !1 }, m()), () => {
737
737
  };
738
- if (!Se())
739
- return o.current = {
738
+ if (!Se()) {
739
+ const R = "Firebase not initialized. Call initializeFirebaseForViewer first.";
740
+ return o.current.error?.message !== R && (o.current = {
740
741
  ...ue,
741
742
  loading: !1,
742
- error: new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")
743
- }, () => {
743
+ error: new Error(R)
744
+ }, m()), () => {
744
745
  };
745
- const C = me(), R = ve(C, `seatmaps/${n}/seat_states`);
746
- return Le(R, (k) => {
747
- const T = k.val() || {}, X = mt(T, a.current), j = o.current;
746
+ }
747
+ const C = me(), M = ve(C, `seatmaps/${n}/seat_states`);
748
+ return De(M, (R) => {
749
+ const k = R.val() || {}, X = mt(k, a.current), j = o.current;
748
750
  (j.loading || !ye(j.myReservedSeats, X.myReserved) || !ye(j.otherReservedSeats, X.otherReserved) || !ye(j.unavailableSeats, X.unavailable)) && (o.current = {
749
- states: T,
751
+ states: k,
750
752
  loading: !1,
751
753
  error: null,
752
754
  lastUpdated: Date.now(),
753
755
  myReservedSeats: X.myReserved,
754
756
  otherReservedSeats: X.otherReserved,
755
757
  unavailableSeats: X.unavailable
756
- }, S.current?.(T), x());
757
- }, (k) => {
758
+ }, x.current?.(k), m());
759
+ }, (R) => {
758
760
  o.current = {
759
761
  ...o.current,
760
762
  loading: !1,
761
- error: k
762
- }, h.current?.(k), x();
763
+ error: R
764
+ }, h.current?.(R), m();
763
765
  }), () => {
764
- De(R);
766
+ Ne(M);
765
767
  };
766
768
  },
767
769
  [n, r, i]
768
770
  // Include currentUserId to re-derive on user change
769
- ), u = I(() => o.current, []), f = I(() => ue, []), g = lt(s, u, f);
771
+ ), u = F(() => o.current, []), f = F(() => ue, []), g = lt(s, u, f);
770
772
  return {
771
773
  states: g.states,
772
774
  loading: g.loading,
@@ -786,26 +788,26 @@ function xt(t) {
786
788
  subscribeToChanges: r = !1,
787
789
  onConfigLoad: d,
788
790
  onError: c
789
- } = t, [o, S] = N(null), [h, a] = N(!0), [s, u] = N(null), f = A(d), g = A(c);
791
+ } = t, [o, x] = T(null), [h, a] = T(!0), [s, u] = T(null), f = A(d), g = A(c);
790
792
  f.current = d, g.current = c;
791
- const x = I(async () => {
793
+ const m = F(async () => {
792
794
  if (!n) return;
793
795
  if (!Se()) {
794
796
  u(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")), a(!1);
795
797
  return;
796
798
  }
797
- const C = me(), R = ve(C, `seatmaps/${n}`);
799
+ const C = me(), M = ve(C, `seatmaps/${n}`);
798
800
  try {
799
801
  a(!0), u(null);
800
- const M = (await ft(R)).val();
801
- if (M) {
802
- const k = gt(M);
803
- S(k), f.current?.(k);
802
+ const E = (await ft(M)).val();
803
+ if (E) {
804
+ const R = gt(E);
805
+ x(R), f.current?.(R);
804
806
  } else
805
807
  u(new Error(`Seat map ${n} not found in Firebase`));
806
- } catch (F) {
807
- const M = F instanceof Error ? F : new Error("Unknown error");
808
- u(M), g.current?.(M);
808
+ } catch (L) {
809
+ const E = L instanceof Error ? L : new Error("Unknown error");
810
+ u(E), g.current?.(E);
809
811
  } finally {
810
812
  a(!1);
811
813
  }
@@ -815,28 +817,28 @@ function xt(t) {
815
817
  a(!1);
816
818
  return;
817
819
  }
818
- if (x(), r && Se()) {
819
- const C = me(), R = ve(C, `seatmaps/${n}/meta/updated_at`);
820
- let F = !0, M = null;
821
- return Le(R, (Y) => {
822
- if (F) {
823
- F = !1, M = Y.val();
820
+ if (m(), r && Se()) {
821
+ const C = me(), M = ve(C, `seatmaps/${n}/meta/updated_at`);
822
+ let L = !0, E = null;
823
+ return De(M, (Y) => {
824
+ if (L) {
825
+ L = !1, E = Y.val();
824
826
  return;
825
827
  }
826
- const T = Y.val();
827
- Y.exists() && T !== M && (M = T, x());
828
+ const k = Y.val();
829
+ Y.exists() && k !== E && (E = k, m());
828
830
  }), () => {
829
- De(R);
831
+ Ne(M);
830
832
  };
831
833
  }
832
834
  }, [n, i, r]), {
833
835
  config: o,
834
836
  loading: h,
835
837
  error: s,
836
- refetch: x
838
+ refetch: m
837
839
  };
838
840
  }
839
- function Lt(t) {
841
+ function Dt(t) {
840
842
  const {
841
843
  seatMapId: n,
842
844
  userId: i,
@@ -844,7 +846,7 @@ function Lt(t) {
844
846
  subscribeToDesignChanges: d = !1,
845
847
  onConfigLoad: c,
846
848
  onStateChange: o,
847
- onError: S
849
+ onError: x
848
850
  } = t, {
849
851
  config: h,
850
852
  loading: a,
@@ -855,31 +857,31 @@ function Lt(t) {
855
857
  enabled: r,
856
858
  subscribeToChanges: d,
857
859
  onConfigLoad: c,
858
- onError: S
860
+ onError: x
859
861
  }), {
860
862
  states: f,
861
863
  loading: g,
862
- error: x,
864
+ error: m,
863
865
  lastUpdated: C,
864
- myReservedSeats: R,
865
- otherReservedSeats: F,
866
- unavailableSeats: M,
867
- reservedSeats: k
866
+ myReservedSeats: M,
867
+ otherReservedSeats: L,
868
+ unavailableSeats: E,
869
+ reservedSeats: R
868
870
  } = St({
869
871
  seatMapId: n,
870
872
  currentUserId: i,
871
873
  enabled: r,
872
874
  onStateChange: o,
873
- onError: S
875
+ onError: x
874
876
  });
875
877
  return {
876
878
  config: h,
877
879
  loading: a || g,
878
- error: s || x,
879
- myReservedSeats: R,
880
- otherReservedSeats: F,
881
- unavailableSeats: M,
882
- reservedSeats: k,
880
+ error: s || m,
881
+ myReservedSeats: M,
882
+ otherReservedSeats: L,
883
+ unavailableSeats: E,
884
+ reservedSeats: R,
883
885
  seatStates: f,
884
886
  lastUpdated: C,
885
887
  refetch: u
@@ -888,13 +890,13 @@ function Lt(t) {
888
890
  export {
889
891
  vt as DEFAULT_COLORS,
890
892
  It as SeatMapViewer,
891
- kt as clearFirebaseInstance,
893
+ Lt as clearFirebaseInstance,
892
894
  Ft as initializeFirebaseForViewer,
893
895
  Se as isFirebaseInitialized,
894
896
  pt as useConfigFetcher,
895
897
  bt as useContainerSize,
896
898
  xt as useFirebaseConfig,
897
899
  St as useFirebaseSeatStates,
898
- Lt as useRealtimeSeatMap,
900
+ Dt as useRealtimeSeatMap,
899
901
  yt as useTouchGestures
900
902
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zonetrix/viewer",
3
- "version": "2.10.4",
3
+ "version": "2.10.5",
4
4
  "type": "module",
5
5
  "description": "Lightweight React component for rendering interactive seat maps",
6
6
  "main": "./dist/index.js",