UNPKG

tessitura-seatmap

Version:

Tessitura-integrated seatmap components, built with React and Mantine (includes SYOS).

23 lines (22 loc) 18.3 kB
(function(i,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("react"),require("react-svg-seatmap"),require("@mantine/core"),require("@mantine/notifications"),require("@tabler/icons-react")):typeof define=="function"&&define.amd?define(["exports","react","react-svg-seatmap","@mantine/core","@mantine/notifications","@tabler/icons-react"],n):(i=typeof globalThis<"u"?globalThis:i||self,n(i.index={},i.React,i.ReactSvgSeatmap,i.MantineCore,i.MantineNotifications,i.TablerIconsReact))})(this,function(i,n,y,c,se,ee){"use strict";var Re=Object.defineProperty;var pe=i=>{throw TypeError(i)};var Pe=(i,n,y)=>n in i?Re(i,n,{enumerable:!0,configurable:!0,writable:!0,value:y}):i[n]=y;var F=(i,n,y)=>Pe(i,typeof n!="symbol"?n+"":n,y),me=(i,n,y)=>n.has(i)||pe("Cannot "+y);var M=(i,n,y)=>(me(i,n,"read from private field"),y?y.call(i):n.get(i)),ie=(i,n,y)=>n.has(i)?pe("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(i):n.set(i,y),Se=(i,n,y,c)=>(me(i,n,"write to private field"),c?c.call(i,y):n.set(i,y),y);var B,C;var te={exports:{}},H={};/** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */var ce;function he(){if(ce)return H;ce=1;var p=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function f(h,m,d){var T=null;if(d!==void 0&&(T=""+d),m.key!==void 0&&(T=""+m.key),"key"in m){d={};for(var b in m)b!=="key"&&(d[b]=m[b])}else d=m;return m=d.ref,{$$typeof:p,type:h,key:T,ref:m!==void 0?m:null,props:d}}return H.Fragment=r,H.jsx=f,H.jsxs=f,H}var J={};/** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */var le;function be(){return le||(le=1,process.env.NODE_ENV!=="production"&&function(){function p(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===R?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case D:return"Fragment";case N:return"Profiler";case Y:return"StrictMode";case u:return"Suspense";case X:return"SuspenseList";case $:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case E:return"Portal";case v:return(e.displayName||"Context")+".Provider";case O:return(e._context.displayName||"Context")+".Consumer";case A:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case V:return t=e.displayName||null,t!==null?t:p(e.type)||"Memo";case z:t=e._payload,e=e._init;try{return p(e(t))}catch{}}return null}function r(e){return""+e}function f(e){try{r(e);var t=!1}catch{t=!0}if(t){t=console;var l=t.error,S=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return l.call(t,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",S),r(e)}}function h(e){if(e===D)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===z)return"<...>";try{var t=p(e);return t?"<"+t+">":"<...>"}catch{return"<...>"}}function m(){var e=L.A;return e===null?null:e.getOwner()}function d(){return Error("react-stack-top-frame")}function T(e){if(U.call(e,"key")){var t=Object.getOwnPropertyDescriptor(e,"key").get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function b(e,t){function l(){ne||(ne=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}l.isReactWarning=!0,Object.defineProperty(e,"key",{get:l,configurable:!0})}function k(){var e=p(this.type);return K[e]||(K[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function x(e,t,l,S,I,P,W,ae){return l=P.ref,e={$$typeof:G,type:e,key:t,props:P,_owner:I},(l!==void 0?l:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:k}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:W}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:ae}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function _(e,t,l,S,I,P,W,ae){var j=t.children;if(j!==void 0)if(S)if(re(j)){for(S=0;S<j.length;S++)w(j[S]);Object.freeze&&Object.freeze(j)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else w(j);if(U.call(t,"key")){j=p(e);var Z=Object.keys(t).filter(function(Ee){return Ee!=="key"});S=0<Z.length?"{key: someKey, "+Z.join(": ..., ")+": ...}":"{key: someKey}",o[j+S]||(Z=0<Z.length?"{"+Z.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`,S,j,Z,j),o[j+S]=!0)}if(j=null,l!==void 0&&(f(l),j=""+l),T(t)&&(f(t.key),j=""+t.key),"key"in t){l={};for(var oe in t)oe!=="key"&&(l[oe]=t[oe])}else l=t;return j&&b(l,typeof e=="function"?e.displayName||e.name||"Unknown":e),x(e,j,P,I,m(),l,W,ae)}function w(e){typeof e=="object"&&e!==null&&e.$$typeof===G&&e._store&&(e._store.validated=1)}var g=n,G=Symbol.for("react.transitional.element"),E=Symbol.for("react.portal"),D=Symbol.for("react.fragment"),Y=Symbol.for("react.strict_mode"),N=Symbol.for("react.profiler"),O=Symbol.for("react.consumer"),v=Symbol.for("react.context"),A=Symbol.for("react.forward_ref"),u=Symbol.for("react.suspense"),X=Symbol.for("react.suspense_list"),V=Symbol.for("react.memo"),z=Symbol.for("react.lazy"),$=Symbol.for("react.activity"),R=Symbol.for("react.client.reference"),L=g.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,U=Object.prototype.hasOwnProperty,re=Array.isArray,Q=console.createTask?console.createTask:function(){return null};g={"react-stack-bottom-frame":function(e){return e()}};var ne,K={},q=g["react-stack-bottom-frame"].bind(g,d)(),a=Q(h(d)),o={};J.Fragment=D,J.jsx=function(e,t,l,S,I){var P=1e4>L.recentlyCreatedOwnerStacks++;return _(e,t,l,!1,S,I,P?Error("react-stack-top-frame"):q,P?Q(h(e)):a)},J.jsxs=function(e,t,l,S,I){var P=1e4>L.recentlyCreatedOwnerStacks++;return _(e,t,l,!0,S,I,P?Error("react-stack-top-frame"):q,P?Q(h(e)):a)}}()),J}var ue;function ge(){return ue||(ue=1,process.env.NODE_ENV==="production"?te.exports=he():te.exports=be()),te.exports}var s=ge();class de{constructor(r){ie(this,B);ie(this,C,async r=>{const f=await fetch(`${M(this,B)}/${r}`);if(!f.ok)throw new Error(`Error fetching data: ${f.statusText}`);return f.json()});F(this,"getPerformanceDetails",async r=>M(this,C).call(this,`TXN/Performances/${r}`));F(this,"getPerformanceSeats",async(r,f,h)=>M(this,C).call(this,`TXN/Performances/${r}/Seats?constituentId=${f}&modeOfSaleId=${h}&performanceId=${r}`));F(this,"getZoneAvailability",async r=>M(this,C).call(this,`TXN/Performances/ZoneAvailabilities?performanceIds=${r}`));F(this,"getPerformancePriceTypes",async(r,f,h)=>M(this,C).call(this,`TXN/Performances/Prices?modeOfSaleId=${f}&performanceIds=${r}&sourceId=${h}`));F(this,"getPriceTypeDetails",async(r,f,h)=>M(this,C).call(this,`TXN/PriceTypes/Details?modeOfSaleId=${f}&performanceIds=${r}&sourceId=${h}`));F(this,"getFacilityScreens",async r=>M(this,C).call(this,`TXN/Facilities/${r}/Screens`));F(this,"getSeatStatuses",async()=>M(this,C).call(this,"ReferenceData/SeatStatuses"));Se(this,B,r)}}B=new WeakMap,C=new WeakMap;const fe=p=>{const r=["#5a8ef7","#de5472","#9b98e5","#f8d376","#e89171","#72a588","#abd0f1","#61d4a4","#f7b7a3","#b5ead7","#ffdac1","#c7ceea","#ffb7b2","#b2f7ef","#f6abb6","#b5ead7","#c9cba3","#ffe156","#6a0572","#ab83a1","#f67280","#355c7d","#99b898","#f8b195","#f6cd61","#3ec300","#f9d423","#e27d60","#85dcb0","#e8a87c","#c38d9e","#41b3a3","#f38181","#a8e063","#f7cac9","#92a8d1","#f9b7b7","#b8a9c9","#ffb347","#b2d7e4"];return r[p%r.length]},Te=({endpoint:p,performanceId:r,svg:f,constituentId:h,modeOfSaleId:m})=>{const[,d]=n.useState(null),T=["allocations","screens","sections","zones","holds","seatType","stairs"],[b,k]=n.useState("allocations"),[x,_]=n.useState({}),[w,g]=n.useState(!0);n.useEffect(()=>{const N=async()=>{try{console.log("Fetching data...");const v=new de(p),A=r.toString(),u=await v.getPerformanceSeats(A,h,m);return g(!1),u}catch(v){console.error("Error fetching data:",v)}},O=v=>{const A={allocations:"SeatStatusId",screens:"ScreenId",sections:"SectionId",zones:"ZoneId",holds:"HoldCodeId",seatType:"SeatTypeId",stairs:"HasStairs"},u={};for(const X of T){const V=A[X||"allocations"],z=v.map(R=>({id:R.Id,cssSelector:`#seat-${R.SeatNumber}-${R.SeatRow.replace("*","_")}-${R.ScreenId}`,displayGroup:V==="HasStairs"?R.HasStairs?"Has Stairs":"No Stairs":R[V].toString()})),$=z.reduce((R,L)=>{const U=L.displayGroup;return R[U]||(R[U]=fe(Object.keys(R).length)),R},{});u[X]={seats:z,groupMapping:$}}_(u)};N().then(v=>{O(v),console.log("Finished fetching data")})},[h,p,m,r,T]);const{seatData:G,displayGroupMapping:E}=n.useMemo(()=>{var v,A;const N=((v=x[b||"allocations"])==null?void 0:v.seats)||[],O=((A=x[b||"allocations"])==null?void 0:A.groupMapping)||{};return{seatData:N,displayGroupMapping:O}},[x,b]),D=c.createTheme({}),Y=n.useMemo(()=>{const N=(O,v)=>{d(v?O:null)};return s.jsx(y.SeatmapAccordion,{svg:f,seats:w?[]:G,onClick:N,displayGroupMapping:E})},[E,w,G,f]);return s.jsxs(c.MantineProvider,{theme:D,children:[s.jsx(c.Tabs,{variant:"outline",value:b,onChange:N=>k(N),children:s.jsxs(c.Tabs.List,{justify:"flex-end",children:[s.jsx(c.Tabs.Tab,{value:"allocations",children:"Availability"}),s.jsx(c.Tabs.Tab,{value:"screens",children:"Screens"}),s.jsx(c.Tabs.Tab,{value:"sections",children:"Sections"}),s.jsx(c.Tabs.Tab,{value:"zones",children:"Zones"}),s.jsx(c.Tabs.Tab,{value:"holds",children:"Holds"}),s.jsx(c.Tabs.Tab,{value:"seatType",children:"Seat Type"}),s.jsx(c.Tabs.Tab,{value:"stairs",children:"Stairs"})]})}),Y]})},ye=(p,r,f,h)=>{const[m,d]=n.useState(!0),[T,b]=n.useState(null),[k,x]=n.useState([]);return n.useEffect(()=>{(async()=>{try{console.log("Fetching data...");const w=await fetch(`${p}/TXN/Performances/${r}/Seats?constituentId=${f}&modeOfSaleId=${h}&performanceId=${r}`);if(!w.ok)throw new Error("Failed to fetch data");const g=await w.json();return console.log("Finished fetching data"),g||[]}catch(w){d(!1),b("Failed to fetch data"),console.error(w)}})().then(w=>{x(w),d(!1)})},[f,p,h,r]),{loading:m,data:k,error:T}},xe=p=>p.filter(r=>r.SeatStatusId===0).map(r=>({id:r.Id,available:r.AllocationId===0,displayGroup:r.ZoneId.toString(),selectionGroups:{row:{value:r.SeatRow,parent:"section"},section:r.ScreenId.toString()},cssSelector:`#seat-${r.SeatNumber}-${r.SeatRow.replace("*","_")}-${r.ScreenId}`})),ve=p=>{const[r,f]=n.useState();n.useEffect(()=>{(async()=>{try{if(!p)return;const d=await fetch(p);if(!d.ok)throw new Error("Network response was not ok");const T=await d.json(),b=h(T.facilities);console.log("Mapped seat images:",b),f(b)}catch(d){console.error("Error fetching seat images:",d)}})()},[p]);const h=m=>m.flatMap(d=>d.seat_images.reduce((T,b)=>{const k=b.split("/").pop(),x=k==null?void 0:k.split("seat");if(!x)return console.error("Invalid file name format:",k),T;const _=x[x.length-1].split("-");return _.length<4?(console.error("Invalid seat information format:",_),T):[{url:b,facilityId:d.facility_no,screenId:parseInt(_[3],10),rowName:_[2],seatName:_[1]},...T]},[]));return{seatImages:r}},je=({performanceName:p,performanceDate:r})=>{const[f,h]=n.useState(!1),m=(d,T,b)=>s.jsxs(c.Flex,{gap:20,align:"center",children:[s.jsx("svg",{viewBox:"0 0 18 18",xmlns:"http://www.w3.org/2000/svg",style:{width:"18px",height:"18px"},children:s.jsx("circle",{cx:"9",cy:"9",r:"6",style:{strokeWidth:"5px",stroke:b,fill:T}})}),s.jsx(c.Text,{size:"sm",children:d})]});return s.jsxs(c.Menu,{opened:f,position:"bottom-end",offset:0,withinPortal:!1,children:[s.jsx(c.Menu.Target,{children:s.jsx(c.Button,{variant:"white",color:"black",size:"xs",rightSection:f?s.jsx(ee.IconChevronUp,{size:14}):s.jsx(ee.IconChevronDown,{size:14}),onClick:()=>h(d=>!d),children:"See details"})}),s.jsxs(c.Menu.Dropdown,{style:{zIndex:0},children:[s.jsxs(c.Flex,{direction:"column",gap:10,p:"md",maw:"275px",children:[s.jsx(c.Title,{order:2,size:"xl",textWrap:"balance",children:p}),s.jsx(c.Title,{order:3,size:"sm",textWrap:"balance",children:r})]}),s.jsxs(c.Flex,{direction:"column",gap:10,p:"md",maw:"275px",style:{borderTop:"1px solid #cecece"},children:[m("Available","#fff","#9b98e5"),m("Selected","#9b98e5","#9b98e5"),m("Not available","#bfbfbf","#bfbfbf")]})]})]})},we=({endpoint:p,performanceId:r,facilityId:f,svg:h,viewFromSeat:m,constituentId:d,modeOfSaleId:T,sourceId:b})=>{var K,q;const[k,x]=n.useState(!1),[_,w]=n.useState([]),[g,G]=n.useState(null),{data:E,loading:D}=ye(p,r,d,T),{seatImages:Y}=ve(m),[N,O]=n.useState(!0),[v,A]=n.useState(""),[u,X]=n.useState(null);n.useEffect(()=>{(async()=>{try{const o=new de(p),e=r.toString(),t=[o.getPerformanceDetails(e),o.getZoneAvailability(e),o.getPerformancePriceTypes(e,T,b),o.getPriceTypeDetails(e,T,b),o.getFacilityScreens(f.toString())];Promise.all(t).then(([l,S,I,P,W])=>{X({performanceDetails:l,zoneAvailability:S,performancePrices:I,priceTypeDetails:P,facilityScreens:W})})}catch(o){console.error("Error fetching data:",o)}})()},[p,r,E]);const V=a=>{if(u&&u.performancePrices){const o=E.find(t=>t.Id===a);return u.performancePrices.filter(t=>t.ZoneId===(o==null?void 0:o.ZoneId)&&t.Enabled===!0)}return null},z=a=>{const o=E.find(e=>e.Id===a);if(o){const e=Y==null?void 0:Y.filter(S=>S.facilityId===f.toString()&&S.screenId===o.ScreenId&&S.rowName===o.SeatRow);if(console.log("imagesInRow",e),(e==null?void 0:e.length)===0)return null;const t=parseInt(o.SeatNumber),l=e==null?void 0:e.reduce(function(S,I){const P=parseInt(I.seatName),W=parseInt(S.seatName);return Math.abs(P-t)<Math.abs(W-t)?I:S});return l?l.url:null}},$=(a,o)=>{G({id:a,action:o?"selecting":"deselecting"}),x(!0),O(!0)},R=(a,o)=>s.jsxs("div",{className:"price-types__selector",children:[s.jsxs("div",{className:"price-types__description",children:[s.jsx(c.Text,{children:a}),s.jsx(c.Text,{fw:700,children:o.toLocaleString("en-US",{style:"currency",currency:"USD"})})]}),s.jsx("div",{className:"price-types__action",children:s.jsx(c.Button,{variant:"outline",color:"black",loading:v===a,onClick:()=>{g&&(w(e=>[...e,g.id]),A(a),setTimeout(()=>{A(""),x(!1);const e=E.find(t=>t.Id===g.id);if(e){const t=u==null?void 0:u.facilityScreens.Screens.find(l=>l.Id===(e==null?void 0:e.ScreenId));se.notifications.show({title:"Added to cart",message:`${t?t.Description.toUpperCase()+", ":""}Seat ${e.SeatNumber}, Row ${e.SeatRow}, ${a}`,position:"top-right",icon:s.jsx(ee.IconShoppingCart,{size:"1rem"}),autoClose:1e4})}},2e3))},children:"Select"})})]}),L=()=>{if(g){const a=E.find(o=>o.Id===g.id);if(u&&u.facilityScreens){const o=u.facilityScreens.Screens.find(t=>t.Id===(a==null?void 0:a.ScreenId));return`${o==null?void 0:o.Description.toUpperCase()}, Row ${a==null?void 0:a.SeatRow}, Seat ${a==null?void 0:a.SeatNumber}`}return`Row ${a==null?void 0:a.SeatRow}, Seat ${a==null?void 0:a.SeatNumber}`}},U=()=>{if(g){if(g.action==="selecting"){const a=V(g.id);if(!a)return null;const o=z(g.id);return s.jsxs("div",{className:"seat-details",children:[o&&s.jsx("div",{className:"view-from-seat",children:s.jsx(c.Skeleton,{visible:N,className:"view-from-seat__skeleton",children:s.jsx("img",{src:o,alt:`View from seat ${g.id}`,className:"view-from-seat__image",onLoad:()=>O(!1)})})}),s.jsx("div",{className:"price-types",children:a.map(e=>{const t=u==null?void 0:u.priceTypeDetails.find(l=>l.PriceTypeId===e.PriceTypeId);return t?R(t.AliasDescription,e.Price):null})})]})}else if(g.action==="deselecting")return s.jsxs(s.Fragment,{children:[s.jsx(c.Text,{size:"sm",children:"You have already selected this seat."}),s.jsx(c.Space,{h:"md"}),s.jsx(c.Button,{color:"black",onClick:()=>{w(a=>a.filter(o=>o!==g.id)),x(!1),se.notifications.show({title:"Removed from cart",color:"red",message:`Seat ${g.id} has been removed from your cart.`,position:"top-right",icon:s.jsx(ee.IconShoppingCart,{size:"1rem"}),autoClose:1e4})},children:"Remove Seat"})]})}return null},re=n.useMemo(()=>{if(D||!E)return[];const a=xe(E);return console.log(a),a},[E]),Q=n.useMemo(()=>D||!E?{}:re.reduce((o,e)=>{const t=e.displayGroup;return t&&!o[t]&&(o[t]=fe(Object.keys(o).length)),o},{}),[E]),ne=c.createTheme({headings:{sizes:{h3:{fontWeight:"normal"}}}});return s.jsxs(c.MantineProvider,{theme:ne,children:[s.jsx(se.Notifications,{portalProps:{target:".seatmap"}}),s.jsx(y.SeatmapAccordion,{svg:h,seats:D?[]:re,selectedSeatIds:_,onClick:$,displayGroupMapping:Q,rightControls:[s.jsx(je,{performanceName:((K=u==null?void 0:u.performanceDetails)==null?void 0:K.Description)||"ERROR",performanceDate:(u!=null&&u.performanceDetails.Date?new Intl.DateTimeFormat("en-GB",{dateStyle:"full",timeStyle:"short",timeZone:"Australia/Sydney"}).format(new Date(u==null?void 0:u.performanceDetails.Date)):"")+(" in "+((q=u==null?void 0:u.performanceDetails)==null?void 0:q.Facility.Description)||"ERROR")})]}),s.jsx(c.Modal,{title:L(),opened:k,onClose:()=>{x(!1)},styles:{inner:{position:"absolute"},title:{fontWeight:700},content:{borderRadius:"0.5rem"}},centered:!0,size:"auto",portalProps:{target:".seatmap"},overlayProps:{fixed:!1},children:U()})]})};i.TessituraPerformanceViewer=Te,i.TessituraSYOS=we,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});