semi finished standing sp comp selection

This commit is contained in:
2023-07-21 14:56:52 +02:00
parent cbadd2a2c1
commit 3fe01239b3
11 changed files with 148 additions and 57 deletions

View File

@@ -56,6 +56,8 @@ if ( settings.init ) {
file = path.join( __dirname + '/../webapp/setup/dist/index.html' ); file = path.join( __dirname + '/../webapp/setup/dist/index.html' );
} }
// TODO: Create plugin loader and manager
app.use( ( request, response ) => { app.use( ( request, response ) => {
response.sendFile( file ); response.sendFile( file );

View File

@@ -1 +1 @@
{"test2":{"draft":{},"save":{"seatInfo":{"data":{"1":{"0":22},"2":{"0":9},"3":{"0":9}},"count":0},"data":{"1":{"x":299.02,"y":17.157,"h":564.951,"w":731.618,"active":false,"draggable":true,"resizable":true,"id":1,"origin":1,"shape":"rectangular","type":"seat","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"numberingDirection":"left","category":"1"},"2":{"x":359.069,"y":661.765,"h":121.324,"w":604.167,"active":false,"draggable":true,"resizable":true,"id":2,"origin":3,"shape":"rectangular","type":"stage","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"ticketCount":1,"numberingDirection":"left","category":"1"},"3":{"x":519.608,"y":671.569,"h":83.333,"w":306.373,"active":false,"draggable":true,"resizable":true,"id":3,"origin":1,"shape":"rectangular","type":"text","startingRow":1,"seatNumberingPosition":2,"sector":"A","text":{"text":"Stage","textSize":25,"colour":"#2160ff"},"ticketCount":1,"numberingDirection":"left","category":"1"}}}},"test":{"draft":{},"save":{"seatInfo":{"data":{"1":{"0":22}},"count":0},"data":{"1":{"x":122.549,"y":122.549,"h":371.324,"w":735.294,"active":false,"draggable":true,"resizable":true,"id":1,"origin":1,"shape":"rectangular","type":"seat","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"numberingDirection":"left","category":"1"}}}}} {"test2":{"draft":{},"save":{"seatInfo":{"data":{"1":{"0":22},"2":{"0":9},"3":{"0":9}},"count":0},"data":{"1":{"x":299.02,"y":17.157,"h":564.951,"w":731.618,"active":false,"draggable":true,"resizable":true,"id":1,"origin":1,"shape":"rectangular","type":"seat","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"numberingDirection":"left","category":"1"},"2":{"x":359.069,"y":661.765,"h":121.324,"w":604.167,"active":false,"draggable":true,"resizable":true,"id":2,"origin":3,"shape":"rectangular","type":"stage","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"ticketCount":1,"numberingDirection":"left","category":"1"},"3":{"x":519.608,"y":671.569,"h":83.333,"w":306.373,"active":false,"draggable":true,"resizable":true,"id":3,"origin":1,"shape":"rectangular","type":"text","startingRow":1,"seatNumberingPosition":2,"sector":"A","text":{"text":"Stage","textSize":25,"colour":"#2160ff"},"ticketCount":1,"numberingDirection":"left","category":"1"}}}},"test":{"draft":{},"save":{"seatInfo":{"data":{"1":{"0":22}},"count":0},"data":{"1":{"x":427.696,"y":160.539,"h":371.324,"w":734.069,"active":false,"draggable":true,"resizable":true,"id":1,"origin":1,"shape":"rectangular","type":"stand","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"numberingDirection":"left","category":"1","ticketCount":50}}}}}

View File

@@ -12,6 +12,7 @@
</title> </title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200">
<script defer src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script> <script defer src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/isocroft/browsengine@0.2.1/dist/browsengine.min.js"></script>
<link rel="stylesheet" href="/coloris.min.css"> <link rel="stylesheet" href="/coloris.min.css">
<script defer src="/coloris.min.js"></script> <script defer src="/coloris.min.js"></script>
</head> </head>

View File

@@ -178,6 +178,11 @@ export default {
} }
}, },
created () { created () {
if ( window.webpage.engine.trident ) {
alert( 'Welcome! We have detected that you are still using Internet Explorer or a similar browser. As a modern webapp, libreevent does NOT officially support Internet Explorer. If you run into problems whilst using this webapp, please switch to a modern browser like Firefox.' )
} else if ( window.webpage.engine.presto ) {
alert( 'Welcome! We have detected that you are a very old version of Opera or related browser. As a modern webapp, libreevent does only support modern browsers. If you run into issues whilst using this webapp, please switch to a modern browser, like Firefox.' )
}
this.theme = localStorage.getItem( 'theme' ) ? localStorage.getItem( 'theme' ) : ''; this.theme = localStorage.getItem( 'theme' ) ? localStorage.getItem( 'theme' ) : '';
if ( window.matchMedia( '(prefers-color-scheme: dark)' ).matches || this.theme === '&#9788;' ) { if ( window.matchMedia( '(prefers-color-scheme: dark)' ).matches || this.theme === '&#9788;' ) {
document.documentElement.classList.add( 'dark' ); document.documentElement.classList.add( 'dark' );

View File

@@ -41,7 +41,7 @@ export default {
data () { data () {
return { return {
tickets: { 'ticket1': { 'name': 'Ticket 1', 'id': 'ticket1', 'category': 1, 'free': 20 }, 'ticket2': { 'name': 'Ticket 2', 'id': 'ticket2', 'category': 2, 'free': 20 } }, tickets: { 'ticket1': { 'name': 'Ticket 1', 'id': 'ticket1', 'category': 1, 'free': 20 }, 'ticket2': { 'name': 'Ticket 2', 'id': 'ticket2', 'category': 2, 'free': 20 } },
event: { 'name': 'TestEvent', 'location': 'TestLocation', 'date': 'TestDate', 'RoomName': 'TestRoom', 'currency': 'CHF', 'categories': { '1': { 'price': { '1':25, '2':35 }, 'bg': 'black', 'fg': 'white', 'name': 'Category 1' }, '2': { 'price': { '1':15, '2':20 }, 'bg': 'green', 'fg': 'white', 'name': 'Category 2' } }, 'ageGroups': { '1':{ 'id': 1, 'name':'Child', 'age':'0 - 15.99 years' }, '2':{ 'id': 2, 'name': 'Adult', 'age': null } }, 'ageGroupCount':2, 'stage': true }, event: { 'name': 'TestEvent', 'location': 'TestLocation', 'date': 'TestDate', 'RoomName': 'TestRoom', 'currency': 'CHF', 'categories': { '1': { 'price': { '1':25, '2':35 }, 'bg': 'black', 'fg': 'white', 'name': 'Category 1' }, '2': { 'price': { '1':15, '2':20 }, 'bg': 'green', 'fg': 'white', 'name': 'Category 2' } }, 'ageGroups': { '1':{ 'id': 1, 'name':'Child', 'age':'0 - 15.99 years' }, '2':{ 'id': 2, 'name': 'Adult', 'age': null } }, 'stage': true },
cart: {}, cart: {},
} }
}, },

View File

@@ -42,6 +42,28 @@
<button class="select-button" @click="closePopupAdvanced( 'ok', selectOption.value )">{{ selectOption.displayName }}</button> <button class="select-button" @click="closePopupAdvanced( 'ok', selectOption.value )">{{ selectOption.displayName }}</button>
</div> </div>
</div> </div>
<div v-else-if="contentType === 'tickets'" class="options">
<h3>{{ data.message }}</h3>
<table>
<tr v-for="ticketOption in data.options.ageGroups">
<td>
{{ ticketOption.name }} <div style="display: inline" v-if="ticketOption.age">({{ ticketOption.age }})</div>
</td>
<td>
{{ data.options.currency }} {{ data.options.price[ ticketOption.id ] }}
</td>
<td>
<span class="material-symbols-outlined controls" @click="selectTicket( ticketOption.id )">add</span>
{{ data.options.count[ ticketOption.id ] }}
<span class="material-symbols-outlined controls" @click="deselectTicket( ticketOption.id )">remove</span>
</td>
</tr>
</table>
<div style="width: 100%; margin-top: 3%;">
<button @click="submitTicket()" title="Save changes">Save</button>
<button @click="closePopup( 'cancel' )" title="Cancel changes">Cancel</button>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -66,7 +88,7 @@
data () { data () {
return { return {
contentType: 'dropdown', contentType: 'dropdown',
data: {} data: {},
} }
}, },
methods: { methods: {
@@ -76,14 +98,32 @@
this.$emit( 'data', { 'data': this.data.selected, 'status': message } ); this.$emit( 'data', { 'data': this.data.selected, 'status': message } );
} }
}, },
selectTicket ( option ) {
let total = 0;
for ( let i in this.data.options.count ) {
total += this.data.options.count[ i ];
}
if ( total < this.data.options.max ) {
this.data.options.count[ option ] += 1;
}
},
deselectTicket ( option ) {
if ( this.data.options.count[ option ] > 0 ) {
this.data.options.count[ option ] -= 1;
}
},
submitTicket () {
$( '#popup-backdrop' ).fadeOut( 300 );
this.$emit( 'ticket', { 'data': this.data.options.count, 'component': this.data.options.id } );
},
closePopupAdvanced ( message, data ) { closePopupAdvanced ( message, data ) {
this.data[ 'selected' ] = data; this.data[ 'selected' ] = data;
this.closePopup( message ); this.closePopup( message );
}, },
openPopup ( message, options, dataType, selected ) { openPopup ( message, options, dataType, selected ) {
let data = { 'message': message ? message : 'No message defined on method call!!', 'options': options ? options : { '1': { 'value': 'undefined', 'displayName': 'No options specified in call' } }, 'selected': selected ? selected : '' }; this.data = { 'message': message ?? 'No message defined on method call!!', 'options': options ?? { '1': { 'value': 'undefined', 'displayName': 'No options specified in call' } }, 'selected': selected ?? '' };
this.data = data; this.contentType = dataType ?? 'string';
this.contentType = dataType ? dataType : 'string';
$( '#popup-backdrop' ).fadeIn( 300 ); $( '#popup-backdrop' ).fadeIn( 300 );
} }
}, },
@@ -200,4 +240,13 @@
.select-button:hover { .select-button:hover {
background-color: var( --hover-color ) !important; background-color: var( --hover-color ) !important;
} }
.controls {
user-select: none;
cursor: pointer;
font-size: 100%;
font-weight: bold;
border: solid var( --primary-color ) 1px;
border-radius: 100%;
}
</style> </style>

View File

@@ -179,9 +179,14 @@
this.available.undo = true; this.available.undo = true;
} }
let supportedBrowser = []; if ( window.webpage.engine.trident ) {
alert( 'Welcome! We have detected that you are still using Internet Explorer or a similar browser. As a modern webapp, libreevent does NOT officially support Internet Explorer. If you run into problems whilst using this webapp, please switch to a modern browser like Firefox.' );
} else if ( window.webpage.engine.presto ) {
alert( 'Welcome! We have detected that you are a very old version of Opera or related browser. As a modern webapp, libreevent does only support modern browsers. If you run into issues whilst using this webapp, please switch to a modern browser, like Firefox.' );
} else if ( window.webpage.engine.webkit ) {
alert( 'Hello! Whilst tested with some versions of Webkit (the browser engine of Safari), support for this engine is still unofficial. Therefore we cannot guarantee that all the features of the seatplan editor function as they should. If you run into problems, please contact us through the link provided in the documentation.' );
}
this.save(); this.save();
// TODO: Add warning for untested browsers & suboptimal window sizes!
}, },
eventHandler ( e ) { eventHandler ( e ) {
if ( this.prevSize.h != window.innerHeight || this.prevSize.w != window.innerWidth ) { if ( this.prevSize.h != window.innerHeight || this.prevSize.w != window.innerWidth ) {

View File

@@ -94,7 +94,7 @@ export default {
this.style = 'border-style: none none none solid'; this.style = 'border-style: none none none solid';
this.circularStyle = 'top: -100%; right: 100%;'; this.circularStyle = 'top: -100%; right: 100%;';
} }
} },
}, },
watch: { watch: {
origin ( value ) { origin ( value ) {

View File

@@ -31,7 +31,8 @@
@seatSelected="( seat ) => { seatSelected( seat ) }" @seatDeselected="( seat ) => { seatDeselected( seat ) }"></rectangularSeatplanComponent> @seatSelected="( seat ) => { seatSelected( seat ) }" @seatDeselected="( seat ) => { seatDeselected( seat ) }"></rectangularSeatplanComponent>
<stagesSeatplanComponent :ref="'component' + draggable.id" v-else-if="draggable.type == 'stage'" :origin="draggable.origin" :shape="draggable.shape"></stagesSeatplanComponent> <stagesSeatplanComponent :ref="'component' + draggable.id" v-else-if="draggable.type == 'stage'" :origin="draggable.origin" :shape="draggable.shape"></stagesSeatplanComponent>
<standingSeatplanComponent :ref="'component' + draggable.id" v-else-if="draggable.type == 'stand'" :origin="draggable.origin" :shape="draggable.shape"></standingSeatplanComponent> <standingSeatplanComponent :ref="'component' + draggable.id" v-else-if="draggable.type == 'stand'" :origin="draggable.origin"
:shape="draggable.shape" @click="standing( draggable.id )"></standingSeatplanComponent>
<textFieldSeatplanComponent :ref="'component' + draggable.id" v-else-if="draggable.type == 'text'" :text="draggable.text.text" :text-size="draggable.text.textSize" :colour="draggable.text.colour" :origin="draggable.origin" :scale-factor="scaleFactor"></textFieldSeatplanComponent> <textFieldSeatplanComponent :ref="'component' + draggable.id" v-else-if="draggable.type == 'text'" :text="draggable.text.text" :text-size="draggable.text.textSize" :colour="draggable.text.colour" :origin="draggable.origin" :scale-factor="scaleFactor"></textFieldSeatplanComponent>
</Vue3DraggableResizable> </Vue3DraggableResizable>
</div> </div>
@@ -43,7 +44,8 @@
</div> </div>
<sideCartView :cart="cart" ref="cart"></sideCartView> <sideCartView :cart="cart" ref="cart"></sideCartView>
<notifications ref="notification" location="topleft"></notifications> <notifications ref="notification" location="topleft"></notifications>
<popups ref="popups" size="normal" @data="data => { reserveTicket( data ) }"></popups> <popups ref="popups" size="normal" @data="data => { reserveTicket( data ) }"
@ticket="data => { standingTicketHandling( data ) }"></popups>
</div> </div>
</template> </template>
@@ -77,7 +79,7 @@
data() { data() {
return { return {
draggables: { 1: { 'x': 100, 'y':100, 'h': 100, 'w': 250, 'active': false, 'draggable': true, 'resizable': true, 'id': 1, 'origin': 1, 'shape':'rectangular', 'type': 'seat', 'startingRow': 1, 'seatCountingStartingPoint': 1, 'sector': 'A', 'text': { 'text': 'TestText', 'textSize': 20, 'colour': '#20FFFF' }, 'ticketCount': 1, 'category': 1 } }, draggables: { 1: { 'x': 100, 'y':100, 'h': 100, 'w': 250, 'active': false, 'draggable': true, 'resizable': true, 'id': 1, 'origin': 1, 'shape':'rectangular', 'type': 'seat', 'startingRow': 1, 'seatCountingStartingPoint': 1, 'sector': 'A', 'text': { 'text': 'TestText', 'textSize': 20, 'colour': '#20FFFF' }, 'ticketCount': 1, 'category': 1 } },
event: { 'name': 'TestEvent2', 'location': 'TestLocation2', 'date': '2023-07-15', 'RoomName': 'TestRoom2', 'currency': 'CHF', 'categories': { '1': { 'price': { '1':25, '2':35 }, 'bg': 'black', 'fg': 'white', 'name': 'Category 1' }, '2': { 'price': { '1':15, '2':20 }, 'bg': 'green', 'fg': 'white', 'name': 'Category 2' } }, 'ageGroups': { '1':{ 'id': 1, 'name':'Child', 'age':'0 - 15.99' }, '2':{ 'id': 2, 'name': 'Adult' } }, 'ageGroupCount': 2, 'maxTickets': 2 }, event: { 'name': 'TestEvent2', 'location': 'TestLocation2', 'date': '2023-07-15', 'RoomName': 'TestRoom2', 'currency': 'CHF', 'categories': { '1': { 'price': { '1':25, '2':35 }, 'bg': 'black', 'fg': 'white', 'name': 'Category 1' }, '2': { 'price': { '1':15, '2':20 }, 'bg': 'green', 'fg': 'white', 'name': 'Category 2' } }, 'ageGroups': { '1':{ 'id': 1, 'name':'Child', 'age':'0 - 15.99' }, '2':{ 'id': 2, 'name': 'Adult' } }, 'maxTickets': 2 },
available: { 'redo': false, 'undo': false }, available: { 'redo': false, 'undo': false },
scaleFactor: 1, scaleFactor: 1,
sizePoll: null, sizePoll: null,
@@ -133,7 +135,39 @@
} }
} ); } );
// TODO: remove scaleDown function again once backend is up // Mark all selected seats + all unavailable seats
// { 'sector': 'A', 'sectorCount': 1, 'unavailableSeats': { 'secAr0s0': 'nav' }, 'categoryInfo': { 'pricing': { '1': { 'displayName': 'Adults - CHF 20.-', 'value': 'adult', 'price': 20 }, '2': { 'displayName': 'Child (0 - 15.99y) - CHF 15.-', 'value': 'child', 'price': 15 } } } }
let categoryDetails = {};
for ( let category in this.event.categories ) {
categoryDetails[ category ] = {};
for ( let group in this.event.ageGroups ) {
categoryDetails[ category ][ group ] = {};
categoryDetails[ category ][ group ] = { 'displayName': this.event.ageGroups[ group ].name + ( this.event.ageGroups[ group ].age ? ' (' + this.event.ageGroups[ group ].age + ')' : '' ) + ' - ' + this.event.currency + ' ' + this.event.categories[ category ].price[ group ], 'value': group, 'price': this.event.categories[ category ].price[ group ] };
}
}
for ( let element in this.draggables ) {
this.draggables[ element ][ 'data' ] = { 'sector': this.draggables[ element ][ 'sector' ], 'unavailableSeats': {}, 'categoryInfo': { 'pricing': categoryDetails[ this.draggables[ element ][ 'category' ] ] } };
}
if ( this.cart[ this.event.name ] ) {
let tickets = this.cart[ this.event.name ][ 'tickets' ];
for ( let ticket in tickets ) {
this.draggables[ tickets[ ticket ].comp ][ 'data' ][ 'unavailableSeats' ][ ticket ] = 'sel';
}
}
// TODO: Check if all seats are available
let allSeatsAvailable = true;
// Method: Server sends all user selected seats + all selected seats. If seat is in both
// then selected, if just in all selected, taken, else available.
if ( !allSeatsAvailable ) {
setTimeout( () => {
self.$refs.popups.openPopup( 'We are sorry to tell you that since the last time the seat plan was refreshed, one or more of the seats you have selected has/have been taken.', {}, 'string' );
}, 500 );
}
// TODO: Optimise for odd screen sizes and aspect ratios and fucking webkit // TODO: Optimise for odd screen sizes and aspect ratios and fucking webkit
sessionStorage.setItem( 'seatplan', JSON.stringify( this.scaleDown( this.draggables ) ) ); sessionStorage.setItem( 'seatplan', JSON.stringify( this.scaleDown( this.draggables ) ) );
}, },
@@ -207,40 +241,6 @@
if ( sessionStorage.getItem( 'seatplan' ) ) { if ( sessionStorage.getItem( 'seatplan' ) ) {
this.draggables = this.scaleUp( JSON.parse( sessionStorage.getItem( 'seatplan' ) ) ); this.draggables = this.scaleUp( JSON.parse( sessionStorage.getItem( 'seatplan' ) ) );
} }
// TODO: Check if all seats are available
let allSeatsAvailable = true;
// Method: Server sends all user selected seats + all selected seats. If seat is in both
// then selected, if just in all selected, taken, else available.
let self = this;
if ( !allSeatsAvailable ) {
setTimeout( () => {
self.$refs.popups.openPopup( 'We are sorry to tell you that since the last time the seat plan was refreshed, one or more of the seats you have selected has/have been taken.', {}, 'string' );
}, 500 );
}
// Mark all selected seats + all unavailable seats
// { 'sector': 'A', 'sectorCount': 1, 'unavailableSeats': { 'secAr0s0': 'nav' }, 'categoryInfo': { 'pricing': { '1': { 'displayName': 'Adults - CHF 20.-', 'value': 'adult', 'price': 20 }, '2': { 'displayName': 'Child (0 - 15.99y) - CHF 15.-', 'value': 'child', 'price': 15 } } } }
let categoryDetails = {};
for ( let category in this.event.categories ) {
categoryDetails[ category ] = {};
for ( let group in this.event.ageGroups ) {
categoryDetails[ category ][ group ] = {};
categoryDetails[ category ][ group ] = { 'displayName': this.event.ageGroups[ group ].name + ( this.event.ageGroups[ group ].age ? ' (' + this.event.ageGroups[ group ].age + ')' : '' ) + ' - ' + this.event.currency + ' ' + this.event.categories[ category ].price[ group ], 'value': group, 'price': this.event.categories[ category ].price[ group ] };
}
}
for ( let element in this.draggables ) {
this.draggables[ element ][ 'data' ] = { 'sector': this.draggables[ element ][ 'sector' ], 'unavailableSeats': {}, 'categoryInfo': { 'pricing': categoryDetails[ this.draggables[ element ][ 'category' ] ] } };
}
if ( this.cart[ this.event.name ] ) {
let tickets = this.cart[ this.event.name ][ 'tickets' ];
for ( let ticket in tickets ) {
this.draggables[ tickets[ ticket ].comp ][ 'data' ][ 'unavailableSeats' ][ ticket ] = 'sel';
}
}
}, },
scaleUp ( valueArray ) { scaleUp ( valueArray ) {
const allowedAttributes = [ 'w', 'h', 'x', 'y' ]; const allowedAttributes = [ 'w', 'h', 'x', 'y' ];
@@ -274,7 +274,6 @@
}, },
seatSelected ( seat ) { seatSelected ( seat ) {
this.selectedSeat = seat; this.selectedSeat = seat;
console.log( seat );
if ( Object.keys( seat.option ).length > 1 ) { if ( Object.keys( seat.option ).length > 1 ) {
this.$refs.popups.openPopup( 'Please choose a ticket option', seat.option, 'selection', 'adult' ); this.$refs.popups.openPopup( 'Please choose a ticket option', seat.option, 'selection', 'adult' );
} else { } else {
@@ -283,7 +282,6 @@
}, },
cartHandling ( operation, data ) { cartHandling ( operation, data ) {
if ( operation === 'select' ) { if ( operation === 'select' ) {
console.log( this.selectedSeat.option );
if ( this.cart[ this.event.name ] ) { if ( this.cart[ this.event.name ] ) {
this.cart[ this.event.name ][ 'tickets' ][ this.selectedSeat.id ] = { 'displayName': this.selectedSeat.displayName, 'price': this.selectedSeat.option[ data ].price, 'id': this.selectedSeat.id, 'option': data, 'comp': this.selectedSeat.componentID }; this.cart[ this.event.name ][ 'tickets' ][ this.selectedSeat.id ] = { 'displayName': this.selectedSeat.displayName, 'price': this.selectedSeat.option[ data ].price, 'id': this.selectedSeat.id, 'option': data, 'comp': this.selectedSeat.componentID };
} else { } else {
@@ -301,17 +299,40 @@
localStorage.setItem( 'cart', JSON.stringify( this.cart ) ); localStorage.setItem( 'cart', JSON.stringify( this.cart ) );
}, },
reserveTicket ( option ) { reserveTicket ( option ) {
console.log( this.selectedSeat.componentID );
if ( option.status == 'ok' ) { if ( option.status == 'ok' ) {
this.$refs[ 'component' + this.selectedSeat.componentID ][ 0 ].validateSeatSelection( this.selectedSeat, option.data ); this.$refs[ 'component' + this.selectedSeat.componentID ][ 0 ].validateSeatSelection( this.selectedSeat, option.data );
this.cartHandling( 'select', option.data ); this.cartHandling( 'select', option.data );
} }
// TODO: Make call to server to reserve ticket when data is returned & save to localStorage array. // TODO: Make call to server to reserve ticket when data is returned
}, },
seatDeselected ( seat ) { seatDeselected ( seat ) {
this.selectedSeat = seat; this.selectedSeat = seat;
this.cartHandling( 'deselect' ); this.cartHandling( 'deselect' );
// TODO: Make call to server to deselect ticket & delete from localStorage array and delete eventArray if empty! // TODO: Make call to server to deselect ticket
},
standing ( id ) {
const d = this.draggables[ id ];
const evG = this.event.ageGroups;
let count = {};
for ( let ageGroup in evG ) {
if ( this.cart[ 'ticket' + id + '_' + ageGroup ] ) {
count[ ageGroup ] = this.cart[ 'ticket' + id + '_' + ageGroup ].count;
} else {
count[ ageGroup ] = 0;
}
}
this.$refs.popups.openPopup( 'Select tickets', {
'id': id,
'max': d.ticketCount,
'name': 'Sector ' + d.sector + ' Ticket ' + id,
'ageGroups': this.event.ageGroups,
'currency': this.event.currency,
'price': this.event.categories[ d.category ],
'count': count
}, 'tickets' );
},
standingTicketHandling ( data ) {
console.log( data );
} }
}, },
created () { created () {

View File

@@ -63,11 +63,11 @@
</div> </div>
<div class="special-settings"> <div class="special-settings">
<h3>General Settings</h3> <h3>General Settings</h3>
<p>Currency codes used must be valid ISO 4217 codes. Read more on <a href="https://libreevent.janishutz.com/docs/admin-panel/events#currency">this page</a> of the documentation <!-- https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes"--></p> <p>Currency codes used must be valid ISO 4217 codes. Read more on <a href="https://libreevent.janishutz.com/docs/admin-panel/events#currency" target="_blank">this page</a> of the documentation <!-- https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes"--></p>
<settings v-model:settings="specialSettings"></settings> <settings v-model:settings="specialSettings"></settings>
</div> </div>
<div> <div>
<p>Please read into the documentation of this section if you want to use the requirements. It requires specific syntax to work. See <a href="https://libreevent.janishutz.com/docs/admin-panel/events#special-requirements">here</a> for more information</p> <p>Please read into the documentation of this section if you want to use the requirements. It requires specific syntax to work. See <a href="https://libreevent.janishutz.com/docs/admin-panel/events#special-requirements" target="_blank">here</a> for more information</p>
</div> </div>
<notifications ref="notification" location="topright"></notifications> <notifications ref="notification" location="topright"></notifications>
</div> </div>
@@ -104,6 +104,9 @@
import settings from '@/components/settings/settings.vue'; import settings from '@/components/settings/settings.vue';
import notifications from '@/components/notifications/notifications.vue'; import notifications from '@/components/notifications/notifications.vue';
// TODO: When loading data form server, also load categories of this seat plan
// and from it construct the array, if not set already.
export default { export default {
name: 'TicketsDetailsView', name: 'TicketsDetailsView',
components: { components: {
@@ -186,6 +189,11 @@
}, },
} }
} }
},
methods: {
save () {
}
} }
}; };
</script> </script>

View File

@@ -42,9 +42,9 @@
this.$router.push( '/tickets' ); this.$router.push( '/tickets' );
} }
this.eventID = sessionStorage.getItem( 'selectedTicket' ); this.eventID = sessionStorage.getItem( 'selectedTicket' );
if ( this.eventID == 'test' ) { // if ( this.eventID == 'test' ) {
this.hasSeatplan = false; // this.hasSeatplan = false;
} // }
} }
}; };
</script> </script>