diff --git a/src/webapp/main/src/components/noseatplan.vue b/src/webapp/main/src/components/noseatplan.vue index 6afdb79..8e489ea 100644 --- a/src/webapp/main/src/components/noseatplan.vue +++ b/src/webapp/main/src/components/noseatplan.vue @@ -5,14 +5,19 @@

Available tickets

- {{ eventInfo[ 'categories' ][ ticket.category ][ 'name' ] }} + {{ event[ 'categories' ][ ticket.category ][ 'name' ] }} - + +
{{ ticketOption.name }}
({{ ticketOption.age }})
- {{ eventInfo.currency }} {{ eventInfo[ 'categories' ][ ticket.category ][ 'price' ][ ticketOption.id ] }} add Selected remove + {{ event.currency }} {{ event[ 'categories' ][ ticket.category ][ 'price' ][ ticketOption.id ] }} + + add + {{ cart[ event.name ] ? ( cart[ event.name ][ 'tickets' ][ ticket.id + '_' + ticketOption.id ] ? cart[ event.name ][ 'tickets' ][ ticket.id + '_' + ticketOption.id ][ 'count' ] : 0 ) : 0 }} + remove
@@ -35,33 +40,73 @@ export default { }, data () { return { - tickets: { 'ticket1': { 'name': 'Ticket 1', 'id': 'ticket1', 'category': 1 }, 'ticket2': { 'name': 'Ticket 2', 'id': 'ticket2', 'category': 2 } }, - eventInfo: { '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 }, + 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 }, cart: {}, } }, methods: { - cartHandling ( operation, data ) { + selectTicket( id, option ) { + let totalTicketsPerID = 0; + if ( this.cart[ this.event.name ] ) { + if ( this.cart[ this.event.name ][ 'tickets' ][ id + '_' + option ] ) { + const tickets = this.cart[ this.event.name ][ 'tickets' ]; + for ( let ticket in tickets ) { + if ( tickets[ ticket ][ 'id' ].split( '_' )[ 0 ] === id ) { + totalTicketsPerID += this.cart[ this.event.name ][ 'tickets' ][ tickets[ ticket ][ 'id' ] ][ 'count' ]; + } + } + if ( totalTicketsPerID < this.tickets[ id ].free ) { + this.cartHandling( 'select', this.tickets[ id ], option ); + } + } else { + this.cartHandling( 'select', this.tickets[ id ], option ); + } + } else { + this.cartHandling( 'select', this.tickets[ id ], option ); + } + }, + cartHandling ( operation, data, option ) { if ( operation === 'select' ) { 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 }; + if ( this.cart[ this.event.name ][ 'tickets' ][ data.id + '_' + option ] ) { + this.cart[ this.event.name ][ 'tickets' ][ data.id + '_' + option ][ 'count' ] += 1; + } else { + this.cart[ this.event.name ][ 'tickets' ][ data.id + '_' + option ] = { 'displayName': data.name + ' (' + this.event.ageGroups[ option ].name + ')', 'price': this.event.categories[ data.category ].price[ option ], 'id': data.id + '_' + option, 'count': 1 }; + } } else { this.cart[ this.event.name ] = { 'displayName': this.event.name, 'tickets': {} }; - this.cart[ this.event.name ][ 'tickets' ][ this.selectedSeat.id ] = { 'displayName': this.selectedSeat.displayName, 'price': this.selectedSeat.option[ data ].price, 'id': this.selectedSeat.id }; + this.cart[ this.event.name ][ 'tickets' ][ data.id + '_' + option ] = { 'displayName': data.name + ' (' + this.event.ageGroups[ option ].name + ')', 'price': this.event.categories[ data.category ].price[ option ], 'id': data.id + '_' + option, 'count': 1 }; } } else if ( operation === 'deselect' ) { - if ( Object.keys( this.cart[ this.event.name ][ 'tickets' ] ).length > 1 ) { - delete this.cart[ this.event.name ][ 'tickets' ][ this.selectedSeat.id ]; + if ( this.cart[ this.event.name ][ 'tickets' ][ data + '_' + option ][ 'count' ] === 1 ) { + delete this.cart[ this.event.name ][ 'tickets' ][ data + '_' + option ]; } else { + this.cart[ this.event.name ][ 'tickets' ][ data + '_' + option ][ 'count' ] -= 1; + } + if ( Object.keys( this.cart[ this.event.name ][ 'tickets' ] ).length < 1 ) { delete this.cart[ this.event.name ]; } } this.$refs.cart.calculateTotal(); localStorage.setItem( 'cart', JSON.stringify( this.cart ) ); }, + deselectTicket( id, option ) { + if ( this.cart[ this.event.name ] ) { + if ( this.cart[ this.event.name ][ 'tickets' ][ id + '_' + option ] ) { + if ( this.cart[ this.event.name ][ 'tickets' ][ id + '_' + option ][ 'count' ] > 0 ) { + this.cartHandling( 'deselect', id, option ); + } + } + } + }, + loadTickets () { + // TODO: Load from server + } }, - created() { - console.log( 'Hello World' ); + created () { + this.cart = localStorage.getItem( 'cart' ) ? JSON.parse( localStorage.getItem( 'cart' ) ): {}; + // this.loadTickets(); } } @@ -82,13 +127,6 @@ export default { height: 100%; } - .sidebar { - grid-area: sidebar; - background-color: var( --accent-background ); - color: var( --secondary-color ); - overflow: scroll; - } - .noseatplan { grid-area: main; display: flex; @@ -107,85 +145,12 @@ export default { text-align: justify; } - .ticket { - width: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - } - - .overlay { - display: none; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: var( --overlay-color ); - height: 100%; - width: 100%; - } - - .popup { - height: 100%; - width: 100%; - display: flex; - justify-content: center; - flex-direction: column; - align-items: center; - } - - .popup-content { - background-color: var( --background-color ); - height: 60%; - width: 50%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: flex-start; - border-radius: 50px; - } - - .popup-content-wrapper { - display: flex; - height: 90%; - width: 100%; - flex-direction: column; - align-items: center; - justify-content: center; - overflow: scroll; - } - - .close-container { - width: 100%; - display: flex; - justify-content: flex-end; - } - .close-button { + .controls { + user-select: none; cursor: pointer; - margin-right: 3vh; - margin-top: 3vh; - } - - .button { - background-color: var( --accent-background ); - color: var( --secondary-color ); + font-size: 100%; font-weight: bold; - font-size: 110%; - border-radius: 20px; - border-style: none; - padding: 10px 40px; - transition: 0.6s; - } - - .button:hover { - background-color: var( --accent-background-hover ); - transition: 0.3s; - cursor: pointer; - } - - .price-table { - width: 100%; + border: solid var( --primary-color ) 1px; + border-radius: 100%; } diff --git a/src/webapp/main/src/components/seatplan/userApp/seatplanComponents/seats/rectangular.vue b/src/webapp/main/src/components/seatplan/userApp/seatplanComponents/seats/rectangular.vue index 0cdeddd..c7706d5 100644 --- a/src/webapp/main/src/components/seatplan/userApp/seatplanComponents/seats/rectangular.vue +++ b/src/webapp/main/src/components/seatplan/userApp/seatplanComponents/seats/rectangular.vue @@ -50,7 +50,7 @@ export default { }, data: { type: Object, - "default": { 'sector': 'A', 'sectorCount': 1, 'unavailableSeats': { 'secAr0s0': true }, 'categoryInfo': { 'pricing': { 'adult': { 'displayName': 'Adults - CHF 20.-', 'value': 'adult', 'price': 20 }, 'child': { 'displayName': 'Child (0 - 15.99y) - CHF 15.-', 'value': 'child', 'price': 15 } } } } + "default": { 'sector': 'A', 'sectorCount': 1, 'unavailableSeats': { 'secAr0s0': 'nav' }, 'categoryInfo': { 'pricing': { '1': { 'displayName': 'Adults - CHF 20.-', 'value': '1', 'price': 20 }, '2': { 'displayName': 'Child (0 - 15.99y) - CHF 15.-', 'value': '2', 'price': 15 } } } } }, id: { type: Number, @@ -91,7 +91,7 @@ export default { if ( this.data.unavailableSeats ) { if ( this.data.unavailableSeats[ this.seats[ row ][ n ][ 'id' ] ] ) { - this.seats[ row ][ n ][ 'status' ] = 'nav'; + this.seats[ row ][ n ][ 'status' ] = this.data.unavailableSeats[ this.seats[ row ][ n ][ 'id' ] ]; } } } @@ -110,7 +110,6 @@ export default { selectedSeat[ 'sector' ] = this.data.sector; selectedSeat[ 'option' ] = this.data.categoryInfo.pricing; selectedSeat[ 'componentID' ] = this.id; - console.log( selectedSeat ); this.$emit( 'seatSelected', selectedSeat ); }, deselectSeat( row, seat ) { diff --git a/src/webapp/main/src/components/seatplan/userApp/userWindow.vue b/src/webapp/main/src/components/seatplan/userApp/userWindow.vue index 7e5055c..9e46d81 100644 --- a/src/webapp/main/src/components/seatplan/userApp/userWindow.vue +++ b/src/webapp/main/src/components/seatplan/userApp/userWindow.vue @@ -24,7 +24,7 @@ @seatSelected="( seat ) => { seatSelected( seat ) }"> @@ -73,8 +73,8 @@ }, data() { 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 }, - 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', 'age': null } }, 'ageGroupCount': 2, 'maxTickets': 2 }, + 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 }, available: { 'redo': false, 'undo': false }, scaleFactor: 1, sizePoll: null, @@ -110,14 +110,16 @@ } }; + + // Load cart + this.cart = localStorage.getItem( 'cart' ) ? JSON.parse( localStorage.getItem( 'cart' ) ): {}; + // Load seat plan this.loadSeatplan(); + // TODO: remove scaleDown function again once backend is up // TODO: Optimise for odd screen sizes and aspect ratios and fucking webkit sessionStorage.setItem( 'seatplan', JSON.stringify( this.scaleDown( this.draggables ) ) ); - - // Load cart - this.cart = localStorage.getItem( 'cart' ) ? JSON.parse( localStorage.getItem( 'cart' ) ): {}; }, eventHandler ( e ) { if ( this.prevSize.h != window.innerHeight || this.prevSize.w != window.innerWidth ) { @@ -202,6 +204,28 @@ 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 ) { const allowedAttributes = [ 'w', 'h', 'x', 'y' ]; @@ -235,6 +259,7 @@ }, seatSelected ( seat ) { this.selectedSeat = seat; + console.log( seat ); if ( Object.keys( seat.option ).length > 1 ) { this.$refs.popups.openPopup( 'Please choose a ticket option', seat.option, 'selection', 'adult' ); } else { @@ -243,11 +268,12 @@ }, cartHandling ( operation, data ) { if ( operation === 'select' ) { + console.log( this.selectedSeat.option ); 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 }; + 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 { this.cart[ this.event.name ] = { 'displayName': this.event.name, 'tickets': {} }; - this.cart[ this.event.name ][ 'tickets' ][ this.selectedSeat.id ] = { 'displayName': this.selectedSeat.displayName, 'price': this.selectedSeat.option[ data ].price, 'id': this.selectedSeat.id }; + 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 if ( operation === 'deselect' ) { if ( Object.keys( this.cart[ this.event.name ][ 'tickets' ] ).length > 1 ) { diff --git a/src/webapp/main/src/components/sideCartView.vue b/src/webapp/main/src/components/sideCartView.vue index 9f1123e..43eda01 100644 --- a/src/webapp/main/src/components/sideCartView.vue +++ b/src/webapp/main/src/components/sideCartView.vue @@ -8,32 +8,35 @@ --> @@ -87,25 +88,46 @@