@zonetrix/viewer 2.10.6 → 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/components/SeatMapViewer.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +358 -356
- package/package.json +4 -1
|
@@ -5,7 +5,9 @@ export interface SeatMapViewerProps {
|
|
|
5
5
|
configUrl?: string;
|
|
6
6
|
floorId?: string;
|
|
7
7
|
onFloorChange?: (floorId: string) => void;
|
|
8
|
+
/** @deprecated Use otherReservedSeats instead (v2.4.0+) */
|
|
8
9
|
reservedSeats?: string[];
|
|
10
|
+
otherReservedSeats?: string[];
|
|
9
11
|
unavailableSeats?: string[];
|
|
10
12
|
selectedSeats?: string[];
|
|
11
13
|
myReservedSeats?: string[];
|
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),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]),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;
|
|
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
|
|
2
|
-
import { useState as T, useEffect as W, useRef as A, useCallback as
|
|
3
|
-
import { Stage as
|
|
4
|
-
import { ref as
|
|
5
|
-
import { fromFirebaseSeatMap as
|
|
6
|
-
function
|
|
7
|
-
const [n, i] = T(null), [r, d] = T(!1), [c, o] = T(null),
|
|
1
|
+
import { jsx as b, jsxs as D } from "react/jsx-runtime";
|
|
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
|
+
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 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
|
+
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
|
|
12
|
-
if (!
|
|
13
|
-
throw new Error(`Failed to fetch config: ${
|
|
14
|
-
const a = await
|
|
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 (
|
|
17
|
-
const a =
|
|
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);
|
|
@@ -22,25 +22,25 @@ function pt(t) {
|
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
24
|
return W(() => {
|
|
25
|
-
|
|
25
|
+
m();
|
|
26
26
|
}, [t]), {
|
|
27
27
|
config: n,
|
|
28
28
|
loading: r,
|
|
29
29
|
error: c,
|
|
30
|
-
refetch:
|
|
30
|
+
refetch: m
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
function
|
|
33
|
+
function yt(t) {
|
|
34
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((
|
|
41
|
-
const
|
|
42
|
-
if (!
|
|
43
|
-
const { width: a, height: s } =
|
|
40
|
+
const o = new ResizeObserver((m) => {
|
|
41
|
+
const g = m[0];
|
|
42
|
+
if (!g) return;
|
|
43
|
+
const { width: a, height: s } = g.contentRect;
|
|
44
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), () => {
|
|
@@ -48,52 +48,52 @@ function bt(t) {
|
|
|
48
48
|
};
|
|
49
49
|
}, [t]), n;
|
|
50
50
|
}
|
|
51
|
-
function
|
|
51
|
+
function Fe(t, n) {
|
|
52
52
|
return Math.sqrt(Math.pow(n.x - t.x, 2) + Math.pow(n.y - t.y, 2));
|
|
53
53
|
}
|
|
54
|
-
function
|
|
54
|
+
function Le(t, n) {
|
|
55
55
|
return {
|
|
56
56
|
x: (t.x + n.x) / 2,
|
|
57
57
|
y: (t.y + n.y) / 2
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
-
function
|
|
60
|
+
function mt(t, n) {
|
|
61
61
|
const i = A(null), r = A(null), d = A(1);
|
|
62
62
|
W(() => {
|
|
63
63
|
const c = t.current;
|
|
64
64
|
if (!c || !n.enabled) return;
|
|
65
|
-
const o = c.container(),
|
|
65
|
+
const o = c.container(), m = (s) => {
|
|
66
66
|
if (s.touches.length === 2) {
|
|
67
67
|
s.preventDefault();
|
|
68
|
-
const u = { x: s.touches[0].clientX, y: s.touches[0].clientY },
|
|
69
|
-
i.current =
|
|
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
|
-
},
|
|
71
|
+
}, g = (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 },
|
|
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
|
-
const C =
|
|
76
|
+
const C = S / i.current, E = Math.min(
|
|
77
77
|
Math.max(n.currentScale * C, n.minScale),
|
|
78
78
|
n.maxScale
|
|
79
|
-
),
|
|
80
|
-
x: (
|
|
81
|
-
y: (
|
|
82
|
-
},
|
|
83
|
-
x:
|
|
84
|
-
y:
|
|
79
|
+
), I = o.getBoundingClientRect(), R = f.x - I.left, M = f.y - I.top, X = n.currentScale, k = {
|
|
80
|
+
x: (R - n.currentPosition.x) / X,
|
|
81
|
+
y: (M - n.currentPosition.y) / X
|
|
82
|
+
}, Y = f.x - r.current.x, P = f.y - r.current.y, V = {
|
|
83
|
+
x: R - k.x * E + Y,
|
|
84
|
+
y: M - k.y * E + P
|
|
85
85
|
};
|
|
86
|
-
n.onScaleChange(
|
|
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",
|
|
92
|
-
o.removeEventListener("touchstart",
|
|
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
|
}
|
|
96
|
-
const
|
|
96
|
+
const St = {
|
|
97
97
|
canvasBackground: "#1a1a1a",
|
|
98
98
|
stageColor: "#808080",
|
|
99
99
|
seatAvailable: "#2C2B30",
|
|
@@ -103,45 +103,45 @@ const vt = {
|
|
|
103
103
|
seatHidden: "#4a4a4a",
|
|
104
104
|
gridLines: "#404040",
|
|
105
105
|
currency: "KD"
|
|
106
|
-
},
|
|
107
|
-
const
|
|
106
|
+
}, ke = re(({ seat: t, state: n, colors: i, onClick: r, onMouseEnter: d, onMouseLeave: c }) => {
|
|
107
|
+
const g = {
|
|
108
108
|
available: i.seatAvailable,
|
|
109
109
|
reserved: i.seatReserved,
|
|
110
110
|
selected: i.seatSelected,
|
|
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 =
|
|
114
|
+
}[n], a = n === "available" || n === "selected", s = L(() => {
|
|
115
115
|
a && r(t);
|
|
116
|
-
}, [t, r, a]), u =
|
|
117
|
-
d(t,
|
|
118
|
-
const C =
|
|
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]),
|
|
120
|
+
}, [t, d, a]), h = L((f) => {
|
|
121
121
|
c();
|
|
122
|
-
const C =
|
|
122
|
+
const C = f.target.getStage();
|
|
123
123
|
C && (C.container().style.cursor = "grab");
|
|
124
|
-
}, [c]),
|
|
124
|
+
}, [c]), S = {
|
|
125
125
|
x: t.position.x,
|
|
126
126
|
y: t.position.y,
|
|
127
|
-
fill:
|
|
127
|
+
fill: g,
|
|
128
128
|
stroke: "#ffffff",
|
|
129
129
|
strokeWidth: 1,
|
|
130
130
|
onClick: s,
|
|
131
131
|
onTap: s,
|
|
132
132
|
onMouseEnter: u,
|
|
133
|
-
onMouseLeave:
|
|
133
|
+
onMouseLeave: h
|
|
134
134
|
};
|
|
135
|
-
return t.shape === "circle" ? /* @__PURE__ */
|
|
136
|
-
|
|
135
|
+
return t.shape === "circle" ? /* @__PURE__ */ b(
|
|
136
|
+
gt,
|
|
137
137
|
{
|
|
138
|
-
...
|
|
138
|
+
...S,
|
|
139
139
|
radius: 12
|
|
140
140
|
}
|
|
141
|
-
) : /* @__PURE__ */
|
|
142
|
-
|
|
141
|
+
) : /* @__PURE__ */ b(
|
|
142
|
+
De,
|
|
143
143
|
{
|
|
144
|
-
...
|
|
144
|
+
...S,
|
|
145
145
|
width: 24,
|
|
146
146
|
height: 24,
|
|
147
147
|
offsetX: 12,
|
|
@@ -150,8 +150,8 @@ const vt = {
|
|
|
150
150
|
}
|
|
151
151
|
);
|
|
152
152
|
});
|
|
153
|
-
|
|
154
|
-
const
|
|
153
|
+
ke.displayName = "ViewerSeat";
|
|
154
|
+
const ze = re(({ stage: t, stageColor: n }) => {
|
|
155
155
|
const i = (c) => ({
|
|
156
156
|
stage: "🎭",
|
|
157
157
|
table: "⬜",
|
|
@@ -162,9 +162,9 @@ const ke = 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__ */ D(
|
|
166
|
-
/* @__PURE__ */
|
|
167
|
-
|
|
165
|
+
return /* @__PURE__ */ D(ft, { x: t.position.x, y: t.position.y, rotation: t.config.rotation || 0, children: [
|
|
166
|
+
/* @__PURE__ */ b(
|
|
167
|
+
De,
|
|
168
168
|
{
|
|
169
169
|
width: t.config.width,
|
|
170
170
|
height: t.config.height,
|
|
@@ -174,8 +174,8 @@ const ke = ne(({ stage: t, stageColor: n }) => {
|
|
|
174
174
|
cornerRadius: 10
|
|
175
175
|
}
|
|
176
176
|
),
|
|
177
|
-
/* @__PURE__ */
|
|
178
|
-
|
|
177
|
+
/* @__PURE__ */ b(
|
|
178
|
+
Ie,
|
|
179
179
|
{
|
|
180
180
|
text: d,
|
|
181
181
|
x: 0,
|
|
@@ -188,8 +188,8 @@ const ke = ne(({ stage: t, stageColor: n }) => {
|
|
|
188
188
|
verticalAlign: "middle"
|
|
189
189
|
}
|
|
190
190
|
),
|
|
191
|
-
/* @__PURE__ */
|
|
192
|
-
|
|
191
|
+
/* @__PURE__ */ b(
|
|
192
|
+
Ie,
|
|
193
193
|
{
|
|
194
194
|
text: t.config.label,
|
|
195
195
|
x: 0,
|
|
@@ -205,8 +205,8 @@ const ke = ne(({ stage: t, stageColor: n }) => {
|
|
|
205
205
|
)
|
|
206
206
|
] });
|
|
207
207
|
});
|
|
208
|
-
|
|
209
|
-
const
|
|
208
|
+
ze.displayName = "ViewerStage";
|
|
209
|
+
const Ae = re(({
|
|
210
210
|
floors: t,
|
|
211
211
|
currentFloorId: n,
|
|
212
212
|
onFloorChange: i,
|
|
@@ -215,8 +215,8 @@ const ze = ne(({
|
|
|
215
215
|
position: c,
|
|
216
216
|
className: o
|
|
217
217
|
}) => {
|
|
218
|
-
const
|
|
219
|
-
() => [...t].sort((
|
|
218
|
+
const m = U(
|
|
219
|
+
() => [...t].sort((h, S) => h.order - S.order),
|
|
220
220
|
[t]
|
|
221
221
|
), a = {
|
|
222
222
|
position: "absolute",
|
|
@@ -252,7 +252,7 @@ const ze = ne(({
|
|
|
252
252
|
borderColor: "#3A7DE5"
|
|
253
253
|
};
|
|
254
254
|
return /* @__PURE__ */ D("div", { className: o, style: a, children: [
|
|
255
|
-
r && /* @__PURE__ */
|
|
255
|
+
r && /* @__PURE__ */ b(
|
|
256
256
|
"button",
|
|
257
257
|
{
|
|
258
258
|
type: "button",
|
|
@@ -261,20 +261,20 @@ const ze = ne(({
|
|
|
261
261
|
children: d
|
|
262
262
|
}
|
|
263
263
|
),
|
|
264
|
-
|
|
264
|
+
m.map((h) => /* @__PURE__ */ b(
|
|
265
265
|
"button",
|
|
266
266
|
{
|
|
267
267
|
type: "button",
|
|
268
|
-
onClick: () => i(
|
|
269
|
-
style: n ===
|
|
270
|
-
children:
|
|
268
|
+
onClick: () => i(h.id),
|
|
269
|
+
style: n === h.id ? u : s,
|
|
270
|
+
children: h.name
|
|
271
271
|
},
|
|
272
|
-
|
|
272
|
+
h.id
|
|
273
273
|
))
|
|
274
274
|
] });
|
|
275
275
|
});
|
|
276
|
-
|
|
277
|
-
const
|
|
276
|
+
Ae.displayName = "FloorSelectorBar";
|
|
277
|
+
const Xe = re(({
|
|
278
278
|
scale: t,
|
|
279
279
|
minScale: n,
|
|
280
280
|
maxScale: i,
|
|
@@ -283,7 +283,7 @@ const Ae = ne(({
|
|
|
283
283
|
position: c,
|
|
284
284
|
className: o
|
|
285
285
|
}) => {
|
|
286
|
-
const
|
|
286
|
+
const g = {
|
|
287
287
|
position: "absolute",
|
|
288
288
|
display: "flex",
|
|
289
289
|
flexDirection: "column",
|
|
@@ -320,9 +320,9 @@ const Ae = ne(({
|
|
|
320
320
|
...a,
|
|
321
321
|
opacity: 0.4,
|
|
322
322
|
cursor: "not-allowed"
|
|
323
|
-
}, u = t < i,
|
|
324
|
-
return /* @__PURE__ */ D("div", { className: o, style:
|
|
325
|
-
/* @__PURE__ */
|
|
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",
|
|
@@ -333,21 +333,21 @@ const Ae = ne(({
|
|
|
333
333
|
children: "+"
|
|
334
334
|
}
|
|
335
335
|
),
|
|
336
|
-
/* @__PURE__ */
|
|
336
|
+
/* @__PURE__ */ b(
|
|
337
337
|
"button",
|
|
338
338
|
{
|
|
339
339
|
type: "button",
|
|
340
340
|
onClick: d,
|
|
341
|
-
disabled: !
|
|
342
|
-
style:
|
|
341
|
+
disabled: !h,
|
|
342
|
+
style: h ? a : s,
|
|
343
343
|
title: "Zoom Out",
|
|
344
344
|
children: "−"
|
|
345
345
|
}
|
|
346
346
|
)
|
|
347
347
|
] });
|
|
348
348
|
});
|
|
349
|
-
|
|
350
|
-
const
|
|
349
|
+
Xe.displayName = "ZoomControls";
|
|
350
|
+
const Ye = re(({
|
|
351
351
|
visible: t,
|
|
352
352
|
x: n,
|
|
353
353
|
y: i,
|
|
@@ -356,13 +356,13 @@ 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"),
|
|
359
|
+
const o = r.seatNumber || (r.rowLabel && r.columnLabel ? `${r.rowLabel}-${r.columnLabel}` : "N/A"), m = {
|
|
360
360
|
position: "fixed",
|
|
361
361
|
left: `${n + 15}px`,
|
|
362
362
|
top: `${i + 15}px`,
|
|
363
363
|
zIndex: 1e3,
|
|
364
364
|
pointerEvents: "none"
|
|
365
|
-
},
|
|
365
|
+
}, g = {
|
|
366
366
|
backgroundColor: "rgba(26, 26, 26, 0.95)",
|
|
367
367
|
color: "#fff",
|
|
368
368
|
border: "1px solid #444",
|
|
@@ -379,305 +379,307 @@ const Xe = ne(({
|
|
|
379
379
|
}, u = {
|
|
380
380
|
color: "#4ade80",
|
|
381
381
|
fontWeight: 600
|
|
382
|
-
},
|
|
382
|
+
}, h = {
|
|
383
383
|
fontSize: "11px",
|
|
384
384
|
color: "#6b7280",
|
|
385
385
|
textTransform: "capitalize",
|
|
386
386
|
marginTop: "4px"
|
|
387
387
|
};
|
|
388
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
391
|
-
/* @__PURE__ */
|
|
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__ */
|
|
395
|
-
/* @__PURE__ */
|
|
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__ */
|
|
398
|
+
/* @__PURE__ */ b("span", { style: a, children: "Price:" }),
|
|
399
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:
|
|
405
|
+
/* @__PURE__ */ D("div", { style: h, children: [
|
|
406
406
|
"Status: ",
|
|
407
407
|
c
|
|
408
408
|
] })
|
|
409
409
|
] }) });
|
|
410
410
|
});
|
|
411
|
-
|
|
412
|
-
const
|
|
411
|
+
Ye.displayName = "SeatTooltip";
|
|
412
|
+
const Lt = ({
|
|
413
413
|
config: t,
|
|
414
414
|
configUrl: n,
|
|
415
415
|
floorId: i,
|
|
416
416
|
onFloorChange: r,
|
|
417
417
|
reservedSeats: d = [],
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
418
|
+
otherReservedSeats: c,
|
|
419
|
+
// v2.4.0: New prop name (preferred)
|
|
420
|
+
unavailableSeats: o = [],
|
|
421
|
+
selectedSeats: m,
|
|
422
|
+
myReservedSeats: g = [],
|
|
423
|
+
onSeatSelect: a,
|
|
424
|
+
onSeatDeselect: s,
|
|
425
|
+
onSelectionChange: u,
|
|
426
|
+
colorOverrides: h,
|
|
427
|
+
showTooltip: S = !0,
|
|
428
|
+
zoomEnabled: f = !0,
|
|
429
|
+
className: C = "",
|
|
430
|
+
onConfigLoad: E,
|
|
431
|
+
onError: I,
|
|
430
432
|
// Floor selector props
|
|
431
|
-
showFloorSelector:
|
|
432
|
-
floorSelectorPosition:
|
|
433
|
-
floorSelectorClassName:
|
|
434
|
-
showAllFloorsOption:
|
|
435
|
-
allFloorsLabel:
|
|
436
|
-
fitToView:
|
|
437
|
-
fitPadding:
|
|
433
|
+
showFloorSelector: R,
|
|
434
|
+
floorSelectorPosition: M = "top-left",
|
|
435
|
+
floorSelectorClassName: X,
|
|
436
|
+
showAllFloorsOption: k = !0,
|
|
437
|
+
allFloorsLabel: Y = "All",
|
|
438
|
+
fitToView: P = !0,
|
|
439
|
+
fitPadding: V = 40,
|
|
438
440
|
// Zoom controls
|
|
439
|
-
showZoomControls:
|
|
440
|
-
zoomControlsPosition:
|
|
441
|
-
zoomControlsClassName:
|
|
441
|
+
showZoomControls: je = !0,
|
|
442
|
+
zoomControlsPosition: Pe = "bottom-right",
|
|
443
|
+
zoomControlsClassName: We,
|
|
442
444
|
minZoom: xe,
|
|
443
445
|
maxZoom: B = 3,
|
|
444
446
|
zoomStep: oe = 0.25,
|
|
445
447
|
// Touch gestures
|
|
446
|
-
touchEnabled:
|
|
448
|
+
touchEnabled: Be = !0
|
|
447
449
|
}) => {
|
|
448
|
-
const he = A(null),
|
|
449
|
-
fe ||
|
|
450
|
-
}, [fe, r]), ge = p?.floors || [],
|
|
451
|
-
() => p ? { ...p.colors, ...
|
|
452
|
-
[p,
|
|
453
|
-
),
|
|
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]
|
|
455
|
+
), q = U(() => {
|
|
454
456
|
if (!p) return [];
|
|
455
457
|
let e = p.seats.filter((l) => l.state !== "hidden");
|
|
456
|
-
return
|
|
457
|
-
(l) => l.floorId ===
|
|
458
|
+
return j && (e = e.filter(
|
|
459
|
+
(l) => l.floorId === j || !l.floorId && j === "floor_default"
|
|
458
460
|
)), e;
|
|
459
|
-
}, [p,
|
|
460
|
-
(e) => e.floorId ===
|
|
461
|
-
) : p.stages : [], [p,
|
|
462
|
-
if (!p ||
|
|
461
|
+
}, [p, j]), ce = U(() => p?.stages ? j ? p.stages.filter(
|
|
462
|
+
(e) => e.floorId === j || !e.floorId && j === "floor_default"
|
|
463
|
+
) : p.stages : [], [p, j]), $ = U(() => {
|
|
464
|
+
if (!p || q.length === 0 && ce.length === 0)
|
|
463
465
|
return null;
|
|
464
466
|
const e = 12;
|
|
465
|
-
let l = 1 / 0,
|
|
466
|
-
return
|
|
467
|
-
l = Math.min(l, w.position.x - e),
|
|
467
|
+
let l = 1 / 0, v = 1 / 0, y = -1 / 0, x = -1 / 0;
|
|
468
|
+
return q.forEach((w) => {
|
|
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);
|
|
468
470
|
}), ce.forEach((w) => {
|
|
469
|
-
l = Math.min(l, w.position.x),
|
|
470
|
-
}), { minX: l, minY:
|
|
471
|
-
}, [p,
|
|
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]);
|
|
472
474
|
W(() => {
|
|
473
|
-
if (!
|
|
474
|
-
const e = Math.abs(
|
|
475
|
+
if (!P || !p || !$ || F.width === 0 || F.height === 0) return;
|
|
476
|
+
const e = Math.abs(F.width - ie.current.width), l = Math.abs(F.height - ie.current.height);
|
|
475
477
|
if (!(ie.current.width === 0) && e < 10 && l < 10) return;
|
|
476
|
-
ie.current =
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
}, [
|
|
480
|
-
const
|
|
481
|
-
const e = new Set(
|
|
482
|
-
return { reserved: e, unavailable: l, myReserved:
|
|
483
|
-
}, [
|
|
484
|
-
const l = e.id,
|
|
485
|
-
return
|
|
486
|
-
}, [
|
|
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, _]);
|
|
487
489
|
W(() => {
|
|
488
|
-
p &&
|
|
489
|
-
}, [p,
|
|
490
|
-
|
|
491
|
-
}, [
|
|
492
|
-
se && pe &&
|
|
490
|
+
p && E && E(p);
|
|
491
|
+
}, [p, E]), W(() => {
|
|
492
|
+
J && I && I(J);
|
|
493
|
+
}, [J, I]), W(() => {
|
|
494
|
+
se && pe && Re(pe);
|
|
493
495
|
}, [se, pe]);
|
|
494
|
-
const
|
|
495
|
-
const l =
|
|
496
|
+
const Ze = L((e) => {
|
|
497
|
+
const l = Q(e);
|
|
496
498
|
if (l !== "available" && l !== "selected")
|
|
497
499
|
return;
|
|
498
|
-
const
|
|
499
|
-
se ||
|
|
500
|
-
const
|
|
501
|
-
return
|
|
502
|
-
}),
|
|
503
|
-
}, [
|
|
500
|
+
const v = _.has(e.id);
|
|
501
|
+
se || Re((y) => {
|
|
502
|
+
const x = new Set(y);
|
|
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, _]);
|
|
504
506
|
W(() => {
|
|
505
|
-
|
|
506
|
-
}, [
|
|
507
|
-
const
|
|
508
|
-
if (!
|
|
507
|
+
u?.(ee);
|
|
508
|
+
}, [ee, u]);
|
|
509
|
+
const G = xe !== void 0 ? xe : He, Ke = L(() => {
|
|
510
|
+
if (!f) return;
|
|
509
511
|
const e = Math.min(N + oe, B);
|
|
510
512
|
if (e !== N) {
|
|
511
|
-
const l =
|
|
512
|
-
x: (
|
|
513
|
-
y: (
|
|
513
|
+
const l = F.width || p?.canvas.width || 800, v = F.height || p?.canvas.height || 600, y = l / 2, x = v / 2, w = {
|
|
514
|
+
x: (y - z.x) / N,
|
|
515
|
+
y: (x - z.y) / N
|
|
514
516
|
};
|
|
515
|
-
|
|
516
|
-
x:
|
|
517
|
-
y:
|
|
517
|
+
Z(e), H({
|
|
518
|
+
x: y - w.x * e,
|
|
519
|
+
y: x - w.y * e
|
|
518
520
|
});
|
|
519
521
|
}
|
|
520
|
-
}, [
|
|
521
|
-
if (!
|
|
522
|
-
const e = Math.max(N - oe,
|
|
522
|
+
}, [f, N, oe, B, F, p, z]), Je = L(() => {
|
|
523
|
+
if (!f) return;
|
|
524
|
+
const e = Math.max(N - oe, G);
|
|
523
525
|
if (e !== N) {
|
|
524
|
-
const l =
|
|
525
|
-
x: (
|
|
526
|
-
y: (
|
|
526
|
+
const l = F.width || p?.canvas.width || 800, v = F.height || p?.canvas.height || 600, y = l / 2, x = v / 2, w = {
|
|
527
|
+
x: (y - z.x) / N,
|
|
528
|
+
y: (x - z.y) / N
|
|
527
529
|
};
|
|
528
|
-
|
|
529
|
-
x:
|
|
530
|
-
y:
|
|
530
|
+
Z(e), H({
|
|
531
|
+
x: y - w.x * e,
|
|
532
|
+
y: x - w.y * e
|
|
531
533
|
});
|
|
532
534
|
}
|
|
533
|
-
}, [
|
|
535
|
+
}, [f, N, oe, G, F, p, z]), Qe = L((e) => {
|
|
534
536
|
H({
|
|
535
537
|
x: e.target.x(),
|
|
536
538
|
y: e.target.y()
|
|
537
539
|
});
|
|
538
|
-
}, []),
|
|
539
|
-
if (!
|
|
540
|
+
}, []), et = L((e) => {
|
|
541
|
+
if (!f) return;
|
|
540
542
|
e.evt.preventDefault();
|
|
541
543
|
const l = he.current;
|
|
542
544
|
if (!l) return;
|
|
543
|
-
const
|
|
544
|
-
if (!
|
|
545
|
-
const
|
|
546
|
-
x: (
|
|
547
|
-
y: (
|
|
548
|
-
},
|
|
549
|
-
x:
|
|
550
|
-
y:
|
|
545
|
+
const v = l.scaleX(), y = l.getPointerPosition();
|
|
546
|
+
if (!y) return;
|
|
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
|
|
550
|
+
}, ve = {
|
|
551
|
+
x: y.x - le.x * te,
|
|
552
|
+
y: y.y - le.y * te
|
|
551
553
|
};
|
|
552
|
-
|
|
553
|
-
}, [
|
|
554
|
-
|
|
555
|
-
enabled:
|
|
556
|
-
minScale:
|
|
554
|
+
Z(te), H(ve);
|
|
555
|
+
}, [f, z, G, B]);
|
|
556
|
+
mt(he, {
|
|
557
|
+
enabled: Be && f,
|
|
558
|
+
minScale: G,
|
|
557
559
|
maxScale: B,
|
|
558
560
|
currentScale: N,
|
|
559
561
|
currentPosition: z,
|
|
560
562
|
onScaleChange: (e, l) => {
|
|
561
|
-
|
|
563
|
+
Z(e), H(l);
|
|
562
564
|
},
|
|
563
565
|
onPositionChange: (e) => {
|
|
564
566
|
H(e);
|
|
565
567
|
}
|
|
566
568
|
});
|
|
567
|
-
const
|
|
568
|
-
if (!
|
|
569
|
-
const
|
|
570
|
-
if (!b) return;
|
|
571
|
-
const v = b.getPointerPosition();
|
|
569
|
+
const tt = L((e, l) => {
|
|
570
|
+
if (!S) return;
|
|
571
|
+
const v = l.target.getStage();
|
|
572
572
|
if (!v) return;
|
|
573
|
-
const
|
|
574
|
-
|
|
573
|
+
const y = v.getPointerPosition();
|
|
574
|
+
if (!y) return;
|
|
575
|
+
const x = v.container().getBoundingClientRect();
|
|
576
|
+
Me({
|
|
575
577
|
visible: !0,
|
|
576
|
-
x:
|
|
577
|
-
y:
|
|
578
|
+
x: x.left + y.x,
|
|
579
|
+
y: x.top + y.y,
|
|
578
580
|
seat: e,
|
|
579
|
-
state:
|
|
581
|
+
state: Q(e)
|
|
580
582
|
});
|
|
581
|
-
}, [
|
|
582
|
-
|
|
583
|
+
}, [S, Q]), nt = L(() => {
|
|
584
|
+
Me((e) => ({ ...e, visible: !1 }));
|
|
583
585
|
}, []);
|
|
584
|
-
if (
|
|
585
|
-
return /* @__PURE__ */
|
|
586
|
-
if (
|
|
587
|
-
return /* @__PURE__ */
|
|
586
|
+
if (_e)
|
|
587
|
+
return /* @__PURE__ */ b("div", { className: `flex items-center justify-center h-full ${C}`, children: /* @__PURE__ */ b("p", { children: "Loading seat map..." }) });
|
|
588
|
+
if (J)
|
|
589
|
+
return /* @__PURE__ */ b("div", { className: `flex items-center justify-center h-full ${C}`, children: /* @__PURE__ */ D("p", { className: "text-red-500", children: [
|
|
588
590
|
"Error loading seat map: ",
|
|
589
|
-
|
|
591
|
+
J.message
|
|
590
592
|
] }) });
|
|
591
593
|
if (!p)
|
|
592
|
-
return /* @__PURE__ */
|
|
593
|
-
const
|
|
594
|
+
return /* @__PURE__ */ b("div", { className: `flex items-center justify-center h-full ${C}`, children: /* @__PURE__ */ b("p", { children: "No configuration provided" }) });
|
|
595
|
+
const rt = F.width || p.canvas.width, ot = F.height || p.canvas.height;
|
|
594
596
|
return /* @__PURE__ */ D(
|
|
595
597
|
"div",
|
|
596
598
|
{
|
|
597
|
-
ref:
|
|
598
|
-
className: `relative ${
|
|
599
|
+
ref: Ce,
|
|
600
|
+
className: `relative ${C}`,
|
|
599
601
|
style: { width: "100%", height: "100%" },
|
|
600
602
|
children: [
|
|
601
|
-
|
|
602
|
-
|
|
603
|
+
Ge && ge.length > 0 && /* @__PURE__ */ b(
|
|
604
|
+
Ae,
|
|
603
605
|
{
|
|
604
606
|
floors: ge,
|
|
605
|
-
currentFloorId:
|
|
606
|
-
onFloorChange:
|
|
607
|
-
showAllOption:
|
|
608
|
-
allLabel:
|
|
609
|
-
position:
|
|
610
|
-
className:
|
|
607
|
+
currentFloorId: j,
|
|
608
|
+
onFloorChange: qe,
|
|
609
|
+
showAllOption: k,
|
|
610
|
+
allLabel: Y,
|
|
611
|
+
position: M,
|
|
612
|
+
className: X
|
|
611
613
|
}
|
|
612
614
|
),
|
|
613
615
|
/* @__PURE__ */ D(
|
|
614
|
-
|
|
616
|
+
ht,
|
|
615
617
|
{
|
|
616
618
|
ref: he,
|
|
617
|
-
width:
|
|
618
|
-
height:
|
|
619
|
+
width: rt,
|
|
620
|
+
height: ot,
|
|
619
621
|
scaleX: N,
|
|
620
622
|
scaleY: N,
|
|
621
623
|
x: z.x,
|
|
622
624
|
y: z.y,
|
|
623
625
|
draggable: !0,
|
|
624
|
-
onDragEnd:
|
|
625
|
-
onWheel:
|
|
626
|
+
onDragEnd: Qe,
|
|
627
|
+
onWheel: et,
|
|
626
628
|
style: { backgroundColor: p.canvas.backgroundColor, cursor: "grab" },
|
|
627
629
|
children: [
|
|
628
|
-
/* @__PURE__ */
|
|
629
|
-
|
|
630
|
+
/* @__PURE__ */ b(Ee, { listening: !1, children: ce.map((e) => /* @__PURE__ */ b(
|
|
631
|
+
ze,
|
|
630
632
|
{
|
|
631
633
|
stage: e,
|
|
632
634
|
stageColor: ae.stageColor
|
|
633
635
|
},
|
|
634
636
|
e.id
|
|
635
637
|
)) }),
|
|
636
|
-
/* @__PURE__ */
|
|
637
|
-
|
|
638
|
+
/* @__PURE__ */ b(Ee, { children: q.map((e) => /* @__PURE__ */ b(
|
|
639
|
+
ke,
|
|
638
640
|
{
|
|
639
641
|
seat: e,
|
|
640
|
-
state:
|
|
642
|
+
state: Q(e),
|
|
641
643
|
colors: ae,
|
|
642
|
-
onClick:
|
|
643
|
-
onMouseEnter:
|
|
644
|
-
onMouseLeave:
|
|
644
|
+
onClick: Ze,
|
|
645
|
+
onMouseEnter: tt,
|
|
646
|
+
onMouseLeave: nt
|
|
645
647
|
},
|
|
646
648
|
e.id
|
|
647
649
|
)) })
|
|
648
650
|
]
|
|
649
651
|
}
|
|
650
652
|
),
|
|
651
|
-
|
|
652
|
-
|
|
653
|
+
S && /* @__PURE__ */ b(
|
|
654
|
+
Ye,
|
|
653
655
|
{
|
|
654
|
-
visible:
|
|
655
|
-
x:
|
|
656
|
-
y:
|
|
657
|
-
seat:
|
|
656
|
+
visible: K.visible,
|
|
657
|
+
x: K.x,
|
|
658
|
+
y: K.y,
|
|
659
|
+
seat: K.seat,
|
|
658
660
|
currency: ae.currency,
|
|
659
|
-
state:
|
|
661
|
+
state: K.state
|
|
660
662
|
}
|
|
661
663
|
),
|
|
662
|
-
|
|
663
|
-
|
|
664
|
+
je && f && /* @__PURE__ */ b(
|
|
665
|
+
Xe,
|
|
664
666
|
{
|
|
665
667
|
scale: N,
|
|
666
|
-
minScale:
|
|
668
|
+
minScale: G,
|
|
667
669
|
maxScale: B,
|
|
668
|
-
onZoomIn:
|
|
669
|
-
onZoomOut:
|
|
670
|
-
position:
|
|
671
|
-
className:
|
|
670
|
+
onZoomIn: Ke,
|
|
671
|
+
onZoomOut: Je,
|
|
672
|
+
position: Pe,
|
|
673
|
+
className: We
|
|
672
674
|
}
|
|
673
675
|
),
|
|
674
|
-
|
|
676
|
+
ee.length > 0 && /* @__PURE__ */ D("div", { className: "absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg", children: [
|
|
675
677
|
/* @__PURE__ */ D("h3", { className: "font-semibold mb-2", children: [
|
|
676
678
|
"Selected Seats (",
|
|
677
|
-
|
|
679
|
+
ee.length,
|
|
678
680
|
")"
|
|
679
681
|
] }),
|
|
680
|
-
/* @__PURE__ */
|
|
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: [
|
|
681
683
|
e.seatNumber,
|
|
682
684
|
e.price && ` - ${ae.currency} ${e.price.toFixed(2)}`
|
|
683
685
|
] }, e.id)) })
|
|
@@ -686,29 +688,29 @@ const It = ({
|
|
|
686
688
|
}
|
|
687
689
|
);
|
|
688
690
|
};
|
|
689
|
-
let
|
|
690
|
-
function
|
|
691
|
-
|
|
691
|
+
let ne = null;
|
|
692
|
+
function Dt(t) {
|
|
693
|
+
ne = t;
|
|
692
694
|
}
|
|
693
695
|
function me() {
|
|
694
|
-
if (!
|
|
696
|
+
if (!ne)
|
|
695
697
|
throw new Error(
|
|
696
698
|
"Firebase database not initialized. Call initializeFirebaseForViewer(db) first."
|
|
697
699
|
);
|
|
698
|
-
return
|
|
700
|
+
return ne;
|
|
699
701
|
}
|
|
700
702
|
function Se() {
|
|
701
|
-
return
|
|
703
|
+
return ne !== null;
|
|
702
704
|
}
|
|
703
|
-
function
|
|
704
|
-
|
|
705
|
+
function Nt() {
|
|
706
|
+
ne = null;
|
|
705
707
|
}
|
|
706
|
-
function
|
|
708
|
+
function be(t, n) {
|
|
707
709
|
if (t.length !== n.length) return !1;
|
|
708
710
|
const i = [...t].sort(), r = [...n].sort();
|
|
709
711
|
return i.every((d, c) => d === r[c]);
|
|
710
712
|
}
|
|
711
|
-
function
|
|
713
|
+
function xt(t, n) {
|
|
712
714
|
const i = [], r = [], d = [];
|
|
713
715
|
return Object.entries(t).forEach(([c, o]) => {
|
|
714
716
|
o && typeof o == "object" && o.state && (o.state === "unavailable" ? d.push(c) : o.state === "reserved" && (n && o.userId === n ? i.push(c) : r.push(c)));
|
|
@@ -727,87 +729,87 @@ const ue = {
|
|
|
727
729
|
otherReservedSeats: [],
|
|
728
730
|
unavailableSeats: []
|
|
729
731
|
};
|
|
730
|
-
function
|
|
731
|
-
const { seatMapId: n, currentUserId: i, enabled: r = !0, onStateChange: d, onError: c } = t, o = A({ ...ue }),
|
|
732
|
-
|
|
733
|
-
const s =
|
|
734
|
-
(
|
|
732
|
+
function wt(t) {
|
|
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;
|
|
735
|
+
const s = L(
|
|
736
|
+
(f) => {
|
|
735
737
|
if (!r || !n)
|
|
736
|
-
return (o.current.loading !== !1 || o.current.states !== null) && (o.current = { ...ue, loading: !1 },
|
|
738
|
+
return (o.current.loading !== !1 || o.current.states !== null) && (o.current = { ...ue, loading: !1 }, f()), () => {
|
|
737
739
|
};
|
|
738
740
|
if (!Se()) {
|
|
739
|
-
const
|
|
740
|
-
return o.current.error?.message !==
|
|
741
|
+
const M = "Firebase not initialized. Call initializeFirebaseForViewer first.";
|
|
742
|
+
return o.current.error?.message !== M && (o.current = {
|
|
741
743
|
...ue,
|
|
742
744
|
loading: !1,
|
|
743
|
-
error: new Error(
|
|
744
|
-
},
|
|
745
|
+
error: new Error(M)
|
|
746
|
+
}, f()), () => {
|
|
745
747
|
};
|
|
746
748
|
}
|
|
747
|
-
const C = me(),
|
|
748
|
-
return
|
|
749
|
-
const k =
|
|
750
|
-
(
|
|
749
|
+
const C = me(), E = ye(C, `seatmaps/${n}/seat_states`);
|
|
750
|
+
return Ne(E, (M) => {
|
|
751
|
+
const k = M.val() || {}, Y = xt(k, a.current), P = o.current;
|
|
752
|
+
(P.loading || !be(P.myReservedSeats, Y.myReserved) || !be(P.otherReservedSeats, Y.otherReserved) || !be(P.unavailableSeats, Y.unavailable)) && (o.current = {
|
|
751
753
|
states: k,
|
|
752
754
|
loading: !1,
|
|
753
755
|
error: null,
|
|
754
756
|
lastUpdated: Date.now(),
|
|
755
|
-
myReservedSeats:
|
|
756
|
-
otherReservedSeats:
|
|
757
|
-
unavailableSeats:
|
|
758
|
-
},
|
|
759
|
-
}, (
|
|
757
|
+
myReservedSeats: Y.myReserved,
|
|
758
|
+
otherReservedSeats: Y.otherReserved,
|
|
759
|
+
unavailableSeats: Y.unavailable
|
|
760
|
+
}, m.current?.(k), f());
|
|
761
|
+
}, (M) => {
|
|
760
762
|
o.current = {
|
|
761
763
|
...o.current,
|
|
762
764
|
loading: !1,
|
|
763
|
-
error:
|
|
764
|
-
},
|
|
765
|
+
error: M
|
|
766
|
+
}, g.current?.(M), f();
|
|
765
767
|
}), () => {
|
|
766
|
-
|
|
768
|
+
Te(E);
|
|
767
769
|
};
|
|
768
770
|
},
|
|
769
771
|
[n, r]
|
|
770
772
|
// Don't include currentUserId - we use currentUserIdRef.current which is always up-to-date
|
|
771
|
-
), u =
|
|
773
|
+
), u = L(() => o.current, []), h = L(() => ue, []), S = ut(s, u, h);
|
|
772
774
|
return {
|
|
773
|
-
states:
|
|
774
|
-
loading:
|
|
775
|
-
error:
|
|
776
|
-
lastUpdated:
|
|
777
|
-
myReservedSeats:
|
|
778
|
-
otherReservedSeats:
|
|
779
|
-
unavailableSeats:
|
|
775
|
+
states: S.states,
|
|
776
|
+
loading: S.loading,
|
|
777
|
+
error: S.error,
|
|
778
|
+
lastUpdated: S.lastUpdated,
|
|
779
|
+
myReservedSeats: S.myReservedSeats,
|
|
780
|
+
otherReservedSeats: S.otherReservedSeats,
|
|
781
|
+
unavailableSeats: S.unavailableSeats,
|
|
780
782
|
// Legacy alias
|
|
781
|
-
reservedSeats:
|
|
783
|
+
reservedSeats: S.otherReservedSeats
|
|
782
784
|
};
|
|
783
785
|
}
|
|
784
|
-
function
|
|
786
|
+
function Ct(t) {
|
|
785
787
|
const {
|
|
786
788
|
seatMapId: n,
|
|
787
789
|
enabled: i = !0,
|
|
788
790
|
subscribeToChanges: r = !1,
|
|
789
791
|
onConfigLoad: d,
|
|
790
792
|
onError: c
|
|
791
|
-
} = t, [o,
|
|
792
|
-
|
|
793
|
-
const
|
|
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 () => {
|
|
794
796
|
if (!n) return;
|
|
795
797
|
if (!Se()) {
|
|
796
798
|
u(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")), a(!1);
|
|
797
799
|
return;
|
|
798
800
|
}
|
|
799
|
-
const C = me(),
|
|
801
|
+
const C = me(), E = ye(C, `seatmaps/${n}`);
|
|
800
802
|
try {
|
|
801
803
|
a(!0), u(null);
|
|
802
|
-
const
|
|
803
|
-
if (
|
|
804
|
-
const
|
|
805
|
-
|
|
804
|
+
const R = (await pt(E)).val();
|
|
805
|
+
if (R) {
|
|
806
|
+
const M = vt(R);
|
|
807
|
+
m(M), h.current?.(M);
|
|
806
808
|
} else
|
|
807
809
|
u(new Error(`Seat map ${n} not found in Firebase`));
|
|
808
|
-
} catch (
|
|
809
|
-
const
|
|
810
|
-
u(
|
|
810
|
+
} catch (I) {
|
|
811
|
+
const R = I instanceof Error ? I : new Error("Unknown error");
|
|
812
|
+
u(R), S.current?.(R);
|
|
811
813
|
} finally {
|
|
812
814
|
a(!1);
|
|
813
815
|
}
|
|
@@ -817,28 +819,28 @@ function xt(t) {
|
|
|
817
819
|
a(!1);
|
|
818
820
|
return;
|
|
819
821
|
}
|
|
820
|
-
if (
|
|
821
|
-
const C = me(),
|
|
822
|
-
let
|
|
823
|
-
return
|
|
824
|
-
if (
|
|
825
|
-
|
|
822
|
+
if (f(), r && Se()) {
|
|
823
|
+
const C = me(), E = ye(C, `seatmaps/${n}/meta/updated_at`);
|
|
824
|
+
let I = !0, R = null;
|
|
825
|
+
return Ne(E, (X) => {
|
|
826
|
+
if (I) {
|
|
827
|
+
I = !1, R = X.val();
|
|
826
828
|
return;
|
|
827
829
|
}
|
|
828
|
-
const k =
|
|
829
|
-
|
|
830
|
+
const k = X.val();
|
|
831
|
+
X.exists() && k !== R && (R = k, f());
|
|
830
832
|
}), () => {
|
|
831
|
-
|
|
833
|
+
Te(E);
|
|
832
834
|
};
|
|
833
835
|
}
|
|
834
836
|
}, [n, i, r]), {
|
|
835
837
|
config: o,
|
|
836
|
-
loading:
|
|
838
|
+
loading: g,
|
|
837
839
|
error: s,
|
|
838
|
-
refetch:
|
|
840
|
+
refetch: f
|
|
839
841
|
};
|
|
840
842
|
}
|
|
841
|
-
function
|
|
843
|
+
function Tt(t) {
|
|
842
844
|
const {
|
|
843
845
|
seatMapId: n,
|
|
844
846
|
userId: i,
|
|
@@ -846,57 +848,57 @@ function Dt(t) {
|
|
|
846
848
|
subscribeToDesignChanges: d = !1,
|
|
847
849
|
onConfigLoad: c,
|
|
848
850
|
onStateChange: o,
|
|
849
|
-
onError:
|
|
851
|
+
onError: m
|
|
850
852
|
} = t, {
|
|
851
|
-
config:
|
|
853
|
+
config: g,
|
|
852
854
|
loading: a,
|
|
853
855
|
error: s,
|
|
854
856
|
refetch: u
|
|
855
|
-
} =
|
|
857
|
+
} = Ct({
|
|
856
858
|
seatMapId: n,
|
|
857
859
|
enabled: r,
|
|
858
860
|
subscribeToChanges: d,
|
|
859
861
|
onConfigLoad: c,
|
|
860
|
-
onError:
|
|
862
|
+
onError: m
|
|
861
863
|
}), {
|
|
862
|
-
states:
|
|
863
|
-
loading:
|
|
864
|
-
error:
|
|
864
|
+
states: h,
|
|
865
|
+
loading: S,
|
|
866
|
+
error: f,
|
|
865
867
|
lastUpdated: C,
|
|
866
|
-
myReservedSeats:
|
|
867
|
-
otherReservedSeats:
|
|
868
|
-
unavailableSeats:
|
|
869
|
-
reservedSeats:
|
|
870
|
-
} =
|
|
868
|
+
myReservedSeats: E,
|
|
869
|
+
otherReservedSeats: I,
|
|
870
|
+
unavailableSeats: R,
|
|
871
|
+
reservedSeats: M
|
|
872
|
+
} = wt({
|
|
871
873
|
seatMapId: n,
|
|
872
874
|
currentUserId: i,
|
|
873
875
|
enabled: r,
|
|
874
876
|
onStateChange: o,
|
|
875
|
-
onError:
|
|
877
|
+
onError: m
|
|
876
878
|
});
|
|
877
879
|
return {
|
|
878
|
-
config:
|
|
879
|
-
loading: a ||
|
|
880
|
-
error: s ||
|
|
881
|
-
myReservedSeats:
|
|
882
|
-
otherReservedSeats:
|
|
883
|
-
unavailableSeats:
|
|
884
|
-
reservedSeats:
|
|
885
|
-
seatStates:
|
|
880
|
+
config: g,
|
|
881
|
+
loading: a || S,
|
|
882
|
+
error: s || f,
|
|
883
|
+
myReservedSeats: E,
|
|
884
|
+
otherReservedSeats: I,
|
|
885
|
+
unavailableSeats: R,
|
|
886
|
+
reservedSeats: M,
|
|
887
|
+
seatStates: h,
|
|
886
888
|
lastUpdated: C,
|
|
887
889
|
refetch: u
|
|
888
890
|
};
|
|
889
891
|
}
|
|
890
892
|
export {
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
893
|
+
St as DEFAULT_COLORS,
|
|
894
|
+
Lt as SeatMapViewer,
|
|
895
|
+
Nt as clearFirebaseInstance,
|
|
896
|
+
Dt as initializeFirebaseForViewer,
|
|
895
897
|
Se as isFirebaseInitialized,
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
898
|
+
bt as useConfigFetcher,
|
|
899
|
+
yt as useContainerSize,
|
|
900
|
+
Ct as useFirebaseConfig,
|
|
901
|
+
wt as useFirebaseSeatStates,
|
|
902
|
+
Tt as useRealtimeSeatMap,
|
|
903
|
+
mt as useTouchGestures
|
|
902
904
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zonetrix/viewer",
|
|
3
|
-
"version": "2.10.
|
|
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",
|
|
@@ -61,5 +61,8 @@
|
|
|
61
61
|
"typescript": "^5.8.3",
|
|
62
62
|
"vite": "^7.3.0",
|
|
63
63
|
"vite-plugin-dts": "^4.5.4"
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"@zonetrix/viewer": "file:../seat-map-studio/packages/viewer"
|
|
64
67
|
}
|
|
65
68
|
}
|