@zonetrix/viewer 2.3.0 → 2.4.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.
- package/README.md +24 -6
- package/dist/components/SeatMapViewer.d.ts +5 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +322 -218
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -113,7 +113,7 @@ function BookingApp() {
|
|
|
113
113
|
| `onSelectionChange` | `(seats: SeatData[]) => void` | No | Callback when selection changes |
|
|
114
114
|
| `colorOverrides` | `Partial<ColorSettings>` | No | Custom colors for seat states |
|
|
115
115
|
| `showTooltip` | `boolean` | No | Show tooltips on hover (default: true) |
|
|
116
|
-
| `zoomEnabled` | `boolean` | No | Enable/disable
|
|
116
|
+
| `zoomEnabled` | `boolean` | No | Enable/disable zoom functionality (default: true) |
|
|
117
117
|
| `className` | `string` | No | Custom CSS class for the container |
|
|
118
118
|
| `onConfigLoad` | `(config: SeatMapConfig) => void` | No | Callback when config is loaded |
|
|
119
119
|
| `onError` | `(error: Error) => void` | No | Callback when an error occurs |
|
|
@@ -122,6 +122,13 @@ function BookingApp() {
|
|
|
122
122
|
| `floorSelectorClassName` | `string` | No | Custom CSS class for floor selector |
|
|
123
123
|
| `showAllFloorsOption` | `boolean` | No | Show "All" button in floor selector (default: true) |
|
|
124
124
|
| `allFloorsLabel` | `string` | No | Custom label for "All" button (default: 'All') |
|
|
125
|
+
| `fitToView` | `boolean` | No | Auto-fit content on load (default: true) |
|
|
126
|
+
| `fitPadding` | `number` | No | Padding around content when fitting (default: 40) |
|
|
127
|
+
| `showZoomControls` | `boolean` | No | Show zoom +/- buttons (default: true) |
|
|
128
|
+
| `zoomControlsPosition` | `string` | No | Position: 'top-left' \| 'top-right' \| 'bottom-left' \| 'bottom-right' (default: 'bottom-right') |
|
|
129
|
+
| `zoomControlsClassName` | `string` | No | Custom CSS class for zoom controls |
|
|
130
|
+
| `maxZoom` | `number` | No | Maximum zoom level (default: 3) |
|
|
131
|
+
| `zoomStep` | `number` | No | Zoom increment per click (default: 0.25) |
|
|
125
132
|
|
|
126
133
|
*Note: Either `config` or `configUrl` must be provided.
|
|
127
134
|
|
|
@@ -245,22 +252,33 @@ function SelectionTracker() {
|
|
|
245
252
|
}
|
|
246
253
|
```
|
|
247
254
|
|
|
248
|
-
### 5.
|
|
255
|
+
### 5. Customize Zoom Controls
|
|
249
256
|
|
|
250
257
|
```tsx
|
|
251
258
|
import { SeatMapViewer } from '@zonetrix/viewer';
|
|
252
259
|
|
|
253
|
-
function
|
|
254
|
-
const isMobile = window.innerWidth < 768;
|
|
255
|
-
|
|
260
|
+
function CustomZoom() {
|
|
256
261
|
return (
|
|
257
262
|
<SeatMapViewer
|
|
258
263
|
config={venueConfig}
|
|
259
|
-
|
|
264
|
+
// Zoom controls appear in bottom-right by default
|
|
265
|
+
zoomControlsPosition="bottom-left"
|
|
266
|
+
maxZoom={5} // Allow up to 5x zoom
|
|
267
|
+
zoomStep={0.5} // Larger zoom increments
|
|
260
268
|
onSeatSelect={(seat) => handleSelection(seat)}
|
|
261
269
|
/>
|
|
262
270
|
);
|
|
263
271
|
}
|
|
272
|
+
|
|
273
|
+
// Hide zoom controls entirely
|
|
274
|
+
function NoZoomControls() {
|
|
275
|
+
return (
|
|
276
|
+
<SeatMapViewer
|
|
277
|
+
config={venueConfig}
|
|
278
|
+
showZoomControls={false}
|
|
279
|
+
/>
|
|
280
|
+
);
|
|
281
|
+
}
|
|
264
282
|
```
|
|
265
283
|
|
|
266
284
|
### 6. Multi-floor Venue (Built-in Floor Selector)
|
|
@@ -23,5 +23,10 @@ export interface SeatMapViewerProps {
|
|
|
23
23
|
allFloorsLabel?: string;
|
|
24
24
|
fitToView?: boolean;
|
|
25
25
|
fitPadding?: number;
|
|
26
|
+
showZoomControls?: boolean;
|
|
27
|
+
zoomControlsPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
28
|
+
zoomControlsClassName?: string;
|
|
29
|
+
maxZoom?: number;
|
|
30
|
+
zoomStep?: number;
|
|
26
31
|
}
|
|
27
32
|
export declare const SeatMapViewer: React.FC<SeatMapViewerProps>;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),t=require("react"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),t=require("react"),k=require("react-konva");function P(i){const[h,u]=t.useState(null),[m,S]=t.useState(!1),[C,x]=t.useState(null),b=async()=>{if(i){S(!0),x(null);try{const f=await fetch(i);if(!f.ok)throw new Error(`Failed to fetch config: ${f.statusText}`);const c=await f.json();u(c)}catch(f){const c=f instanceof Error?f:new Error("Unknown error occurred");x(c),console.error("Failed to fetch seat map config:",c)}finally{S(!1)}}};return t.useEffect(()=>{b()},[i]),{config:h,loading:m,error:C,refetch:b}}const G={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},J=t.memo(({seat:i,state:h,colors:u,onClick:m})=>{const x={available:u.seatAvailable,reserved:u.seatReserved,selected:u.seatSelected,unavailable:u.seatUnavailable,hidden:u.seatHidden}[h],b=h==="available"||h==="selected",f=t.useCallback(()=>{b&&m(i)},[i,m,b]),c={x:i.position.x,y:i.position.y,fill:x,stroke:"#ffffff",strokeWidth:1,onClick:f,onTap:f};return i.shape==="circle"?o.jsx(k.Circle,{...c,radius:12}):o.jsx(k.Rect,{...c,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:i.shape==="square"?0:4})});J.displayName="ViewerSeat";const Q=t.memo(({stage:i,stageColor:h})=>o.jsxs(k.Group,{x:i.position.x,y:i.position.y,children:[o.jsx(k.Rect,{width:i.config.width,height:i.config.height,fill:h+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),o.jsx(k.Text,{text:i.config.label,x:0,y:0,width:i.config.width,height:i.config.height,fontSize:24,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle"})]}));Q.displayName="ViewerStage";const ee=t.memo(({floors:i,currentFloorId:h,onFloorChange:u,showAllOption:m,allLabel:S,position:C,className:x})=>{const b=t.useMemo(()=>[...i].sort((p,E)=>p.order-E.order),[i]),c={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}}[C]},M={padding:"6px 14px",fontSize:"14px",fontWeight:500,border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",transition:"all 0.2s ease"},y={...M,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return o.jsxs("div",{className:x,style:c,children:[m&&o.jsx("button",{type:"button",onClick:()=>u(null),style:h===null?y:M,children:S}),b.map(p=>o.jsx("button",{type:"button",onClick:()=>u(p.id),style:h===p.id?y:M,children:p.name},p.id))]})});ee.displayName="FloorSelectorBar";const te=t.memo(({scale:i,minScale:h,maxScale:u,onZoomIn:m,onZoomOut:S,position:C,className:x})=>{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}}[C]},c={width:"36px",height:"36px",fontSize:"20px",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"},M={...c,opacity:.4,cursor:"not-allowed"},y=i<u,p=i>h;return o.jsxs("div",{className:x,style:f,children:[o.jsx("button",{type:"button",onClick:m,disabled:!y,style:y?c:M,title:"Zoom In",children:"+"}),o.jsx("button",{type:"button",onClick:S,disabled:!p,style:p?c:M,title:"Zoom Out",children:"−"})]})});te.displayName="ZoomControls";const Ee=({config:i,configUrl:h,floorId:u,onFloorChange:m,reservedSeats:S=[],unavailableSeats:C=[],onSeatSelect:x,onSeatDeselect:b,onSelectionChange:f,colorOverrides:c,showTooltip:M=!0,zoomEnabled:y=!0,className:p="",onConfigLoad:E,onError:W,showFloorSelector:q,floorSelectorPosition:ne="top-left",floorSelectorClassName:oe,showAllFloorsOption:se=!0,allFloorsLabel:ie="All",fitToView:Y=!0,fitPadding:B=40,showZoomControls:ae=!0,zoomControlsPosition:re="bottom-right",zoomControlsClassName:le,maxZoom:F=3,zoomStep:O=.25})=>{const ce=t.useRef(null),[I,de]=t.useState(new Set),[g,H]=t.useState(1),[w,T]=t.useState({x:0,y:0}),[ue,fe]=t.useState(null),[U,K]=t.useState(!1),[he,pe]=t.useState(1),{config:ge,loading:xe,error:R}=P(h),n=i||ge,$=u!==void 0,v=$?u||null:ue,me=t.useCallback(e=>{$||fe(e),m?.(e)},[$,m]),Z=n?.floors||[],be=q!==void 0?q:Z.length>1,z=t.useMemo(()=>n?{...n.colors,...c}:{...G,...c},[n,c]),N=t.useMemo(()=>{if(!n)return[];let e=n.seats.filter(s=>s.state!=="hidden");return v&&(e=e.filter(s=>s.floorId===v||!s.floorId&&v==="floor_default")),e},[n,v]),D=t.useMemo(()=>n?.stages?v?n.stages.filter(e=>e.floorId===v||!e.floorId&&v==="floor_default"):n.stages:[],[n,v]),j=t.useMemo(()=>{if(!n||N.length===0&&D.length===0)return null;const e=12;let s=1/0,r=1/0,d=-1/0,l=-1/0;return N.forEach(a=>{s=Math.min(s,a.position.x-e),r=Math.min(r,a.position.y-e),d=Math.max(d,a.position.x+e),l=Math.max(l,a.position.y+e)}),D.forEach(a=>{s=Math.min(s,a.position.x),r=Math.min(r,a.position.y),d=Math.max(d,a.position.x+(a.config?.width||200)),l=Math.max(l,a.position.y+(a.config?.height||100))}),{minX:s,minY:r,maxX:d,maxY:l,width:d-s,height:l-r}},[n,N,D]);t.useEffect(()=>{if(!Y||U||!n||!j)return;const e=n.canvas.width,s=n.canvas.height,r=e-B*2,d=s-B*2,l=r/j.width,a=d/j.height,L=Math.min(l,a,F),we=j.minX+j.width/2,je=j.minY+j.height/2,ke=e/2,Me=s/2,Ie=ke-we*L,Ne=Me-je*L;H(L),T({x:Ie,y:Ne}),pe(L),K(!0)},[Y,U,n,j,B,F]),t.useEffect(()=>{Y&&K(!1)},[v,Y]);const A=t.useMemo(()=>{const e=new Set(S),s=new Set(C);return{reserved:e,unavailable:s}},[S,C]),V=t.useCallback(e=>{const s=e.id,r=e.seatNumber||"";return A.unavailable.has(s)||A.unavailable.has(r)?"unavailable":A.reserved.has(s)||A.reserved.has(r)?"reserved":I.has(s)?"selected":e.state},[A,I]);t.useEffect(()=>{n&&E&&E(n)},[n,E]),t.useEffect(()=>{R&&W&&W(R)},[R,W]);const ye=t.useCallback(e=>{const s=V(e);if(s!=="available"&&s!=="selected")return;const r=I.has(e.id);de(d=>{const l=new Set(d);return r?l.delete(e.id):l.add(e.id),l}),r?b?.(e):(x?.(e),x||console.log("Seat selected:",e))},[V,I,x,b]),X=t.useMemo(()=>n?N.filter(e=>I.has(e.id)):[],[N,I]);t.useEffect(()=>{f?.(X)},[X,f]);const _=he,Se=t.useCallback(()=>{if(!y)return;const e=Math.min(g+O,F);if(e!==g){const s=n?.canvas.width||800,r=n?.canvas.height||600,d=s/2,l=r/2,a={x:(d-w.x)/g,y:(l-w.y)/g};H(e),T({x:d-a.x*e,y:l-a.y*e})}},[y,g,O,F,n,w]),ve=t.useCallback(()=>{if(!y)return;const e=Math.max(g-O,_);if(e!==g){const s=n?.canvas.width||800,r=n?.canvas.height||600,d=s/2,l=r/2,a={x:(d-w.x)/g,y:(l-w.y)/g};H(e),T({x:d-a.x*e,y:l-a.y*e})}},[y,g,O,_,n,w]),Ce=t.useCallback(e=>{T({x:e.target.x(),y:e.target.y()})},[]);return xe?o.jsx("div",{className:`flex items-center justify-center h-full ${p}`,children:o.jsx("p",{children:"Loading seat map..."})}):R?o.jsx("div",{className:`flex items-center justify-center h-full ${p}`,children:o.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",R.message]})}):n?o.jsxs("div",{className:`relative ${p}`,children:[be&&Z.length>0&&o.jsx(ee,{floors:Z,currentFloorId:v,onFloorChange:me,showAllOption:se,allLabel:ie,position:ne,className:oe}),o.jsxs(k.Stage,{ref:ce,width:n.canvas.width,height:n.canvas.height,scaleX:g,scaleY:g,x:w.x,y:w.y,draggable:!0,onDragEnd:Ce,style:{backgroundColor:n.canvas.backgroundColor,cursor:"grab"},children:[o.jsx(k.Layer,{listening:!1,children:D.map(e=>o.jsx(Q,{stage:e,stageColor:z.stageColor},e.id))}),o.jsx(k.Layer,{children:N.map(e=>o.jsx(J,{seat:e,state:V(e),colors:z,onClick:ye},e.id))})]}),ae&&y&&o.jsx(te,{scale:g,minScale:_,maxScale:F,onZoomIn:Se,onZoomOut:ve,position:re,className:le}),X.length>0&&o.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[o.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",X.length,")"]}),o.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:X.map(e=>o.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${z.currency} ${e.price.toFixed(2)}`]},e.id))})]})]}):o.jsx("div",{className:`flex items-center justify-center h-full ${p}`,children:o.jsx("p",{children:"No configuration provided"})})};exports.DEFAULT_COLORS=G;exports.SeatMapViewer=Ee;exports.useConfigFetcher=P;
|
package/dist/index.mjs
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { useState as
|
|
3
|
-
import { Stage as
|
|
4
|
-
function
|
|
5
|
-
const [
|
|
6
|
-
if (
|
|
7
|
-
x(!0),
|
|
1
|
+
import { jsx as i, jsxs as w } from "react/jsx-runtime";
|
|
2
|
+
import { useState as C, useEffect as Y, useRef as Et, useCallback as M, useMemo as F, memo as Z } from "react";
|
|
3
|
+
import { Stage as Wt, Layer as tt, Group as jt, Rect as et, Text as Bt, Circle as Dt } from "react-konva";
|
|
4
|
+
function Ht(o) {
|
|
5
|
+
const [f, d] = C(null), [m, x] = C(!1), [S, g] = C(null), y = async () => {
|
|
6
|
+
if (o) {
|
|
7
|
+
x(!0), g(null);
|
|
8
8
|
try {
|
|
9
|
-
const
|
|
10
|
-
if (!
|
|
11
|
-
throw new Error(`Failed to fetch config: ${
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
} catch (
|
|
15
|
-
const
|
|
16
|
-
|
|
9
|
+
const h = await fetch(o);
|
|
10
|
+
if (!h.ok)
|
|
11
|
+
throw new Error(`Failed to fetch config: ${h.statusText}`);
|
|
12
|
+
const l = await h.json();
|
|
13
|
+
d(l);
|
|
14
|
+
} catch (h) {
|
|
15
|
+
const l = h instanceof Error ? h : new Error("Unknown error occurred");
|
|
16
|
+
g(l), console.error("Failed to fetch seat map config:", l);
|
|
17
17
|
} finally {
|
|
18
18
|
x(!1);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
}, [
|
|
25
|
-
config:
|
|
26
|
-
loading:
|
|
27
|
-
error:
|
|
28
|
-
refetch:
|
|
22
|
+
return Y(() => {
|
|
23
|
+
y();
|
|
24
|
+
}, [o]), {
|
|
25
|
+
config: f,
|
|
26
|
+
loading: m,
|
|
27
|
+
error: S,
|
|
28
|
+
refetch: y
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
-
const
|
|
31
|
+
const Tt = {
|
|
32
32
|
canvasBackground: "#1a1a1a",
|
|
33
33
|
stageColor: "#808080",
|
|
34
34
|
seatAvailable: "#2C2B30",
|
|
@@ -38,64 +38,64 @@ const Fe = {
|
|
|
38
38
|
seatHidden: "#4a4a4a",
|
|
39
39
|
gridLines: "#404040",
|
|
40
40
|
currency: "KD"
|
|
41
|
-
},
|
|
42
|
-
const
|
|
43
|
-
available:
|
|
44
|
-
reserved:
|
|
45
|
-
selected:
|
|
46
|
-
unavailable:
|
|
47
|
-
hidden:
|
|
41
|
+
}, nt = Z(({ seat: o, state: f, colors: d, onClick: m }) => {
|
|
42
|
+
const g = {
|
|
43
|
+
available: d.seatAvailable,
|
|
44
|
+
reserved: d.seatReserved,
|
|
45
|
+
selected: d.seatSelected,
|
|
46
|
+
unavailable: d.seatUnavailable,
|
|
47
|
+
hidden: d.seatHidden
|
|
48
48
|
// Hidden seats are filtered out, but included for type safety
|
|
49
|
-
}[
|
|
50
|
-
|
|
51
|
-
}, [
|
|
52
|
-
x:
|
|
53
|
-
y:
|
|
54
|
-
fill:
|
|
49
|
+
}[f], y = f === "available" || f === "selected", h = M(() => {
|
|
50
|
+
y && m(o);
|
|
51
|
+
}, [o, m, y]), l = {
|
|
52
|
+
x: o.position.x,
|
|
53
|
+
y: o.position.y,
|
|
54
|
+
fill: g,
|
|
55
55
|
stroke: "#ffffff",
|
|
56
56
|
strokeWidth: 1,
|
|
57
|
-
onClick:
|
|
58
|
-
onTap:
|
|
57
|
+
onClick: h,
|
|
58
|
+
onTap: h
|
|
59
59
|
};
|
|
60
|
-
return
|
|
61
|
-
|
|
60
|
+
return o.shape === "circle" ? /* @__PURE__ */ i(
|
|
61
|
+
Dt,
|
|
62
62
|
{
|
|
63
|
-
...
|
|
63
|
+
...l,
|
|
64
64
|
radius: 12
|
|
65
65
|
}
|
|
66
|
-
) : /* @__PURE__ */
|
|
67
|
-
|
|
66
|
+
) : /* @__PURE__ */ i(
|
|
67
|
+
et,
|
|
68
68
|
{
|
|
69
|
-
...
|
|
69
|
+
...l,
|
|
70
70
|
width: 24,
|
|
71
71
|
height: 24,
|
|
72
72
|
offsetX: 12,
|
|
73
73
|
offsetY: 12,
|
|
74
|
-
cornerRadius:
|
|
74
|
+
cornerRadius: o.shape === "square" ? 0 : 4
|
|
75
75
|
}
|
|
76
76
|
);
|
|
77
77
|
});
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
/* @__PURE__ */
|
|
81
|
-
|
|
78
|
+
nt.displayName = "ViewerSeat";
|
|
79
|
+
const ot = Z(({ stage: o, stageColor: f }) => /* @__PURE__ */ w(jt, { x: o.position.x, y: o.position.y, children: [
|
|
80
|
+
/* @__PURE__ */ i(
|
|
81
|
+
et,
|
|
82
82
|
{
|
|
83
|
-
width:
|
|
84
|
-
height:
|
|
85
|
-
fill:
|
|
83
|
+
width: o.config.width,
|
|
84
|
+
height: o.config.height,
|
|
85
|
+
fill: f + "80",
|
|
86
86
|
stroke: "#ffffff",
|
|
87
87
|
strokeWidth: 2,
|
|
88
88
|
cornerRadius: 10
|
|
89
89
|
}
|
|
90
90
|
),
|
|
91
|
-
/* @__PURE__ */
|
|
92
|
-
|
|
91
|
+
/* @__PURE__ */ i(
|
|
92
|
+
Bt,
|
|
93
93
|
{
|
|
94
|
-
text:
|
|
94
|
+
text: o.config.label,
|
|
95
95
|
x: 0,
|
|
96
96
|
y: 0,
|
|
97
|
-
width:
|
|
98
|
-
height:
|
|
97
|
+
width: o.config.width,
|
|
98
|
+
height: o.config.height,
|
|
99
99
|
fontSize: 24,
|
|
100
100
|
fontStyle: "bold",
|
|
101
101
|
fill: "#ffffff",
|
|
@@ -104,20 +104,20 @@ const ne = O(({ stage: i, stageColor: h }) => /* @__PURE__ */ v(ke, { x: i.posit
|
|
|
104
104
|
}
|
|
105
105
|
)
|
|
106
106
|
] }));
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
floors:
|
|
110
|
-
currentFloorId:
|
|
111
|
-
onFloorChange:
|
|
112
|
-
showAllOption:
|
|
107
|
+
ot.displayName = "ViewerStage";
|
|
108
|
+
const it = Z(({
|
|
109
|
+
floors: o,
|
|
110
|
+
currentFloorId: f,
|
|
111
|
+
onFloorChange: d,
|
|
112
|
+
showAllOption: m,
|
|
113
113
|
allLabel: x,
|
|
114
|
-
position:
|
|
115
|
-
className:
|
|
114
|
+
position: S,
|
|
115
|
+
className: g
|
|
116
116
|
}) => {
|
|
117
|
-
const
|
|
118
|
-
() => [...
|
|
119
|
-
[
|
|
120
|
-
),
|
|
117
|
+
const y = F(
|
|
118
|
+
() => [...o].sort((u, A) => u.order - A.order),
|
|
119
|
+
[o]
|
|
120
|
+
), l = {
|
|
121
121
|
position: "absolute",
|
|
122
122
|
display: "flex",
|
|
123
123
|
alignItems: "center",
|
|
@@ -132,8 +132,8 @@ const ie = O(({
|
|
|
132
132
|
"top-right": { top: 0, right: 0 },
|
|
133
133
|
"bottom-left": { bottom: 0, left: 0 },
|
|
134
134
|
"bottom-right": { bottom: 0, right: 0 }
|
|
135
|
-
}[
|
|
136
|
-
},
|
|
135
|
+
}[S]
|
|
136
|
+
}, N = {
|
|
137
137
|
padding: "6px 14px",
|
|
138
138
|
fontSize: "14px",
|
|
139
139
|
fontWeight: 500,
|
|
@@ -143,197 +143,301 @@ const ie = O(({
|
|
|
143
143
|
color: "#fff",
|
|
144
144
|
cursor: "pointer",
|
|
145
145
|
transition: "all 0.2s ease"
|
|
146
|
-
},
|
|
147
|
-
|
|
146
|
+
}, b = {
|
|
147
|
+
...N,
|
|
148
148
|
backgroundColor: "#3A7DE5",
|
|
149
149
|
borderColor: "#3A7DE5"
|
|
150
150
|
};
|
|
151
|
-
return /* @__PURE__ */
|
|
152
|
-
|
|
151
|
+
return /* @__PURE__ */ w("div", { className: g, style: l, children: [
|
|
152
|
+
m && /* @__PURE__ */ i(
|
|
153
153
|
"button",
|
|
154
154
|
{
|
|
155
155
|
type: "button",
|
|
156
|
-
onClick: () =>
|
|
157
|
-
style:
|
|
156
|
+
onClick: () => d(null),
|
|
157
|
+
style: f === null ? b : N,
|
|
158
158
|
children: x
|
|
159
159
|
}
|
|
160
160
|
),
|
|
161
|
-
|
|
161
|
+
y.map((u) => /* @__PURE__ */ i(
|
|
162
162
|
"button",
|
|
163
163
|
{
|
|
164
164
|
type: "button",
|
|
165
|
-
onClick: () =>
|
|
166
|
-
style:
|
|
165
|
+
onClick: () => d(u.id),
|
|
166
|
+
style: f === u.id ? b : N,
|
|
167
167
|
children: u.name
|
|
168
168
|
},
|
|
169
169
|
u.id
|
|
170
170
|
))
|
|
171
171
|
] });
|
|
172
172
|
});
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
173
|
+
it.displayName = "FloorSelectorBar";
|
|
174
|
+
const st = Z(({
|
|
175
|
+
scale: o,
|
|
176
|
+
minScale: f,
|
|
177
|
+
maxScale: d,
|
|
178
|
+
onZoomIn: m,
|
|
179
|
+
onZoomOut: x,
|
|
180
|
+
position: S,
|
|
181
|
+
className: g
|
|
182
|
+
}) => {
|
|
183
|
+
const h = {
|
|
184
|
+
position: "absolute",
|
|
185
|
+
display: "flex",
|
|
186
|
+
flexDirection: "column",
|
|
187
|
+
gap: "4px",
|
|
188
|
+
padding: "8px",
|
|
189
|
+
backgroundColor: "rgba(26, 26, 26, 0.95)",
|
|
190
|
+
borderRadius: "8px",
|
|
191
|
+
margin: "12px",
|
|
192
|
+
zIndex: 10,
|
|
193
|
+
...{
|
|
194
|
+
"top-left": { top: 0, left: 0 },
|
|
195
|
+
"top-right": { top: 0, right: 0 },
|
|
196
|
+
"bottom-left": { bottom: 0, left: 0 },
|
|
197
|
+
"bottom-right": { bottom: 0, right: 0 }
|
|
198
|
+
}[S]
|
|
199
|
+
}, l = {
|
|
200
|
+
width: "36px",
|
|
201
|
+
height: "36px",
|
|
202
|
+
fontSize: "20px",
|
|
203
|
+
fontWeight: "bold",
|
|
204
|
+
border: "1px solid #444",
|
|
205
|
+
borderRadius: "6px",
|
|
206
|
+
backgroundColor: "transparent",
|
|
207
|
+
color: "#fff",
|
|
208
|
+
cursor: "pointer",
|
|
209
|
+
display: "flex",
|
|
210
|
+
alignItems: "center",
|
|
211
|
+
justifyContent: "center",
|
|
212
|
+
transition: "all 0.2s ease"
|
|
213
|
+
}, N = {
|
|
214
|
+
...l,
|
|
215
|
+
opacity: 0.4,
|
|
216
|
+
cursor: "not-allowed"
|
|
217
|
+
}, b = o < d, u = o > f;
|
|
218
|
+
return /* @__PURE__ */ w("div", { className: g, style: h, children: [
|
|
219
|
+
/* @__PURE__ */ i(
|
|
220
|
+
"button",
|
|
221
|
+
{
|
|
222
|
+
type: "button",
|
|
223
|
+
onClick: m,
|
|
224
|
+
disabled: !b,
|
|
225
|
+
style: b ? l : N,
|
|
226
|
+
title: "Zoom In",
|
|
227
|
+
children: "+"
|
|
228
|
+
}
|
|
229
|
+
),
|
|
230
|
+
/* @__PURE__ */ i(
|
|
231
|
+
"button",
|
|
232
|
+
{
|
|
233
|
+
type: "button",
|
|
234
|
+
onClick: x,
|
|
235
|
+
disabled: !u,
|
|
236
|
+
style: u ? l : N,
|
|
237
|
+
title: "Zoom Out",
|
|
238
|
+
children: "−"
|
|
239
|
+
}
|
|
240
|
+
)
|
|
241
|
+
] });
|
|
242
|
+
});
|
|
243
|
+
st.displayName = "ZoomControls";
|
|
244
|
+
const zt = ({
|
|
245
|
+
config: o,
|
|
246
|
+
configUrl: f,
|
|
247
|
+
floorId: d,
|
|
248
|
+
onFloorChange: m,
|
|
179
249
|
reservedSeats: x = [],
|
|
180
|
-
unavailableSeats:
|
|
181
|
-
onSeatSelect:
|
|
182
|
-
onSeatDeselect:
|
|
183
|
-
onSelectionChange:
|
|
184
|
-
colorOverrides:
|
|
185
|
-
showTooltip:
|
|
186
|
-
zoomEnabled:
|
|
250
|
+
unavailableSeats: S = [],
|
|
251
|
+
onSeatSelect: g,
|
|
252
|
+
onSeatDeselect: y,
|
|
253
|
+
onSelectionChange: h,
|
|
254
|
+
colorOverrides: l,
|
|
255
|
+
showTooltip: N = !0,
|
|
256
|
+
zoomEnabled: b = !0,
|
|
187
257
|
className: u = "",
|
|
188
|
-
onConfigLoad:
|
|
189
|
-
onError:
|
|
258
|
+
onConfigLoad: A,
|
|
259
|
+
onError: z,
|
|
190
260
|
// Floor selector props
|
|
191
|
-
showFloorSelector:
|
|
192
|
-
floorSelectorPosition:
|
|
193
|
-
floorSelectorClassName:
|
|
194
|
-
showAllFloorsOption:
|
|
195
|
-
allFloorsLabel:
|
|
196
|
-
fitToView:
|
|
197
|
-
fitPadding:
|
|
261
|
+
showFloorSelector: P,
|
|
262
|
+
floorSelectorPosition: rt = "top-left",
|
|
263
|
+
floorSelectorClassName: at,
|
|
264
|
+
showAllFloorsOption: lt = !0,
|
|
265
|
+
allFloorsLabel: ct = "All",
|
|
266
|
+
fitToView: D = !0,
|
|
267
|
+
fitPadding: L = 40,
|
|
268
|
+
// Zoom controls
|
|
269
|
+
showZoomControls: dt = !0,
|
|
270
|
+
zoomControlsPosition: ht = "bottom-right",
|
|
271
|
+
zoomControlsClassName: ft,
|
|
272
|
+
maxZoom: E = 3,
|
|
273
|
+
zoomStep: H = 0.25
|
|
198
274
|
}) => {
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
}, [
|
|
202
|
-
() =>
|
|
203
|
-
[
|
|
204
|
-
),
|
|
205
|
-
if (!
|
|
206
|
-
let
|
|
207
|
-
return
|
|
208
|
-
(
|
|
209
|
-
)),
|
|
210
|
-
}, [
|
|
211
|
-
(
|
|
212
|
-
) :
|
|
213
|
-
if (!
|
|
275
|
+
const ut = Et(null), [R, pt] = C(/* @__PURE__ */ new Set()), [p, V] = C(1), [k, T] = C({ x: 0, y: 0 }), [gt, mt] = C(null), [J, Q] = C(!1), [yt, bt] = C(1), { config: xt, loading: vt, error: W } = Ht(f), e = o || xt, _ = d !== void 0, v = _ ? d || null : gt, St = M((t) => {
|
|
276
|
+
_ || mt(t), m?.(t);
|
|
277
|
+
}, [_, m]), U = e?.floors || [], wt = P !== void 0 ? P : U.length > 1, q = F(
|
|
278
|
+
() => e ? { ...e.colors, ...l } : { ...Tt, ...l },
|
|
279
|
+
[e, l]
|
|
280
|
+
), X = F(() => {
|
|
281
|
+
if (!e) return [];
|
|
282
|
+
let t = e.seats.filter((n) => n.state !== "hidden");
|
|
283
|
+
return v && (t = t.filter(
|
|
284
|
+
(n) => n.floorId === v || !n.floorId && v === "floor_default"
|
|
285
|
+
)), t;
|
|
286
|
+
}, [e, v]), $ = F(() => e?.stages ? v ? e.stages.filter(
|
|
287
|
+
(t) => t.floorId === v || !t.floorId && v === "floor_default"
|
|
288
|
+
) : e.stages : [], [e, v]), I = F(() => {
|
|
289
|
+
if (!e || X.length === 0 && $.length === 0)
|
|
214
290
|
return null;
|
|
215
|
-
const
|
|
216
|
-
let
|
|
217
|
-
return
|
|
218
|
-
|
|
219
|
-
}),
|
|
220
|
-
|
|
221
|
-
}), { minX:
|
|
222
|
-
}, [
|
|
223
|
-
|
|
224
|
-
if (!
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
}, [
|
|
228
|
-
|
|
229
|
-
}, [
|
|
230
|
-
const
|
|
231
|
-
const
|
|
232
|
-
return { reserved:
|
|
233
|
-
}, [x,
|
|
234
|
-
const
|
|
235
|
-
return
|
|
236
|
-
}, [
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}, [
|
|
240
|
-
|
|
241
|
-
}, [
|
|
242
|
-
const
|
|
243
|
-
const
|
|
244
|
-
if (
|
|
291
|
+
const t = 12;
|
|
292
|
+
let n = 1 / 0, r = 1 / 0, c = -1 / 0, a = -1 / 0;
|
|
293
|
+
return X.forEach((s) => {
|
|
294
|
+
n = Math.min(n, s.position.x - t), r = Math.min(r, s.position.y - t), c = Math.max(c, s.position.x + t), a = Math.max(a, s.position.y + t);
|
|
295
|
+
}), $.forEach((s) => {
|
|
296
|
+
n = Math.min(n, s.position.x), r = Math.min(r, s.position.y), c = Math.max(c, s.position.x + (s.config?.width || 200)), a = Math.max(a, s.position.y + (s.config?.height || 100));
|
|
297
|
+
}), { minX: n, minY: r, maxX: c, maxY: a, width: c - n, height: a - r };
|
|
298
|
+
}, [e, X, $]);
|
|
299
|
+
Y(() => {
|
|
300
|
+
if (!D || J || !e || !I) return;
|
|
301
|
+
const t = e.canvas.width, n = e.canvas.height, r = t - L * 2, c = n - L * 2, a = r / I.width, s = c / I.height, O = Math.min(a, s, E), Mt = I.minX + I.width / 2, Ft = I.minY + I.height / 2, Rt = t / 2, Xt = n / 2, Yt = Rt - Mt * O, At = Xt - Ft * O;
|
|
302
|
+
V(O), T({ x: Yt, y: At }), bt(O), Q(!0);
|
|
303
|
+
}, [D, J, e, I, L, E]), Y(() => {
|
|
304
|
+
D && Q(!1);
|
|
305
|
+
}, [v, D]);
|
|
306
|
+
const j = F(() => {
|
|
307
|
+
const t = new Set(x), n = new Set(S);
|
|
308
|
+
return { reserved: t, unavailable: n };
|
|
309
|
+
}, [x, S]), G = M((t) => {
|
|
310
|
+
const n = t.id, r = t.seatNumber || "";
|
|
311
|
+
return j.unavailable.has(n) || j.unavailable.has(r) ? "unavailable" : j.reserved.has(n) || j.reserved.has(r) ? "reserved" : R.has(n) ? "selected" : t.state;
|
|
312
|
+
}, [j, R]);
|
|
313
|
+
Y(() => {
|
|
314
|
+
e && A && A(e);
|
|
315
|
+
}, [e, A]), Y(() => {
|
|
316
|
+
W && z && z(W);
|
|
317
|
+
}, [W, z]);
|
|
318
|
+
const Ct = M((t) => {
|
|
319
|
+
const n = G(t);
|
|
320
|
+
if (n !== "available" && n !== "selected")
|
|
245
321
|
return;
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
const a = new Set(
|
|
249
|
-
return
|
|
250
|
-
}),
|
|
251
|
-
}, [
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}, [
|
|
255
|
-
const
|
|
256
|
-
if (!
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
322
|
+
const r = R.has(t.id);
|
|
323
|
+
pt((c) => {
|
|
324
|
+
const a = new Set(c);
|
|
325
|
+
return r ? a.delete(t.id) : a.add(t.id), a;
|
|
326
|
+
}), r ? y?.(t) : (g?.(t), g || console.log("Seat selected:", t));
|
|
327
|
+
}, [G, R, g, y]), B = F(() => e ? X.filter((t) => R.has(t.id)) : [], [X, R]);
|
|
328
|
+
Y(() => {
|
|
329
|
+
h?.(B);
|
|
330
|
+
}, [B, h]);
|
|
331
|
+
const K = yt, kt = M(() => {
|
|
332
|
+
if (!b) return;
|
|
333
|
+
const t = Math.min(p + H, E);
|
|
334
|
+
if (t !== p) {
|
|
335
|
+
const n = e?.canvas.width || 800, r = e?.canvas.height || 600, c = n / 2, a = r / 2, s = {
|
|
336
|
+
x: (c - k.x) / p,
|
|
337
|
+
y: (a - k.y) / p
|
|
338
|
+
};
|
|
339
|
+
V(t), T({
|
|
340
|
+
x: c - s.x * t,
|
|
341
|
+
y: a - s.y * t
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}, [b, p, H, E, e, k]), It = M(() => {
|
|
345
|
+
if (!b) return;
|
|
346
|
+
const t = Math.max(p - H, K);
|
|
347
|
+
if (t !== p) {
|
|
348
|
+
const n = e?.canvas.width || 800, r = e?.canvas.height || 600, c = n / 2, a = r / 2, s = {
|
|
349
|
+
x: (c - k.x) / p,
|
|
350
|
+
y: (a - k.y) / p
|
|
351
|
+
};
|
|
352
|
+
V(t), T({
|
|
353
|
+
x: c - s.x * t,
|
|
354
|
+
y: a - s.y * t
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}, [b, p, H, K, e, k]), Nt = M((t) => {
|
|
358
|
+
T({
|
|
359
|
+
x: t.target.x(),
|
|
360
|
+
y: t.target.y()
|
|
270
361
|
});
|
|
271
|
-
}, [
|
|
272
|
-
return
|
|
362
|
+
}, []);
|
|
363
|
+
return vt ? /* @__PURE__ */ i("div", { className: `flex items-center justify-center h-full ${u}`, children: /* @__PURE__ */ i("p", { children: "Loading seat map..." }) }) : W ? /* @__PURE__ */ i("div", { className: `flex items-center justify-center h-full ${u}`, children: /* @__PURE__ */ w("p", { className: "text-red-500", children: [
|
|
273
364
|
"Error loading seat map: ",
|
|
274
|
-
|
|
275
|
-
] }) }) :
|
|
276
|
-
|
|
277
|
-
|
|
365
|
+
W.message
|
|
366
|
+
] }) }) : e ? /* @__PURE__ */ w("div", { className: `relative ${u}`, children: [
|
|
367
|
+
wt && U.length > 0 && /* @__PURE__ */ i(
|
|
368
|
+
it,
|
|
278
369
|
{
|
|
279
|
-
floors:
|
|
280
|
-
currentFloorId:
|
|
281
|
-
onFloorChange:
|
|
282
|
-
showAllOption:
|
|
283
|
-
allLabel:
|
|
284
|
-
position:
|
|
285
|
-
className:
|
|
370
|
+
floors: U,
|
|
371
|
+
currentFloorId: v,
|
|
372
|
+
onFloorChange: St,
|
|
373
|
+
showAllOption: lt,
|
|
374
|
+
allLabel: ct,
|
|
375
|
+
position: rt,
|
|
376
|
+
className: at
|
|
286
377
|
}
|
|
287
378
|
),
|
|
288
|
-
/* @__PURE__ */
|
|
289
|
-
|
|
379
|
+
/* @__PURE__ */ w(
|
|
380
|
+
Wt,
|
|
290
381
|
{
|
|
291
|
-
ref:
|
|
292
|
-
width:
|
|
293
|
-
height:
|
|
294
|
-
scaleX:
|
|
295
|
-
scaleY:
|
|
296
|
-
x:
|
|
297
|
-
y:
|
|
298
|
-
|
|
299
|
-
|
|
382
|
+
ref: ut,
|
|
383
|
+
width: e.canvas.width,
|
|
384
|
+
height: e.canvas.height,
|
|
385
|
+
scaleX: p,
|
|
386
|
+
scaleY: p,
|
|
387
|
+
x: k.x,
|
|
388
|
+
y: k.y,
|
|
389
|
+
draggable: !0,
|
|
390
|
+
onDragEnd: Nt,
|
|
391
|
+
style: { backgroundColor: e.canvas.backgroundColor, cursor: "grab" },
|
|
300
392
|
children: [
|
|
301
|
-
/* @__PURE__ */
|
|
302
|
-
|
|
393
|
+
/* @__PURE__ */ i(tt, { listening: !1, children: $.map((t) => /* @__PURE__ */ i(
|
|
394
|
+
ot,
|
|
303
395
|
{
|
|
304
|
-
stage:
|
|
305
|
-
stageColor:
|
|
396
|
+
stage: t,
|
|
397
|
+
stageColor: q.stageColor
|
|
306
398
|
},
|
|
307
|
-
|
|
399
|
+
t.id
|
|
308
400
|
)) }),
|
|
309
|
-
/* @__PURE__ */
|
|
310
|
-
|
|
401
|
+
/* @__PURE__ */ i(tt, { children: X.map((t) => /* @__PURE__ */ i(
|
|
402
|
+
nt,
|
|
311
403
|
{
|
|
312
|
-
seat:
|
|
313
|
-
state:
|
|
314
|
-
colors:
|
|
315
|
-
onClick:
|
|
404
|
+
seat: t,
|
|
405
|
+
state: G(t),
|
|
406
|
+
colors: q,
|
|
407
|
+
onClick: Ct
|
|
316
408
|
},
|
|
317
|
-
|
|
409
|
+
t.id
|
|
318
410
|
)) })
|
|
319
411
|
]
|
|
320
412
|
}
|
|
321
413
|
),
|
|
322
|
-
|
|
323
|
-
|
|
414
|
+
dt && b && /* @__PURE__ */ i(
|
|
415
|
+
st,
|
|
416
|
+
{
|
|
417
|
+
scale: p,
|
|
418
|
+
minScale: K,
|
|
419
|
+
maxScale: E,
|
|
420
|
+
onZoomIn: kt,
|
|
421
|
+
onZoomOut: It,
|
|
422
|
+
position: ht,
|
|
423
|
+
className: ft
|
|
424
|
+
}
|
|
425
|
+
),
|
|
426
|
+
B.length > 0 && /* @__PURE__ */ w("div", { className: "absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg", children: [
|
|
427
|
+
/* @__PURE__ */ w("h3", { className: "font-semibold mb-2", children: [
|
|
324
428
|
"Selected Seats (",
|
|
325
|
-
|
|
429
|
+
B.length,
|
|
326
430
|
")"
|
|
327
431
|
] }),
|
|
328
|
-
/* @__PURE__ */
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
] },
|
|
432
|
+
/* @__PURE__ */ i("div", { className: "max-h-48 overflow-y-auto space-y-1", children: B.map((t) => /* @__PURE__ */ w("div", { className: "text-sm", children: [
|
|
433
|
+
t.seatNumber,
|
|
434
|
+
t.price && ` - ${q.currency} ${t.price.toFixed(2)}`
|
|
435
|
+
] }, t.id)) })
|
|
332
436
|
] })
|
|
333
|
-
] }) : /* @__PURE__ */
|
|
437
|
+
] }) : /* @__PURE__ */ i("div", { className: `flex items-center justify-center h-full ${u}`, children: /* @__PURE__ */ i("p", { children: "No configuration provided" }) });
|
|
334
438
|
};
|
|
335
439
|
export {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
440
|
+
Tt as DEFAULT_COLORS,
|
|
441
|
+
zt as SeatMapViewer,
|
|
442
|
+
Ht as useConfigFetcher
|
|
339
443
|
};
|