mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 13:24:24 +00:00
finish popup engine, settings module tweak
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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 ] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
14
src/webapp/src/views/admin/events/AnalyticsView.vue
Normal file
14
src/webapp/src/views/admin/events/AnalyticsView.vue
Normal 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>
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user