add more documentation & move setting to comp

This commit is contained in:
2023-06-02 17:16:00 +02:00
parent 8fcd65c153
commit 49d785f2d7
11 changed files with 364 additions and 164 deletions

View File

@@ -0,0 +1,166 @@
<!--
* libreevent - SettingsView.vue
*
* Created by Janis Hutz 05/14/2023, Licensed under the GPL V3 License
* https://janishutz.com, development@janishutz.com
*
*
-->
<template>
<div>
<table class="settings-toggles">
<tr class="settings-option" v-for="setting in settings">
<td class="info-wrapper">
{{ setting.display }}
<div class="info-container" @mouseenter="showInfo( setting.id )" @mouseleave="hideInfo( setting.id )">
<span class="material-symbols-outlined info-icon">info</span>
<div class="info-box" :id="setting.id">
<div class="info-box-container">
{{ setting.tooltip }}
</div>
</div>
</div>
</td>
<td>
<label class="switch">
<input type="checkbox" v-model="setting.value">
<span class="slider round"></span>
</label>
</td>
</tr>
</table>
</div>
</template>
<script>
export default {
props: {
settings: Object,
},
methods: {
showInfo ( box ) {
$( '#' + box ).stop();
$( '#' + box ).fadeIn( 300 );
},
hideInfo ( box ) {
$( '#' + box ).stop();
$( '#' + box ).fadeOut( 300 );
}
}
};
</script>
<style scoped>
.settings-toggles {
width: 80%;
}
.info-wrapper {
display: inline;
position: relative;
}
.info-container {
display: inline;
}
.info-icon {
font-size: 100%;
cursor: default;
}
.info-box {
display: none;
position: absolute;
z-index: 10;
width: 20vw;
height: 20vh;
background-color: var( --popup-color );
border-radius: 20px;
top: 125%;
left: -50%
}
.info-box::before {
content: " ";
position: absolute;
bottom: 100%; /* At the bottom of the tooltip */
left: 50%;
margin-left: -5px;
border-width: 10px;
border-style: solid;
border-color: transparent transparent var( --popup-color ) transparent;
}
.info-box-container {
display: flex;
width: 80%;
height: 80%;
padding: 10%;
padding-top: 5%;
align-items: center;
justify-content: center;
}
/* https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_switch */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
</style>

View File

@@ -71,5 +71,14 @@ export default {
adminAuthRequired: true, adminAuthRequired: true,
} }
}, },
{
path: 'events/view',
name: 'eventDetails',
component: () => import( '../views/admin/events/EventsDetailsView.vue' ),
meta: {
title: 'Admin - libreevent',
adminAuthRequired: true,
}
},
] ]
} }

View File

@@ -9,9 +9,8 @@
<template> <template>
<div class="details"> <div class="details">
<h1>Details</h1> <h1>{{ event.name }}</h1>
<router-link to="/tickets"><span class="material-symbols-outlined" style="font-size: 100%;">arrow_back</span>Back</router-link> <router-link to="/tickets"><span class="material-symbols-outlined" style="font-size: 100%;">arrow_back</span>Back</router-link>
<h3>{{ event.name }}</h3>
<p>{{ event.description }}</p> <p>{{ event.description }}</p>
<router-link to="/tickets/order">Order tickets</router-link> <router-link to="/tickets/order">Order tickets</router-link>
</div> </div>

View File

@@ -8,31 +8,89 @@
--> -->
<template> <template>
<div> <div class="order">
<div class="main-view"> <h2>Events</h2>
<h2>Events</h2> <div class="order-app" v-if="events">
<ul> <ul>
<li v-for="event in events"></li> <li v-for="event in events">
<router-link to="/admin/events/view" class="ticket" @click="setActiveTicket( event.eventID );">
<div class="ticket-name">
<h3>{{ event.name }}</h3>
<p>{{ event.description }}</p>
</div>
<img :src="require( '@/assets/' + event.logo )" alt="event logo" class="ticket-logo">
</router-link>
</li>
</ul> </ul>
<router-view v-slot="{ Component, route }"> </div>
<transition :name="route.meta.transition || 'fade'" mode="out-in"> <div class="order-app" v-else>
<component :is="Component" /> No future events are available!
</transition>
</router-view>
</div> </div>
</div> </div>
</template> </template>
<style scoped>
.order-app {
text-align: justify;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
ul {
list-style: none;
width: 80%;
}
.ticket {
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
color: var( --primary-color );
border-color: var( --primary-color );
border-width: 1px;
height: fit-content;
border-style: solid;
padding: 10px;
transition: 0.4s;
}
.ticket:hover {
background-color: var( --hover-color );
transition: 0.4s;
}
.ticket-logo {
height: 20vh;
width: auto;
margin-left: auto;
}
.ticket-name {
margin-right: auto;
max-width: 35%;
}
.ticket-info {
margin-left: auto;
margin-right: auto
}
</style>
<script> <script>
export default { export default {
data () { name: 'OrderView',
return { methods: {
events: {}, setActiveTicket ( id ) {
sessionStorage.setItem( 'selectedTicket', id );
} }
}, },
methods: { data () {
setup () { 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' } }
} }
} }
}; };

View File

@@ -10,33 +10,18 @@
<template> <template>
<div> <div>
<h2>Settings</h2> <h2>Settings</h2>
<!-- TODO: Move to per event settings --> <settings v-model:settings="settings"></settings>
<table class="settings-toggles">
<tr class="settings-option" v-for="setting in settings">
<td class="info-wrapper">
{{ setting.display }}
<div class="info-container" @mouseenter="showInfo( setting.id )" @mouseleave="hideInfo( setting.id )">
<span class="material-symbols-outlined info-icon">info</span>
<div class="info-box" :id="setting.id">
<div class="info-box-container">
{{ setting.tooltip }}
</div>
</div>
</div>
</td>
<td>
<label class="switch">
<input type="checkbox" v-model="setting.value">
<span class="slider round"></span>
</label>
</td>
</tr>
</table>
</div> </div>
</template> </template>
<script> <script>
import settings from '@/components/settings/settings.vue';
export default { export default {
name: 'adminSettingsView',
components: {
settings,
},
data () { data () {
return { return {
settings: { settings: {
@@ -57,129 +42,5 @@
} }
} }
}, },
methods: {
showInfo ( box ) {
$( '#' + box ).stop();
$( '#' + box ).fadeIn( 300 );
},
hideInfo ( box ) {
$( '#' + box ).stop();
$( '#' + box ).fadeOut( 300 );
}
}
}; };
</script> </script>
<style scoped>
.settings-toggles {
width: 80%;
}
.info-wrapper {
display: inline;
position: relative;
}
.info-container {
display: inline;
}
.info-icon {
font-size: 100%;
cursor: default;
}
.info-box {
display: none;
position: absolute;
z-index: 10;
width: 20vw;
height: 20vh;
background-color: var( --popup-color );
border-radius: 20px;
top: 125%;
left: -50%
}
.info-box::before {
content: " ";
position: absolute;
bottom: 100%; /* At the bottom of the tooltip */
left: 50%;
margin-left: -5px;
border-width: 10px;
border-style: solid;
border-color: transparent transparent var( --popup-color ) transparent;
}
.info-box-container {
display: flex;
width: 80%;
height: 80%;
padding: 10%;
padding-top: 5%;
align-items: center;
justify-content: center;
}
/* https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_switch */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
</style>

View File

@@ -0,0 +1,66 @@
<!--
* libreevent - TicketsDetailsView.vue
*
* Created by Janis Hutz 05/14/2023, Licensed under the GPL V3 License
* https://janishutz.com, development@janishutz.com
*
*
-->
<template>
<div class="details">
<h2>{{ event.name }}</h2>
<div class="general-settings">
<textarea v-model="event.description" class="big-text"></textarea>
<input v-model="event.location" class="small-text">
<input v-model="event.date" class="small-text" type="date">
</div>
<div class="ticket-settings"></div>
<div class="special-settings"><settings v-model:settings="settings"></settings></div>
</div>
</template>
<style scoped>
.details {
flex-grow: 1;
}
</style>
<script>
import settings from '@/components/settings/settings.vue';
export default {
name: 'TicketsDetailsView',
components: {
settings,
},
created () {
if ( !sessionStorage.getItem( 'selectedTicket' ) ) {
this.$router.push( '/tickets' );
}
this.eventID = sessionStorage.getItem( 'selectedTicket' );
},
data() {
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' },
settings: {
'guest-purchase': {
'display': 'Enable guest purchase',
'id': 'guest-purchase',
'tooltip':'Allowing guest purchase means that a user does not have to create an account in order for them to be able to make a purchase. Default: On',
'value': true,
'type': 'toggle'
},
'overbooking': {
'display': 'Enable overbooking of event',
'id': 'overbooking',
'tooltip':'Allow more ticket reservations than you have tickets available. Currently only available for events without seatplans. Default: Off',
'value': false,
'type': 'toggle'
}
}
}
}
};
</script>

View File

@@ -9,3 +9,6 @@ Here's a list of the pages available when logged in as the root user. All other
- [Settings](&/admin-panel/settings) - [Settings](&/admin-panel/settings)
Additionally, some settings might not be available to all admin accounts on all pages. Additionally, some settings might not be available to all admin accounts on all pages.
*As a general recommendation, we do not encourage logging in as the root user if not strictly necessary, as this can help protect the libreevent installation*.

View File

@@ -4,9 +4,18 @@ On this page you may add, modify or remove admin accounts. Note that in order fo
## Adding an account ## Adding an account
### Privileges ### Privileges
libreevent features a privilege system where you can choose to what group of users you want to add a user you are currently creating. Possible values are:
Group | Allowed settings
----------------|------------------
Root | All pages. Can only be one account (the root account)
Admin | Can access all pages and settings except for Admin Accounts
Event-Manager | Access the events & pages page
Event-Handler | Can log into the apps to do entry control
### Email ### Email
An Email address is required for account activation and to recover a password in case it gets lost. The system will automatically send an activation email so the user can confirm that the email address is valid.
### 2FA ### 2FA

View File

@@ -0,0 +1,14 @@
# Events
This is the most feature rich admin page of libreevent. Here you can change everything regarding an event.
## Creating new events
Creating new events is as simple as clicking the plus icon in the top right corner and following the prompts.
### Event name
This is the name that is being displayed when users are browsing your events. Cannot be longer than 50 characters.
### Event description
Describe what your event is about. It will be displayed underneath the event name when users are browsing your events. In the browsing view, the length of the description is limited to 150 characters, after which three dots will be added to the text and a 'continue reading' button will be added. Technically, there's no limit to the length of the event description, but don't overdo it with the length, as the user is unlikely to read more than a couple words anyway.
### Event location
Choose a location where your event is going to take place. You can do so by selecting an existing location from the dropdown or by adding a new one. In the same step, you'll also need to choose between a seat plan and no seat plan, and if you choose a seat plan, you'll need to create one using out handy seatplan editor. See our seatplan editor guide [here](&/admin-panel/seatplan-editor)

View File

@@ -0,0 +1 @@
# Plugins

View File

@@ -0,0 +1,14 @@
# Seatplan editor
The seatplan editor is a graphical editor where you can create and modify the seating plan of virtually any room. We recommend that you start in the top left corner of the seatplan and then move down diagonally, as it is the easiest to do. Each so-called component can be either a stand area, a stage area or a seating area, with each of them featuring different layouts. You can change everything in the properties pane.
## Adding more components
You may add more components by simply clicking the plus icon in the toolbar of the editor. The component will spawn in the top left corner of the seatplan and the view will automatically be moved towards it.
## Removing components
You may remove components by clicking the trash icon or by hitting 'delete' on your keyboard.
## Editing history
The editor features undo and redo functions such that you can undo your mistakes and accidental undos can be reverted. Just hit the corresponding button in the toolbar.
## Saving
The editor does auto-save a draft every minute. Pressing Ctrl + S or hitting the Save button in the toolbar will immediately save the seatplan as a draft. Click the deploy button to save the seatplan permanently, irreversibly overwriting any potentially existing old seatplan of that location, except you change the location name after the fact.