mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 05:14:23 +00:00
ticket gen working + various changes
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -17,3 +17,10 @@ node_modules
|
||||
/dist
|
||||
|
||||
*.secret.json
|
||||
|
||||
# ignore all latex files except .tex
|
||||
*.aux
|
||||
*.fls
|
||||
*.synctex.gz
|
||||
*.fdb_latexmk
|
||||
._wordcount_selection.tex
|
||||
3
assets/basicTicketTemplate/README.md
Normal file
3
assets/basicTicketTemplate/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Ticket Template
|
||||
|
||||
This template can be used by libreevent if you do not edit the template. It is entirely copyleft and you can change it to your liking. The LaTex document is included with libreevent.
|
||||
BIN
assets/basicTicketTemplate/basicTicketTemplate.pdf
Normal file
BIN
assets/basicTicketTemplate/basicTicketTemplate.pdf
Normal file
Binary file not shown.
25
assets/basicTicketTemplate/basicTicketTemplate.tex
Normal file
25
assets/basicTicketTemplate/basicTicketTemplate.tex
Normal file
@@ -0,0 +1,25 @@
|
||||
\documentclass[11pt]{article}
|
||||
|
||||
% Imports %
|
||||
\usepackage{amsmath}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{subcaption}
|
||||
\usepackage[export]{adjustbox}
|
||||
\usepackage{tcolorbox}
|
||||
\usepackage{xcolor}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[a4paper]{geometry}
|
||||
|
||||
\addtolength{\oddsidemargin}{-0.5in}
|
||||
\addtolength{\textwidth}{1in}
|
||||
\addtolength{\evensidemargin}{-0.55in}
|
||||
\addtolength{\topmargin}{-0.75in}
|
||||
\addtolength{\textheight}{1.5in}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{tcolorbox}[colback=gray!5!white,colframe=black!75!black,title=Your Ticket - libreevent event management solution]
|
||||
\vspace{6cm}
|
||||
\end{tcolorbox}
|
||||
|
||||
\end{document}
|
||||
@@ -28,10 +28,9 @@ module.exports = ( app, settings ) => {
|
||||
if ( request.body.mail && request.body.password ) {
|
||||
pwdmanager.checkpassword( request.body.mail, request.body.password ).then( data => {
|
||||
request.session.username = request.body.mail;
|
||||
if ( data ) {
|
||||
if ( data.status ) {
|
||||
request.session.username = request.body.mail;
|
||||
// TODO: Check if user has 2fa enabled
|
||||
if ( settings.twoFA === 'standard' ) {
|
||||
if ( data.twoFA === 'simple' ) {
|
||||
( async () => {
|
||||
let tok = twoFA.registerStandardAuthentication()[ 'token' ];
|
||||
let ipRetrieved = request.headers[ 'x-forwarded-for' ];
|
||||
@@ -40,7 +39,7 @@ module.exports = ( app, settings ) => {
|
||||
request.session.token = tok;
|
||||
response.send( { 'status': '2fa' } );
|
||||
} )();
|
||||
} else if ( settings.twoFA === 'enhanced' ) {
|
||||
} else if ( data.twoFA === 'enhanced' ) {
|
||||
( async () => {
|
||||
let res = twoFA.registerEnhancedAuthentication();
|
||||
let ipRetrieved = request.headers[ 'x-forwarded-for' ];
|
||||
@@ -50,7 +49,7 @@ module.exports = ( app, settings ) => {
|
||||
response.send( { 'status': '2fa+', 'code': res.code } );
|
||||
} )();
|
||||
} else {
|
||||
request.session.loggedInUser = true;
|
||||
request.session.loggedInAdmin = true;
|
||||
response.send( { 'status': 'ok' } );
|
||||
}
|
||||
} else {
|
||||
@@ -63,7 +62,6 @@ module.exports = ( app, settings ) => {
|
||||
} );
|
||||
|
||||
app.get( '/admin/2fa', ( request, response ) => {
|
||||
// TODO: Add multi language
|
||||
let tokType = twoFA.verifySimple( request.query.token );
|
||||
if ( tokType === 'standard' ) {
|
||||
request.session.loggedInAdmin = true;
|
||||
|
||||
@@ -42,7 +42,13 @@ class GETHandler {
|
||||
} );
|
||||
} else if ( call === 'getLocations' ) {
|
||||
db.getJSONData( 'locations' ).then( data => {
|
||||
resolve( data );
|
||||
resolve( data ?? {} );
|
||||
} ).catch( error => {
|
||||
reject( { 'code': 500, 'error': error } );
|
||||
} );
|
||||
} else if ( call === 'getTicketTemplate' ) {
|
||||
db.getJSONDataSimple( 'tickets', query.ticket ).then( data => {
|
||||
resolve( data ?? {} );
|
||||
} ).catch( error => {
|
||||
reject( { 'code': 500, 'error': error } );
|
||||
} );
|
||||
|
||||
@@ -24,7 +24,7 @@ module.exports.checkpassword = ( username, password ) => {
|
||||
if ( data ) {
|
||||
if ( data[ 0 ] ) {
|
||||
bcrypt.compare( password, data[ 0 ].pass ).then( res => {
|
||||
resolve( res );
|
||||
resolve( { 'status': res, 'twoFA': data[ 0 ].two_fa } );
|
||||
} );
|
||||
} else {
|
||||
resolve( false );
|
||||
|
||||
@@ -101,6 +101,6 @@ app.use( ( request, response ) => {
|
||||
|
||||
console.log( '\n\n[ Server ] loading complete!\n\n' );
|
||||
|
||||
const PORT = process.env.PORT || 8081;
|
||||
const PORT = process.env.PORT || 8080;
|
||||
console.log( '[ Server ] listening on port ' + PORT );
|
||||
http.createServer( app ).listen( PORT );
|
||||
@@ -30,7 +30,7 @@ class GETHandler {
|
||||
if ( query.event ) {
|
||||
db.getJSONDataSimple( 'booked', query.event ).then( data => {
|
||||
db.getDataSimple( 'temp', 'user_id', session.id ).then( dat => {
|
||||
resolve( { 'booked': data ? data.booked : {}, 'user': dat[ 0 ] ? JSON.parse( dat[ 0 ].data )[ query.event ] ?? {} : {} } );
|
||||
resolve( { 'booked': data ?? {}, 'user': dat[ 0 ] ? JSON.parse( dat[ 0 ].data )[ query.event ] ?? {} : {} } );
|
||||
} );
|
||||
} ).catch( error => {
|
||||
reject( { 'code': 500, 'message': error } );
|
||||
|
||||
@@ -39,7 +39,9 @@ class POSTHandler {
|
||||
return;
|
||||
}
|
||||
transmit[ data.eventID ][ data.id ] = data;
|
||||
// TODO: Prevent seat selection if already taken (also if in booked!)
|
||||
// TODO: Respect max ticket count per user
|
||||
// TODO: maybe move to per event setting
|
||||
let totalUserTickets = 0;
|
||||
for ( let event in transmit ) {
|
||||
for ( let ticket in transmit[ event ] ) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -58,6 +58,16 @@ module.exports.writeDataSimple = ( db, column, searchQuery, data ) => {
|
||||
} );
|
||||
};
|
||||
|
||||
module.exports.deleteDataSimple = ( db, column, searchQuery ) => {
|
||||
return new Promise( ( resolve, reject ) => {
|
||||
dbh.query( { 'command': 'deleteData', 'property': column, 'searchQuery': searchQuery }, dbRef[ db ] ).then( dat => {
|
||||
resolve( dat );
|
||||
} ).catch( error => {
|
||||
reject( error );
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
module.exports.checkDataAvailability = ( db, column, searchQuery ) => {
|
||||
return new Promise( ( resolve, reject ) => {
|
||||
dbh.query( { 'command': 'checkDataAvailability', 'property': column, 'searchQuery': searchQuery }, dbRef[ db ] ).then( res => {
|
||||
|
||||
@@ -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, name TEXT, first_name TEXT, two_fa TINYTEXT, user_data VARCHAR( 60000 ), mail_confirmed TINYTEXT, marketing_ok 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 ), mail_confirmed TINYTEXT, marketing TINYTEXT, 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, order_name TINYTEXT, account_id INT ( 10 ) NOT NULL, tickets VARCHAR( 60000 ), processed TINYTEXT, 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;
|
||||
@@ -104,6 +104,10 @@ class SQLDB {
|
||||
- addData:
|
||||
- operation.data (key-value pair with all data as values and column to insert into as key)
|
||||
|
||||
- deleteData:
|
||||
- operation.property (the column to search for the value)
|
||||
- operation.searchQuery (the value to search for [will be sanitised by method])
|
||||
|
||||
- updateData:
|
||||
- operation.newValues (a object with keys being the column and value being the value to be inserted into that column, values are being
|
||||
sanitised by the function)
|
||||
|
||||
@@ -40,6 +40,7 @@ module.exports = ( app, settings ) => {
|
||||
if ( dat[ 0 ] ) {
|
||||
db.getJSONData( 'events' ).then( events => {
|
||||
let data = JSON.parse( dat[ 0 ].data );
|
||||
console.log( data );
|
||||
( async () => {
|
||||
for ( let event in data ) {
|
||||
for ( let item in data[ event ] ) {
|
||||
@@ -116,7 +117,7 @@ module.exports = ( app, settings ) => {
|
||||
}
|
||||
} );
|
||||
|
||||
app.post( '/payments/webhook', bodyParser.raw( { type: 'application/json' } ), ( req, res ) => {
|
||||
app.post( '/payments/webhook', bodyParser.raw( { type: 'application/json' } ), async ( req, res ) => {
|
||||
const payload = req.body;
|
||||
const sig = req.headers[ 'stripe-signature' ];
|
||||
|
||||
@@ -139,9 +140,26 @@ module.exports = ( app, settings ) => {
|
||||
db.getDataSimple( 'users', 'email', sessionReference[ event.data.object.id ][ 'email' ] ).then( user => {
|
||||
if ( user[ 0 ] ) {
|
||||
console.log( sessionReference[ event.data.object.id ][ 'tok' ] );
|
||||
const tickets = JSON.parse( dat[ 0 ].data );
|
||||
db.writeDataSimple( 'orders', 'account_id', user[ 0 ].account_id, { 'account_id': user[ 0 ].account_id, 'tickets': dat[ 0 ].data, 'order_name': sessionReference[ event.data.object.id ][ 'tok' ] } ).then( () => {
|
||||
TicketGenerator.generateTickets( sessionReference[ event.data.object.id ] );
|
||||
} );
|
||||
db.getJSONData( 'booked' ).then( ret => {
|
||||
let booked = ret ?? {};
|
||||
for ( let event in tickets ) {
|
||||
if ( !booked[ String( event ) ] ) {
|
||||
booked[ String( event ) ] = {};
|
||||
}
|
||||
for ( let tik in tickets[ event ] ) {
|
||||
booked[ event ][ tik ] = tickets[ event ][ tik ];
|
||||
}
|
||||
}
|
||||
db.writeJSONData( 'booked', booked );
|
||||
} );
|
||||
|
||||
db.deleteDataSimple( 'temp', 'user_id', sessionReference[ event.data.object.id ][ 'tok' ] ).catch( error => {
|
||||
console.error( '[ STRIPE ] ERROR whilst deleting data from DB: ' + error );
|
||||
} );
|
||||
} else {
|
||||
console.log( sessionReference[ event.data.object.id ][ 'email' ] );
|
||||
console.error( 'user not found' );
|
||||
|
||||
@@ -35,7 +35,7 @@ class TicketGenerator {
|
||||
this.runningTickets = {};
|
||||
}
|
||||
|
||||
// TODO: Save to disk in case of crash of server / reboot / whatever
|
||||
// TODO: Save to disk / DB in case of crash of server / reboot / whatever
|
||||
// and continue processing once back online
|
||||
generateTickets ( order ) {
|
||||
this.ticketQueue[ this.jobId ] = { 'order': order };
|
||||
@@ -114,8 +114,10 @@ class TicketGenerator {
|
||||
for ( let event in order ) {
|
||||
const template = this.tickets[ event ];
|
||||
for ( let ticket in order[ event ] ) {
|
||||
for ( let tik = 0; tik < ( order[ event ][ ticket ].count ?? 1 ); tik++ ) {
|
||||
const data = [ {
|
||||
'locationAndTime': this.events[ event ][ 'date' ],
|
||||
'eventName': this.events[ event ][ 'name' ],
|
||||
'locationAndTime': new Date( this.events[ event ][ 'date' ] ).toLocaleString(),
|
||||
'ticketName': order[ event ][ ticket ][ 'name' ],
|
||||
'ticketQRCode': ord[ 0 ].order_name + '_' + order[ event ][ ticket ][ 'id' ],
|
||||
} ];
|
||||
@@ -125,6 +127,7 @@ class TicketGenerator {
|
||||
p.forEach( ( page ) => doc.addPage( page ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
const f = path.join( __dirname + '/store/' + ord[ 0 ].order_name + '.pdf' );
|
||||
fs.writeFileSync( f, await doc.save() );
|
||||
resolve( { 'status': true, 'file': f, 'user': ord[ 0 ].account_id, 'order': ord[ 0 ].order_name } );
|
||||
|
||||
@@ -49,8 +49,8 @@ module.exports = ( app, settings ) => {
|
||||
app.post( '/user/login', bodyParser.json(), ( request, response ) => {
|
||||
if ( request.body.mail && request.body.password ) {
|
||||
pwdmanager.checkpassword( request.body.mail, request.body.password ).then( data => {
|
||||
request.session.username = request.body.mail;
|
||||
if ( data.status ) {
|
||||
request.session.username = request.body.mail;
|
||||
if ( data.twoFA === 'simple' ) {
|
||||
( async () => {
|
||||
let tok = twoFA.registerStandardAuthentication()[ 'token' ];
|
||||
@@ -83,7 +83,6 @@ module.exports = ( app, settings ) => {
|
||||
} );
|
||||
|
||||
app.get( '/user/2fa', ( request, response ) => {
|
||||
// TODO: Add multi language
|
||||
let tokType = twoFA.verifySimple( request.query.token );
|
||||
if ( tokType === 'standard' ) {
|
||||
request.session.loggedInUser = true;
|
||||
@@ -154,7 +153,7 @@ module.exports = ( app, settings ) => {
|
||||
mailManager.sendMail( request.body.mail, await twoFA.generateSignupEmail( tok, settings.yourDomain, settings.name ), 'Confirm your email', settings.mailSender );
|
||||
} )();
|
||||
pwdmanager.hashPassword( request.body.password ).then( hash => {
|
||||
db.writeDataSimple( 'users', 'email', request.body.mail, { 'email': request.body.mail, 'pass': hash, 'first_name': request.body.firstName, 'name': request.body.name, 'two_fa': 'disabled', 'user_data': JSON.stringify( { 'country': request.body.country } ) } ).then( () => {
|
||||
db.writeDataSimple( 'users', 'email', request.body.mail, { 'email': request.body.mail, 'pass': hash, 'first_name': request.body.firstName, 'name': request.body.name, 'two_fa': 'disabled', 'user_data': JSON.stringify( { 'country': request.body.country } ), 'marketing': request.body.newsletter ? generator.generateToken( 60 ) : null } ).then( () => {
|
||||
request.session.loggedInUser = true;
|
||||
request.session.username = request.body.mail;
|
||||
response.send( 'ok' );
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
"db": "mysql",
|
||||
"payments": "stripe",
|
||||
"name": "libreevent",
|
||||
"yourDomain": "http://localhost:8081",
|
||||
"yourDomain": "http://localhost:8080",
|
||||
"mailSender": "libreevent <info@libreevent.janishutz.com>"
|
||||
}
|
||||
@@ -3,11 +3,13 @@
|
||||
|
||||
- make pricing groups changeable in UI (event categories)
|
||||
|
||||
- create function that parses DB every 15 minutes and clears out junk
|
||||
- create function that parses DB every 15 minutes and clears out junk --> Also update data in db when user goes to purchase to prevent clearing during purchase
|
||||
|
||||
- Require user to confirm email before purchasing
|
||||
|
||||
- Guest purchase in the future (remove from matura shit)
|
||||
|
||||
|
||||
- Guest purchase in the future (maybe remove from matura)
|
||||
|
||||
- Create password changing endpoint (to reset forgotten pwd)
|
||||
- Add Admin profile (page to change account settings per person like changing pwd)
|
||||
@@ -19,7 +21,9 @@
|
||||
|
||||
- Implement Permission system
|
||||
|
||||
- Seat numbering
|
||||
- Seat numbering!!
|
||||
|
||||
- Add localization for date
|
||||
|
||||
|
||||
- add webpack (or any other minifying tool) to project website to decrease file size (OPTIONAL)
|
||||
@@ -169,7 +169,7 @@
|
||||
} );
|
||||
|
||||
if ( !sessionStorage.getItem( 'seatplan-history' ) ) {
|
||||
sessionStorage.setItem( 'seatplaTODO:n-history', JSON.stringify( { '1': this.scaleDown( this.draggables ) } ) );
|
||||
sessionStorage.setItem( 'seatplan-history', JSON.stringify( { '1': this.scaleDown( this.draggables ) } ) );
|
||||
}
|
||||
|
||||
let history = sessionStorage.getItem( 'seatplan-history' ) ? JSON.parse( sessionStorage.getItem( 'seatplan-history' ) ) : {};
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
<template>
|
||||
<div id="window">
|
||||
<h2>Seat plan: {{ event.name }}</h2>
|
||||
<div class="parent" id="parent" @wheel="( e ) => { handleScroll( e ); }" @mousemove="( e ) => { handleDrag( e ); }" @mousedown="( e ) => { setOffset( e ); }">
|
||||
<div class="content-parent">
|
||||
<Vue3DraggableResizable v-for="draggable in draggables" :initW="draggable.w" :initH="draggable.h" :x="draggable.x" :y="draggable.y" :w="draggable.w" :h="draggable.h"
|
||||
@@ -42,7 +41,7 @@
|
||||
<button title="Reset zoom [=]" @click="zoom( 1 );"><span class="material-symbols-outlined">center_focus_strong</span></button>
|
||||
<button title="Zoom out [-]" @click="zoom( -0.2 )"><span class="material-symbols-outlined">zoom_out</span></button>
|
||||
</div>
|
||||
<sideCartView :cart="cart" ref="cart"></sideCartView>
|
||||
<sideCartView :cart="cart" :name="event.name" ref="cart"></sideCartView>
|
||||
<notifications ref="notification" location="topright"></notifications>
|
||||
<popups ref="popups" size="normal" @data="data => { reserveTicket( data ) }"
|
||||
@ticket="data => { standingTicketHandling( data ) }"></popups>
|
||||
@@ -156,7 +155,6 @@
|
||||
}
|
||||
|
||||
this.seatChecks();
|
||||
// TODO: Optimise for odd screen sizes and aspect ratios and fucking webkit
|
||||
// TODO: Trim scroll box to about 200px more than seatplan size
|
||||
sessionStorage.setItem( 'seatplan', JSON.stringify( this.scaleDown( this.draggables ) ) );
|
||||
window.addEventListener( 'visibilitychange', ( e ) => {
|
||||
@@ -171,15 +169,6 @@
|
||||
if ( res.status === 200 ) {
|
||||
let unavailableSeats = {};
|
||||
res.json().then( data => {
|
||||
for ( let seat in data.booked ) {
|
||||
if ( data.booked[ seat ] ) {
|
||||
if ( !unavailableSeats[ data.booked[ seat ].component ] ) {
|
||||
unavailableSeats[ data.booked[ seat ].component ];
|
||||
}
|
||||
unavailableSeats[ data.booked[ seat ].component ][ data.booked[ seat ].id ] = 'nav';
|
||||
}
|
||||
}
|
||||
|
||||
for ( let seat in data.reserved ) {
|
||||
if ( data.reserved[ seat ] ) {
|
||||
if ( !unavailableSeats[ data.reserved[ seat ].component ] ) {
|
||||
@@ -198,6 +187,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
for ( let seat in data.booked ) {
|
||||
if ( data.booked[ seat ] ) {
|
||||
if ( !unavailableSeats[ data.booked[ seat ].component ] ) {
|
||||
unavailableSeats[ data.booked[ seat ].component ];
|
||||
}
|
||||
unavailableSeats[ data.booked[ seat ].component ][ data.booked[ seat ].id ] = 'nav';
|
||||
}
|
||||
}
|
||||
|
||||
let tickets = {};
|
||||
if ( this.cart[ this.event.eventID ] ) {
|
||||
tickets = this.cart[ this.event.eventID ][ 'tickets' ];
|
||||
@@ -449,8 +447,7 @@
|
||||
if ( data.data[ group ] > 0 ) {
|
||||
const options = {
|
||||
method: 'post',
|
||||
// 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 ' } ),
|
||||
body: JSON.stringify( { 'id': 'ticket' + data.component + '_' + group, 'component': data.component, 'ticketOption': group, 'eventID': this.event.eventID, 'count': data.data[ group ], 'category': this.draggables[ data.component ].category, 'name': 'Ticket ' + data.component + ' (' + this.event.ageGroups[ group ].name + ')' } ),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'charset': 'utf-8'
|
||||
@@ -510,7 +507,7 @@
|
||||
.parent {
|
||||
height: 80vh;
|
||||
width: 70vw;
|
||||
top: 17vh;
|
||||
top: 90px;
|
||||
left: 5vw;
|
||||
position: absolute;
|
||||
border: black 1px solid;
|
||||
@@ -548,7 +545,7 @@
|
||||
.toolbar {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
top: 17vh;
|
||||
top: 90px;
|
||||
left: 5.5vw;
|
||||
}
|
||||
.toolbar button {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<template>
|
||||
<div id="sideCartView">
|
||||
<h1>Seat plan: {{ name }}</h1>
|
||||
<h2>Cart</h2>
|
||||
<div v-if="Object.keys( cart ).length > 0" style="height: 100%; width: 100%;">
|
||||
<div class="scroll-wrapper">
|
||||
@@ -64,6 +65,10 @@ export default {
|
||||
'height': {
|
||||
type: Number,
|
||||
default: 17
|
||||
},
|
||||
'name': {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -92,7 +97,7 @@ export default {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
height: 100vh;
|
||||
top: 17vh;
|
||||
top: 90px;
|
||||
width: 25vw;
|
||||
background-color: var( --accent-background );
|
||||
color: var( --secondary-color );
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>Detailed explanation of payment gateways can be found <a href="https://libreevent.janishutz.com/docs/payments" target="_blank">here</a>. You may install more payment gateway integrations in the plugins section.</p>
|
||||
<p>Detailed explanation of payment gateways can be found <a href="https://libreevent.janishutz.com/docs/payments" target="_blank">here</a>. You may install more payment gateway integrations in the plugins section. Only one may be used at any given time.</p>
|
||||
|
||||
<div class="admin-settings">
|
||||
<h2>Admin Accounts</h2>
|
||||
@@ -103,8 +103,8 @@
|
||||
'value': 'stripe'
|
||||
},
|
||||
'adyen': {
|
||||
'displayName':'Adyen',
|
||||
'value': 'adyen'
|
||||
'displayName':'Payrexx',
|
||||
'value': 'payrexx'
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -43,6 +43,12 @@
|
||||
<input type="password" v-model="formData[ 'password2' ]" name="password2" id="password2" required><br><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="news">Do you want to potentially get newsletter?</label><br>
|
||||
<input type="checkbox" v-model="formData[ 'newsletter' ]" name="news" id="news"><br><br>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- TODO: Ask for permission to send emails (Make question sound really optional) -->
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user