@zonetrix/viewer 2.10.7 → 2.10.8

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"),at=require("@zonetrix/shared");function Ce(n){const[s,a]=t.useState(null),[r,h]=t.useState(!1),[u,o]=t.useState(null),v=async()=>{if(n){h(!0),o(null);try{const f=await fetch(n);if(!f.ok)throw new Error(`Failed to fetch config: ${f.statusText}`);const l=await f.json();a(l)}catch(f){const l=f instanceof Error?f:new Error("Unknown error occurred");o(l),console.error("Failed to fetch seat map config:",l)}finally{h(!1)}}};return t.useEffect(()=>{v()},[n]),{config:s,loading:r,error:u,refetch:v}}function Re(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(v=>{const f=v[0];if(!f)return;const{width:l,height:c}=f.contentRect;l>0&&c>0&&a(g=>g.width===l&&g.height===c?g:{width:l,height:c})});return o.observe(r),()=>{o.disconnect()}},[n]),s}function me(n,s){return Math.sqrt(Math.pow(s.x-n.x,2)+Math.pow(s.y-n.y,2))}function we(n,s){return{x:(n.x+s.x)/2,y:(n.y+s.y)/2}}function je(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(),v=c=>{if(c.touches.length===2){c.preventDefault();const g={x:c.touches[0].clientX,y:c.touches[0].clientY},p={x:c.touches[1].clientX,y:c.touches[1].clientY};a.current=me(g,p),r.current=we(g,p),h.current=s.currentScale}},f=c=>{if(c.touches.length!==2)return;c.preventDefault();const g={x:c.touches[0].clientX,y:c.touches[0].clientY},p={x:c.touches[1].clientX,y:c.touches[1].clientY},m=me(g,p),x=we(g,p);if(a.current!==null&&r.current!==null){const R=m/a.current,E=Math.min(Math.max(s.currentScale*R,s.minScale),s.maxScale),F=o.getBoundingClientRect(),j=x.x-F.left,M=x.y-F.top,D=s.currentScale,L={x:(j-s.currentPosition.x)/D,y:(M-s.currentPosition.y)/D},z=x.x-r.current.x,A=x.y-r.current.y,$={x:j-L.x*E+z,y:M-L.y*E+A};s.onScaleChange(E,$),a.current=m,r.current=x}},l=c=>{c.touches.length<2&&(a.current=null,r.current=null)};return o.addEventListener("touchstart",v,{passive:!1}),o.addEventListener("touchmove",f,{passive:!1}),o.addEventListener("touchend",l),()=>{o.removeEventListener("touchstart",v),o.removeEventListener("touchmove",f),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:a,onClick:r,onMouseEnter:h,onMouseLeave:u})=>{const f={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]),g=t.useCallback(x=>{h(n,x);const R=x.target.getStage();R&&l&&(R.container().style.cursor="pointer")},[n,h,l]),p=t.useCallback(x=>{u();const R=x.target.getStage();R&&(R.container().style.cursor="grab")},[u]),m={x:n.position.x,y:n.position.y,fill:f,stroke:"#ffffff",strokeWidth:1,onClick:c,onTap:c,onMouseEnter:g,onMouseLeave:p};return n.shape==="circle"?i.jsx(X.Circle,{...m,radius:12}):i.jsx(X.Rect,{...m,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 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"})]})});Fe.displayName="ViewerStage";const ke=t.memo(({floors:n,currentFloorId:s,onFloorChange:a,showAllOption:r,allLabel:h,position:u,className:o})=>{const v=t.useMemo(()=>[...n].sort((p,m)=>p.order-m.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"},g={...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?g:c,children:h}),v.map(p=>i.jsx("button",{type:"button",onClick:()=>a(p.id),style:s===p.id?g:c,children:p.name},p.id))]})});ke.displayName="FloorSelectorBar";const Ie=t.memo(({scale:n,minScale:s,maxScale:a,onZoomIn:r,onZoomOut:h,position:u,className:o})=>{const f={position:"absolute",display:"flex",flexDirection:"column",gap:"4px",padding:"8px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[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"},g=n<a,p=n>s;return i.jsxs("div",{className:o,style:f,children:[i.jsx("button",{type:"button",onClick:r,disabled:!g,style:g?l:c,title:"Zoom In",children:"+"}),i.jsx("button",{type:"button",onClick:h,disabled:!p,style:p?l:c,title:"Zoom Out",children:"−"})]})});Ie.displayName="ZoomControls";const Le=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"),v={position:"fixed",left:`${s+15}px`,top:`${a+15}px`,zIndex:1e3,pointerEvents:"none"},f={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},g={color:"#4ade80",fontWeight:600},p={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return i.jsx("div",{style:v,children:i.jsxs("div",{style:f,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:g,children:[h," ",r.price.toFixed(2)]})]}),i.jsxs("div",{style:p,children:["Status: ",u]})]})})});Le.displayName="SeatTooltip";const ct=({config:n,configUrl:s,floorId:a,onFloorChange:r,reservedSeats:h=[],otherReservedSeats:u,unavailableSeats:o=[],selectedSeats:v,myReservedSeats:f=[],onSeatSelect:l,onSeatDeselect:c,onSelectionChange:g,colorOverrides:p,showTooltip:m=!0,zoomEnabled:x=!0,className:R="",onConfigLoad:E,onError:F,showFloorSelector:j,floorSelectorPosition:M="top-left",floorSelectorClassName:D,showAllFloorsOption:L=!0,allFloorsLabel:z="All",fitToView:A=!0,fitPadding:$=40,showZoomControls:ze=!0,zoomControlsPosition:Ne="bottom-right",zoomControlsClassName:Ae,minZoom:be,maxZoom:Y=3,zoomStep:ee=.25,touchEnabled:Xe=!0})=>{const te=u!==void 0?u:h;console.log("🔍 ZonetrixViewer received props:",{reservedSeats:h,otherReservedSeats:u,effectiveOtherReservedSeats:te,myReservedSeats:f,unavailableSeats:o});const ue=t.useRef(null),Se=t.useRef(null),k=Re(Se),[U,ye]=t.useState(new Set),[I,q]=t.useState(1),[T,B]=t.useState({x:0,y:0}),[Ye,Pe]=t.useState(null),[We,Be]=t.useState(1),ne=t.useRef({width:0,height:0}),[_,ve]=t.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Oe,loading:$e,error:G}=Ce(s),b=n||Oe,de=a!==void 0,N=de?a||null:Ye,se=v!==void 0,Ue=t.useCallback(e=>{de||Pe(e),r?.(e)},[de,r]),he=b?.floors||[],Ve=j!==void 0?j:he.length>1,re=t.useMemo(()=>b?{...b.colors,...p}:{...Me,...p},[b,p]),V=t.useMemo(()=>{if(!b)return[];let e=b.seats.filter(d=>d.state!=="hidden");return N&&(e=e.filter(d=>d.floorId===N||!d.floorId&&N==="floor_default")),e},[b,N]),oe=t.useMemo(()=>b?.stages?N?b.stages.filter(e=>e.floorId===N||!e.floorId&&N==="floor_default"):b.stages:[],[b,N]),P=t.useMemo(()=>{if(!b||V.length===0&&oe.length===0)return null;const e=12;let d=1/0,S=1/0,y=-1/0,w=-1/0;return V.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),w=Math.max(w,C.position.y+e)}),oe.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)),w=Math.max(w,C.position.y+(C.config?.height||100))}),{minX:d,minY:S,maxX:y,maxY:w,width:y-d,height:w-S}},[b,V,oe]);t.useEffect(()=>{if(!A||!b||!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,w=k.height,C=y-$*2,J=w-$*2,ie=C/P.width,ge=J/P.height,ae=Math.min(ie,ge,Y),tt=P.minX+P.width/2,nt=P.minY+P.height/2,st=y/2,rt=w/2,ot=st-tt*ae,it=rt-nt*ae;q(ae),B({x:ot,y:it}),Be(ae)},[A,b,P,$,Y,k,N]);const O=t.useMemo(()=>{console.log("🔍 Creating seatStateOverrides:",{effectiveOtherReservedSeats:te,myReservedSeats:f,unavailableSeats:o});const e=new Set(te),d=new Set(o),S=new Set(f);return{reserved:e,unavailable:d,myReserved:S}},[te,o,f]),fe=t.useMemo(()=>v?new Set(v):null,[v]),Z=t.useCallback(e=>{const d=e.id,S=e.seatNumber||"";return O.unavailable.has(d)||O.unavailable.has(S)?"unavailable":O.reserved.has(d)||O.reserved.has(S)?"reserved":O.myReserved.has(d)||O.myReserved.has(S)||U.has(d)?"selected":e.state},[O,U]);t.useEffect(()=>{b&&E&&E(b)},[b,E]),t.useEffect(()=>{G&&F&&F(G)},[G,F]),t.useEffect(()=>{se&&fe&&ye(fe)},[se,fe]);const He=t.useCallback(e=>{const d=Z(e);if(d!=="available"&&d!=="selected")return;const S=U.has(e.id);se||ye(y=>{const w=new Set(y);return S?w.delete(e.id):w.add(e.id),w}),S?c?.(e):(l?.(e),l||console.log("Seat selected:",e))},[Z,U,se,l,c]),K=t.useMemo(()=>b?V.filter(e=>U.has(e.id)):[],[V,U]);t.useEffect(()=>{g?.(K)},[K,g]);const H=be!==void 0?be:We,qe=t.useCallback(()=>{if(!x)return;const e=Math.min(I+ee,Y);if(e!==I){const d=k.width||b?.canvas.width||800,S=k.height||b?.canvas.height||600,y=d/2,w=S/2,C={x:(y-T.x)/I,y:(w-T.y)/I};q(e),B({x:y-C.x*e,y:w-C.y*e})}},[x,I,ee,Y,k,b,T]),_e=t.useCallback(()=>{if(!x)return;const e=Math.max(I-ee,H);if(e!==I){const d=k.width||b?.canvas.width||800,S=k.height||b?.canvas.height||600,y=d/2,w=S/2,C={x:(y-T.x)/I,y:(w-T.y)/I};q(e),B({x:y-C.x*e,y:w-C.y*e})}},[x,I,ee,H,k,b,T]),Ge=t.useCallback(e=>{B({x:e.target.x(),y:e.target.y()})},[]),Ze=t.useCallback(e=>{if(!x)return;e.evt.preventDefault();const d=ue.current;if(!d)return;const S=d.scaleX(),y=d.getPointerPosition();if(!y)return;const w=1.1,C=e.evt.deltaY>0?S/w:S*w,J=Math.min(Math.max(C,H),Y),ie={x:(y.x-T.x)/S,y:(y.y-T.y)/S},ge={x:y.x-ie.x*J,y:y.y-ie.y*J};q(J),B(ge)},[x,T,H,Y]);je(ue,{enabled:Xe&&x,minScale:H,maxScale:Y,currentScale:I,currentPosition:T,onScaleChange:(e,d)=>{q(e),B(d)},onPositionChange:e=>{B(e)}});const Ke=t.useCallback((e,d)=>{if(!m)return;const S=d.target.getStage();if(!S)return;const y=S.getPointerPosition();if(!y)return;const w=S.container().getBoundingClientRect();ve({visible:!0,x:w.left+y.x,y:w.top+y.y,seat:e,state:Z(e)})},[m,Z]),Je=t.useCallback(()=>{ve(e=>({...e,visible:!1}))},[]);if($e)return i.jsx("div",{className:`flex items-center justify-center h-full ${R}`,children:i.jsx("p",{children:"Loading seat map..."})});if(G)return i.jsx("div",{className:`flex items-center justify-center h-full ${R}`,children:i.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",G.message]})});if(!b)return i.jsx("div",{className:`flex items-center justify-center h-full ${R}`,children:i.jsx("p",{children:"No configuration provided"})});const Qe=k.width||b.canvas.width,et=k.height||b.canvas.height;return i.jsxs("div",{ref:Se,className:`relative ${R}`,style:{width:"100%",height:"100%"},children:[Ve&&he.length>0&&i.jsx(ke,{floors:he,currentFloorId:N,onFloorChange:Ue,showAllOption:L,allLabel:z,position:M,className:D}),i.jsxs(X.Stage,{ref:ue,width:Qe,height:et,scaleX:I,scaleY:I,x:T.x,y:T.y,draggable:!0,onDragEnd:Ge,onWheel:Ze,style:{backgroundColor:b.canvas.backgroundColor,cursor:"grab"},children:[i.jsx(X.Layer,{listening:!1,children:oe.map(e=>i.jsx(Fe,{stage:e,stageColor:re.stageColor},e.id))}),i.jsx(X.Layer,{children:V.map(e=>i.jsx(Ee,{seat:e,state:Z(e),colors:re,onClick:He,onMouseEnter:Ke,onMouseLeave:Je},e.id))})]}),m&&i.jsx(Le,{visible:_.visible,x:_.x,y:_.y,seat:_.seat,currency:re.currency,state:_.state}),ze&&x&&i.jsx(Ie,{scale:I,minScale:H,maxScale:Y,onZoomIn:qe,onZoomOut:_e,position:Ne,className:Ae}),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&&` - ${re.currency} ${e.price.toFixed(2)}`]},e.id))})]})]})};let Q=null;function lt(n){Q=n}function xe(){if(!Q)throw new Error("Firebase database not initialized. Call initializeFirebaseForViewer(db) first.");return Q}function le(){return Q!==null}function ut(){Q=null}function pe(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 dt(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 ce={states:null,loading:!0,error:null,lastUpdated:null,myReservedSeats:[],otherReservedSeats:[],unavailableSeats:[]};function Te(n){const{seatMapId:s,currentUserId:a,enabled:r=!0,onStateChange:h,onError:u}=n,o=t.useRef({...ce}),v=t.useRef(h),f=t.useRef(u),l=t.useRef(a);v.current=h,f.current=u,l.current=a;const c=t.useCallback(x=>{if(!r||!s)return(o.current.loading!==!1||o.current.states!==null)&&(o.current={...ce,loading:!1},x()),()=>{};if(!le()){const M="Firebase not initialized. Call initializeFirebaseForViewer first.";return o.current.error?.message!==M&&(o.current={...ce,loading:!1,error:new Error(M)},x()),()=>{}}const R=xe(),E=W.ref(R,`seatmaps/${s}/seat_states`),F=M=>{const L=M.val()||{},z=dt(L,l.current),A=o.current;(A.loading||!pe(A.myReservedSeats,z.myReserved)||!pe(A.otherReservedSeats,z.otherReserved)||!pe(A.unavailableSeats,z.unavailable))&&(o.current={states:L,loading:!1,error:null,lastUpdated:Date.now(),myReservedSeats:z.myReserved,otherReservedSeats:z.otherReserved,unavailableSeats:z.unavailable},v.current?.(L),x())},j=M=>{o.current={...o.current,loading:!1,error:M},f.current?.(M),x()};return W.onValue(E,F,j),()=>{W.off(E)}},[s,r]),g=t.useCallback(()=>o.current,[]),p=t.useCallback(()=>ce,[]),m=t.useSyncExternalStore(c,g,p);return{states:m.states,loading:m.loading,error:m.error,lastUpdated:m.lastUpdated,myReservedSeats:m.myReservedSeats,otherReservedSeats:m.otherReservedSeats,unavailableSeats:m.unavailableSeats,reservedSeats:m.otherReservedSeats}}function De(n){const{seatMapId:s,enabled:a=!0,subscribeToChanges:r=!1,onConfigLoad:h,onError:u}=n,[o,v]=t.useState(null),[f,l]=t.useState(!0),[c,g]=t.useState(null),p=t.useRef(h),m=t.useRef(u);p.current=h,m.current=u;const x=t.useCallback(async()=>{if(!s)return;if(!le()){g(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")),l(!1);return}const R=xe(),E=W.ref(R,`seatmaps/${s}`);try{l(!0),g(null);const j=(await W.get(E)).val();if(j){const M=at.fromFirebaseSeatMap(j);v(M),p.current?.(M)}else g(new Error(`Seat map ${s} not found in Firebase`))}catch(F){const j=F instanceof Error?F:new Error("Unknown error");g(j),m.current?.(j)}finally{l(!1)}},[s]);return t.useEffect(()=>{if(!a||!s){l(!1);return}if(x(),r&&le()){const R=xe(),E=W.ref(R,`seatmaps/${s}/meta/updated_at`);let F=!0,j=null;const M=D=>{if(F){F=!1,j=D.val();return}const L=D.val();D.exists()&&L!==j&&(j=L,x())};return W.onValue(E,M),()=>{W.off(E)}}},[s,a,r]),{config:o,loading:f,error:c,refetch:x}}function ht(n){const{seatMapId:s,userId:a,enabled:r=!0,subscribeToDesignChanges:h=!1,onConfigLoad:u,onStateChange:o,onError:v}=n,{config:f,loading:l,error:c,refetch:g}=De({seatMapId:s,enabled:r,subscribeToChanges:h,onConfigLoad:u,onError:v}),{states:p,loading:m,error:x,lastUpdated:R,myReservedSeats:E,otherReservedSeats:F,unavailableSeats:j,reservedSeats:M}=Te({seatMapId:s,currentUserId:a,enabled:r,onStateChange:o,onError:v});return{config:f,loading:l||m,error:c||x,myReservedSeats:E,otherReservedSeats:F,unavailableSeats:j,reservedSeats:M,seatStates:p,lastUpdated:R,refetch:g}}exports.DEFAULT_COLORS=Me;exports.SeatMapViewer=ct;exports.clearFirebaseInstance=ut;exports.initializeFirebaseForViewer=lt;exports.isFirebaseInitialized=le;exports.useConfigFetcher=Ce;exports.useContainerSize=Re;exports.useFirebaseConfig=De;exports.useFirebaseSeatStates=Te;exports.useRealtimeSeatMap=ht;exports.useTouchGestures=je;
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"),at=require("@zonetrix/shared");function Ce(n){const[s,a]=t.useState(null),[r,h]=t.useState(!1),[u,o]=t.useState(null),y=async()=>{if(n){h(!0),o(null);try{const b=await fetch(n);if(!b.ok)throw new Error(`Failed to fetch config: ${b.statusText}`);const l=await b.json();a(l)}catch(b){const l=b instanceof Error?b:new Error("Unknown error occurred");o(l),console.error("Failed to fetch seat map config:",l)}finally{h(!1)}}};return t.useEffect(()=>{y()},[n]),{config:s,loading:r,error:u,refetch:y}}function Re(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(y=>{const b=y[0];if(!b)return;const{width:l,height:c}=b.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 me(n,s){return Math.sqrt(Math.pow(s.x-n.x,2)+Math.pow(s.y-n.y,2))}function we(n,s){return{x:(n.x+s.x)/2,y:(n.y+s.y)/2}}function je(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(),y=c=>{if(c.touches.length===2){c.preventDefault();const f={x:c.touches[0].clientX,y:c.touches[0].clientY},g={x:c.touches[1].clientX,y:c.touches[1].clientY};a.current=me(f,g),r.current=we(f,g),h.current=s.currentScale}},b=c=>{if(c.touches.length!==2)return;c.preventDefault();const f={x:c.touches[0].clientX,y:c.touches[0].clientY},g={x:c.touches[1].clientX,y:c.touches[1].clientY},m=me(f,g),p=we(f,g);if(a.current!==null&&r.current!==null){const R=m/a.current,E=Math.min(Math.max(s.currentScale*R,s.minScale),s.maxScale),F=o.getBoundingClientRect(),j=p.x-F.left,M=p.y-F.top,D=s.currentScale,L={x:(j-s.currentPosition.x)/D,y:(M-s.currentPosition.y)/D},z=p.x-r.current.x,A=p.y-r.current.y,O={x:j-L.x*E+z,y:M-L.y*E+A};s.onScaleChange(E,O),a.current=m,r.current=p}},l=c=>{c.touches.length<2&&(a.current=null,r.current=null)};return o.addEventListener("touchstart",y,{passive:!1}),o.addEventListener("touchmove",b,{passive:!1}),o.addEventListener("touchend",l),()=>{o.removeEventListener("touchstart",y),o.removeEventListener("touchmove",b),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:a,onClick:r,onMouseEnter:h,onMouseLeave:u})=>{const b={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(p=>{h(n,p);const R=p.target.getStage();R&&l&&(R.container().style.cursor="pointer")},[n,h,l]),g=t.useCallback(p=>{u();const R=p.target.getStage();R&&(R.container().style.cursor="grab")},[u]),m={x:n.position.x,y:n.position.y,fill:b,stroke:"#ffffff",strokeWidth:1,onClick:c,onTap:c,onMouseEnter:f,onMouseLeave:g};return n.shape==="circle"?i.jsx(X.Circle,{...m,radius:12}):i.jsx(X.Rect,{...m,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 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"})]})});Fe.displayName="ViewerStage";const ke=t.memo(({floors:n,currentFloorId:s,onFloorChange:a,showAllOption:r,allLabel:h,position:u,className:o})=>{const y=t.useMemo(()=>[...n].sort((g,m)=>g.order-m.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}),y.map(g=>i.jsx("button",{type:"button",onClick:()=>a(g.id),style:s===g.id?f:c,children:g.name},g.id))]})});ke.displayName="FloorSelectorBar";const Ie=t.memo(({scale:n,minScale:s,maxScale:a,onZoomIn:r,onZoomOut:h,position:u,className:o})=>{const b={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,g=n>s;return i.jsxs("div",{className:o,style:b,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:!g,style:g?l:c,title:"Zoom Out",children:"−"})]})});Ie.displayName="ZoomControls";const Le=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"),y={position:"fixed",left:`${s+15}px`,top:`${a+15}px`,zIndex:1e3,pointerEvents:"none"},b={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},g={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return i.jsx("div",{style:y,children:i.jsxs("div",{style:b,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:g,children:["Status: ",u]})]})})});Le.displayName="SeatTooltip";const ct=({config:n,configUrl:s,floorId:a,onFloorChange:r,reservedSeats:h=[],otherReservedSeats:u,unavailableSeats:o=[],selectedSeats:y,myReservedSeats:b=[],onSeatSelect:l,onSeatDeselect:c,onSelectionChange:f,colorOverrides:g,showTooltip:m=!0,zoomEnabled:p=!0,className:R="",onConfigLoad:E,onError:F,showFloorSelector:j,floorSelectorPosition:M="top-left",floorSelectorClassName:D,showAllFloorsOption:L=!0,allFloorsLabel:z="All",fitToView:A=!0,fitPadding:O=40,showZoomControls:ze=!0,zoomControlsPosition:Ne="bottom-right",zoomControlsClassName:Ae,minZoom:be,maxZoom:Y=3,zoomStep:ee=.25,touchEnabled:Xe=!0})=>{const xe=u!==void 0?u:h,le=t.useRef(null),Se=t.useRef(null),k=Re(Se),[U,ve]=t.useState(new Set),[I,q]=t.useState(1),[T,B]=t.useState({x:0,y:0}),[Ye,Pe]=t.useState(null),[We,Be]=t.useState(1),te=t.useRef({width:0,height:0}),[_,ye]=t.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:$e,loading:Oe,error:G}=Ce(s),x=n||$e,ue=a!==void 0,N=ue?a||null:Ye,ne=y!==void 0,Ue=t.useCallback(e=>{ue||Pe(e),r?.(e)},[ue,r]),de=x?.floors||[],Ve=j!==void 0?j:de.length>1,se=t.useMemo(()=>x?{...x.colors,...g}:{...Me,...g},[x,g]),V=t.useMemo(()=>{if(!x)return[];let e=x.seats.filter(d=>d.state!=="hidden");return N&&(e=e.filter(d=>d.floorId===N||!d.floorId&&N==="floor_default")),e},[x,N]),re=t.useMemo(()=>x?.stages?N?x.stages.filter(e=>e.floorId===N||!e.floorId&&N==="floor_default"):x.stages:[],[x,N]),P=t.useMemo(()=>{if(!x||V.length===0&&re.length===0)return null;const e=12;let d=1/0,S=1/0,v=-1/0,w=-1/0;return V.forEach(C=>{d=Math.min(d,C.position.x-e),S=Math.min(S,C.position.y-e),v=Math.max(v,C.position.x+e),w=Math.max(w,C.position.y+e)}),re.forEach(C=>{d=Math.min(d,C.position.x),S=Math.min(S,C.position.y),v=Math.max(v,C.position.x+(C.config?.width||200)),w=Math.max(w,C.position.y+(C.config?.height||100))}),{minX:d,minY:S,maxX:v,maxY:w,width:v-d,height:w-S}},[x,V,re]);t.useEffect(()=>{if(!A||!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 v=k.width,w=k.height,C=v-O*2,J=w-O*2,oe=C/P.width,fe=J/P.height,ie=Math.min(oe,fe,Y),tt=P.minX+P.width/2,nt=P.minY+P.height/2,st=v/2,rt=w/2,ot=st-tt*ie,it=rt-nt*ie;q(ie),B({x:ot,y:it}),Be(ie)},[A,x,P,O,Y,k,N]);const $=t.useMemo(()=>{const e=new Set(xe),d=new Set(o),S=new Set(b);return{reserved:e,unavailable:d,myReserved:S}},[xe,o,b]),he=t.useMemo(()=>y?new Set(y):null,[y]),K=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&&E&&E(x)},[x,E]),t.useEffect(()=>{G&&F&&F(G)},[G,F]),t.useEffect(()=>{ne&&he&&ve(he)},[ne,he]);const He=t.useCallback(e=>{const d=K(e);if(d!=="available"&&d!=="selected")return;const S=U.has(e.id);ne||ve(v=>{const w=new Set(v);return S?w.delete(e.id):w.add(e.id),w}),S?c?.(e):(l?.(e),l||console.log("Seat selected:",e))},[K,U,ne,l,c]),Z=t.useMemo(()=>x?V.filter(e=>U.has(e.id)):[],[V,U]);t.useEffect(()=>{f?.(Z)},[Z,f]);const H=be!==void 0?be:We,qe=t.useCallback(()=>{if(!p)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,v=d/2,w=S/2,C={x:(v-T.x)/I,y:(w-T.y)/I};q(e),B({x:v-C.x*e,y:w-C.y*e})}},[p,I,ee,Y,k,x,T]),_e=t.useCallback(()=>{if(!p)return;const e=Math.max(I-ee,H);if(e!==I){const d=k.width||x?.canvas.width||800,S=k.height||x?.canvas.height||600,v=d/2,w=S/2,C={x:(v-T.x)/I,y:(w-T.y)/I};q(e),B({x:v-C.x*e,y:w-C.y*e})}},[p,I,ee,H,k,x,T]),Ge=t.useCallback(e=>{B({x:e.target.x(),y:e.target.y()})},[]),Ke=t.useCallback(e=>{if(!p)return;e.evt.preventDefault();const d=le.current;if(!d)return;const S=d.scaleX(),v=d.getPointerPosition();if(!v)return;const w=1.1,C=e.evt.deltaY>0?S/w:S*w,J=Math.min(Math.max(C,H),Y),oe={x:(v.x-T.x)/S,y:(v.y-T.y)/S},fe={x:v.x-oe.x*J,y:v.y-oe.y*J};q(J),B(fe)},[p,T,H,Y]);je(le,{enabled:Xe&&p,minScale:H,maxScale:Y,currentScale:I,currentPosition:T,onScaleChange:(e,d)=>{q(e),B(d)},onPositionChange:e=>{B(e)}});const Ze=t.useCallback((e,d)=>{if(!m)return;const S=d.target.getStage();if(!S)return;const v=S.getPointerPosition();if(!v)return;const w=S.container().getBoundingClientRect();ye({visible:!0,x:w.left+v.x,y:w.top+v.y,seat:e,state:K(e)})},[m,K]),Je=t.useCallback(()=>{ye(e=>({...e,visible:!1}))},[]);if(Oe)return i.jsx("div",{className:`flex items-center justify-center h-full ${R}`,children:i.jsx("p",{children:"Loading seat map..."})});if(G)return i.jsx("div",{className:`flex items-center justify-center h-full ${R}`,children:i.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",G.message]})});if(!x)return i.jsx("div",{className:`flex items-center justify-center h-full ${R}`,children:i.jsx("p",{children:"No configuration provided"})});const Qe=k.width||x.canvas.width,et=k.height||x.canvas.height;return i.jsxs("div",{ref:Se,className:`relative ${R}`,style:{width:"100%",height:"100%"},children:[Ve&&de.length>0&&i.jsx(ke,{floors:de,currentFloorId:N,onFloorChange:Ue,showAllOption:L,allLabel:z,position:M,className:D}),i.jsxs(X.Stage,{ref:le,width:Qe,height:et,scaleX:I,scaleY:I,x:T.x,y:T.y,draggable:!0,onDragEnd:Ge,onWheel:Ke,style:{backgroundColor:x.canvas.backgroundColor,cursor:"grab"},children:[i.jsx(X.Layer,{listening:!1,children:re.map(e=>i.jsx(Fe,{stage:e,stageColor:se.stageColor},e.id))}),i.jsx(X.Layer,{children:V.map(e=>i.jsx(Ee,{seat:e,state:K(e),colors:se,onClick:He,onMouseEnter:Ze,onMouseLeave:Je},e.id))})]}),m&&i.jsx(Le,{visible:_.visible,x:_.x,y:_.y,seat:_.seat,currency:se.currency,state:_.state}),ze&&p&&i.jsx(Ie,{scale:I,minScale:H,maxScale:Y,onZoomIn:qe,onZoomOut:_e,position:Ne,className:Ae}),Z.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 (",Z.length,")"]}),i.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:Z.map(e=>i.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${se.currency} ${e.price.toFixed(2)}`]},e.id))})]})]})};let Q=null;function lt(n){Q=n}function pe(){if(!Q)throw new Error("Firebase database not initialized. Call initializeFirebaseForViewer(db) first.");return Q}function ce(){return Q!==null}function ut(){Q=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 dt(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 Te(n){const{seatMapId:s,currentUserId:a,enabled:r=!0,onStateChange:h,onError:u}=n,o=t.useRef({...ae}),y=t.useRef(h),b=t.useRef(u),l=t.useRef(a);y.current=h,b.current=u,l.current=a;const c=t.useCallback(p=>{if(!r||!s)return(o.current.loading!==!1||o.current.states!==null)&&(o.current={...ae,loading:!1},p()),()=>{};if(!ce()){const M="Firebase not initialized. Call initializeFirebaseForViewer first.";return o.current.error?.message!==M&&(o.current={...ae,loading:!1,error:new Error(M)},p()),()=>{}}const R=pe(),E=W.ref(R,`seatmaps/${s}/seat_states`),F=M=>{const L=M.val()||{},z=dt(L,l.current),A=o.current;(A.loading||!ge(A.myReservedSeats,z.myReserved)||!ge(A.otherReservedSeats,z.otherReserved)||!ge(A.unavailableSeats,z.unavailable))&&(o.current={states:L,loading:!1,error:null,lastUpdated:Date.now(),myReservedSeats:z.myReserved,otherReservedSeats:z.otherReserved,unavailableSeats:z.unavailable},y.current?.(L),p())},j=M=>{o.current={...o.current,loading:!1,error:M},b.current?.(M),p()};return W.onValue(E,F,j),()=>{W.off(E)}},[s,r]),f=t.useCallback(()=>o.current,[]),g=t.useCallback(()=>ae,[]),m=t.useSyncExternalStore(c,f,g);return{states:m.states,loading:m.loading,error:m.error,lastUpdated:m.lastUpdated,myReservedSeats:m.myReservedSeats,otherReservedSeats:m.otherReservedSeats,unavailableSeats:m.unavailableSeats,reservedSeats:m.otherReservedSeats}}function De(n){const{seatMapId:s,enabled:a=!0,subscribeToChanges:r=!1,onConfigLoad:h,onError:u}=n,[o,y]=t.useState(null),[b,l]=t.useState(!0),[c,f]=t.useState(null),g=t.useRef(h),m=t.useRef(u);g.current=h,m.current=u;const p=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 j=(await W.get(E)).val();if(j){const M=at.fromFirebaseSeatMap(j);y(M),g.current?.(M)}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),m.current?.(j)}finally{l(!1)}},[s]);return t.useEffect(()=>{if(!a||!s){l(!1);return}if(p(),r&&ce()){const R=pe(),E=W.ref(R,`seatmaps/${s}/meta/updated_at`);let F=!0,j=null;const M=D=>{if(F){F=!1,j=D.val();return}const L=D.val();D.exists()&&L!==j&&(j=L,p())};return W.onValue(E,M),()=>{W.off(E)}}},[s,a,r]),{config:o,loading:b,error:c,refetch:p}}function ht(n){const{seatMapId:s,userId:a,enabled:r=!0,subscribeToDesignChanges:h=!1,onConfigLoad:u,onStateChange:o,onError:y}=n,{config:b,loading:l,error:c,refetch:f}=De({seatMapId:s,enabled:r,subscribeToChanges:h,onConfigLoad:u,onError:y}),{states:g,loading:m,error:p,lastUpdated:R,myReservedSeats:E,otherReservedSeats:F,unavailableSeats:j,reservedSeats:M}=Te({seatMapId:s,currentUserId:a,enabled:r,onStateChange:o,onError:y});return{config:b,loading:l||m,error:c||p,myReservedSeats:E,otherReservedSeats:F,unavailableSeats:j,reservedSeats:M,seatStates:g,lastUpdated:R,refetch:f}}exports.DEFAULT_COLORS=Me;exports.SeatMapViewer=ct;exports.clearFirebaseInstance=ut;exports.initializeFirebaseForViewer=lt;exports.isFirebaseInitialized=ce;exports.useConfigFetcher=Ce;exports.useContainerSize=Re;exports.useFirebaseConfig=De;exports.useFirebaseSeatStates=Te;exports.useRealtimeSeatMap=ht;exports.useTouchGestures=je;
package/dist/index.mjs CHANGED
@@ -1,20 +1,20 @@
1
- import { jsx as v, jsxs as D } from "react/jsx-runtime";
1
+ import { jsx as b, jsxs as D } from "react/jsx-runtime";
2
2
  import { useState as T, useEffect as W, useRef as A, useCallback as L, useMemo as U, memo as re, useSyncExternalStore as ut } from "react";
3
3
  import { Stage as ht, Layer as Ee, Group as ft, Rect as De, Text as Ie, Circle as gt } from "react-konva";
4
- import { ref as me, onValue as Ne, off as Te, get as pt } from "firebase/database";
5
- import { fromFirebaseSeatMap as bt } from "@zonetrix/shared";
6
- function vt(t) {
4
+ import { ref as ye, onValue as Ne, off as Te, get as pt } from "firebase/database";
5
+ import { fromFirebaseSeatMap as vt } from "@zonetrix/shared";
6
+ function bt(t) {
7
7
  const [n, i] = T(null), [r, d] = T(!1), [c, o] = T(null), m = async () => {
8
8
  if (t) {
9
9
  d(!0), o(null);
10
10
  try {
11
- const u = await fetch(t);
12
- if (!u.ok)
13
- throw new Error(`Failed to fetch config: ${u.statusText}`);
14
- const a = await u.json();
11
+ const g = await fetch(t);
12
+ if (!g.ok)
13
+ throw new Error(`Failed to fetch config: ${g.statusText}`);
14
+ const a = await g.json();
15
15
  i(a);
16
- } catch (u) {
17
- const a = u instanceof Error ? u : new Error("Unknown error occurred");
16
+ } catch (g) {
17
+ const a = g instanceof Error ? g : new Error("Unknown error occurred");
18
18
  o(a), console.error("Failed to fetch seat map config:", a);
19
19
  } finally {
20
20
  d(!1);
@@ -38,10 +38,10 @@ function yt(t) {
38
38
  const { width: d, height: c } = r.getBoundingClientRect();
39
39
  d > 0 && c > 0 && i({ width: d, height: c });
40
40
  const o = new ResizeObserver((m) => {
41
- const u = m[0];
42
- if (!u) return;
43
- const { width: a, height: s } = u.contentRect;
44
- a > 0 && s > 0 && i((h) => h.width === a && h.height === s ? h : { width: a, height: s });
41
+ const g = m[0];
42
+ if (!g) return;
43
+ const { width: a, height: s } = g.contentRect;
44
+ a > 0 && s > 0 && i((u) => u.width === a && u.height === s ? u : { width: a, height: s });
45
45
  });
46
46
  return o.observe(r), () => {
47
47
  o.disconnect();
@@ -65,31 +65,31 @@ function mt(t, n) {
65
65
  const o = c.container(), m = (s) => {
66
66
  if (s.touches.length === 2) {
67
67
  s.preventDefault();
68
- const h = { x: s.touches[0].clientX, y: s.touches[0].clientY }, f = { x: s.touches[1].clientX, y: s.touches[1].clientY };
69
- i.current = Fe(h, f), r.current = Le(h, f), d.current = n.currentScale;
68
+ const u = { x: s.touches[0].clientX, y: s.touches[0].clientY }, h = { x: s.touches[1].clientX, y: s.touches[1].clientY };
69
+ i.current = Fe(u, h), r.current = Le(u, h), d.current = n.currentScale;
70
70
  }
71
- }, u = (s) => {
71
+ }, g = (s) => {
72
72
  if (s.touches.length !== 2) return;
73
73
  s.preventDefault();
74
- const h = { x: s.touches[0].clientX, y: s.touches[0].clientY }, f = { x: s.touches[1].clientX, y: s.touches[1].clientY }, S = Fe(h, f), g = Le(h, f);
74
+ const u = { x: s.touches[0].clientX, y: s.touches[0].clientY }, h = { x: s.touches[1].clientX, y: s.touches[1].clientY }, S = Fe(u, h), f = Le(u, h);
75
75
  if (i.current !== null && r.current !== null) {
76
76
  const C = S / i.current, E = Math.min(
77
77
  Math.max(n.currentScale * C, n.minScale),
78
78
  n.maxScale
79
- ), I = o.getBoundingClientRect(), R = g.x - I.left, M = g.y - I.top, X = n.currentScale, k = {
79
+ ), I = o.getBoundingClientRect(), R = f.x - I.left, M = f.y - I.top, X = n.currentScale, k = {
80
80
  x: (R - n.currentPosition.x) / X,
81
81
  y: (M - n.currentPosition.y) / X
82
- }, Y = g.x - r.current.x, P = g.y - r.current.y, H = {
82
+ }, Y = f.x - r.current.x, P = f.y - r.current.y, V = {
83
83
  x: R - k.x * E + Y,
84
84
  y: M - k.y * E + P
85
85
  };
86
- n.onScaleChange(E, H), i.current = S, r.current = g;
86
+ n.onScaleChange(E, V), i.current = S, r.current = f;
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", m, { passive: !1 }), o.addEventListener("touchmove", u, { passive: !1 }), o.addEventListener("touchend", a), () => {
92
- o.removeEventListener("touchstart", m), o.removeEventListener("touchmove", u), o.removeEventListener("touchend", a);
91
+ return o.addEventListener("touchstart", m, { passive: !1 }), o.addEventListener("touchmove", g, { passive: !1 }), o.addEventListener("touchend", a), () => {
92
+ o.removeEventListener("touchstart", m), o.removeEventListener("touchmove", g), o.removeEventListener("touchend", a);
93
93
  };
94
94
  }, [t, n]);
95
95
  }
@@ -104,7 +104,7 @@ const St = {
104
104
  gridLines: "#404040",
105
105
  currency: "KD"
106
106
  }, ke = re(({ seat: t, state: n, colors: i, onClick: r, onMouseEnter: d, onMouseLeave: c }) => {
107
- const u = {
107
+ const g = {
108
108
  available: i.seatAvailable,
109
109
  reserved: i.seatReserved,
110
110
  selected: i.seatSelected,
@@ -113,32 +113,32 @@ const St = {
113
113
  // Hidden seats are filtered out, but included for type safety
114
114
  }[n], a = n === "available" || n === "selected", s = L(() => {
115
115
  a && r(t);
116
- }, [t, r, a]), h = L((g) => {
117
- d(t, g);
118
- const C = g.target.getStage();
116
+ }, [t, r, a]), u = L((f) => {
117
+ d(t, f);
118
+ const C = f.target.getStage();
119
119
  C && a && (C.container().style.cursor = "pointer");
120
- }, [t, d, a]), f = L((g) => {
120
+ }, [t, d, a]), h = L((f) => {
121
121
  c();
122
- const C = g.target.getStage();
122
+ const C = f.target.getStage();
123
123
  C && (C.container().style.cursor = "grab");
124
124
  }, [c]), S = {
125
125
  x: t.position.x,
126
126
  y: t.position.y,
127
- fill: u,
127
+ fill: g,
128
128
  stroke: "#ffffff",
129
129
  strokeWidth: 1,
130
130
  onClick: s,
131
131
  onTap: s,
132
- onMouseEnter: h,
133
- onMouseLeave: f
132
+ onMouseEnter: u,
133
+ onMouseLeave: h
134
134
  };
135
- return t.shape === "circle" ? /* @__PURE__ */ v(
135
+ return t.shape === "circle" ? /* @__PURE__ */ b(
136
136
  gt,
137
137
  {
138
138
  ...S,
139
139
  radius: 12
140
140
  }
141
- ) : /* @__PURE__ */ v(
141
+ ) : /* @__PURE__ */ b(
142
142
  De,
143
143
  {
144
144
  ...S,
@@ -163,7 +163,7 @@ const ze = re(({ stage: t, stageColor: n }) => {
163
163
  custom: "➕"
164
164
  })[c || "stage"] || "🎭", r = t.config.color || n, d = i(t.config.objectType);
165
165
  return /* @__PURE__ */ D(ft, { x: t.position.x, y: t.position.y, rotation: t.config.rotation || 0, children: [
166
- /* @__PURE__ */ v(
166
+ /* @__PURE__ */ b(
167
167
  De,
168
168
  {
169
169
  width: t.config.width,
@@ -174,7 +174,7 @@ const ze = re(({ stage: t, stageColor: n }) => {
174
174
  cornerRadius: 10
175
175
  }
176
176
  ),
177
- /* @__PURE__ */ v(
177
+ /* @__PURE__ */ b(
178
178
  Ie,
179
179
  {
180
180
  text: d,
@@ -188,7 +188,7 @@ const ze = re(({ stage: t, stageColor: n }) => {
188
188
  verticalAlign: "middle"
189
189
  }
190
190
  ),
191
- /* @__PURE__ */ v(
191
+ /* @__PURE__ */ b(
192
192
  Ie,
193
193
  {
194
194
  text: t.config.label,
@@ -216,7 +216,7 @@ const Ae = re(({
216
216
  className: o
217
217
  }) => {
218
218
  const m = U(
219
- () => [...t].sort((f, S) => f.order - S.order),
219
+ () => [...t].sort((h, S) => h.order - S.order),
220
220
  [t]
221
221
  ), a = {
222
222
  position: "absolute",
@@ -246,30 +246,30 @@ const Ae = re(({
246
246
  transition: "all 0.2s ease",
247
247
  minHeight: "44px",
248
248
  touchAction: "manipulation"
249
- }, h = {
249
+ }, u = {
250
250
  ...s,
251
251
  backgroundColor: "#3A7DE5",
252
252
  borderColor: "#3A7DE5"
253
253
  };
254
254
  return /* @__PURE__ */ D("div", { className: o, style: a, children: [
255
- r && /* @__PURE__ */ v(
255
+ r && /* @__PURE__ */ b(
256
256
  "button",
257
257
  {
258
258
  type: "button",
259
259
  onClick: () => i(null),
260
- style: n === null ? h : s,
260
+ style: n === null ? u : s,
261
261
  children: d
262
262
  }
263
263
  ),
264
- m.map((f) => /* @__PURE__ */ v(
264
+ m.map((h) => /* @__PURE__ */ b(
265
265
  "button",
266
266
  {
267
267
  type: "button",
268
- onClick: () => i(f.id),
269
- style: n === f.id ? h : s,
270
- children: f.name
268
+ onClick: () => i(h.id),
269
+ style: n === h.id ? u : s,
270
+ children: h.name
271
271
  },
272
- f.id
272
+ h.id
273
273
  ))
274
274
  ] });
275
275
  });
@@ -283,7 +283,7 @@ const Xe = re(({
283
283
  position: c,
284
284
  className: o
285
285
  }) => {
286
- const u = {
286
+ const g = {
287
287
  position: "absolute",
288
288
  display: "flex",
289
289
  flexDirection: "column",
@@ -320,26 +320,26 @@ const Xe = re(({
320
320
  ...a,
321
321
  opacity: 0.4,
322
322
  cursor: "not-allowed"
323
- }, h = t < i, f = t > n;
324
- return /* @__PURE__ */ D("div", { className: o, style: u, children: [
325
- /* @__PURE__ */ v(
323
+ }, u = t < i, h = t > n;
324
+ return /* @__PURE__ */ D("div", { className: o, style: g, children: [
325
+ /* @__PURE__ */ b(
326
326
  "button",
327
327
  {
328
328
  type: "button",
329
329
  onClick: r,
330
- disabled: !h,
331
- style: h ? a : s,
330
+ disabled: !u,
331
+ style: u ? a : s,
332
332
  title: "Zoom In",
333
333
  children: "+"
334
334
  }
335
335
  ),
336
- /* @__PURE__ */ v(
336
+ /* @__PURE__ */ b(
337
337
  "button",
338
338
  {
339
339
  type: "button",
340
340
  onClick: d,
341
- disabled: !f,
342
- style: f ? a : s,
341
+ disabled: !h,
342
+ style: h ? a : s,
343
343
  title: "Zoom Out",
344
344
  children: "−"
345
345
  }
@@ -362,7 +362,7 @@ const Ye = re(({
362
362
  top: `${i + 15}px`,
363
363
  zIndex: 1e3,
364
364
  pointerEvents: "none"
365
- }, u = {
365
+ }, g = {
366
366
  backgroundColor: "rgba(26, 26, 26, 0.95)",
367
367
  color: "#fff",
368
368
  border: "1px solid #444",
@@ -376,33 +376,33 @@ const Ye = re(({
376
376
  marginRight: "4px"
377
377
  }, s = {
378
378
  fontWeight: 600
379
- }, h = {
379
+ }, u = {
380
380
  color: "#4ade80",
381
381
  fontWeight: 600
382
- }, f = {
382
+ }, h = {
383
383
  fontSize: "11px",
384
384
  color: "#6b7280",
385
385
  textTransform: "capitalize",
386
386
  marginTop: "4px"
387
387
  };
388
- return /* @__PURE__ */ v("div", { style: m, children: /* @__PURE__ */ D("div", { style: u, children: [
388
+ return /* @__PURE__ */ b("div", { style: m, children: /* @__PURE__ */ D("div", { style: g, children: [
389
389
  r.sectionName && /* @__PURE__ */ D("div", { style: { marginBottom: "4px" }, children: [
390
- /* @__PURE__ */ v("span", { style: a, children: "Section:" }),
391
- /* @__PURE__ */ v("span", { style: { ...s, color: "#3b82f6" }, children: r.sectionName })
390
+ /* @__PURE__ */ b("span", { style: a, children: "Section:" }),
391
+ /* @__PURE__ */ b("span", { style: { ...s, color: "#3b82f6" }, children: r.sectionName })
392
392
  ] }),
393
393
  /* @__PURE__ */ D("div", { style: { marginBottom: "4px" }, children: [
394
- /* @__PURE__ */ v("span", { style: a, children: "Seat:" }),
395
- /* @__PURE__ */ v("span", { style: s, children: o })
394
+ /* @__PURE__ */ b("span", { style: a, children: "Seat:" }),
395
+ /* @__PURE__ */ b("span", { style: s, children: o })
396
396
  ] }),
397
397
  r.price !== void 0 && r.price > 0 && c === "available" && /* @__PURE__ */ D("div", { style: { marginBottom: "4px" }, children: [
398
- /* @__PURE__ */ v("span", { style: a, children: "Price:" }),
399
- /* @__PURE__ */ D("span", { style: h, children: [
398
+ /* @__PURE__ */ b("span", { style: a, children: "Price:" }),
399
+ /* @__PURE__ */ D("span", { style: u, children: [
400
400
  d,
401
401
  " ",
402
402
  r.price.toFixed(2)
403
403
  ] })
404
404
  ] }),
405
- /* @__PURE__ */ D("div", { style: f, children: [
405
+ /* @__PURE__ */ D("div", { style: h, children: [
406
406
  "Status: ",
407
407
  c
408
408
  ] })
@@ -419,13 +419,13 @@ const Lt = ({
419
419
  // v2.4.0: New prop name (preferred)
420
420
  unavailableSeats: o = [],
421
421
  selectedSeats: m,
422
- myReservedSeats: u = [],
422
+ myReservedSeats: g = [],
423
423
  onSeatSelect: a,
424
424
  onSeatDeselect: s,
425
- onSelectionChange: h,
426
- colorOverrides: f,
425
+ onSelectionChange: u,
426
+ colorOverrides: h,
427
427
  showTooltip: S = !0,
428
- zoomEnabled: g = !0,
428
+ zoomEnabled: f = !0,
429
429
  className: C = "",
430
430
  onConfigLoad: E,
431
431
  onError: I,
@@ -436,156 +436,143 @@ const Lt = ({
436
436
  showAllFloorsOption: k = !0,
437
437
  allFloorsLabel: Y = "All",
438
438
  fitToView: P = !0,
439
- fitPadding: H = 40,
439
+ fitPadding: V = 40,
440
440
  // Zoom controls
441
441
  showZoomControls: je = !0,
442
442
  zoomControlsPosition: Pe = "bottom-right",
443
443
  zoomControlsClassName: We,
444
- minZoom: we,
444
+ minZoom: xe,
445
445
  maxZoom: B = 3,
446
446
  zoomStep: oe = 0.25,
447
447
  // Touch gestures
448
448
  touchEnabled: Be = !0
449
449
  }) => {
450
- const ie = c !== void 0 ? c : d;
451
- console.log("🔍 ZonetrixViewer received props:", {
452
- reservedSeats: d,
453
- otherReservedSeats: c,
454
- effectiveOtherReservedSeats: ie,
455
- myReservedSeats: u,
456
- unavailableSeats: o
457
- });
458
- const fe = A(null), Ce = A(null), F = yt(Ce), [_, Re] = T(/* @__PURE__ */ new Set()), [N, G] = T(1), [z, O] = T({ x: 0, y: 0 }), [$e, Ue] = T(null), [Oe, Ve] = T(1), se = A({ width: 0, height: 0 }), [K, Me] = T({ visible: !1, x: 0, y: 0, seat: null, state: "available" }), { config: He, loading: _e, error: J } = vt(n), p = t || He, ge = i !== void 0, j = ge ? i || null : $e, ae = m !== void 0, qe = L((e) => {
459
- ge || Ue(e), r?.(e);
460
- }, [ge, r]), pe = p?.floors || [], Ze = R !== void 0 ? R : pe.length > 1, ce = U(
461
- () => p ? { ...p.colors, ...f } : { ...St, ...f },
462
- [p, f]
450
+ const we = c !== void 0 ? c : d, he = A(null), Ce = A(null), F = yt(Ce), [_, Re] = T(/* @__PURE__ */ new Set()), [N, Z] = T(1), [z, H] = T({ x: 0, y: 0 }), [$e, Ue] = T(null), [He, Oe] = T(1), ie = A({ width: 0, height: 0 }), [K, Me] = T({ visible: !1, x: 0, y: 0, seat: null, state: "available" }), { config: Ve, loading: _e, error: J } = bt(n), p = t || Ve, fe = i !== void 0, j = fe ? i || null : $e, se = m !== void 0, qe = L((e) => {
451
+ fe || Ue(e), r?.(e);
452
+ }, [fe, r]), ge = p?.floors || [], Ge = R !== void 0 ? R : ge.length > 1, ae = U(
453
+ () => p ? { ...p.colors, ...h } : { ...St, ...h },
454
+ [p, h]
463
455
  ), q = U(() => {
464
456
  if (!p) return [];
465
457
  let e = p.seats.filter((l) => l.state !== "hidden");
466
458
  return j && (e = e.filter(
467
459
  (l) => l.floorId === j || !l.floorId && j === "floor_default"
468
460
  )), e;
469
- }, [p, j]), le = U(() => p?.stages ? j ? p.stages.filter(
461
+ }, [p, j]), ce = U(() => p?.stages ? j ? p.stages.filter(
470
462
  (e) => e.floorId === j || !e.floorId && j === "floor_default"
471
463
  ) : p.stages : [], [p, j]), $ = U(() => {
472
- if (!p || q.length === 0 && le.length === 0)
464
+ if (!p || q.length === 0 && ce.length === 0)
473
465
  return null;
474
466
  const e = 12;
475
- let l = 1 / 0, b = 1 / 0, y = -1 / 0, x = -1 / 0;
467
+ let l = 1 / 0, v = 1 / 0, y = -1 / 0, x = -1 / 0;
476
468
  return q.forEach((w) => {
477
- l = Math.min(l, w.position.x - e), b = Math.min(b, w.position.y - e), y = Math.max(y, w.position.x + e), x = Math.max(x, w.position.y + e);
478
- }), le.forEach((w) => {
479
- l = Math.min(l, w.position.x), b = Math.min(b, w.position.y), y = Math.max(y, w.position.x + (w.config?.width || 200)), x = Math.max(x, w.position.y + (w.config?.height || 100));
480
- }), { minX: l, minY: b, maxX: y, maxY: x, width: y - l, height: x - b };
481
- }, [p, q, le]);
469
+ l = Math.min(l, w.position.x - e), v = Math.min(v, w.position.y - e), y = Math.max(y, w.position.x + e), x = Math.max(x, w.position.y + e);
470
+ }), ce.forEach((w) => {
471
+ l = Math.min(l, w.position.x), v = Math.min(v, w.position.y), y = Math.max(y, w.position.x + (w.config?.width || 200)), x = Math.max(x, w.position.y + (w.config?.height || 100));
472
+ }), { minX: l, minY: v, maxX: y, maxY: x, width: y - l, height: x - v };
473
+ }, [p, q, ce]);
482
474
  W(() => {
483
475
  if (!P || !p || !$ || F.width === 0 || F.height === 0) return;
484
- const e = Math.abs(F.width - se.current.width), l = Math.abs(F.height - se.current.height);
485
- if (!(se.current.width === 0) && e < 10 && l < 10) return;
486
- se.current = F;
487
- const y = F.width, x = F.height, w = y - H * 2, te = x - H * 2, de = w / $.width, ve = te / $.height, ue = Math.min(de, ve, B), it = $.minX + $.width / 2, st = $.minY + $.height / 2, at = y / 2, ct = x / 2, lt = at - it * ue, dt = ct - st * ue;
488
- G(ue), O({ x: lt, y: dt }), Ve(ue);
489
- }, [P, p, $, H, B, F, j]);
490
- const V = U(() => {
491
- console.log("🔍 Creating seatStateOverrides:", {
492
- effectiveOtherReservedSeats: ie,
493
- myReservedSeats: u,
494
- unavailableSeats: o
495
- });
496
- const e = new Set(ie), l = new Set(o), b = new Set(u);
497
- return { reserved: e, unavailable: l, myReserved: b };
498
- }, [ie, o, u]), be = U(() => m ? new Set(m) : null, [m]), Q = L((e) => {
499
- const l = e.id, b = e.seatNumber || "";
500
- 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) || _.has(l) ? "selected" : e.state;
501
- }, [V, _]);
476
+ const e = Math.abs(F.width - ie.current.width), l = Math.abs(F.height - ie.current.height);
477
+ if (!(ie.current.width === 0) && e < 10 && l < 10) return;
478
+ ie.current = F;
479
+ const y = F.width, x = F.height, w = y - V * 2, te = x - V * 2, le = w / $.width, ve = te / $.height, de = Math.min(le, ve, B), it = $.minX + $.width / 2, st = $.minY + $.height / 2, at = y / 2, ct = x / 2, lt = at - it * de, dt = ct - st * de;
480
+ Z(de), H({ x: lt, y: dt }), Oe(de);
481
+ }, [P, p, $, V, B, F, j]);
482
+ const O = U(() => {
483
+ const e = new Set(we), l = new Set(o), v = new Set(g);
484
+ return { reserved: e, unavailable: l, myReserved: v };
485
+ }, [we, o, g]), pe = U(() => m ? new Set(m) : null, [m]), Q = L((e) => {
486
+ const l = e.id, v = e.seatNumber || "";
487
+ return O.unavailable.has(l) || O.unavailable.has(v) ? "unavailable" : O.reserved.has(l) || O.reserved.has(v) ? "reserved" : O.myReserved.has(l) || O.myReserved.has(v) || _.has(l) ? "selected" : e.state;
488
+ }, [O, _]);
502
489
  W(() => {
503
490
  p && E && E(p);
504
491
  }, [p, E]), W(() => {
505
492
  J && I && I(J);
506
493
  }, [J, I]), W(() => {
507
- ae && be && Re(be);
508
- }, [ae, be]);
509
- const Ge = L((e) => {
494
+ se && pe && Re(pe);
495
+ }, [se, pe]);
496
+ const Ze = L((e) => {
510
497
  const l = Q(e);
511
498
  if (l !== "available" && l !== "selected")
512
499
  return;
513
- const b = _.has(e.id);
514
- ae || Re((y) => {
500
+ const v = _.has(e.id);
501
+ se || Re((y) => {
515
502
  const x = new Set(y);
516
- return b ? x.delete(e.id) : x.add(e.id), x;
517
- }), b ? s?.(e) : (a?.(e), a || console.log("Seat selected:", e));
518
- }, [Q, _, ae, a, s]), ee = U(() => p ? q.filter((e) => _.has(e.id)) : [], [q, _]);
503
+ return v ? x.delete(e.id) : x.add(e.id), x;
504
+ }), v ? s?.(e) : (a?.(e), a || console.log("Seat selected:", e));
505
+ }, [Q, _, se, a, s]), ee = U(() => p ? q.filter((e) => _.has(e.id)) : [], [q, _]);
519
506
  W(() => {
520
- h?.(ee);
521
- }, [ee, h]);
522
- const Z = we !== void 0 ? we : Oe, Ke = L(() => {
523
- if (!g) return;
507
+ u?.(ee);
508
+ }, [ee, u]);
509
+ const G = xe !== void 0 ? xe : He, Ke = L(() => {
510
+ if (!f) return;
524
511
  const e = Math.min(N + oe, B);
525
512
  if (e !== N) {
526
- const l = F.width || p?.canvas.width || 800, b = F.height || p?.canvas.height || 600, y = l / 2, x = b / 2, w = {
513
+ const l = F.width || p?.canvas.width || 800, v = F.height || p?.canvas.height || 600, y = l / 2, x = v / 2, w = {
527
514
  x: (y - z.x) / N,
528
515
  y: (x - z.y) / N
529
516
  };
530
- G(e), O({
517
+ Z(e), H({
531
518
  x: y - w.x * e,
532
519
  y: x - w.y * e
533
520
  });
534
521
  }
535
- }, [g, N, oe, B, F, p, z]), Je = L(() => {
536
- if (!g) return;
537
- const e = Math.max(N - oe, Z);
522
+ }, [f, N, oe, B, F, p, z]), Je = L(() => {
523
+ if (!f) return;
524
+ const e = Math.max(N - oe, G);
538
525
  if (e !== N) {
539
- const l = F.width || p?.canvas.width || 800, b = F.height || p?.canvas.height || 600, y = l / 2, x = b / 2, w = {
526
+ const l = F.width || p?.canvas.width || 800, v = F.height || p?.canvas.height || 600, y = l / 2, x = v / 2, w = {
540
527
  x: (y - z.x) / N,
541
528
  y: (x - z.y) / N
542
529
  };
543
- G(e), O({
530
+ Z(e), H({
544
531
  x: y - w.x * e,
545
532
  y: x - w.y * e
546
533
  });
547
534
  }
548
- }, [g, N, oe, Z, F, p, z]), Qe = L((e) => {
549
- O({
535
+ }, [f, N, oe, G, F, p, z]), Qe = L((e) => {
536
+ H({
550
537
  x: e.target.x(),
551
538
  y: e.target.y()
552
539
  });
553
540
  }, []), et = L((e) => {
554
- if (!g) return;
541
+ if (!f) return;
555
542
  e.evt.preventDefault();
556
- const l = fe.current;
543
+ const l = he.current;
557
544
  if (!l) return;
558
- const b = l.scaleX(), y = l.getPointerPosition();
545
+ const v = l.scaleX(), y = l.getPointerPosition();
559
546
  if (!y) return;
560
- const x = 1.1, w = e.evt.deltaY > 0 ? b / x : b * x, te = Math.min(Math.max(w, Z), B), de = {
561
- x: (y.x - z.x) / b,
562
- y: (y.y - z.y) / b
547
+ const x = 1.1, w = e.evt.deltaY > 0 ? v / x : v * x, te = Math.min(Math.max(w, G), B), le = {
548
+ x: (y.x - z.x) / v,
549
+ y: (y.y - z.y) / v
563
550
  }, ve = {
564
- x: y.x - de.x * te,
565
- y: y.y - de.y * te
551
+ x: y.x - le.x * te,
552
+ y: y.y - le.y * te
566
553
  };
567
- G(te), O(ve);
568
- }, [g, z, Z, B]);
569
- mt(fe, {
570
- enabled: Be && g,
571
- minScale: Z,
554
+ Z(te), H(ve);
555
+ }, [f, z, G, B]);
556
+ mt(he, {
557
+ enabled: Be && f,
558
+ minScale: G,
572
559
  maxScale: B,
573
560
  currentScale: N,
574
561
  currentPosition: z,
575
562
  onScaleChange: (e, l) => {
576
- G(e), O(l);
563
+ Z(e), H(l);
577
564
  },
578
565
  onPositionChange: (e) => {
579
- O(e);
566
+ H(e);
580
567
  }
581
568
  });
582
569
  const tt = L((e, l) => {
583
570
  if (!S) return;
584
- const b = l.target.getStage();
585
- if (!b) return;
586
- const y = b.getPointerPosition();
571
+ const v = l.target.getStage();
572
+ if (!v) return;
573
+ const y = v.getPointerPosition();
587
574
  if (!y) return;
588
- const x = b.container().getBoundingClientRect();
575
+ const x = v.container().getBoundingClientRect();
589
576
  Me({
590
577
  visible: !0,
591
578
  x: x.left + y.x,
@@ -597,14 +584,14 @@ const Lt = ({
597
584
  Me((e) => ({ ...e, visible: !1 }));
598
585
  }, []);
599
586
  if (_e)
600
- return /* @__PURE__ */ v("div", { className: `flex items-center justify-center h-full ${C}`, children: /* @__PURE__ */ v("p", { children: "Loading seat map..." }) });
587
+ return /* @__PURE__ */ b("div", { className: `flex items-center justify-center h-full ${C}`, children: /* @__PURE__ */ b("p", { children: "Loading seat map..." }) });
601
588
  if (J)
602
- return /* @__PURE__ */ v("div", { className: `flex items-center justify-center h-full ${C}`, children: /* @__PURE__ */ D("p", { className: "text-red-500", children: [
589
+ return /* @__PURE__ */ b("div", { className: `flex items-center justify-center h-full ${C}`, children: /* @__PURE__ */ D("p", { className: "text-red-500", children: [
603
590
  "Error loading seat map: ",
604
591
  J.message
605
592
  ] }) });
606
593
  if (!p)
607
- return /* @__PURE__ */ v("div", { className: `flex items-center justify-center h-full ${C}`, children: /* @__PURE__ */ v("p", { children: "No configuration provided" }) });
594
+ return /* @__PURE__ */ b("div", { className: `flex items-center justify-center h-full ${C}`, children: /* @__PURE__ */ b("p", { children: "No configuration provided" }) });
608
595
  const rt = F.width || p.canvas.width, ot = F.height || p.canvas.height;
609
596
  return /* @__PURE__ */ D(
610
597
  "div",
@@ -613,10 +600,10 @@ const Lt = ({
613
600
  className: `relative ${C}`,
614
601
  style: { width: "100%", height: "100%" },
615
602
  children: [
616
- Ze && pe.length > 0 && /* @__PURE__ */ v(
603
+ Ge && ge.length > 0 && /* @__PURE__ */ b(
617
604
  Ae,
618
605
  {
619
- floors: pe,
606
+ floors: ge,
620
607
  currentFloorId: j,
621
608
  onFloorChange: qe,
622
609
  showAllOption: k,
@@ -628,7 +615,7 @@ const Lt = ({
628
615
  /* @__PURE__ */ D(
629
616
  ht,
630
617
  {
631
- ref: fe,
618
+ ref: he,
632
619
  width: rt,
633
620
  height: ot,
634
621
  scaleX: N,
@@ -640,21 +627,21 @@ const Lt = ({
640
627
  onWheel: et,
641
628
  style: { backgroundColor: p.canvas.backgroundColor, cursor: "grab" },
642
629
  children: [
643
- /* @__PURE__ */ v(Ee, { listening: !1, children: le.map((e) => /* @__PURE__ */ v(
630
+ /* @__PURE__ */ b(Ee, { listening: !1, children: ce.map((e) => /* @__PURE__ */ b(
644
631
  ze,
645
632
  {
646
633
  stage: e,
647
- stageColor: ce.stageColor
634
+ stageColor: ae.stageColor
648
635
  },
649
636
  e.id
650
637
  )) }),
651
- /* @__PURE__ */ v(Ee, { children: q.map((e) => /* @__PURE__ */ v(
638
+ /* @__PURE__ */ b(Ee, { children: q.map((e) => /* @__PURE__ */ b(
652
639
  ke,
653
640
  {
654
641
  seat: e,
655
642
  state: Q(e),
656
- colors: ce,
657
- onClick: Ge,
643
+ colors: ae,
644
+ onClick: Ze,
658
645
  onMouseEnter: tt,
659
646
  onMouseLeave: nt
660
647
  },
@@ -663,22 +650,22 @@ const Lt = ({
663
650
  ]
664
651
  }
665
652
  ),
666
- S && /* @__PURE__ */ v(
653
+ S && /* @__PURE__ */ b(
667
654
  Ye,
668
655
  {
669
656
  visible: K.visible,
670
657
  x: K.x,
671
658
  y: K.y,
672
659
  seat: K.seat,
673
- currency: ce.currency,
660
+ currency: ae.currency,
674
661
  state: K.state
675
662
  }
676
663
  ),
677
- je && g && /* @__PURE__ */ v(
664
+ je && f && /* @__PURE__ */ b(
678
665
  Xe,
679
666
  {
680
667
  scale: N,
681
- minScale: Z,
668
+ minScale: G,
682
669
  maxScale: B,
683
670
  onZoomIn: Ke,
684
671
  onZoomOut: Je,
@@ -692,9 +679,9 @@ const Lt = ({
692
679
  ee.length,
693
680
  ")"
694
681
  ] }),
695
- /* @__PURE__ */ v("div", { className: "max-h-48 overflow-y-auto space-y-1", children: ee.map((e) => /* @__PURE__ */ D("div", { className: "text-sm", children: [
682
+ /* @__PURE__ */ b("div", { className: "max-h-48 overflow-y-auto space-y-1", children: ee.map((e) => /* @__PURE__ */ D("div", { className: "text-sm", children: [
696
683
  e.seatNumber,
697
- e.price && ` - ${ce.currency} ${e.price.toFixed(2)}`
684
+ e.price && ` - ${ae.currency} ${e.price.toFixed(2)}`
698
685
  ] }, e.id)) })
699
686
  ] })
700
687
  ]
@@ -705,20 +692,20 @@ let ne = null;
705
692
  function Dt(t) {
706
693
  ne = t;
707
694
  }
708
- function Se() {
695
+ function me() {
709
696
  if (!ne)
710
697
  throw new Error(
711
698
  "Firebase database not initialized. Call initializeFirebaseForViewer(db) first."
712
699
  );
713
700
  return ne;
714
701
  }
715
- function xe() {
702
+ function Se() {
716
703
  return ne !== null;
717
704
  }
718
705
  function Nt() {
719
706
  ne = null;
720
707
  }
721
- function ye(t, n) {
708
+ function be(t, n) {
722
709
  if (t.length !== n.length) return !1;
723
710
  const i = [...t].sort(), r = [...n].sort();
724
711
  return i.every((d, c) => d === r[c]);
@@ -733,7 +720,7 @@ function xt(t, n) {
733
720
  unavailable: d.sort()
734
721
  };
735
722
  }
736
- const he = {
723
+ const ue = {
737
724
  states: null,
738
725
  loading: !0,
739
726
  error: null,
@@ -743,26 +730,26 @@ const he = {
743
730
  unavailableSeats: []
744
731
  };
745
732
  function wt(t) {
746
- const { seatMapId: n, currentUserId: i, enabled: r = !0, onStateChange: d, onError: c } = t, o = A({ ...he }), m = A(d), u = A(c), a = A(i);
747
- m.current = d, u.current = c, a.current = i;
733
+ const { seatMapId: n, currentUserId: i, enabled: r = !0, onStateChange: d, onError: c } = t, o = A({ ...ue }), m = A(d), g = A(c), a = A(i);
734
+ m.current = d, g.current = c, a.current = i;
748
735
  const s = L(
749
- (g) => {
736
+ (f) => {
750
737
  if (!r || !n)
751
- return (o.current.loading !== !1 || o.current.states !== null) && (o.current = { ...he, loading: !1 }, g()), () => {
738
+ return (o.current.loading !== !1 || o.current.states !== null) && (o.current = { ...ue, loading: !1 }, f()), () => {
752
739
  };
753
- if (!xe()) {
740
+ if (!Se()) {
754
741
  const M = "Firebase not initialized. Call initializeFirebaseForViewer first.";
755
742
  return o.current.error?.message !== M && (o.current = {
756
- ...he,
743
+ ...ue,
757
744
  loading: !1,
758
745
  error: new Error(M)
759
- }, g()), () => {
746
+ }, f()), () => {
760
747
  };
761
748
  }
762
- const C = Se(), E = me(C, `seatmaps/${n}/seat_states`);
749
+ const C = me(), E = ye(C, `seatmaps/${n}/seat_states`);
763
750
  return Ne(E, (M) => {
764
751
  const k = M.val() || {}, Y = xt(k, a.current), P = o.current;
765
- (P.loading || !ye(P.myReservedSeats, Y.myReserved) || !ye(P.otherReservedSeats, Y.otherReserved) || !ye(P.unavailableSeats, Y.unavailable)) && (o.current = {
752
+ (P.loading || !be(P.myReservedSeats, Y.myReserved) || !be(P.otherReservedSeats, Y.otherReserved) || !be(P.unavailableSeats, Y.unavailable)) && (o.current = {
766
753
  states: k,
767
754
  loading: !1,
768
755
  error: null,
@@ -770,20 +757,20 @@ function wt(t) {
770
757
  myReservedSeats: Y.myReserved,
771
758
  otherReservedSeats: Y.otherReserved,
772
759
  unavailableSeats: Y.unavailable
773
- }, m.current?.(k), g());
760
+ }, m.current?.(k), f());
774
761
  }, (M) => {
775
762
  o.current = {
776
763
  ...o.current,
777
764
  loading: !1,
778
765
  error: M
779
- }, u.current?.(M), g();
766
+ }, g.current?.(M), f();
780
767
  }), () => {
781
768
  Te(E);
782
769
  };
783
770
  },
784
771
  [n, r]
785
772
  // Don't include currentUserId - we use currentUserIdRef.current which is always up-to-date
786
- ), h = L(() => o.current, []), f = L(() => he, []), S = ut(s, h, f);
773
+ ), u = L(() => o.current, []), h = L(() => ue, []), S = ut(s, u, h);
787
774
  return {
788
775
  states: S.states,
789
776
  loading: S.loading,
@@ -803,26 +790,26 @@ function Ct(t) {
803
790
  subscribeToChanges: r = !1,
804
791
  onConfigLoad: d,
805
792
  onError: c
806
- } = t, [o, m] = T(null), [u, a] = T(!0), [s, h] = T(null), f = A(d), S = A(c);
807
- f.current = d, S.current = c;
808
- const g = L(async () => {
793
+ } = t, [o, m] = T(null), [g, a] = T(!0), [s, u] = T(null), h = A(d), S = A(c);
794
+ h.current = d, S.current = c;
795
+ const f = L(async () => {
809
796
  if (!n) return;
810
- if (!xe()) {
811
- h(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")), a(!1);
797
+ if (!Se()) {
798
+ u(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")), a(!1);
812
799
  return;
813
800
  }
814
- const C = Se(), E = me(C, `seatmaps/${n}`);
801
+ const C = me(), E = ye(C, `seatmaps/${n}`);
815
802
  try {
816
- a(!0), h(null);
803
+ a(!0), u(null);
817
804
  const R = (await pt(E)).val();
818
805
  if (R) {
819
- const M = bt(R);
820
- m(M), f.current?.(M);
806
+ const M = vt(R);
807
+ m(M), h.current?.(M);
821
808
  } else
822
- h(new Error(`Seat map ${n} not found in Firebase`));
809
+ u(new Error(`Seat map ${n} not found in Firebase`));
823
810
  } catch (I) {
824
811
  const R = I instanceof Error ? I : new Error("Unknown error");
825
- h(R), S.current?.(R);
812
+ u(R), S.current?.(R);
826
813
  } finally {
827
814
  a(!1);
828
815
  }
@@ -832,8 +819,8 @@ function Ct(t) {
832
819
  a(!1);
833
820
  return;
834
821
  }
835
- if (g(), r && xe()) {
836
- const C = Se(), E = me(C, `seatmaps/${n}/meta/updated_at`);
822
+ if (f(), r && Se()) {
823
+ const C = me(), E = ye(C, `seatmaps/${n}/meta/updated_at`);
837
824
  let I = !0, R = null;
838
825
  return Ne(E, (X) => {
839
826
  if (I) {
@@ -841,16 +828,16 @@ function Ct(t) {
841
828
  return;
842
829
  }
843
830
  const k = X.val();
844
- X.exists() && k !== R && (R = k, g());
831
+ X.exists() && k !== R && (R = k, f());
845
832
  }), () => {
846
833
  Te(E);
847
834
  };
848
835
  }
849
836
  }, [n, i, r]), {
850
837
  config: o,
851
- loading: u,
838
+ loading: g,
852
839
  error: s,
853
- refetch: g
840
+ refetch: f
854
841
  };
855
842
  }
856
843
  function Tt(t) {
@@ -863,10 +850,10 @@ function Tt(t) {
863
850
  onStateChange: o,
864
851
  onError: m
865
852
  } = t, {
866
- config: u,
853
+ config: g,
867
854
  loading: a,
868
855
  error: s,
869
- refetch: h
856
+ refetch: u
870
857
  } = Ct({
871
858
  seatMapId: n,
872
859
  enabled: r,
@@ -874,9 +861,9 @@ function Tt(t) {
874
861
  onConfigLoad: c,
875
862
  onError: m
876
863
  }), {
877
- states: f,
864
+ states: h,
878
865
  loading: S,
879
- error: g,
866
+ error: f,
880
867
  lastUpdated: C,
881
868
  myReservedSeats: E,
882
869
  otherReservedSeats: I,
@@ -890,16 +877,16 @@ function Tt(t) {
890
877
  onError: m
891
878
  });
892
879
  return {
893
- config: u,
880
+ config: g,
894
881
  loading: a || S,
895
- error: s || g,
882
+ error: s || f,
896
883
  myReservedSeats: E,
897
884
  otherReservedSeats: I,
898
885
  unavailableSeats: R,
899
886
  reservedSeats: M,
900
- seatStates: f,
887
+ seatStates: h,
901
888
  lastUpdated: C,
902
- refetch: h
889
+ refetch: u
903
890
  };
904
891
  }
905
892
  export {
@@ -907,8 +894,8 @@ export {
907
894
  Lt as SeatMapViewer,
908
895
  Nt as clearFirebaseInstance,
909
896
  Dt as initializeFirebaseForViewer,
910
- xe as isFirebaseInitialized,
911
- vt as useConfigFetcher,
897
+ Se as isFirebaseInitialized,
898
+ bt as useConfigFetcher,
912
899
  yt as useContainerSize,
913
900
  Ct as useFirebaseConfig,
914
901
  wt as useFirebaseSeatStates,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zonetrix/viewer",
3
- "version": "2.10.7",
3
+ "version": "2.10.8",
4
4
  "type": "module",
5
5
  "description": "Lightweight React component for rendering interactive seat maps",
6
6
  "main": "./dist/index.js",