mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 13:24:24 +00:00
notifications, settings, editor, event view fixes
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
<span class="material-symbols-outlined types" v-else-if="messageType == 'error'" style="background-color: red;">close</span>
|
<span class="material-symbols-outlined types" v-else-if="messageType == 'error'" style="background-color: red;">close</span>
|
||||||
<span class="material-symbols-outlined types progress-spinner" v-else-if="messageType == 'progress'" style="background-color: blue;">progress_activity</span>
|
<span class="material-symbols-outlined types progress-spinner" v-else-if="messageType == 'progress'" style="background-color: blue;">progress_activity</span>
|
||||||
<span class="material-symbols-outlined types" v-else-if="messageType == 'info'" style="background-color: lightblue;">info</span>
|
<span class="material-symbols-outlined types" v-else-if="messageType == 'info'" style="background-color: lightblue;">info</span>
|
||||||
|
<span class="material-symbols-outlined types" v-else-if="messageType == 'warning'" style="background-color: orangered;">warning</span>
|
||||||
<p class="message">{{ message }}</p>
|
<p class="message">{{ message }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
this.currentID[ 'low' ] += 1;
|
this.currentID[ 'low' ] += 1;
|
||||||
id = this.currentID[ 'low' ];
|
id = this.currentID[ 'low' ];
|
||||||
}
|
}
|
||||||
this.notifications[ id ] = { 'message': message, 'showDuration': showDuration, 'messageType': messageType, 'priority': priority };
|
this.notifications[ id ] = { 'message': message, 'showDuration': showDuration, 'messageType': messageType, 'priority': priority, 'id': id };
|
||||||
this.queue.push( id );
|
this.queue.push( id );
|
||||||
console.log( 'scheduled notification: ' + id + ' (' + message + ')' );
|
console.log( 'scheduled notification: ' + id + ' (' + message + ')' );
|
||||||
if ( this.displayTimeCurrentNotification >= this.notificationDisplayTime ) {
|
if ( this.displayTimeCurrentNotification >= this.notificationDisplayTime ) {
|
||||||
@@ -67,8 +68,12 @@
|
|||||||
/*
|
/*
|
||||||
This method deletes a notification and, in case the notification is being displayed, hides it.
|
This method deletes a notification and, in case the notification is being displayed, hides it.
|
||||||
*/
|
*/
|
||||||
|
try {
|
||||||
delete notifications[ id ];
|
delete notifications[ id ];
|
||||||
delete this.queue[ this.queue.findIndex( id ) ];
|
delete this.queue[ this.queue.findIndex( id ) ];
|
||||||
|
} catch ( error ) {
|
||||||
|
console.log( 'notification to be deleted is nonexistent or currently being displayed' );
|
||||||
|
}
|
||||||
if ( this.currentlyDisplayedNotificationID == id ) {
|
if ( this.currentlyDisplayedNotificationID == id ) {
|
||||||
this.handleNotifications();
|
this.handleNotifications();
|
||||||
}
|
}
|
||||||
@@ -85,6 +90,7 @@
|
|||||||
this.message = this.notifications[ this.queue[ 0 ] ][ 'message' ];
|
this.message = this.notifications[ this.queue[ 0 ] ][ 'message' ];
|
||||||
this.messageType = this.notifications[ this.queue[ 0 ] ][ 'messageType' ];
|
this.messageType = this.notifications[ this.queue[ 0 ] ][ 'messageType' ];
|
||||||
this.priority = this.notifications[ this.queue[ 0 ] ][ 'priority' ];
|
this.priority = this.notifications[ this.queue[ 0 ] ][ 'priority' ];
|
||||||
|
this.currentlyDisplayedNotificationID = this.notifications[ this.queue[ 0 ] ][ 'id' ];
|
||||||
this.notificationDisplayTime = this.notifications[ this.queue[ 0 ] ][ 'showDuration' ];
|
this.notificationDisplayTime = this.notifications[ this.queue[ 0 ] ][ 'showDuration' ];
|
||||||
this.queue.reverse();
|
this.queue.reverse();
|
||||||
this.queue.pop();
|
this.queue.pop();
|
||||||
@@ -111,7 +117,7 @@
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.message-box {
|
.message-box {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 5;
|
z-index: 10;
|
||||||
color: white;
|
color: white;
|
||||||
height: 10vh;
|
height: 10vh;
|
||||||
width: 15vw;
|
width: 15vw;
|
||||||
@@ -119,23 +125,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.topleft {
|
.topleft {
|
||||||
top: 3%;
|
top: 3vh;
|
||||||
left: 0.5%;
|
left: 0.5vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topright {
|
.topright {
|
||||||
top: 3%;
|
top: 3vh;
|
||||||
right: 0.5%;
|
right: 0.5vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bottomright {
|
.bottomright {
|
||||||
bottom: 3%;
|
bottom: 3vh;
|
||||||
right: 0.5%;
|
right: 0.5vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bottomleft {
|
.bottomleft {
|
||||||
top: 3%;
|
top: 3vh;
|
||||||
right: 0.5%;
|
right: 0.5vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-container {
|
.message-container {
|
||||||
@@ -154,11 +160,13 @@
|
|||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-left: 5%;
|
margin-left: 5%;
|
||||||
|
padding: 1.5%;
|
||||||
font-size: 200%;
|
font-size: 200%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message {
|
.message {
|
||||||
margin-right: 5%;
|
margin-right: 5%;
|
||||||
|
text-align: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ok {
|
.ok {
|
||||||
@@ -173,6 +181,10 @@
|
|||||||
background-color: rgb(44, 112, 151);
|
background-color: rgb(44, 112, 151);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.warning {
|
||||||
|
background-color: orange;
|
||||||
|
}
|
||||||
|
|
||||||
.hide {
|
.hide {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,7 @@
|
|||||||
<div class="info-container" @mouseenter="showInfo( setting.id )" @mouseleave="hideInfo( setting.id )">
|
<div class="info-container" @mouseenter="showInfo( setting.id )" @mouseleave="hideInfo( setting.id )">
|
||||||
<span class="material-symbols-outlined info-icon">info</span>
|
<span class="material-symbols-outlined info-icon">info</span>
|
||||||
<div class="info-box" :id="setting.id">
|
<div class="info-box" :id="setting.id">
|
||||||
<div class="info-box-container">
|
<div class="info-box-container" v-html="setting.tooltip">
|
||||||
{{ setting.tooltip }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,17 +11,22 @@
|
|||||||
<div class="details">
|
<div class="details">
|
||||||
<h2>{{ event.name }}</h2>
|
<h2>{{ event.name }}</h2>
|
||||||
<div class="general-settings">
|
<div class="general-settings">
|
||||||
<textarea v-model="event.description" class="big-text"></textarea><br>
|
<p>Event Description</p>
|
||||||
|
<textarea v-model="event.description" class="big-text" cols="70" rows="3" placeholder="Event description..."></textarea>
|
||||||
|
<p>Event location</p>
|
||||||
<select v-model="event.location" class="small-text">
|
<select v-model="event.location" class="small-text">
|
||||||
<option value="TestLocation">TestLocation</option>
|
<option value="TestLocation">TestLocation</option>
|
||||||
</select><br>
|
</select>
|
||||||
|
<p>Event date</p>
|
||||||
<input v-model="event.date" class="small-text" type="date"><br>
|
<input v-model="event.date" class="small-text" type="date"><br>
|
||||||
|
<p>Ticket editor</p>
|
||||||
<router-link to="/admin/ticketEditor">Edit ticket layout</router-link>
|
<router-link to="/admin/ticketEditor">Edit ticket layout</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="ticket-settings">
|
<div class="ticket-settings">
|
||||||
<h3>Ticket Settings</h3>
|
<h3>Ticket Settings</h3>
|
||||||
|
<p>The foreground and background colours of the seats are used to show the customer to which category the seats belong.</p>
|
||||||
<table class="category" v-for="category in event.categories">
|
<table class="category" v-for="category in event.categories">
|
||||||
{{ category.name }}:
|
{{ category.name }}
|
||||||
<tr v-for="price in category.price">
|
<tr v-for="price in category.price">
|
||||||
<td>
|
<td>
|
||||||
{{ price.name }}:
|
{{ price.name }}:
|
||||||
@@ -45,10 +50,14 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="special-settings">
|
<div class="special-settings">
|
||||||
<h3>Special 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>
|
||||||
<settings v-model:settings="specialSettings"></settings>
|
<settings v-model:settings="specialSettings"></settings>
|
||||||
</div>
|
</div>
|
||||||
<notifications ref="notification" location="'topright'"></notifications>
|
<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>
|
||||||
|
</div>
|
||||||
|
<notifications ref="notification" location="topright"></notifications>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -86,6 +95,13 @@
|
|||||||
return {
|
return {
|
||||||
event: { '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':'TestDate', 'startingPrice':15, 'location': 'TestLocation', 'eventID': 'test', 'currency': 'CHF', 'logo': 'logo.png', 'categories': { '1': { 'price': { '1': { 'price':25, 'name':'Child (0-15.99 years)'}, '2': { 'price':35, 'name':'Adult'} }, 'bg': 'black', 'fg': 'white', 'name': 'Category 1' }, '2': { 'price': { '1': { 'price':25, 'name':'Child (0-15.99 years)' }, '2': { 'price':35, 'name':'Adult'} }, 'bg': 'green', 'fg': 'white', 'name': 'Category 2' } } },
|
event: { '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':'TestDate', 'startingPrice':15, 'location': 'TestLocation', 'eventID': 'test', 'currency': 'CHF', 'logo': 'logo.png', 'categories': { '1': { 'price': { '1': { 'price':25, 'name':'Child (0-15.99 years)'}, '2': { 'price':35, 'name':'Adult'} }, 'bg': 'black', 'fg': 'white', 'name': 'Category 1' }, '2': { 'price': { '1': { 'price':25, 'name':'Child (0-15.99 years)' }, '2': { 'price':35, 'name':'Adult'} }, 'bg': 'green', 'fg': 'white', 'name': 'Category 2' } } },
|
||||||
specialSettings: {
|
specialSettings: {
|
||||||
|
'currency': {
|
||||||
|
'display': 'Currency',
|
||||||
|
'id': 'currency',
|
||||||
|
'tooltip':'Specify a currency in which the prices are displayed to the customer. Defaults to USD. Please use valid currency codes.',
|
||||||
|
'value': 'USD',
|
||||||
|
'type': 'text',
|
||||||
|
},
|
||||||
'guest-purchase': {
|
'guest-purchase': {
|
||||||
'display': 'Enable guest purchase',
|
'display': 'Enable guest purchase',
|
||||||
'id': 'guest-purchase',
|
'id': 'guest-purchase',
|
||||||
@@ -137,15 +153,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
'requiredParameterValue': {
|
'requiredParameterValue': {
|
||||||
'display': 'Maximum ticket count per account',
|
'display': 'Special requirements values ',
|
||||||
'id': 'requiredParameterValue',
|
'id': 'requiredParameterValue',
|
||||||
'tooltip':'With this setting you can control how many tickets a person can buy. Defaults to 0, which means do not limit.',
|
'tooltip':'Put a filter here, corresponding to your selection above. Please read the documentation on our website. See link below!',
|
||||||
'value': 0,
|
'value': '',
|
||||||
'type': 'number',
|
'type': 'text',
|
||||||
'restrictions': {
|
|
||||||
'min': 0,
|
|
||||||
'max': 100,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="ticketEditor">
|
<div id="ticketEditor">
|
||||||
<h1>Ticket Editor</h1>
|
<h1>Ticket Editor</h1>
|
||||||
<router-link to="/admin/events/view">Back to event settings</router-link>
|
<div class="toolbar">
|
||||||
<button @click="saveTemplate()">Save Template</button>
|
<router-link to="/admin/events/view" class="toolbar-item" title="Back to event settings">Back</router-link>
|
||||||
|
<form class="toolbar-item">
|
||||||
|
<input type="file" accept="application/pdf" id="pdfTemplate" class="toolbar-item">
|
||||||
|
</form>
|
||||||
|
<button @click="loadPDF();" class="toolbar-item">Load file</button>
|
||||||
|
<button @click="saveTemplate()" class="toolbar-item" title="Save your ticket">Save Template</button>
|
||||||
|
<button @click="testNotifications();" class="toolbar-item">Test notifications</button>
|
||||||
|
</div>
|
||||||
<div id="editor">Loading editor...</div>
|
<div id="editor">Loading editor...</div>
|
||||||
|
<notifications ref="notification" location="topleft"></notifications>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Designer, BLANK_PDF } from '@pdfme/ui';
|
import { Designer, BLANK_PDF } from '@pdfme/ui';
|
||||||
|
import notifications from '@/components/notifications/notifications.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ticketEditor',
|
name: 'ticketEditor',
|
||||||
@@ -17,14 +26,57 @@
|
|||||||
designer: null,
|
designer: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
notifications
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
saveTemplate() {
|
saveTemplate() {
|
||||||
|
// Save to server instead
|
||||||
|
this.$refs.notification.createNotification( 'Saving...', 5, 'progress', 'normal' );
|
||||||
|
this.$refs.notification.createNotification( 'Saved successfully', 5, 'ok', 'normal' );
|
||||||
console.log( this.designer.getTemplate() );
|
console.log( this.designer.getTemplate() );
|
||||||
|
},
|
||||||
|
testNotifications () {
|
||||||
|
this.$refs.notification.createNotification( 'Warning', 10, 'warning', 'normal' );
|
||||||
|
this.$refs.notification.createNotification( 'Error', 10, 'error', 'normal' );
|
||||||
|
this.$refs.notification.createNotification( 'Info', 10, 'info', 'normal' );
|
||||||
|
this.$refs.notification.createNotification( 'Ok', 10, 'ok', 'normal' );
|
||||||
|
this.$refs.notification.createNotification( 'Progress', 10, 'progress', 'normal' );
|
||||||
|
},
|
||||||
|
loadPDF () {
|
||||||
|
let files = document.getElementById( 'pdfTemplate' ).files;
|
||||||
|
if ( files.length ) {
|
||||||
|
let pdfLoading = this.$refs.notification.createNotification( 'Loading pdf...', 5, 'progress', 'normal' );
|
||||||
|
let pdf = files[ 0 ];
|
||||||
|
if ( pdf.name.substring( pdf.name.length - 4 ) === '.pdf' ) {
|
||||||
|
let fileReader = new FileReader();
|
||||||
|
let base64;
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
// Onload of file read the file content
|
||||||
|
// https://stackoverflow.com/questions/13538832/convert-pdf-to-a-base64-encoded-string-in-javascript?rq=4
|
||||||
|
|
||||||
|
fileReader.onload = function( fileLoadedEvent ) {
|
||||||
|
base64 = fileLoadedEvent.target.result;
|
||||||
|
let oldTemplate = self.designer.getTemplate();
|
||||||
|
oldTemplate[ 'basePdf' ] = base64;
|
||||||
|
self.designer.updateTemplate( oldTemplate );
|
||||||
|
self.$refs.notification.cancelNotification( pdfLoading );
|
||||||
|
self.$refs.notification.createNotification( 'Loaded pdf successfully', 5, 'ok', 'normal' );
|
||||||
|
};
|
||||||
|
fileReader.readAsDataURL( pdf );
|
||||||
|
} else {
|
||||||
|
this.$refs.notification.createNotification( 'Cannot load pdf: Not a pdf!', 5, 'error', 'normal' );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$refs.notification.createNotification( 'Cannot load pdf: No file selected', 5, 'error', 'normal' );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
const domContainer = document.getElementById( 'editor' );
|
const domContainer = document.getElementById( 'editor' );
|
||||||
|
// TODO: Load from server if available
|
||||||
const template = {
|
const template = {
|
||||||
basePdf: BLANK_PDF,
|
basePdf: BLANK_PDF,
|
||||||
schemas: [
|
schemas: [
|
||||||
@@ -61,8 +113,24 @@
|
|||||||
nav {
|
nav {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
#editor {
|
#editor {
|
||||||
height: 90vh;
|
height: 85vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar {
|
||||||
|
height: 5vh;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-item {
|
||||||
|
margin: 0;
|
||||||
|
margin-left: 0.5%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user