mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 13:24:24 +00:00
stripe almost working
This commit is contained in:
@@ -91,7 +91,8 @@ if ( settings.init ) {
|
||||
}
|
||||
|
||||
console.log( '[ Server ] loading plugins' );
|
||||
// pluginManager.load( app, settings );
|
||||
// TODO: load dynamically
|
||||
require( './backend/plugins/payments/stripe/stripeRoutes.js' )( app, settings ); // setup routes
|
||||
|
||||
app.use( ( request, response ) => {
|
||||
response.sendFile( file );
|
||||
|
||||
@@ -0,0 +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 } }
|
||||
@@ -55,7 +55,7 @@ class SQLDB {
|
||||
if ( error ) throw error;
|
||||
if ( results[ 0 ][ '@@default_storage_engine' ] !== 'InnoDB' ) return 'DB HAS TO USE InnoDB!';
|
||||
} );
|
||||
this.sqlConnection.query( 'CREATE TABLE libreevent_users ( account_id INT ( 10 ) NOT NULL AUTO_INCREMENT, email TINYTEXT NOT NULL, pass TEXT, street TEXT, house_number TINYTEXT, country TEXT, phone TEXT, name TEXT, first_name TEXT, two_fa TINYTEXT, PRIMARY KEY ( account_id ) ) ENGINE=INNODB;', ( error ) => {
|
||||
this.sqlConnection.query( 'CREATE TABLE libreevent_users ( account_id INT ( 10 ) NOT NULL AUTO_INCREMENT, email TINYTEXT NOT NULL, pass TEXT, name TEXT, first_name TEXT, two_fa TINYTEXT, user_data VARCHAR( 60000 ), PRIMARY KEY ( account_id ) ) ENGINE=INNODB;', ( error ) => {
|
||||
if ( error ) if ( error.code !== 'ER_TABLE_EXISTS_ERROR' ) throw error;
|
||||
this.sqlConnection.query( 'CREATE TABLE libreevent_orders ( order_id INT ( 10 ) NOT NULL AUTO_INCREMENT, account_id INT ( 10 ) NOT NULL, seats VARCHAR( 60000 ), PRIMARY KEY ( order_id ), FOREIGN KEY ( account_id ) REFERENCES libreevent_users( account_id ) ) ENGINE=INNODB;', ( error ) => {
|
||||
if ( error ) if ( error.code !== 'ER_TABLE_EXISTS_ERROR' ) throw error;
|
||||
|
||||
14
src/server/backend/payments/paymentHandler.js
Normal file
14
src/server/backend/payments/paymentHandler.js
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* libreevent - successHandler.js
|
||||
*
|
||||
* Created by Janis Hutz 08/02/2023, Licensed under the GPL V3 License
|
||||
* https://janishutz.com, development@janishutz.com
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class PaymentHandler {
|
||||
constructor () {}
|
||||
}
|
||||
|
||||
module.exports = PaymentHandler;
|
||||
8
src/server/backend/payments/paymentRoutes.js
Normal file
8
src/server/backend/payments/paymentRoutes.js
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* libreevent - paymentRoutes.js
|
||||
*
|
||||
* Created by Janis Hutz 08/02/2023, Licensed under the GPL V3 License
|
||||
* https://janishutz.com, development@janishutz.com
|
||||
*
|
||||
*
|
||||
*/
|
||||
@@ -9,10 +9,16 @@
|
||||
|
||||
const fs = require( 'fs' );
|
||||
const path = require( 'path' );
|
||||
const stripe = require( 'stripe' )( fs.readFileSync( path.join( __dirname + '/../../../../config/payments.config.secret.json' ) )[ 'stripe' ][ 'APIKey' ] );
|
||||
const db = require( '../../../db/db.js' );
|
||||
const stripConfig = JSON.parse( fs.readFileSync( path.join( __dirname + '/../../../../config/payments.config.secret.json' ) ) )[ 'stripe' ];
|
||||
const stripe = require( 'stripe' )( stripConfig[ 'APIKey' ] );
|
||||
|
||||
const endpointSecret = stripConfig[ 'endpointSecret' ];
|
||||
|
||||
// TODO: Remove all selected tickets if timestamp more than user defined amount ago
|
||||
|
||||
module.exports = ( app, settings ) => {
|
||||
app.post( '/payments/prepare', async ( req, res ) => {
|
||||
app.post( '/payments/prepare', ( req, res ) => {
|
||||
let purchase = {
|
||||
'line_items': [],
|
||||
'mode': 'payment',
|
||||
@@ -22,20 +28,36 @@ module.exports = ( app, settings ) => {
|
||||
'customer_email': req.body.mail
|
||||
};
|
||||
|
||||
for ( let item in req.body.products ) {
|
||||
db.getDataSimple( 'temp', 'user_id', req.session.id ).then( dat => {
|
||||
if ( dat[ 0 ] ) {
|
||||
db.getJSONData( 'events' ).then( events => {
|
||||
let data = JSON.parse( dat[ 0 ].data );
|
||||
( async () => {
|
||||
for ( let event in data ) {
|
||||
for ( let item in data[ event ] ) {
|
||||
purchase[ 'line_items' ].push( {
|
||||
'price_data': {
|
||||
'currency': req.body.currency,
|
||||
'product_data': {
|
||||
'name': req.body.products[ item ].name,
|
||||
'name': data[ event ][ item ].name,
|
||||
},
|
||||
'unit_amount': req.body.products[ item ].price
|
||||
'currency': events[ event ].currency,
|
||||
'unit_amount': Math.round( parseFloat( events[ event ][ 'categories' ][ data[ event ][ item ].category ].price[ data[ event ][ item ][ 'ticketOption' ] ] ) * 100 ),
|
||||
},
|
||||
'quantity': req.body.products[ item ].count ?? 1,
|
||||
'quantity': data[ event ][ item ].count ?? 1,
|
||||
} );
|
||||
}
|
||||
}
|
||||
const session = await stripe.checkout.sessions.create( purchase );
|
||||
res.send( session.url );
|
||||
} )();
|
||||
} );
|
||||
} else {
|
||||
res.status( 400 ).send( 'ERR_UID_NOT_FOUND' );
|
||||
}
|
||||
} ).catch( error => {
|
||||
console.error( '[ STRIPE ] DB ERROR: ' + error );
|
||||
res.status( 500 ).send( 'ERR_DB' );
|
||||
} );
|
||||
} );
|
||||
|
||||
app.get( '/payments/status', ( request, response ) => {
|
||||
@@ -50,6 +72,17 @@ module.exports = ( app, settings ) => {
|
||||
} );
|
||||
|
||||
app.post( '/payments/webhook', ( req, res ) => {
|
||||
// The webhook stripe sends data to
|
||||
const payload = req.body;
|
||||
const sig = req.headers[ 'stripe-signature' ];
|
||||
|
||||
let event;
|
||||
|
||||
try {
|
||||
event = stripe.webhooks.constructEvent( payload, sig, endpointSecret );
|
||||
} catch ( err ) {
|
||||
return res.status( 400 ).send( 'Webhook Error' );
|
||||
}
|
||||
|
||||
res.status( 200 ).end();
|
||||
} );
|
||||
};
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
- make pricing groups changeable in UI (event categories)
|
||||
|
||||
- create function that parses DB every 15 minutes and clears out junk
|
||||
|
||||
- Create password changing endpoint (to reset forgotten pwd)
|
||||
- Add Admin profile (page to change account settings per person like changing pwd)
|
||||
|
||||
|
||||
@@ -48,12 +48,12 @@ export default {
|
||||
methods: {
|
||||
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' ];
|
||||
if ( this.cart[ this.event.eventID ] ) {
|
||||
if ( this.cart[ this.event.eventID ][ 'tickets' ][ id + '_' + option ] ) {
|
||||
const tickets = this.cart[ this.event.eventID ][ 'tickets' ];
|
||||
for ( let ticket in tickets ) {
|
||||
if ( tickets[ ticket ][ 'id' ].split( '_' )[ 0 ] === id ) {
|
||||
totalTicketsPerID += this.cart[ this.event.name ][ 'tickets' ][ tickets[ ticket ][ 'id' ] ][ 'count' ];
|
||||
totalTicketsPerID += this.cart[ this.event.eventID ][ 'tickets' ][ tickets[ ticket ][ 'id' ] ][ 'count' ];
|
||||
}
|
||||
}
|
||||
if ( totalTicketsPerID < this.tickets[ id ].free ) {
|
||||
@@ -69,33 +69,33 @@ export default {
|
||||
},
|
||||
cartHandling ( operation, data, option ) {
|
||||
if ( operation === 'select' ) {
|
||||
if ( this.cart[ this.event.name ] ) {
|
||||
if ( this.cart[ this.event.name ][ 'tickets' ][ data.id + '_' + option ] ) {
|
||||
this.cart[ this.event.name ][ 'tickets' ][ data.id + '_' + option ][ 'count' ] += 1;
|
||||
if ( this.cart[ this.event.eventID ] ) {
|
||||
if ( this.cart[ this.event.eventID ][ 'tickets' ][ data.id + '_' + option ] ) {
|
||||
this.cart[ this.event.eventID ][ '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 };
|
||||
this.cart[ this.event.eventID ][ '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' ][ 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 };
|
||||
this.cart[ this.event.eventID ] = { 'displayName': this.event.name, 'tickets': {} };
|
||||
this.cart[ this.event.eventID ][ '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 ( this.cart[ this.event.name ][ 'tickets' ][ data + '_' + option ][ 'count' ] === 1 ) {
|
||||
delete this.cart[ this.event.name ][ 'tickets' ][ data + '_' + option ];
|
||||
if ( this.cart[ this.event.eventID ][ 'tickets' ][ data + '_' + option ][ 'count' ] === 1 ) {
|
||||
delete this.cart[ this.event.eventID ][ 'tickets' ][ data + '_' + option ];
|
||||
} else {
|
||||
this.cart[ this.event.name ][ 'tickets' ][ data + '_' + option ][ 'count' ] -= 1;
|
||||
this.cart[ this.event.eventID ][ 'tickets' ][ data + '_' + option ][ 'count' ] -= 1;
|
||||
}
|
||||
if ( Object.keys( this.cart[ this.event.name ][ 'tickets' ] ).length < 1 ) {
|
||||
delete this.cart[ this.event.name ];
|
||||
if ( Object.keys( this.cart[ this.event.eventID ][ 'tickets' ] ).length < 1 ) {
|
||||
delete this.cart[ this.event.eventID ];
|
||||
}
|
||||
}
|
||||
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 ) {
|
||||
if ( this.cart[ this.event.eventID ] ) {
|
||||
if ( this.cart[ this.event.eventID ][ 'tickets' ][ id + '_' + option ] ) {
|
||||
if ( this.cart[ this.event.eventID ][ 'tickets' ][ id + '_' + option ][ 'count' ] > 0 ) {
|
||||
this.cartHandling( 'deselect', id, option );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
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, 'category': 1 } },
|
||||
event: { 'name': 'TestEvent2', 'location': 'TestLocation2', '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 },
|
||||
event: { '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 },
|
||||
available: { 'redo': false, 'undo': false },
|
||||
scaleFactor: 1,
|
||||
sizePoll: null,
|
||||
@@ -167,7 +167,7 @@
|
||||
let self = this;
|
||||
let allSeatsAvailable = true;
|
||||
|
||||
fetch( localStorage.getItem( 'url' ) + '/getAPI/getReservedSeats?event=' + this.event.name ).then( res => {
|
||||
fetch( localStorage.getItem( 'url' ) + '/getAPI/getReservedSeats?event=' + this.event.eventID ).then( res => {
|
||||
if ( res.status === 200 ) {
|
||||
let unavailableSeats = {};
|
||||
res.json().then( data => {
|
||||
@@ -194,23 +194,23 @@
|
||||
}
|
||||
|
||||
let tickets = {};
|
||||
if ( this.cart[ this.event.name ] ) {
|
||||
tickets = this.cart[ this.event.name ][ 'tickets' ];
|
||||
if ( this.cart[ this.event.eventID ] ) {
|
||||
tickets = this.cart[ this.event.eventID ][ 'tickets' ];
|
||||
}
|
||||
|
||||
if ( data.user ) {
|
||||
for ( let element in tickets ) {
|
||||
if ( !data.user[ element ] ) {
|
||||
allSeatsAvailable = false;
|
||||
if ( Object.keys( this.cart[ this.event.name ][ 'tickets' ] ).length > 1 ) {
|
||||
delete this.cart[ this.event.name ][ 'tickets' ][ element ];
|
||||
if ( Object.keys( this.cart[ this.event.eventID ][ 'tickets' ] ).length > 1 ) {
|
||||
delete this.cart[ this.event.eventID ][ 'tickets' ][ element ];
|
||||
} else {
|
||||
delete this.cart[ this.event.name ];
|
||||
delete this.cart[ this.event.eventID ];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
delete this.cart[ this.event.name ];
|
||||
delete this.cart[ this.event.eventID ];
|
||||
allSeatsAvailable = false;
|
||||
}
|
||||
|
||||
@@ -299,8 +299,8 @@
|
||||
this.draggables = this.scaleUp( JSON.parse( sessionStorage.getItem( 'seatplan' ) ) );
|
||||
}
|
||||
|
||||
if ( this.cart[ this.event.name ] ) {
|
||||
let tickets = this.cart[ this.event.name ][ 'tickets' ];
|
||||
if ( this.cart[ this.event.eventID ] ) {
|
||||
let tickets = this.cart[ this.event.eventID ][ 'tickets' ];
|
||||
for ( let seat in tickets ) {
|
||||
if ( !unavailableSeats[ data.user[ seat ].component ] ) {
|
||||
unavailableSeats[ data.reserved[ seat ].component ] = {};
|
||||
@@ -350,17 +350,17 @@
|
||||
},
|
||||
cartHandling ( operation, data ) {
|
||||
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, 'option': data, 'comp': this.selectedSeat.componentID };
|
||||
if ( this.cart[ this.event.eventID ] ) {
|
||||
this.cart[ this.event.eventID ][ '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, 'option': data, 'comp': this.selectedSeat.componentID };
|
||||
this.cart[ this.event.eventID ] = { 'displayName': this.event.name, 'tickets': {}, 'eventID': this.event.eventID };
|
||||
this.cart[ this.event.eventID ][ '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 ) {
|
||||
delete this.cart[ this.event.name ][ 'tickets' ][ this.selectedSeat.id ];
|
||||
if ( Object.keys( this.cart[ this.event.eventID ][ 'tickets' ] ).length > 1 ) {
|
||||
delete this.cart[ this.event.eventID ][ 'tickets' ][ this.selectedSeat.id ];
|
||||
} else {
|
||||
delete this.cart[ this.event.name ];
|
||||
delete this.cart[ this.event.eventID ];
|
||||
}
|
||||
}
|
||||
this.$refs.cart.calculateTotal();
|
||||
@@ -371,7 +371,7 @@
|
||||
// Make call to server to reserve ticket to have server also keep track of reserved tickets
|
||||
const options = {
|
||||
method: 'post',
|
||||
body: JSON.stringify( { 'id': this.selectedSeat[ 'id' ], 'component': this.selectedSeat[ 'componentID' ], 'ticketOption': option.data, 'eventID': this.event.name } ),
|
||||
body: JSON.stringify( { 'id': this.selectedSeat[ 'id' ], 'component': this.selectedSeat[ 'componentID' ], 'ticketOption': option.data, 'eventID': this.event.eventID, 'category': this.draggables[ this.selectedSeat[ 'componentID' ] ].category, 'name': this.selectedSeat.displayName } ),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'charset': 'utf-8'
|
||||
@@ -400,7 +400,7 @@
|
||||
// Make call to server to deselect ticket
|
||||
const options = {
|
||||
method: 'post',
|
||||
body: JSON.stringify( { 'id': seat[ 'id' ], 'eventID': this.event.name } ),
|
||||
body: JSON.stringify( { 'id': seat[ 'id' ], 'eventID': this.event.eventID } ),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'charset': 'utf-8'
|
||||
@@ -416,10 +416,10 @@
|
||||
const d = this.draggables[ id ];
|
||||
const evG = this.event.ageGroups;
|
||||
let count = {};
|
||||
if ( this.cart[ this.event.name ] ) {
|
||||
if ( this.cart[ this.event.eventID ] ) {
|
||||
for ( let ageGroup in evG ) {
|
||||
if ( this.cart[ this.event.name ][ 'tickets' ][ 'ticket' + id + '_' + ageGroup ] ) {
|
||||
count[ ageGroup ] = this.cart[ this.event.name ][ 'tickets' ][ 'ticket' + id + '_' + ageGroup ].count;
|
||||
if ( this.cart[ this.event.eventID ][ 'tickets' ][ 'ticket' + id + '_' + ageGroup ] ) {
|
||||
count[ ageGroup ] = this.cart[ this.event.eventID ][ 'tickets' ][ 'ticket' + id + '_' + ageGroup ].count;
|
||||
} else {
|
||||
count[ ageGroup ] = 0;
|
||||
}
|
||||
@@ -440,16 +440,17 @@
|
||||
}, 'tickets' );
|
||||
},
|
||||
standingTicketHandling ( data ) {
|
||||
if ( !this.cart[ this.event.name ] ) {
|
||||
this.cart[ this.event.name ] = { 'displayName': this.event.name, 'tickets': {} };
|
||||
if ( !this.cart[ this.event.eventID ] ) {
|
||||
this.cart[ this.event.eventID ] = { 'displayName': this.event.name, 'tickets': {}, 'eventID': this.event.eventID };
|
||||
}
|
||||
|
||||
for ( let group in data.data ) {
|
||||
if ( !this.cart[ this.event.name ][ 'tickets' ][ 'ticket' + data.component + '_' + group ] ) {
|
||||
if ( !this.cart[ this.event.eventID ][ 'tickets' ][ 'ticket' + data.component + '_' + group ] ) {
|
||||
if ( data.data[ group ] > 0 ) {
|
||||
const options = {
|
||||
method: 'post',
|
||||
body: JSON.stringify( { 'id': 'ticket' + data.component + '_' + group, 'component': data.component, 'ticketOption': '', 'eventID': this.event.name, 'count': data.data[ group ] } ),
|
||||
// TODO: Add correct name here as well once it is working at all
|
||||
body: JSON.stringify( { 'id': 'ticket' + data.component + '_' + group, 'component': data.component, 'ticketOption': '', 'eventID': this.event.eventID, 'count': data.data[ group ], 'category': this.draggables[ data.component ].category, 'name': 'Ticket ' } ),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'charset': 'utf-8'
|
||||
@@ -457,24 +458,24 @@
|
||||
};
|
||||
fetch( localStorage.getItem( 'url' ) + '/API/reserveTicket', options ).then( res => {
|
||||
if ( res.status === 200 ) {
|
||||
this.cart[ this.event.name ][ 'tickets' ][ 'ticket' + data.component + '_' + group ] = { 'displayName': 'Ticket ' + data.component + ' (' + this.event.ageGroups[ group ].name + ')', 'price': this.event.categories[ this.draggables[ data.component ].category ].price[ group ], 'id': 'ticket' + data.component + '_' + group, 'count': data.data[ group ], 'comp': data.component };
|
||||
this.cart[ this.event.eventID ][ 'tickets' ][ 'ticket' + data.component + '_' + group ] = { 'displayName': 'Ticket ' + data.component + ' (' + this.event.ageGroups[ group ].name + ')', 'price': this.event.categories[ this.draggables[ data.component ].category ].price[ group ], 'id': 'ticket' + data.component + '_' + group, 'count': data.data[ group ], 'comp': data.component };
|
||||
} else if ( res.status === 409 ) {
|
||||
setTimeout( () => {
|
||||
this.$refs.popups.openPopup( 'Unfortunately, the seat you just tried to select was reserved by somebody else since the last time the seat plan was refreshed. Please select another one. We are sorry for the inconvenience.', {}, 'string' );
|
||||
}, 300 );
|
||||
}
|
||||
if ( Object.keys( this.cart[ this.event.name ][ 'tickets' ] ).length < 1 ) {
|
||||
delete this.cart[ this.event.name ];
|
||||
if ( Object.keys( this.cart[ this.event.eventID ][ 'tickets' ] ).length < 1 ) {
|
||||
delete this.cart[ this.event.eventID ];
|
||||
}
|
||||
|
||||
this.$refs.cart.calculateTotal();
|
||||
localStorage.setItem( 'cart', JSON.stringify( this.cart ) );
|
||||
} );
|
||||
} else {
|
||||
delete this.cart[ this.event.name ][ 'tickets' ][ 'ticket' + data.component + '_' + group ];
|
||||
delete this.cart[ this.event.eventID ][ 'tickets' ][ 'ticket' + data.component + '_' + group ];
|
||||
const options = {
|
||||
method: 'post',
|
||||
body: JSON.stringify( { 'id': 'ticket' + data.component + '_' + group, 'eventID': this.event.name } ),
|
||||
body: JSON.stringify( { 'id': 'ticket' + data.component + '_' + group, 'eventID': this.event.eventID } ),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'charset': 'utf-8'
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<h4 class="price"><div style="display: inline;" v-if="ticket.count">{{ ticket.count }}x</div> {{ ticket.displayName }}: </h4>
|
||||
</td>
|
||||
<td>
|
||||
{{ backend.currency }} {{ ticket.price }} <span class="material-symbols-outlined deleteButton" @click="deleteTicket( ticket.id, event.displayName )" title="Delete ticket">delete</span>
|
||||
{{ backend.currency }} {{ ticket.price }} <span class="material-symbols-outlined deleteButton" @click="deleteTicket( ticket.id, event.eventID )" title="Delete ticket">delete</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<template>
|
||||
<div class="purchase">
|
||||
<h1>Purchase</h1>
|
||||
<div class="purchase-app">
|
||||
<div class="purchase-app" v-if="cartNotEmpty">
|
||||
<div v-if="!isAuthenticated" class="wrapper-buttons">
|
||||
<router-link to="/login" class="option-button" @click="setRedirect()">Log in with an existing account</router-link><br>
|
||||
<router-link to="/signup" class="option-button" @click="setRedirect()">Create new account</router-link><br>
|
||||
@@ -67,6 +67,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
Cart is empty. Please add tickets <router-link to="/tickets">here</router-link>
|
||||
<div class="empty-cart-wrapper">
|
||||
<span class="material-symbols-outlined empty-cart">remove_shopping_cart</span>
|
||||
</div>
|
||||
</div>
|
||||
<notifications ref="notification" location="topleft" size="bigger"></notifications>
|
||||
</div>
|
||||
</template>
|
||||
@@ -188,6 +194,19 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.empty-cart-wrapper {
|
||||
width: 100%;
|
||||
height: 70vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.empty-cart {
|
||||
display: block;
|
||||
font-size: 20rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@@ -227,7 +246,6 @@ export default {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if ( this.cartNotEmpty ) {
|
||||
this.cart = cart;
|
||||
this.isAuthenticated = this.userStore.getUserAuthenticated;
|
||||
@@ -255,12 +273,32 @@ export default {
|
||||
route (plain HTML document) which then awaits processing completion and gives the
|
||||
user a link to download the ticket. A mail has been sent to user automatically.
|
||||
*/
|
||||
let prep = this.$refs.notification.createNotification( 'Preparing payment...', 20, 'progress', 'high' );
|
||||
let prep = this.$refs.notification.createNotification( 'Preparing payment...', 20, 'progress', 'normal' );
|
||||
|
||||
setTimeout( () => {
|
||||
let fetchOptions = {
|
||||
method: 'post',
|
||||
body: JSON.stringify( this.userData ),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'charset': 'utf-8'
|
||||
}
|
||||
};
|
||||
|
||||
fetch( '/payments/prepare', fetchOptions ).then( res => {
|
||||
if ( res.status === 200 ) {
|
||||
this.$refs.notification.cancelNotification( prep );
|
||||
this.$refs.notification.createNotification( 'Payment prepared, redirecting...', 5, 'progress', 'high' );
|
||||
}, 5000 );
|
||||
res.text().then( text => {
|
||||
setTimeout( () => {
|
||||
window.location.href = text;
|
||||
}, 300 );
|
||||
} );
|
||||
}
|
||||
} ).catch( err => {
|
||||
console.error( err );
|
||||
this.$refs.notification.cancelNotification( prep );
|
||||
this.$refs.notification.createNotification( 'An error occurred during preparation of payments. Please try again.', 10, 'error', 'high' );
|
||||
} );
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
||||
Reference in New Issue
Block a user