finish popup engine, settings module tweak

This commit is contained in:
2023-06-28 17:53:04 +02:00
parent a22305f814
commit f1f36b135c
9 changed files with 145 additions and 50 deletions

View File

@@ -35,6 +35,7 @@
--overlay-color: rgba(0, 0, 0, 0.7);
--inactive-color: rgb(100, 100, 100);
--highlight-backdrop: rgb(143, 134, 192);
--hint-color: rgb(174, 210, 221);
--PI: 3.14159265358979;
}
@@ -50,21 +51,23 @@
--overlay-color: rgba(104, 104, 104, 0.575);
--inactive-color: rgb(190, 190, 190);
--highlight-backdrop: rgb(85, 63, 207);
--hint-color: rgb(88, 91, 110);
}
@media ( prefers-color-scheme: dark ) {
:root {
--primary-color: white;
--popup-color: rgb(58, 58, 58);
--accent-background: rgb(56, 56, 112);
--secondary-color: white;
--background-color: rgb(32, 32, 32);
--popup-color: rgb(58, 58, 58);
--accent-color: #42b983;
--hover-color: rgb(83, 83, 83);
--accent-background-hover: #4380a8;
--overlay-color: rgba(104, 104, 104, 0.575);
--inactive-color: rgb(190, 190, 190);
--highlight-backdrop: rgb(85, 63, 207);
--hint-color: rgb(88, 91, 110);
}
}

View File

@@ -2,27 +2,34 @@
<div id="popup-backdrop">
<div class="popup-container">
<div class="popup" :class="size">
<div class="close-wrapper"><span class="material-symbols-outlined close-button" @click="closePopup( 'cancel' );">close</span></div>
<div class="close-wrapper"><span class="material-symbols-outlined close-button" @click="closePopup( 'cancel' );" title="Close this popup">close</span></div>
<div class="message-container">
<div v-if="contentType === 'string'">{{ data.message }}</div>
<div v-else-if="contentType === 'html'" v-html="data.message"></div>
<div v-else-if="contentType === 'settings'">
<settings v-model:settings="data.settings"></settings>
<div v-if="contentType === 'string'" class="options"><h3>{{ data.message }}</h3></div>
<div v-else-if="contentType === 'html'" v-html="data.message" class="options"></div>
<div v-else-if="contentType === 'settings'" class="options">
<h3>{{ data.message }}</h3>
<settings v-model:settings="data.options"></settings>
<div style="width: 100%; margin-top: 3%;">
<button @click="closePopup( 'ok' )" title="Save changes">Save</button>
<button @click="closePopup( 'cancel' )" title="Cancel changes">Cancel</button>
</div>
</div>
<div v-else-if="contentType === 'confirm'" class="confirm">
{{ data.message }}
<div v-else-if="contentType === 'confirm'" class="confirm options">
<h3>{{ data.message }}</h3>
<div style="width: 100%; margin-top: 3%;">
<button @click="closePopup( 'ok' )">Ok</button>
<button @click="closePopup( 'cancel' )">Cancel</button>
</div>
</div>
<div v-else-if="contentType === 'radio'">
<form>
<div v-for="selectOption in data.radio">
<input type="radio" value="selectOption.value" name="group1" id="selectOption.id">
<label for="selectOption.id">selectOption.displayName</label>
</div>
</form>
<div v-else-if="contentType === 'dropdown'" class="options">
<h3>{{ data.message }}</h3>
<select id="select" v-model="data.selected">
<option v-for="selectOption in data.options" :value="selectOption.value">{{ selectOption.displayName }}</option>
</select>
<div style="width: 100%; margin-top: 3%;">
<button @click="closePopup( 'ok' )" title="Save changes">Save</button>
<button @click="closePopup( 'cancel' )" title="Cancel changes">Cancel</button>
</div>
</div>
</div>
</div>
@@ -30,7 +37,7 @@
</div>
</template>
<!-- Options to be passed in: html, settings (for settings component), strings, confirm, radio, dropdowns, selection -->
<!-- Options to be passed in: html, settings (for settings component), strings, confirm, dropdowns, selection -->
<script>
import settings from '@/components/settings/settings.vue';
@@ -47,22 +54,25 @@
},
data () {
return {
status: 'hidden',
contentType: 'dropdown',
data: { 'message': 'No message defined on method call' }
data: {}
}
},
methods: {
closePopup( message ) {
$( '#popup-backdrop' ).fadeOut( 300 );
if ( message ) {
this.$emit( 'data', message );
this.$emit( 'status', message );
this.$emit( 'data', this.data );
}
},
openPopup () {
openPopup ( message, options, dataType, selected ) {
let data = { 'message': message ? message : 'No message defined on method call!!', 'options': options ? options : { '1': { 'value': 'undefined', 'displayName': 'No options specified in call' } }, 'selected': selected ? selected : '' };
this.data = data;
this.contentType = dataType ? dataType : 'string';
$( '#popup-backdrop' ).fadeIn( 300 );
}
}
},
}
</script>
@@ -138,22 +148,20 @@
height: 90%;
width: 90%;
margin-left: 5%;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
overflow: scroll;
}
.confirm {
.options {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
overflow: visible;
min-height: 100%;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
flex-direction: column;
}
.confirm button {
.options button {
padding: 1% 2%;
display: inline-block;
background-color: var( --accent-background );
@@ -161,7 +169,7 @@
cursor: pointer;
}
.confirm button:hover {
.options button:hover {
background-color: var( --accent-background-hover );
}
</style>

View File

@@ -44,6 +44,9 @@
<td v-else-if="setting.type == 'date'">
<input type="date" v-model="setting.value">
</td>
<td v-else-if="setting.type == 'link'">
<router-link :to="setting.restrictions.to">{{ setting.restrictions.displayName }}</router-link>
</td>
</tr>
</table>
</div>
@@ -102,7 +105,7 @@
z-index: 10;
width: 20vw;
height: 20vh;
background-color: var( --popup-color );
background-color: var( --hint-color );
border-radius: 20px;
top: 125%;
right: -9.3vw;
@@ -116,7 +119,7 @@
margin-left: -5px;
border-width: 10px;
border-style: solid;
border-color: transparent transparent var( --popup-color ) transparent;
border-color: transparent transparent var( --hint-color ) transparent;
}
.info-box-container {

View File

@@ -76,16 +76,16 @@ export default {
name: 'eventDetails',
component: () => import( '../views/admin/events/EventsDetailsView.vue' ),
meta: {
title: 'Admin - libreevent',
title: 'Event details :: Admin - libreevent',
adminAuthRequired: true,
}
},
{
path: 'locations/view',
name: 'locationDetails',
component: () => import( '../views/admin/locations/LocationEditView.vue' ),
path: 'events/analytics',
name: 'eventAnalytics',
component: () => import( '../views/admin/events/AnalyticsView.vue' ),
meta: {
title: 'Admin - libreevent',
title: 'Event analytics :: Admin - libreevent',
adminAuthRequired: true,
}
},

View File

@@ -11,12 +11,22 @@
<div class="order">
<h2>Events</h2>
<div class="order-app" v-if="events">
<ul>
<li v-for="event in events">
<router-link to="/admin/events/view" class="ticket" @click="setActiveTicket( event.eventID );">
<ul v-for="timeframe in eventList">
<h3>{{ timeframe.name }}</h3>
<li v-for="event in timeframe.content">
<router-link to="/admin/events/view" class="ticket" @click="setActiveTicket( event.eventID );" v-if="new Date( event.date ).getTime() > currentDate">
<div class="ticket-name">
<h3>{{ event.name }}</h3>
<p>{{ event.description }}</p>
<b>{{ event.date }}</b>
</div>
<img :src="require( '@/assets/' + event.logo )" alt="event logo" class="ticket-logo">
</router-link>
<router-link to="/admin/events/analytics" class="ticket" @click="setActiveTicket( event.eventID );" v-else="new Date( event.date ).getTime() > currentDate">
<div class="ticket-name">
<h3>{{ event.name }}</h3>
<p>{{ event.description }}</p>
<b>{{ event.date }}</b>
</div>
<img :src="require( '@/assets/' + event.logo )" alt="event logo" class="ticket-logo">
</router-link>
@@ -71,7 +81,7 @@
.ticket-name {
margin-right: auto;
max-width: 35%;
max-width: 60%;
}
.ticket-info {
@@ -90,7 +100,27 @@
},
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':'TestDate', 'startingPrice':15, 'location': 'TestLocation', 'eventID': 'test', 'currency': 'CHF', 'logo': 'logo.png' }, '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':'TestDate', 'startingPrice':15, 'location': 'TestLocation', 'eventID': 'test2', 'currency': 'CHF', 'logo': 'logo.png' } }
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-07-15', 'startingPrice':15, 'location': 'TestLocation', 'eventID': 'test', 'currency': 'CHF', 'logo': 'logo.png' }, '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-06-14', 'startingPrice':15, 'location': 'TestLocation', 'eventID': 'test2', 'currency': 'CHF', 'logo': 'logo.png' } },
currentDate: new Date().getTime(),
eventList: { 'upcoming': { 'name': 'Upcoming', 'content': {} }, 'past': { 'name': 'Past', 'content': {} } },
}
},
created() {
// Sort events object such that events closest to today are displayed first and past events displayed last
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 ] ];
}
}
}
};

View File

@@ -16,9 +16,9 @@
<router-link to="/admin/pages" class="bigButton">Pages</router-link>
<router-link to="/admin/events" class="bigButton">Events</router-link>
<router-link to="/admin/locations" class="bigButton">Locations</router-link>
<router-link to="/admin/events" class="bigButton">Plugins</router-link>
<router-link to="/admin/events" class="bigButton">Settings</router-link>
<a href="https://libreevent.janishutz.com/docs/admin-panel" class="bigButton" target="_blank">Documentation</a>
<router-link to="/admin/plugins" class="bigButton">Plugins</router-link>
<router-link to="/admin/settings" class="bigButton">Settings</router-link>
<a href="https://libreevent.janishutz.com/docs/admin-panel" class="bigButton" target="_blank">Documentation <span class="material-symbols-outlined" style="display: inline; font-size: 100%;">open_in_new</span></a>
</div>
</div>
</template>

View File

@@ -14,32 +14,65 @@
<div class="location-app" v-if="Object.keys( locations ).length">
<ul>
<li v-for="location in locations">
<router-link to="/admin/locations/view" class="location" @click="selectLocation( location.locationID );">
<div class="location" @click="selectLocation( location.locationID );" title="Edit this location">
<div class="location-name">
<h3>{{ location.name }}</h3>
<p v-if="location['seatplan-enabled']">This location has a seatplan.</p>
<p v-else>This location has NO seatplan.</p>
</div>
</router-link>
</div>
</li>
</ul>
</div>
<div v-else class="no-location-hint">
No locations configured, please <b @click="addLocation();" style="cursor: pointer;">add</b> one
</div>
<popups ref="popup" size="big"></popups>
</div>
</template>
<script>
import popups from '@/components/notifications/popups.vue';
export default {
data () {
return {
locations: { 'test':{ 'name':'TestLocation', 'locationID':'test', 'seatplan-enabled': true, 'seatplan': {} } },
}
},
components: {
popups,
},
methods: {
selectLocation ( locationID ) {
sessionStorage.setItem( 'locationID', locationID );
this.$refs.popup.openPopup( 'Settings for ' + this.locations[ locationID ][ 'name' ], {
'locationName': {
'display': 'Location name',
'id': 'locationName',
'tooltip':'Give the location the event takes place a name. This name will also be shown to customers',
'value': '',
'type': 'text',
},
'usesSeatplan': {
'display': 'Use seat plan?',
'id': 'usesSeatplan',
'tooltip':'With this toggle you may specify whether or not this location has a seat plan or not.',
'value': true,
'type': 'toggle',
},
'seatplanEditor': {
'display': 'Seat plan editor',
'id': 'seatplanEditor',
'tooltip':'The seat plan editor allows you to create a seat plan that closely resembles the location you host the event in.',
'type': 'link',
'restrictions': {
'to': '/admin/seatplan',
'displayName': 'Edit seat plan'
}
},
}
, 'settings' );
},
addLocation () {
@@ -76,6 +109,7 @@
border-style: solid;
padding: 10px;
transition: 0.4s;
cursor: pointer;
}
.location:hover {

View File

@@ -0,0 +1,14 @@
<!--
* libreevent - AnalyticsView.vue
*
* Created by Janis Hutz 06/28/2023, Licensed under the GPL V3 License
* https://janishutz.com, development@janishutz.com
*
*
-->
<template>
<div>
<h2>Event analytics</h2>
</div>
</template>

View File

@@ -25,7 +25,7 @@
</table>
</div>
<button @click="openPopup()">Open Popup</button>
<popups ref="popup"></popups>
<popups ref="popup" @data="( event ) => { popupReturnHandling( event ) }"></popups>
<notifications ref="notification" location="topright"></notifications>
</div>
</template>
@@ -78,6 +78,9 @@
openPopup() {
console.log( 'opening' );
this.$refs.popup.openPopup();
},
popupReturnHandling( event ) {
console.log( event );
}
}
};