From dbfe89998ec6345c8ada35dfa77374104d974ce0 Mon Sep 17 00:00:00 2001 From: Janis Hutz Date: Fri, 11 Aug 2023 16:32:53 +0200 Subject: [PATCH] fix some things with event loading --- src/server/admin/adminAPIRoutes.js | 2 +- src/server/admin/api/getHandler.js | 6 +- src/server/backend/api/getHandler.js | 6 ++ src/server/backend/db/data/eventDrafts.json | 2 +- src/server/backend/db/data/events.json | 2 +- src/server/backend/db/data/seatplan.json | 2 +- src/server/config/settings.config.json | 2 +- src/webapp/main/src/components/noseatplan.vue | 4 +- .../main/src/views/admin/EventsView.vue | 55 ++++++------ .../views/admin/events/EventsDetailsView.vue | 84 +++++++++++++------ .../main/src/views/purchasing/OrderView.vue | 22 ++++- 11 files changed, 120 insertions(+), 67 deletions(-) diff --git a/src/server/admin/adminAPIRoutes.js b/src/server/admin/adminAPIRoutes.js index ad8a30d..75dcb60 100644 --- a/src/server/admin/adminAPIRoutes.js +++ b/src/server/admin/adminAPIRoutes.js @@ -10,12 +10,12 @@ const posth = require( './api/postHandler.js' ); const geth = require( './api/getHandler.js' ); const postHandler = new posth(); -const getHandler = new geth(); const path = require( 'path' ); const bodyParser = require( 'body-parser' ); const mlt = require( 'multer' ); const multer = mlt(); const fs = require( 'fs' ); +const getHandler = new geth( JSON.parse( fs.readFileSync( path.join( __dirname + '/../config/settings.config.json' ) ) ) ); // settings is missing in arguments which shouldn't pose any problem diff --git a/src/server/admin/api/getHandler.js b/src/server/admin/api/getHandler.js index 22942c6..9d659ec 100644 --- a/src/server/admin/api/getHandler.js +++ b/src/server/admin/api/getHandler.js @@ -10,8 +10,8 @@ const db = require( '../../backend/db/db.js' ); class GETHandler { - constructor () { - + constructor ( settings ) { + this.settings = settings; } handleCall ( call, query ) { @@ -72,6 +72,8 @@ class GETHandler { } ).catch( error => { reject( { 'code': 500, 'error': error } ); } ); + } else if ( call === 'getCurrency' ) { + resolve( this.settings.currency ); } else { reject( { 'code': 404, 'error': 'Route not found' } ); } diff --git a/src/server/backend/api/getHandler.js b/src/server/backend/api/getHandler.js index 5682590..7664c79 100644 --- a/src/server/backend/api/getHandler.js +++ b/src/server/backend/api/getHandler.js @@ -46,6 +46,12 @@ class GETHandler { } ).catch( error => { reject( { 'code': 500, 'error': error } ); } ); + } else if ( call === 'getAllEvents' ) { + db.getJSONData( 'events' ).then( data => { + resolve( data ?? {} ); + } ).catch( error => { + reject( { 'code': 500, 'error': error } ); + } ); } else if ( call === 'getName' ) { resolve( { 'name': settings.name } ); } else { diff --git a/src/server/backend/db/data/eventDrafts.json b/src/server/backend/db/data/eventDrafts.json index 20b6a3f..8678d10 100644 --- a/src/server/backend/db/data/eventDrafts.json +++ b/src/server/backend/db/data/eventDrafts.json @@ -1 +1 @@ -{"test3":{"name":"TestEvent3","description":"Test event to see if it works to save data to backend","location":"test2","date":"2023-08-25","categories":{"1":{"price":{"1":20,"2":30},"bg":"#FFFFFF","fg":"#000000","name":"Category 1","id":"1","ticketCount":1}},"ageGroups":{"1":{"id":1,"name":"Child","age":"0 - 15.99"},"2":{"id":2,"name":"Adult"}},"maxTickets":0,"eventID":"test3","time":"10:00","currency":"USD","isDraft":true}} \ No newline at end of file +{"test4":{"name":"Test4Event","description":"Let's see...","location":"test2","date":"2023-09-18T10:00:00.000Z","categories":{"1":{"price":{"1":20,"2":30},"bg":"#FFFFFF","fg":"#000000","name":"Category 1","id":"1","ticketCount":1}},"ageGroups":{"1":{"id":1,"name":"Child","age":"0 - 15.99"},"2":{"id":2,"name":"Adult"}},"maxTickets":0,"eventID":"test4","time":"10:00:00.000","startingPrice":20,"currency":"USD","isDraft":true,"locationName":"TestLocation2","hasSeatplan":true}} \ No newline at end of file diff --git a/src/server/backend/db/data/events.json b/src/server/backend/db/data/events.json index 7e0b892..8678d10 100644 --- a/src/server/backend/db/data/events.json +++ b/src/server/backend/db/data/events.json @@ -1 +1 @@ -{ "test2": { "name": "TestEvent2", "location": "TestLocation2", "eventID": "test2", "date": "2023-07-15", "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 } } \ No newline at end of file +{"test4":{"name":"Test4Event","description":"Let's see...","location":"test2","date":"2023-09-18T10:00:00.000Z","categories":{"1":{"price":{"1":20,"2":30},"bg":"#FFFFFF","fg":"#000000","name":"Category 1","id":"1","ticketCount":1}},"ageGroups":{"1":{"id":1,"name":"Child","age":"0 - 15.99"},"2":{"id":2,"name":"Adult"}},"maxTickets":0,"eventID":"test4","time":"10:00:00.000","startingPrice":20,"currency":"USD","isDraft":true,"locationName":"TestLocation2","hasSeatplan":true}} \ No newline at end of file diff --git a/src/server/backend/db/data/seatplan.json b/src/server/backend/db/data/seatplan.json index 44c32ae..9cc80be 100644 --- a/src/server/backend/db/data/seatplan.json +++ b/src/server/backend/db/data/seatplan.json @@ -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":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}}}}} \ No newline at end of file +{"test2":{"draft":{},"save":{"seatInfo":{"data":{"1":{"0":22},"2":{"0":9},"3":{"0":9}},"count":100},"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}}}}} \ No newline at end of file diff --git a/src/server/config/settings.config.json b/src/server/config/settings.config.json index b08a5d6..9a1ec7b 100644 --- a/src/server/config/settings.config.json +++ b/src/server/config/settings.config.json @@ -9,5 +9,5 @@ "yourDomain": "http://localhost:8080", "mailSender": "libreevent ", "maxTickets": 10, - "currency": "USD" + "currency": "CHF" } \ No newline at end of file diff --git a/src/webapp/main/src/components/noseatplan.vue b/src/webapp/main/src/components/noseatplan.vue index 4757705..aa6f366 100644 --- a/src/webapp/main/src/components/noseatplan.vue +++ b/src/webapp/main/src/components/noseatplan.vue @@ -161,7 +161,9 @@ export default { } }, loadTickets () { - // TODO: Load from server + fetch( '/getAPI/getEvent?event=' + sessionStorage.getItem( 'selectedTicket' ) ).then( res => { + + } ); } }, created () { diff --git a/src/webapp/main/src/views/admin/EventsView.vue b/src/webapp/main/src/views/admin/EventsView.vue index 0af12da..426eee4 100644 --- a/src/webapp/main/src/views/admin/EventsView.vue +++ b/src/webapp/main/src/views/admin/EventsView.vue @@ -14,7 +14,7 @@

    {{ timeframe.name }}

    -
  • +
  • {{ event.name }}

    @@ -119,26 +119,29 @@ methods: { loadData () { fetch( '/admin/getAPI/getAllEvents' ).then( res => { - res.json().then( dat => { - this.events = dat[ 'live' ] ?? {}; - this.eventList.drafts[ 'content' ] = dat[ 'drafts' ] ?? {}; - let sortable = []; - for ( let event in this.events ) { - sortable.push( [ this.events[ event ][ 'eventID' ], new Date( this.events[ event ][ 'date' ] ).getTime() ] ); - } - sortable.sort( function( a, b ) { - return a[ 1 ] - b[ 1 ]; - } ); - - for ( let element in sortable ) { - if ( sortable[ element ][ 1 ] > this.currentDate ) { - this.eventList.upcoming.content[ sortable[ element ][ 0 ] ] = this.events[ sortable[ element ][ 0 ] ]; - } else { - this.eventList.past.content[ sortable[ element ][ 0 ] ] = this.events[ sortable[ element ][ 0 ] ]; + res.json().then( dat => { + this.events = dat[ 'live' ] ?? {}; + this.eventList.drafts[ 'content' ] = dat[ 'drafts' ] ?? {}; + let sortable = []; + for ( let event in this.events ) { + sortable.push( [ this.events[ event ][ 'eventID' ], new Date( this.events[ event ][ 'date' ] ).getTime() ] ); } - } + sortable.sort( function( a, b ) { + return a[ 1 ] - b[ 1 ]; + } ); + + for ( let element in sortable ) { + if ( this.eventList.drafts[ 'content' ][ sortable[ element ][ 0 ] ] ) { + delete this.eventList.drafts[ 'content' ][ sortable[ element ][ 0 ] ]; + } + if ( sortable[ element ][ 1 ] > this.currentDate ) { + this.eventList.upcoming.content[ sortable[ element ][ 0 ] ] = this.events[ sortable[ element ][ 0 ] ]; + } else { + this.eventList.past.content[ sortable[ element ][ 0 ] ] = this.events[ sortable[ element ][ 0 ] ]; + } + } + } ); } ); - } ); }, openRightClickMenu( id, event ) { this.$refs.rclk.openRightClickMenu( event, { 'edit': { 'command': 'editEvent', 'symbol': 'edit', 'display': 'Edit event' }, 'delete': { 'command': 'deleteEvent', 'symbol': 'delete', 'display': 'Delete event' } } ) @@ -161,12 +164,7 @@ sessionStorage.setItem( 'selectedTicket', id ); }, handleData ( data ) { - if ( this.currentPopup === 'delete' ) { - this.currentPopup = ''; - if ( data.status === 'ok' ) { - delete this.events[ this.currentlyOpenMenu ]; - } - } else if ( this.currentPopup === 'add' ) { + if ( this.currentPopup === 'add' ) { if ( data.status === 'ok' ) { const options = { method: 'post', @@ -188,10 +186,11 @@ } ); } } else if ( this.currentPopup === 'delete' ) { + console.log( data ); if ( data.status === 'ok' ) { const options = { method: 'post', - body: JSON.stringify( { 'event': data.data } ), + body: JSON.stringify( { 'event': this.currentlyOpenMenu } ), headers: { 'Content-Type': 'application/json', 'charset': 'utf-8' @@ -199,9 +198,9 @@ }; fetch( localStorage.getItem( 'url' ) + '/admin/api/deleteEvent', options ).then( res => { if ( res.status === 200 ) { - res.text().then( text => { + res.text().then( () => { this.currentlyOpenMenu = ''; - console.log( text ); + this.loadData(); } ); } } ); diff --git a/src/webapp/main/src/views/admin/events/EventsDetailsView.vue b/src/webapp/main/src/views/admin/events/EventsDetailsView.vue index dd65ef0..7abeef0 100644 --- a/src/webapp/main/src/views/admin/events/EventsDetailsView.vue +++ b/src/webapp/main/src/views/admin/events/EventsDetailsView.vue @@ -271,35 +271,47 @@ currency: 'USD', hasLiveVersion: false, hasSeatPlan: true, + totalSeats: 0, } }, created () { - if ( !sessionStorage.getItem( 'selectedTicket' ) ) { - this.$router.push( '/admin/events' ); - } - this.eventID = sessionStorage.getItem( 'selectedTicket' ); - fetch( localStorage.getItem( 'url' ) + '/admin/getAPI/getLocations' ).then( res => { - res.json().then( data => { - this.locations = data; - fetch( localStorage.getItem( 'url' ) + '/admin/getAPI/getEvent?event=' + this.eventID ).then( res => { - if ( res.status === 200 ) { - res.json().then( data => { - this.event = data; - this.currentLocation = this.event.location; - this.hasSeatPlan = this.locations[ this.event.location ] ? ( this.locations[ this.event.location ][ 'seatplan-enabled' ] ?? false ) : false; - } ).catch( error => { - console.error( error ); - } ); - } else if ( res.status === 404 ) { - this.$router.push( '/admin/events' ); - } - } ); - } ).catch( error => { - console.error( error ); - } ); - } ); + this.loadData(); }, methods: { + loadData () { + fetch( localStorage.getItem( 'url' ) + '/admin/getAPI/getCurrency' ).then( res => { + res.text().then( currency => { + this.currency = currency; + } ); + } ); + if ( !sessionStorage.getItem( 'selectedTicket' ) ) { + this.$router.push( '/admin/events' ); + } + this.eventID = sessionStorage.getItem( 'selectedTicket' ); + fetch( localStorage.getItem( 'url' ) + '/admin/getAPI/getLocations' ).then( res => { + res.json().then( data => { + this.locations = data; + fetch( localStorage.getItem( 'url' ) + '/admin/getAPI/getEvent?event=' + this.eventID ).then( res => { + if ( res.status === 200 ) { + res.json().then( data => { + this.event = data; + this.currentLocation = this.event.location; + const dt = this.event.date.split( 'T' ); + this.event.date = dt[ 0 ]; + this.event.time = dt[ 1 ].slice( 0, dt[ 1 ].length - 1 ); + this.hasSeatPlan = this.locations[ this.event.location ] ? ( this.locations[ this.event.location ][ 'seatplan-enabled' ] ?? false ) : false; + } ).catch( error => { + console.error( error ); + } ); + } else if ( res.status === 404 ) { + this.$router.push( '/admin/events' ); + } + } ); + } ).catch( error => { + console.error( error ); + } ); + } ); + }, saveImages() { if ( this.$refs.logo.file && this.$refs.banner.file ) { let fd = new FormData(); @@ -312,7 +324,9 @@ body: fd, }; fetch( localStorage.getItem( 'url' ) + '/admin/events/uploadImages?event=' + sessionStorage.getItem( 'selectedTicket' ) + '&image=' + 'logo', fetchOptions ).then( res => { - console.log( res ); + if ( res.status === 200 ) { + this.$refs.notification.createNotification( 'Images saved successfully!', 5, 'ok', 'normal' ); + } } ).catch( err => { console.error( err ); } ); @@ -328,16 +342,29 @@ return; } } + + let lowestPrice = 1000000; for ( let category in this.event.categories ) { for ( let price in this.event.categories[ category ].price ) { if ( this.event.categories[ category ].price[ price ] < 0.5 || ( !this.event.categories[ category ].ticketCount && this.hasSeatPlan ) ) { this.$refs.popups.openPopup( 'At least one of the prices for at least one of the categories is below the minimum of ' + this.currency + ' 0.5', {}, 'string' ); return; } + if ( this.event.categories[ category ].price[ price ] < lowestPrice ) { + lowestPrice = this.event.categories[ category ].price[ price ]; + }; } } + + this.event[ 'startingPrice' ] = lowestPrice; this.event[ 'currency' ] = this.currency; - this.event[ 'isDraft' ] = true; + this.event[ 'locationName' ] = this.locations[ this.event.location ].name; + this.event[ 'hasSeatplan' ] = this.hasSeatPlan; + const fullDate = new Date( this.event.date + 'T' + this.event.time +'Z' ); + this.event.date = fullDate.toISOString(); + if ( !this.event.maxTickets ) { + this.event.maxTickets = this.totalSeats; + } this.event.maxTickets = this.specialSettings[ 'maxTickets' ].value; let url = localStorage.getItem( 'url' ) + '/admin/api/saveEvent'; if ( action === 'deploy' ) { @@ -354,11 +381,12 @@ fetch( url, options ).then( res => { if ( res.status === 200 ) { if ( action === 'deploy' ) { - this.$refs.notification.createNotification( 'Your event has been set to be live successfully!', 5, 'ok', 'normal' ); + this.$refs.notification.createNotification( 'Your event has been published successfully.', 5, 'ok', 'normal' ); this.hasLiveVersion = true; } else { this.$refs.notification.createNotification( 'Saved as draft successfully!', 5, 'ok', 'normal' ); } + this.loadData(); } } ); } else { @@ -434,6 +462,8 @@ res.json().then( json => { this.hasSeatPlan = this.locations[ this.event.location ][ 'seatplan-enabled' ] ?? false; this.event.categories = {}; + this.totalSeats = json.seatInfo.count; + // TODO: Make sure ticket counting actually works from the seat plan editor for ( let element in json.data ) { if ( json.data[ element ][ 'type' ] === 'seat' || json.data[ element ][ 'type' ] === 'stand' ) { this.event.categories[ json.data[ element ][ 'category' ] ] = { 'price': {}, 'bg': '#FFFFFF', 'fg': '#000000', 'name': 'Category ' + json.data[ element ][ 'category' ], 'id': json.data[ element ][ 'category' ], 'ticketCount': 1 }; diff --git a/src/webapp/main/src/views/purchasing/OrderView.vue b/src/webapp/main/src/views/purchasing/OrderView.vue index b98bf68..0856a78 100644 --- a/src/webapp/main/src/views/purchasing/OrderView.vue +++ b/src/webapp/main/src/views/purchasing/OrderView.vue @@ -19,8 +19,8 @@

    {{ event.description }}

    -

    Free seats: {{ event.freeSeats }} / {{ event.maxSeats }}

    -

    {{ event.location }}, {{ event.dateString }}

    +

    Free seats: {{ event.free }} / {{ event.maxTickets }}

    +

    {{ event.locationName }}, {{ event.dateString }}

    Starting at {{ event.currency }} {{ event.startingPrice }}

    @@ -91,12 +91,26 @@ methods: { setActiveTicket ( id ) { sessionStorage.setItem( 'selectedTicket', id ); + }, + loadEvents () { + fetch( '/getAPI/getAllEvents' ).then( res => { + res.json().then( dat => { + this.events = dat ?? {}; + for ( let event in dat ) { + this.events[ event ][ 'logo' ] = new URL( location.protocol + '//' + location.hostname + ':' + location.port + '/eventAssets/' + this.events[ event ].eventID + 'Logo.jpg' ); + } + } ); + } ); } }, + created() { + this.loadEvents(); + }, data () { return { - events: { 'test':{ 'name': 'TestEvent', 'description': 'This is a description for the TestEvent to test multiline support and proper positioning of the Fields', 'freeSeats': 2, 'maxSeats': 2, 'date':'2023-08-31T09:00:00Z', 'startingPrice':15, 'location': 'TestLocation', 'eventID': 'test', 'currency': 'CHF', 'logo': new URL( '/src/assets/logo.png', import.meta.url ).href }, 'test2':{ 'name': 'TestEvent2', 'description': 'This is a description for the TestEvent to test multiline support and proper positioning of the Fields', 'freeSeats': 2, 'maxSeats': 2, 'date':'2023-08-15T09:00:00Z', 'startingPrice':15, 'location': 'TestLocation', 'eventID': 'test2', 'currency': 'CHF', 'logo': new URL( '/src/assets/logo.png', import.meta.url ).href } }, - today: new Date().getTime() + events: { 'test':{ 'name': 'TestEvent', 'description': 'This is a description for the TestEvent to test multiline support and proper positioning of the Fields', 'free': 2, 'maxTickets': 2, 'date':'2023-08-31T09:00:00Z', 'startingPrice':15, 'location': 'TestLocation', 'eventID': 'test', 'currency': 'CHF', 'logo': new URL( '/src/assets/logo.png', import.meta.url ).href }, 'test2':{ 'name': 'TestEvent2', 'description': 'This is a description for the TestEvent to test multiline support and proper positioning of the Fields', 'freeSeats': 2, 'maxSeats': 2, 'date':'2023-08-15T09:00:00Z', 'startingPrice':15, 'location': 'TestLocation', 'eventID': 'test2', 'currency': 'CHF', 'logo': new URL( '/src/assets/logo.png', import.meta.url ).href } }, + today: new Date().getTime(), + locations: {}, } }, computed: {