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