@zonetrix/viewer 2.9.0 → 2.10.0
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.
|
@@ -8,6 +8,7 @@ export interface SeatMapViewerProps {
|
|
|
8
8
|
reservedSeats?: string[];
|
|
9
9
|
unavailableSeats?: string[];
|
|
10
10
|
selectedSeats?: string[];
|
|
11
|
+
myReservedSeats?: string[];
|
|
11
12
|
onSeatSelect?: (seat: SeatData) => void;
|
|
12
13
|
onSeatDeselect?: (seat: SeatData) => void;
|
|
13
14
|
onSelectionChange?: (seats: SeatData[]) => void;
|
|
@@ -2,6 +2,8 @@ import { FirebaseSeatStates } from '@zonetrix/shared';
|
|
|
2
2
|
export interface UseFirebaseSeatStatesOptions {
|
|
3
3
|
/** The seat map ID to subscribe to */
|
|
4
4
|
seatMapId: string | null;
|
|
5
|
+
/** Current user ID for user-aware state derivation */
|
|
6
|
+
currentUserId?: string;
|
|
5
7
|
/** Whether the subscription is enabled (default: true) */
|
|
6
8
|
enabled?: boolean;
|
|
7
9
|
/** Callback when states change */
|
|
@@ -18,23 +20,30 @@ export interface UseFirebaseSeatStatesResult {
|
|
|
18
20
|
error: Error | null;
|
|
19
21
|
/** Timestamp of last update */
|
|
20
22
|
lastUpdated: number | null;
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
+
/** Seats reserved by current user (show as selected) */
|
|
24
|
+
myReservedSeats: string[];
|
|
25
|
+
/** Seats reserved by other users (show as reserved) */
|
|
26
|
+
otherReservedSeats: string[];
|
|
27
|
+
/** Seats unavailable for everyone */
|
|
23
28
|
unavailableSeats: string[];
|
|
29
|
+
/** @deprecated Use otherReservedSeats instead */
|
|
30
|
+
reservedSeats: string[];
|
|
24
31
|
}
|
|
25
32
|
/**
|
|
26
33
|
* Subscribe to real-time seat state updates from Firebase
|
|
27
34
|
*
|
|
28
35
|
* @example
|
|
29
36
|
* ```tsx
|
|
30
|
-
* const {
|
|
37
|
+
* const { myReservedSeats, otherReservedSeats, unavailableSeats, loading } = useFirebaseSeatStates({
|
|
31
38
|
* seatMapId: '123',
|
|
39
|
+
* currentUserId: 'user-abc',
|
|
32
40
|
* });
|
|
33
41
|
*
|
|
34
42
|
* return (
|
|
35
43
|
* <SeatMapViewer
|
|
36
44
|
* config={config}
|
|
37
|
-
*
|
|
45
|
+
* myReservedSeats={myReservedSeats}
|
|
46
|
+
* reservedSeats={otherReservedSeats}
|
|
38
47
|
* unavailableSeats={unavailableSeats}
|
|
39
48
|
* />
|
|
40
49
|
* );
|
|
@@ -3,6 +3,8 @@ import { FirebaseSeatStates } from '@zonetrix/shared';
|
|
|
3
3
|
export interface UseRealtimeSeatMapOptions {
|
|
4
4
|
/** The seat map ID to load and subscribe to */
|
|
5
5
|
seatMapId: string | null;
|
|
6
|
+
/** Current user ID for user-aware state derivation */
|
|
7
|
+
userId?: string;
|
|
6
8
|
/** Whether the hook is enabled (default: true) */
|
|
7
9
|
enabled?: boolean;
|
|
8
10
|
/** Subscribe to design changes in real-time (default: false) */
|
|
@@ -21,10 +23,14 @@ export interface UseRealtimeSeatMapResult {
|
|
|
21
23
|
loading: boolean;
|
|
22
24
|
/** Any error that occurred */
|
|
23
25
|
error: Error | null;
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
/**
|
|
26
|
+
/** Seats reserved by current user (show as selected) */
|
|
27
|
+
myReservedSeats: string[];
|
|
28
|
+
/** Seats reserved by other users (show as reserved) */
|
|
29
|
+
otherReservedSeats: string[];
|
|
30
|
+
/** Seats unavailable for everyone */
|
|
27
31
|
unavailableSeats: string[];
|
|
32
|
+
/** @deprecated Use otherReservedSeats instead */
|
|
33
|
+
reservedSeats: string[];
|
|
28
34
|
/** Raw seat states map */
|
|
29
35
|
seatStates: FirebaseSeatStates | null;
|
|
30
36
|
/** Timestamp of last state update */
|
|
@@ -39,14 +45,15 @@ export interface UseRealtimeSeatMapResult {
|
|
|
39
45
|
* ```tsx
|
|
40
46
|
* import { useRealtimeSeatMap, SeatMapViewer } from '@zonetrix/viewer';
|
|
41
47
|
*
|
|
42
|
-
* function BookingPage({ seatMapId }) {
|
|
48
|
+
* function BookingPage({ seatMapId, userId }) {
|
|
43
49
|
* const {
|
|
44
50
|
* config,
|
|
45
|
-
*
|
|
51
|
+
* myReservedSeats,
|
|
52
|
+
* otherReservedSeats,
|
|
46
53
|
* unavailableSeats,
|
|
47
54
|
* loading,
|
|
48
55
|
* error
|
|
49
|
-
* } = useRealtimeSeatMap({ seatMapId });
|
|
56
|
+
* } = useRealtimeSeatMap({ seatMapId, userId });
|
|
50
57
|
*
|
|
51
58
|
* if (loading) return <LoadingSpinner />;
|
|
52
59
|
* if (error) return <ErrorMessage error={error} />;
|
|
@@ -55,7 +62,8 @@ export interface UseRealtimeSeatMapResult {
|
|
|
55
62
|
* return (
|
|
56
63
|
* <SeatMapViewer
|
|
57
64
|
* config={config}
|
|
58
|
-
*
|
|
65
|
+
* myReservedSeats={myReservedSeats}
|
|
66
|
+
* reservedSeats={otherReservedSeats}
|
|
59
67
|
* unavailableSeats={unavailableSeats}
|
|
60
68
|
* onSeatSelect={handleSeatSelect}
|
|
61
69
|
* />
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),t=require("react"),T=require("react-konva"),Y=require("firebase/database"),nt=require("@zonetrix/shared");function we(n){const[s,c]=t.useState(null),[o,g]=t.useState(!1),[p,d]=t.useState(null),m=async()=>{if(n){g(!0),d(null);try{const h=await fetch(n);if(!h.ok)throw new Error(`Failed to fetch config: ${h.statusText}`);const a=await h.json();c(a)}catch(h){const a=h instanceof Error?h:new Error("Unknown error occurred");d(a),console.error("Failed to fetch seat map config:",a)}finally{g(!1)}}};return t.useEffect(()=>{m()},[n]),{config:s,loading:o,error:p,refetch:m}}function Ce(n){const[s,c]=t.useState({width:0,height:0});return t.useEffect(()=>{const o=n.current;if(!o)return;const{width:g,height:p}=o.getBoundingClientRect();g>0&&p>0&&c({width:g,height:p});const d=new ResizeObserver(m=>{const h=m[0];if(!h)return;const{width:a,height:i}=h.contentRect;a>0&&i>0&&c(f=>f.width===a&&f.height===i?f:{width:a,height:i})});return d.observe(o),()=>{d.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 ve(n,s){return{x:(n.x+s.x)/2,y:(n.y+s.y)/2}}function je(n,s){const c=t.useRef(null),o=t.useRef(null),g=t.useRef(1);t.useEffect(()=>{const p=n.current;if(!p||!s.enabled)return;const d=p.container(),m=i=>{if(i.touches.length===2){i.preventDefault();const f={x:i.touches[0].clientX,y:i.touches[0].clientY},l={x:i.touches[1].clientX,y:i.touches[1].clientY};c.current=me(f,l),o.current=ve(f,l),g.current=s.currentScale}},h=i=>{if(i.touches.length!==2)return;i.preventDefault();const f={x:i.touches[0].clientX,y:i.touches[0].clientY},l={x:i.touches[1].clientX,y:i.touches[1].clientY},C=me(f,l),v=ve(f,l);if(c.current!==null&&o.current!==null){const j=C/c.current,F=Math.min(Math.max(s.currentScale*j,s.minScale),s.maxScale),R=d.getBoundingClientRect(),M=v.x-R.left,L=v.y-R.top,P=s.currentScale,W={x:(M-s.currentPosition.x)/P,y:(L-s.currentPosition.y)/P},A=v.x-o.current.x,N=v.y-o.current.y,ne={x:M-W.x*F+A,y:L-W.y*F+N};s.onScaleChange(F,ne),c.current=C,o.current=v}},a=i=>{i.touches.length<2&&(c.current=null,o.current=null)};return d.addEventListener("touchstart",m,{passive:!1}),d.addEventListener("touchmove",h,{passive:!1}),d.addEventListener("touchend",a),()=>{d.removeEventListener("touchstart",m),d.removeEventListener("touchmove",h),d.removeEventListener("touchend",a)}},[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:c,onClick:o,onMouseEnter:g,onMouseLeave:p})=>{const h={available:c.seatAvailable,reserved:c.seatReserved,selected:c.seatSelected,unavailable:c.seatUnavailable,hidden:c.seatHidden}[s],a=s==="available"||s==="selected",i=t.useCallback(()=>{a&&o(n)},[n,o,a]),f=t.useCallback(v=>{g(n,v);const j=v.target.getStage();j&&a&&(j.container().style.cursor="pointer")},[n,g,a]),l=t.useCallback(v=>{p();const j=v.target.getStage();j&&(j.container().style.cursor="grab")},[p]),C={x:n.position.x,y:n.position.y,fill:h,stroke:"#ffffff",strokeWidth:1,onClick:i,onTap:i,onMouseEnter:f,onMouseLeave:l};return n.shape==="circle"?r.jsx(T.Circle,{...C,radius:12}):r.jsx(T.Rect,{...C,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 c=p=>({stage:"🎭",table:"⬜",wall:"▬",barrier:"🛡️","dj-booth":"🎵",bar:"🍷","entry-exit":"🚪",custom:"➕"})[p||"stage"]||"🎭",o=n.config.color||s,g=c(n.config.objectType);return r.jsxs(T.Group,{x:n.position.x,y:n.position.y,rotation:n.config.rotation||0,children:[r.jsx(T.Rect,{width:n.config.width,height:n.config.height,fill:o+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),r.jsx(T.Text,{text:g,x:0,y:0,width:n.config.width,height:n.config.height*.4,fontSize:32,fill:"#ffffff",align:"center",verticalAlign:"middle"}),r.jsx(T.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 Re=t.memo(({floors:n,currentFloorId:s,onFloorChange:c,showAllOption:o,allLabel:g,position:p,className:d})=>{const m=t.useMemo(()=>[...n].sort((l,C)=>l.order-C.order),[n]),a={position:"absolute",display:"flex",alignItems:"center",gap:"8px",padding:"8px 12px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[p]},i={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={...i,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return r.jsxs("div",{className:d,style:a,children:[o&&r.jsx("button",{type:"button",onClick:()=>c(null),style:s===null?f:i,children:g}),m.map(l=>r.jsx("button",{type:"button",onClick:()=>c(l.id),style:s===l.id?f:i,children:l.name},l.id))]})});Re.displayName="FloorSelectorBar";const ke=t.memo(({scale:n,minScale:s,maxScale:c,onZoomIn:o,onZoomOut:g,position:p,className:d})=>{const h={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}}[p]},a={width:"44px",height:"44px",minWidth:"44px",minHeight:"44px",fontSize:"22px",fontWeight:"bold",border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s ease",touchAction:"manipulation"},i={...a,opacity:.4,cursor:"not-allowed"},f=n<c,l=n>s;return r.jsxs("div",{className:d,style:h,children:[r.jsx("button",{type:"button",onClick:o,disabled:!f,style:f?a:i,title:"Zoom In",children:"+"}),r.jsx("button",{type:"button",onClick:g,disabled:!l,style:l?a:i,title:"Zoom Out",children:"−"})]})});ke.displayName="ZoomControls";const Ie=t.memo(({visible:n,x:s,y:c,seat:o,currency:g,state:p})=>{if(!n||!o)return null;const d=o.seatNumber||(o.rowLabel&&o.columnLabel?`${o.rowLabel}-${o.columnLabel}`:"N/A"),m={position:"fixed",left:`${s+15}px`,top:`${c+15}px`,zIndex:1e3,pointerEvents:"none"},h={backgroundColor:"rgba(26, 26, 26, 0.95)",color:"#fff",border:"1px solid #444",borderRadius:"8px",padding:"8px 12px",fontSize:"13px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.3)",minWidth:"140px"},a={color:"#9ca3af",marginRight:"4px"},i={fontWeight:600},f={color:"#4ade80",fontWeight:600},l={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return r.jsx("div",{style:m,children:r.jsxs("div",{style:h,children:[o.sectionName&&r.jsxs("div",{style:{marginBottom:"4px"},children:[r.jsx("span",{style:a,children:"Section:"}),r.jsx("span",{style:{...i,color:"#3b82f6"},children:o.sectionName})]}),r.jsxs("div",{style:{marginBottom:"4px"},children:[r.jsx("span",{style:a,children:"Seat:"}),r.jsx("span",{style:i,children:d})]}),o.price!==void 0&&o.price>0&&p==="available"&&r.jsxs("div",{style:{marginBottom:"4px"},children:[r.jsx("span",{style:a,children:"Price:"}),r.jsxs("span",{style:f,children:[g," ",o.price.toFixed(2)]})]}),r.jsxs("div",{style:l,children:["Status: ",p]})]})})});Ie.displayName="SeatTooltip";const st=({config:n,configUrl:s,floorId:c,onFloorChange:o,reservedSeats:g=[],unavailableSeats:p=[],selectedSeats:d,onSeatSelect:m,onSeatDeselect:h,onSelectionChange:a,colorOverrides:i,showTooltip:f=!0,zoomEnabled:l=!0,className:C="",onConfigLoad:v,onError:j,showFloorSelector:F,floorSelectorPosition:R="top-left",floorSelectorClassName:M,showAllFloorsOption:L=!0,allFloorsLabel:P="All",fitToView:W=!0,fitPadding:A=40,showZoomControls:N=!0,zoomControlsPosition:ne="bottom-right",zoomControlsClassName:U,minZoom:q,maxZoom:D=3,zoomStep:$=.25,touchEnabled:se=!0})=>{const de=t.useRef(null),be=t.useRef(null),E=Ce(be),[V,Se]=t.useState(new Set),[k,_]=t.useState(1),[I,B]=t.useState({x:0,y:0}),[ze,Te]=t.useState(null),[Ne,Xe]=t.useState(1),oe=t.useRef({width:0,height:0}),[G,ye]=t.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Ye,loading:Pe,error:K}=we(s),x=n||Ye,he=c!==void 0,z=he?c||null:ze,ie=d!==void 0,We=t.useCallback(e=>{he||Te(e),o?.(e)},[he,o]),fe=x?.floors||[],Ae=F!==void 0?F:fe.length>1,re=t.useMemo(()=>x?{...x.colors,...i}:{...Me,...i},[x,i]),O=t.useMemo(()=>{if(!x)return[];let e=x.seats.filter(u=>u.state!=="hidden");return z&&(e=e.filter(u=>u.floorId===z||!u.floorId&&z==="floor_default")),e},[x,z]),ae=t.useMemo(()=>x?.stages?z?x.stages.filter(e=>e.floorId===z||!e.floorId&&z==="floor_default"):x.stages:[],[x,z]),X=t.useMemo(()=>{if(!x||O.length===0&&ae.length===0)return null;const e=12;let u=1/0,S=1/0,b=-1/0,y=-1/0;return O.forEach(w=>{u=Math.min(u,w.position.x-e),S=Math.min(S,w.position.y-e),b=Math.max(b,w.position.x+e),y=Math.max(y,w.position.y+e)}),ae.forEach(w=>{u=Math.min(u,w.position.x),S=Math.min(S,w.position.y),b=Math.max(b,w.position.x+(w.config?.width||200)),y=Math.max(y,w.position.y+(w.config?.height||100))}),{minX:u,minY:S,maxX:b,maxY:y,width:b-u,height:y-S}},[x,O,ae]);t.useEffect(()=>{if(!W||!x||!X||E.width===0||E.height===0)return;const e=Math.abs(E.width-oe.current.width),u=Math.abs(E.height-oe.current.height);if(!(oe.current.width===0)&&e<10&&u<10)return;oe.current=E;const b=E.width,y=E.height,w=b-A*2,ee=y-A*2,ce=w/X.width,pe=ee/X.height,le=Math.min(ce,pe,D),Ke=X.minX+X.width/2,Ze=X.minY+X.height/2,Je=b/2,Qe=y/2,et=Je-Ke*le,tt=Qe-Ze*le;_(le),B({x:et,y:tt}),Xe(le)},[W,x,X,A,D,E,z]);const Z=t.useMemo(()=>{const e=new Set(g),u=new Set(p);return{reserved:e,unavailable:u}},[g,p]),ge=t.useMemo(()=>d?new Set(d):null,[d]),J=t.useCallback(e=>{const u=e.id,S=e.seatNumber||"";return Z.unavailable.has(u)||Z.unavailable.has(S)?"unavailable":Z.reserved.has(u)||Z.reserved.has(S)?"reserved":V.has(u)?"selected":e.state},[Z,V]);t.useEffect(()=>{x&&v&&v(x)},[x,v]),t.useEffect(()=>{K&&j&&j(K)},[K,j]),t.useEffect(()=>{ie&&ge&&Se(ge)},[ie,ge]);const $e=t.useCallback(e=>{const u=J(e);if(u!=="available"&&u!=="selected")return;const S=V.has(e.id);ie||Se(b=>{const y=new Set(b);return S?y.delete(e.id):y.add(e.id),y}),S?h?.(e):(m?.(e),m||console.log("Seat selected:",e))},[J,V,ie,m,h]),Q=t.useMemo(()=>x?O.filter(e=>V.has(e.id)):[],[O,V]);t.useEffect(()=>{a?.(Q)},[Q,a]);const H=q!==void 0?q:Ne,Be=t.useCallback(()=>{if(!l)return;const e=Math.min(k+$,D);if(e!==k){const u=E.width||x?.canvas.width||800,S=E.height||x?.canvas.height||600,b=u/2,y=S/2,w={x:(b-I.x)/k,y:(y-I.y)/k};_(e),B({x:b-w.x*e,y:y-w.y*e})}},[l,k,$,D,E,x,I]),Ve=t.useCallback(()=>{if(!l)return;const e=Math.max(k-$,H);if(e!==k){const u=E.width||x?.canvas.width||800,S=E.height||x?.canvas.height||600,b=u/2,y=S/2,w={x:(b-I.x)/k,y:(y-I.y)/k};_(e),B({x:b-w.x*e,y:y-w.y*e})}},[l,k,$,H,E,x,I]),Oe=t.useCallback(e=>{B({x:e.target.x(),y:e.target.y()})},[]),He=t.useCallback(e=>{if(!l)return;e.evt.preventDefault();const u=de.current;if(!u)return;const S=u.scaleX(),b=u.getPointerPosition();if(!b)return;const y=1.1,w=e.evt.deltaY>0?S/y:S*y,ee=Math.min(Math.max(w,H),D),ce={x:(b.x-I.x)/S,y:(b.y-I.y)/S},pe={x:b.x-ce.x*ee,y:b.y-ce.y*ee};_(ee),B(pe)},[l,I,H,D]);je(de,{enabled:se&&l,minScale:H,maxScale:D,currentScale:k,currentPosition:I,onScaleChange:(e,u)=>{_(e),B(u)},onPositionChange:e=>{B(e)}});const Ue=t.useCallback((e,u)=>{if(!f)return;const S=u.target.getStage();if(!S)return;const b=S.getPointerPosition();if(!b)return;const y=S.container().getBoundingClientRect();ye({visible:!0,x:y.left+b.x,y:y.top+b.y,seat:e,state:J(e)})},[f,J]),qe=t.useCallback(()=>{ye(e=>({...e,visible:!1}))},[]);if(Pe)return r.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:r.jsx("p",{children:"Loading seat map..."})});if(K)return r.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:r.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",K.message]})});if(!x)return r.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:r.jsx("p",{children:"No configuration provided"})});const _e=E.width||x.canvas.width,Ge=E.height||x.canvas.height;return r.jsxs("div",{ref:be,className:`relative ${C}`,style:{width:"100%",height:"100%"},children:[Ae&&fe.length>0&&r.jsx(Re,{floors:fe,currentFloorId:z,onFloorChange:We,showAllOption:L,allLabel:P,position:R,className:M}),r.jsxs(T.Stage,{ref:de,width:_e,height:Ge,scaleX:k,scaleY:k,x:I.x,y:I.y,draggable:!0,onDragEnd:Oe,onWheel:He,style:{backgroundColor:x.canvas.backgroundColor,cursor:"grab"},children:[r.jsx(T.Layer,{listening:!1,children:ae.map(e=>r.jsx(Fe,{stage:e,stageColor:re.stageColor},e.id))}),r.jsx(T.Layer,{children:O.map(e=>r.jsx(Ee,{seat:e,state:J(e),colors:re,onClick:$e,onMouseEnter:Ue,onMouseLeave:qe},e.id))})]}),f&&r.jsx(Ie,{visible:G.visible,x:G.x,y:G.y,seat:G.seat,currency:re.currency,state:G.state}),N&&l&&r.jsx(ke,{scale:k,minScale:H,maxScale:D,onZoomIn:Be,onZoomOut:Ve,position:ne,className:U}),Q.length>0&&r.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[r.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",Q.length,")"]}),r.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:Q.map(e=>r.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${re.currency} ${e.price.toFixed(2)}`]},e.id))})]})]})};let te=null;function ot(n){te=n}function xe(){if(!te)throw new Error("Firebase database not initialized. Call initializeFirebaseForViewer(db) first.");return te}function ue(){return te!==null}function it(){te=null}function Le(n){const{seatMapId:s,enabled:c=!0,onStateChange:o,onError:g}=n,[p,d]=t.useState(null),[m,h]=t.useState(!0),[a,i]=t.useState(null),[f,l]=t.useState(null),[C,v]=t.useState([]),[j,F]=t.useState([]),R=t.useRef(o),M=t.useRef(g);return R.current=o,M.current=g,t.useEffect(()=>{if(!c||!s){h(!1);return}if(!ue()){h(!1),i(new Error("Firebase not initialized. Call initializeFirebaseForViewer first."));return}const L=xe(),P=Y.ref(L,`seat_states/${s}`);h(!0),i(null);const W=N=>{const U=N.val()||{};d(U),h(!1),l(Date.now());const q=[],D=[];Object.entries(U).forEach(([$,se])=>{se==="reserved"?q.push($):se==="unavailable"&&D.push($)}),v(q),F(D),R.current?.(U)},A=N=>{i(N),h(!1),M.current?.(N)};return Y.onValue(P,W,A),()=>{Y.off(P)}},[s,c]),{states:p,loading:m,error:a,lastUpdated:f,reservedSeats:C,unavailableSeats:j}}function De(n){const{seatMapId:s,enabled:c=!0,subscribeToChanges:o=!1,onConfigLoad:g,onError:p}=n,[d,m]=t.useState(null),[h,a]=t.useState(!0),[i,f]=t.useState(null),l=t.useRef(g),C=t.useRef(p);l.current=g,C.current=p;const v=t.useCallback(async()=>{if(!s)return;if(!ue()){f(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")),a(!1);return}const j=xe(),F=Y.ref(j,`seatmaps/${s}`);try{a(!0),f(null);const M=(await Y.get(F)).val();if(M){const L=nt.fromFirebaseSeatMap(M);m(L),l.current?.(L)}else f(new Error(`Seat map ${s} not found in Firebase`))}catch(R){const M=R instanceof Error?R:new Error("Unknown error");f(M),C.current?.(M)}finally{a(!1)}},[s]);return t.useEffect(()=>{if(!c||!s){a(!1);return}if(v(),o&&ue()){const j=xe(),F=Y.ref(j,`seatmaps/${s}/meta/updated_at`);let R=!0;const M=L=>{if(R){R=!1;return}L.exists()&&v()};return Y.onValue(F,M),()=>{Y.off(F)}}},[s,c,o,v]),{config:d,loading:h,error:i,refetch:v}}function rt(n){const{seatMapId:s,enabled:c=!0,subscribeToDesignChanges:o=!1,onConfigLoad:g,onStateChange:p,onError:d}=n,{config:m,loading:h,error:a,refetch:i}=De({seatMapId:s,enabled:c,subscribeToChanges:o,onConfigLoad:g,onError:d}),{states:f,loading:l,error:C,lastUpdated:v,reservedSeats:j,unavailableSeats:F}=Le({seatMapId:s,enabled:c,onStateChange:p,onError:d});return{config:m,loading:h||l,error:a||C,reservedSeats:j,unavailableSeats:F,seatStates:f,lastUpdated:v,refetch:i}}exports.DEFAULT_COLORS=Me;exports.SeatMapViewer=st;exports.clearFirebaseInstance=it;exports.initializeFirebaseForViewer=ot;exports.isFirebaseInitialized=ue;exports.useConfigFetcher=we;exports.useContainerSize=Ce;exports.useFirebaseConfig=De;exports.useFirebaseSeatStates=Le;exports.useRealtimeSeatMap=rt;exports.useTouchGestures=je;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),t=require("react"),N=require("react-konva"),$=require("firebase/database"),ot=require("@zonetrix/shared");function je(n){const[s,c]=t.useState(null),[o,f]=t.useState(!1),[d,i]=t.useState(null),v=async()=>{if(n){f(!0),i(null);try{const p=await fetch(n);if(!p.ok)throw new Error(`Failed to fetch config: ${p.statusText}`);const a=await p.json();c(a)}catch(p){const a=p instanceof Error?p:new Error("Unknown error occurred");i(a),console.error("Failed to fetch seat map config:",a)}finally{f(!1)}}};return t.useEffect(()=>{v()},[n]),{config:s,loading:o,error:d,refetch:v}}function Re(n){const[s,c]=t.useState({width:0,height:0});return t.useEffect(()=>{const o=n.current;if(!o)return;const{width:f,height:d}=o.getBoundingClientRect();f>0&&d>0&&c({width:f,height:d});const i=new ResizeObserver(v=>{const p=v[0];if(!p)return;const{width:a,height:l}=p.contentRect;a>0&&l>0&&c(h=>h.width===a&&h.height===l?h:{width:a,height:l})});return i.observe(o),()=>{i.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 we(n,s){return{x:(n.x+s.x)/2,y:(n.y+s.y)/2}}function Me(n,s){const c=t.useRef(null),o=t.useRef(null),f=t.useRef(1);t.useEffect(()=>{const d=n.current;if(!d||!s.enabled)return;const i=d.container(),v=l=>{if(l.touches.length===2){l.preventDefault();const h={x:l.touches[0].clientX,y:l.touches[0].clientY},g={x:l.touches[1].clientX,y:l.touches[1].clientY};c.current=ve(h,g),o.current=we(h,g),f.current=s.currentScale}},p=l=>{if(l.touches.length!==2)return;l.preventDefault();const h={x:l.touches[0].clientX,y:l.touches[0].clientY},g={x:l.touches[1].clientX,y:l.touches[1].clientY},w=ve(h,g),m=we(h,g);if(c.current!==null&&o.current!==null){const j=w/c.current,R=Math.min(Math.max(s.currentScale*j,s.minScale),s.maxScale),M=i.getBoundingClientRect(),E=m.x-M.left,k=m.y-M.top,X=s.currentScale,Y={x:(E-s.currentPosition.x)/X,y:(k-s.currentPosition.y)/X},B=m.x-o.current.x,z=m.y-o.current.y,A={x:E-Y.x*R+B,y:k-Y.y*R+z};s.onScaleChange(R,A),c.current=w,o.current=m}},a=l=>{l.touches.length<2&&(c.current=null,o.current=null)};return i.addEventListener("touchstart",v,{passive:!1}),i.addEventListener("touchmove",p,{passive:!1}),i.addEventListener("touchend",a),()=>{i.removeEventListener("touchstart",v),i.removeEventListener("touchmove",p),i.removeEventListener("touchend",a)}},[n,s])}const Ee={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},Fe=t.memo(({seat:n,state:s,colors:c,onClick:o,onMouseEnter:f,onMouseLeave:d})=>{const p={available:c.seatAvailable,reserved:c.seatReserved,selected:c.seatSelected,unavailable:c.seatUnavailable,hidden:c.seatHidden}[s],a=s==="available"||s==="selected",l=t.useCallback(()=>{a&&o(n)},[n,o,a]),h=t.useCallback(m=>{f(n,m);const j=m.target.getStage();j&&a&&(j.container().style.cursor="pointer")},[n,f,a]),g=t.useCallback(m=>{d();const j=m.target.getStage();j&&(j.container().style.cursor="grab")},[d]),w={x:n.position.x,y:n.position.y,fill:p,stroke:"#ffffff",strokeWidth:1,onClick:l,onTap:l,onMouseEnter:h,onMouseLeave:g};return n.shape==="circle"?r.jsx(N.Circle,{...w,radius:12}):r.jsx(N.Rect,{...w,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:n.shape==="square"?0:4})});Fe.displayName="ViewerSeat";const ke=t.memo(({stage:n,stageColor:s})=>{const c=d=>({stage:"🎭",table:"⬜",wall:"▬",barrier:"🛡️","dj-booth":"🎵",bar:"🍷","entry-exit":"🚪",custom:"➕"})[d||"stage"]||"🎭",o=n.config.color||s,f=c(n.config.objectType);return r.jsxs(N.Group,{x:n.position.x,y:n.position.y,rotation:n.config.rotation||0,children:[r.jsx(N.Rect,{width:n.config.width,height:n.config.height,fill:o+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),r.jsx(N.Text,{text:f,x:0,y:0,width:n.config.width,height:n.config.height*.4,fontSize:32,fill:"#ffffff",align:"center",verticalAlign:"middle"}),r.jsx(N.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"})]})});ke.displayName="ViewerStage";const Ie=t.memo(({floors:n,currentFloorId:s,onFloorChange:c,showAllOption:o,allLabel:f,position:d,className:i})=>{const v=t.useMemo(()=>[...n].sort((g,w)=>g.order-w.order),[n]),a={position:"absolute",display:"flex",alignItems:"center",gap:"8px",padding:"8px 12px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[d]},l={padding:"10px 16px",fontSize:"14px",fontWeight:500,border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",transition:"all 0.2s ease",minHeight:"44px",touchAction:"manipulation"},h={...l,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return r.jsxs("div",{className:i,style:a,children:[o&&r.jsx("button",{type:"button",onClick:()=>c(null),style:s===null?h:l,children:f}),v.map(g=>r.jsx("button",{type:"button",onClick:()=>c(g.id),style:s===g.id?h:l,children:g.name},g.id))]})});Ie.displayName="FloorSelectorBar";const Le=t.memo(({scale:n,minScale:s,maxScale:c,onZoomIn:o,onZoomOut:f,position:d,className:i})=>{const p={position:"absolute",display:"flex",flexDirection:"column",gap:"4px",padding:"8px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[d]},a={width:"44px",height:"44px",minWidth:"44px",minHeight:"44px",fontSize:"22px",fontWeight:"bold",border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s ease",touchAction:"manipulation"},l={...a,opacity:.4,cursor:"not-allowed"},h=n<c,g=n>s;return r.jsxs("div",{className:i,style:p,children:[r.jsx("button",{type:"button",onClick:o,disabled:!h,style:h?a:l,title:"Zoom In",children:"+"}),r.jsx("button",{type:"button",onClick:f,disabled:!g,style:g?a:l,title:"Zoom Out",children:"−"})]})});Le.displayName="ZoomControls";const De=t.memo(({visible:n,x:s,y:c,seat:o,currency:f,state:d})=>{if(!n||!o)return null;const i=o.seatNumber||(o.rowLabel&&o.columnLabel?`${o.rowLabel}-${o.columnLabel}`:"N/A"),v={position:"fixed",left:`${s+15}px`,top:`${c+15}px`,zIndex:1e3,pointerEvents:"none"},p={backgroundColor:"rgba(26, 26, 26, 0.95)",color:"#fff",border:"1px solid #444",borderRadius:"8px",padding:"8px 12px",fontSize:"13px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.3)",minWidth:"140px"},a={color:"#9ca3af",marginRight:"4px"},l={fontWeight:600},h={color:"#4ade80",fontWeight:600},g={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return r.jsx("div",{style:v,children:r.jsxs("div",{style:p,children:[o.sectionName&&r.jsxs("div",{style:{marginBottom:"4px"},children:[r.jsx("span",{style:a,children:"Section:"}),r.jsx("span",{style:{...l,color:"#3b82f6"},children:o.sectionName})]}),r.jsxs("div",{style:{marginBottom:"4px"},children:[r.jsx("span",{style:a,children:"Seat:"}),r.jsx("span",{style:l,children:i})]}),o.price!==void 0&&o.price>0&&d==="available"&&r.jsxs("div",{style:{marginBottom:"4px"},children:[r.jsx("span",{style:a,children:"Price:"}),r.jsxs("span",{style:h,children:[f," ",o.price.toFixed(2)]})]}),r.jsxs("div",{style:g,children:["Status: ",d]})]})})});De.displayName="SeatTooltip";const rt=({config:n,configUrl:s,floorId:c,onFloorChange:o,reservedSeats:f=[],unavailableSeats:d=[],selectedSeats:i,myReservedSeats:v=[],onSeatSelect:p,onSeatDeselect:a,onSelectionChange:l,colorOverrides:h,showTooltip:g=!0,zoomEnabled:w=!0,className:m="",onConfigLoad:j,onError:R,showFloorSelector:M,floorSelectorPosition:E="top-left",floorSelectorClassName:k,showAllFloorsOption:X=!0,allFloorsLabel:Y="All",fitToView:B=!0,fitPadding:z=40,showZoomControls:A=!0,zoomControlsPosition:G="bottom-right",zoomControlsClassName:he,minZoom:O,maxZoom:T=3,zoomStep:P=.25,touchEnabled:fe=!0})=>{const K=t.useRef(null),oe=t.useRef(null),F=Re(oe),[H,ye]=t.useState(new Set),[I,Z]=t.useState(1),[L,V]=t.useState({x:0,y:0}),[Ne,Xe]=t.useState(null),[Ye,Ae]=t.useState(1),re=t.useRef({width:0,height:0}),[J,me]=t.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Pe,loading:We,error:Q}=je(s),x=n||Pe,ge=c!==void 0,D=ge?c||null:Ne,ie=i!==void 0,$e=t.useCallback(e=>{ge||Xe(e),o?.(e)},[ge,o]),pe=x?.floors||[],Be=M!==void 0?M:pe.length>1,ae=t.useMemo(()=>x?{...x.colors,...h}:{...Ee,...h},[x,h]),q=t.useMemo(()=>{if(!x)return[];let e=x.seats.filter(u=>u.state!=="hidden");return D&&(e=e.filter(u=>u.floorId===D||!u.floorId&&D==="floor_default")),e},[x,D]),ce=t.useMemo(()=>x?.stages?D?x.stages.filter(e=>e.floorId===D||!e.floorId&&D==="floor_default"):x.stages:[],[x,D]),W=t.useMemo(()=>{if(!x||q.length===0&&ce.length===0)return null;const e=12;let u=1/0,b=1/0,S=-1/0,y=-1/0;return q.forEach(C=>{u=Math.min(u,C.position.x-e),b=Math.min(b,C.position.y-e),S=Math.max(S,C.position.x+e),y=Math.max(y,C.position.y+e)}),ce.forEach(C=>{u=Math.min(u,C.position.x),b=Math.min(b,C.position.y),S=Math.max(S,C.position.x+(C.config?.width||200)),y=Math.max(y,C.position.y+(C.config?.height||100))}),{minX:u,minY:b,maxX:S,maxY:y,width:S-u,height:y-b}},[x,q,ce]);t.useEffect(()=>{if(!B||!x||!W||F.width===0||F.height===0)return;const e=Math.abs(F.width-re.current.width),u=Math.abs(F.height-re.current.height);if(!(re.current.width===0)&&e<10&&u<10)return;re.current=F;const S=F.width,y=F.height,C=S-z*2,ne=y-z*2,le=C/W.width,be=ne/W.height,ue=Math.min(le,be,T),Je=W.minX+W.width/2,Qe=W.minY+W.height/2,et=S/2,tt=y/2,nt=et-Je*ue,st=tt-Qe*ue;Z(ue),V({x:nt,y:st}),Ae(ue)},[B,x,W,z,T,F,D]);const U=t.useMemo(()=>{const e=new Set(f),u=new Set(d),b=new Set(v);return{reserved:e,unavailable:u,myReserved:b}},[f,d,v]),xe=t.useMemo(()=>i?new Set(i):null,[i]),ee=t.useCallback(e=>{const u=e.id,b=e.seatNumber||"";return U.unavailable.has(u)||U.unavailable.has(b)?"unavailable":U.reserved.has(u)||U.reserved.has(b)?"reserved":U.myReserved.has(u)||U.myReserved.has(b)||H.has(u)?"selected":e.state},[U,H]);t.useEffect(()=>{x&&j&&j(x)},[x,j]),t.useEffect(()=>{Q&&R&&R(Q)},[Q,R]),t.useEffect(()=>{ie&&xe&&ye(xe)},[ie,xe]);const Oe=t.useCallback(e=>{const u=ee(e);if(u!=="available"&&u!=="selected")return;const b=H.has(e.id);ie||ye(S=>{const y=new Set(S);return b?y.delete(e.id):y.add(e.id),y}),b?a?.(e):(p?.(e),p||console.log("Seat selected:",e))},[ee,H,ie,p,a]),te=t.useMemo(()=>x?q.filter(e=>H.has(e.id)):[],[q,H]);t.useEffect(()=>{l?.(te)},[te,l]);const _=O!==void 0?O:Ye,Ve=t.useCallback(()=>{if(!w)return;const e=Math.min(I+P,T);if(e!==I){const u=F.width||x?.canvas.width||800,b=F.height||x?.canvas.height||600,S=u/2,y=b/2,C={x:(S-L.x)/I,y:(y-L.y)/I};Z(e),V({x:S-C.x*e,y:y-C.y*e})}},[w,I,P,T,F,x,L]),Ue=t.useCallback(()=>{if(!w)return;const e=Math.max(I-P,_);if(e!==I){const u=F.width||x?.canvas.width||800,b=F.height||x?.canvas.height||600,S=u/2,y=b/2,C={x:(S-L.x)/I,y:(y-L.y)/I};Z(e),V({x:S-C.x*e,y:y-C.y*e})}},[w,I,P,_,F,x,L]),He=t.useCallback(e=>{V({x:e.target.x(),y:e.target.y()})},[]),qe=t.useCallback(e=>{if(!w)return;e.evt.preventDefault();const u=K.current;if(!u)return;const b=u.scaleX(),S=u.getPointerPosition();if(!S)return;const y=1.1,C=e.evt.deltaY>0?b/y:b*y,ne=Math.min(Math.max(C,_),T),le={x:(S.x-L.x)/b,y:(S.y-L.y)/b},be={x:S.x-le.x*ne,y:S.y-le.y*ne};Z(ne),V(be)},[w,L,_,T]);Me(K,{enabled:fe&&w,minScale:_,maxScale:T,currentScale:I,currentPosition:L,onScaleChange:(e,u)=>{Z(e),V(u)},onPositionChange:e=>{V(e)}});const _e=t.useCallback((e,u)=>{if(!g)return;const b=u.target.getStage();if(!b)return;const S=b.getPointerPosition();if(!S)return;const y=b.container().getBoundingClientRect();me({visible:!0,x:y.left+S.x,y:y.top+S.y,seat:e,state:ee(e)})},[g,ee]),Ge=t.useCallback(()=>{me(e=>({...e,visible:!1}))},[]);if(We)return r.jsx("div",{className:`flex items-center justify-center h-full ${m}`,children:r.jsx("p",{children:"Loading seat map..."})});if(Q)return r.jsx("div",{className:`flex items-center justify-center h-full ${m}`,children:r.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",Q.message]})});if(!x)return r.jsx("div",{className:`flex items-center justify-center h-full ${m}`,children:r.jsx("p",{children:"No configuration provided"})});const Ke=F.width||x.canvas.width,Ze=F.height||x.canvas.height;return r.jsxs("div",{ref:oe,className:`relative ${m}`,style:{width:"100%",height:"100%"},children:[Be&&pe.length>0&&r.jsx(Ie,{floors:pe,currentFloorId:D,onFloorChange:$e,showAllOption:X,allLabel:Y,position:E,className:k}),r.jsxs(N.Stage,{ref:K,width:Ke,height:Ze,scaleX:I,scaleY:I,x:L.x,y:L.y,draggable:!0,onDragEnd:He,onWheel:qe,style:{backgroundColor:x.canvas.backgroundColor,cursor:"grab"},children:[r.jsx(N.Layer,{listening:!1,children:ce.map(e=>r.jsx(ke,{stage:e,stageColor:ae.stageColor},e.id))}),r.jsx(N.Layer,{children:q.map(e=>r.jsx(Fe,{seat:e,state:ee(e),colors:ae,onClick:Oe,onMouseEnter:_e,onMouseLeave:Ge},e.id))})]}),g&&r.jsx(De,{visible:J.visible,x:J.x,y:J.y,seat:J.seat,currency:ae.currency,state:J.state}),A&&w&&r.jsx(Le,{scale:I,minScale:_,maxScale:T,onZoomIn:Ve,onZoomOut:Ue,position:G,className:he}),te.length>0&&r.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[r.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",te.length,")"]}),r.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:te.map(e=>r.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${ae.currency} ${e.price.toFixed(2)}`]},e.id))})]})]})};let se=null;function it(n){se=n}function Se(){if(!se)throw new Error("Firebase database not initialized. Call initializeFirebaseForViewer(db) first.");return se}function de(){return se!==null}function at(){se=null}function Ce(n,s){const c=[],o=[],f=[];return Object.entries(n).forEach(([d,i])=>{i&&typeof i=="object"&&i.state&&(i.state==="unavailable"?f.push(d):i.state==="reserved"&&(s&&i.userId===s?c.push(d):o.push(d)))}),{myReservedSeats:c,otherReservedSeats:o,unavailableSeats:f}}function ze(n){const{seatMapId:s,currentUserId:c,enabled:o=!0,onStateChange:f,onError:d}=n,[i,v]=t.useState(null),[p,a]=t.useState(!0),[l,h]=t.useState(null),[g,w]=t.useState(null),[m,j]=t.useState([]),[R,M]=t.useState([]),[E,k]=t.useState([]),X=t.useRef(f),Y=t.useRef(d),B=t.useRef(c);return X.current=f,Y.current=d,B.current=c,t.useEffect(()=>{if(!o||!s){a(!1);return}if(!de()){a(!1),h(new Error("Firebase not initialized. Call initializeFirebaseForViewer first."));return}const z=Se(),A=$.ref(z,`seat_states/${s}`);a(!0),h(null);const G=O=>{const P=O.val()||{};v(P),a(!1),w(Date.now());const{myReservedSeats:fe,otherReservedSeats:K,unavailableSeats:oe}=Ce(P,B.current);j(fe),M(K),k(oe),X.current?.(P)},he=O=>{h(O),a(!1),Y.current?.(O)};return $.onValue(A,G,he),()=>{$.off(A)}},[s,o]),t.useEffect(()=>{if(i){const{myReservedSeats:z,otherReservedSeats:A,unavailableSeats:G}=Ce(i,c);j(z),M(A),k(G)}},[c,i]),{states:i,loading:p,error:l,lastUpdated:g,myReservedSeats:m,otherReservedSeats:R,unavailableSeats:E,reservedSeats:R}}function Te(n){const{seatMapId:s,enabled:c=!0,subscribeToChanges:o=!1,onConfigLoad:f,onError:d}=n,[i,v]=t.useState(null),[p,a]=t.useState(!0),[l,h]=t.useState(null),g=t.useRef(f),w=t.useRef(d);g.current=f,w.current=d;const m=t.useCallback(async()=>{if(!s)return;if(!de()){h(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")),a(!1);return}const j=Se(),R=$.ref(j,`seatmaps/${s}`);try{a(!0),h(null);const E=(await $.get(R)).val();if(E){const k=ot.fromFirebaseSeatMap(E);v(k),g.current?.(k)}else h(new Error(`Seat map ${s} not found in Firebase`))}catch(M){const E=M instanceof Error?M:new Error("Unknown error");h(E),w.current?.(E)}finally{a(!1)}},[s]);return t.useEffect(()=>{if(!c||!s){a(!1);return}if(m(),o&&de()){const j=Se(),R=$.ref(j,`seatmaps/${s}/meta/updated_at`);let M=!0;const E=k=>{if(M){M=!1;return}k.exists()&&m()};return $.onValue(R,E),()=>{$.off(R)}}},[s,c,o,m]),{config:i,loading:p,error:l,refetch:m}}function ct(n){const{seatMapId:s,userId:c,enabled:o=!0,subscribeToDesignChanges:f=!1,onConfigLoad:d,onStateChange:i,onError:v}=n,{config:p,loading:a,error:l,refetch:h}=Te({seatMapId:s,enabled:o,subscribeToChanges:f,onConfigLoad:d,onError:v}),{states:g,loading:w,error:m,lastUpdated:j,myReservedSeats:R,otherReservedSeats:M,unavailableSeats:E,reservedSeats:k}=ze({seatMapId:s,currentUserId:c,enabled:o,onStateChange:i,onError:v});return{config:p,loading:a||w,error:l||m,myReservedSeats:R,otherReservedSeats:M,unavailableSeats:E,reservedSeats:k,seatStates:g,lastUpdated:j,refetch:h}}exports.DEFAULT_COLORS=Ee;exports.SeatMapViewer=rt;exports.clearFirebaseInstance=at;exports.initializeFirebaseForViewer=it;exports.isFirebaseInitialized=de;exports.useConfigFetcher=je;exports.useContainerSize=Re;exports.useFirebaseConfig=Te;exports.useFirebaseSeatStates=ze;exports.useRealtimeSeatMap=ct;exports.useTouchGestures=Me;
|