mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 13:24:24 +00:00
lost of progress
This commit is contained in:
@@ -29,10 +29,10 @@
|
|||||||
</td>
|
</td>
|
||||||
<td v-for="place in row.content">
|
<td v-for="place in row.content">
|
||||||
<div :class="place.category" class="active" v-if="place.available" @click="selectSeat( place.id, row.id )">
|
<div :class="place.category" class="active" v-if="place.available" @click="selectSeat( place.id, row.id )">
|
||||||
<div v-if="place.selected">
|
<div v-if="place.selected" :title="row.name + ', ' + place.name + ' is currently selected, click to deselect'">
|
||||||
<span class="material-symbols-outlined">done</span>
|
<span class="material-symbols-outlined">done</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else :title="row.name + ', ' + place.name + ' is not currently selected, click to select'">
|
||||||
<span class="material-symbols-outlined">living</span>
|
<span class="material-symbols-outlined">living</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -85,7 +85,7 @@ export default {
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
seating: { 'r1': { 'name': 'Row 1', 'id': 'r1', 'content':{ 'S1':{ 'name': 'Seat 1', 'id': 'S1', 'available': true, 'selected': false, 'category':'1' } } }, 'r2': { 'name': 'Row 2', 'id': 'r2', 'content':{ 'S1':{ 'name': 'S1', 'id': 'S1', 'available': true, 'selected': false, 'category':'2' } } } },
|
seating: { 'r1': { 'name': 'Row 1', 'id': 'r1', 'content':{ 'S1':{ 'name': 'Seat 1', 'id': 'S1', 'available': true, 'selected': false, 'category':'1' } } }, 'r2': { 'name': 'Row 2', 'id': 'r2', 'content':{ 'S1':{ 'name': 'S1', 'id': 'S1', 'available': true, 'selected': false, 'category':'2' } } } },
|
||||||
eventInfo: { 'name': 'TestEvent', 'location': 'TestLocation', 'date': 'TestDate', 'RoomName': 'TestRoom', 'currency': 'CHF', 'categories': { '1': { 'price': { '1':25, '2':35 }, 'bg': 'black', 'fg': 'white', 'name': 'Category 1' }, '2': { 'price': { '1':15, '2':20 }, 'bg': 'green', 'fg': 'white', 'name': 'Category 1' } }, 'ageGroups': { '1':{ 'id': 1, 'name':'Child', 'age':'0 - 15.99' }, '2':{ 'id': 2, 'name': 'Adult', 'age': null } }, 'ageGroupCount':2, 'stage': true },
|
eventInfo: { 'name': 'TestEvent', 'location': 'TestLocation', 'date': 'TestDate', 'RoomName': 'TestRoom', 'currency': 'CHF', 'categories': { '1': { 'price': { '1':25, '2':35 }, 'bg': 'black', 'fg': 'white', 'name': 'Category 1' }, '2': { 'price': { '1':15, '2':20 }, 'bg': 'green', 'fg': 'white', 'name': 'Category 2' } }, 'ageGroups': { '1':{ 'id': 1, 'name':'Child', 'age':'0 - 15.99' }, '2':{ 'id': 2, 'name': 'Adult', 'age': null } }, 'ageGroupCount':2, 'stage': true },
|
||||||
selectedSeats: {},
|
selectedSeats: {},
|
||||||
pricingCurrentlySelected: {},
|
pricingCurrentlySelected: {},
|
||||||
total: 0,
|
total: 0,
|
||||||
@@ -138,7 +138,16 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let back = {};
|
||||||
|
|
||||||
|
back[ 'total' ] = price;
|
||||||
|
back[ 'currency' ] = this.eventInfo.currency;
|
||||||
|
|
||||||
|
sessionStorage.setItem( 'backend', JSON.stringify( back ) );
|
||||||
|
|
||||||
this.total = price;
|
this.total = price;
|
||||||
|
|
||||||
|
sessionStorage.setItem( 'cart', JSON.stringify( cart ) );
|
||||||
},
|
},
|
||||||
closePlaceNotAvailablePopup () {
|
closePlaceNotAvailablePopup () {
|
||||||
$( '#placeNotAvailable' ).hide( 300 );
|
$( '#placeNotAvailable' ).hide( 300 );
|
||||||
@@ -200,15 +209,16 @@ export default {
|
|||||||
|
|
||||||
let seat = JSON.parse( sessionStorage.getItem( 'tempStorage' ) );
|
let seat = JSON.parse( sessionStorage.getItem( 'tempStorage' ) );
|
||||||
|
|
||||||
let ticket = this.seating[ seat[ 1 ][ 1 ] ][ 'content' ][ seat[ 1 ][ 0 ] ]
|
let ticket = this.seating[ seat[ 1 ][ 1 ] ][ 'content' ][ seat[ 1 ][ 0 ] ];
|
||||||
let ticketData = { 'name': ticket[ 'name' ], 'categoryID': ticketOption, 'category': this.eventInfo[ 'categories' ][ ticket[ 'category' ] ], 'price': this.eventInfo[ 'categories' ][ this.seating[ seat[ 1 ][ 1 ] ][ 'content' ][ seat[ 1 ][ 0 ] ][ 'category' ] ][ 'price' ][ ticketOption ], 'row':seat[ 1 ][ 1 ], 'seat':seat[ 1 ][ 0 ], 'ageGroup': this.eventInfo[ 'ageGroups' ][ ticketOption ][ 'name' ] };
|
let ticketData = { 'name': ticket[ 'name' ], 'categoryID': ticketOption, 'category': this.eventInfo[ 'categories' ][ ticket[ 'category' ] ], 'price': this.eventInfo[ 'categories' ][ this.seating[ seat[ 1 ][ 1 ] ][ 'content' ][ seat[ 1 ][ 0 ] ][ 'category' ] ][ 'price' ][ ticketOption ], 'row':seat[ 1 ][ 1 ], 'seat':seat[ 1 ][ 0 ], 'ageGroup': this.eventInfo[ 'ageGroups' ][ ticketOption ][ 'name' ] };
|
||||||
data[ String( seat[ 1 ][ 1 ] ) + String( seat[ 1 ][ 0 ] ) ] = ticketData;
|
data[ String( seat[ 1 ][ 1 ] ) + String( seat[ 1 ][ 0 ] ) ] = ticketData;
|
||||||
|
|
||||||
cart[ this.ticketID ?? 'default' ][ 'selectedSeats' ] = data;
|
cart[ this.ticketID ?? 'default' ][ 'selectedSeats' ] = data;
|
||||||
|
|
||||||
|
|
||||||
sessionStorage.setItem( 'cart', JSON.stringify( cart ) );
|
sessionStorage.setItem( 'cart', JSON.stringify( cart ) );
|
||||||
this.selectedSeats = cart;
|
|
||||||
$( '#overlay' ).hide( 200 );
|
$( '#overlay' ).hide( 200 );
|
||||||
|
this.selectedSeats = cart;
|
||||||
this.sumUp();
|
this.sumUp();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -45,8 +45,37 @@ const routes = [
|
|||||||
meta: {
|
meta: {
|
||||||
title: 'Login :: Admin - myevent',
|
title: 'Login :: Admin - myevent',
|
||||||
requiresSetupKey: true,
|
requiresSetupKey: true,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: 'setupStart',
|
||||||
|
component: () => import( '../views/setup/SetupStartView.vue' ),
|
||||||
|
meta: {
|
||||||
|
title: 'Start :: Setup - myevent',
|
||||||
|
adminAuthRequired: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'root',
|
||||||
|
name: 'setupRoot',
|
||||||
|
component: () => import( '../views/setup/SetupRootView.vue' ),
|
||||||
|
meta: {
|
||||||
|
title: 'Root account :: Setup - myevent',
|
||||||
|
adminAuthRequired: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'page',
|
||||||
|
name: 'setupPage',
|
||||||
|
component: () => import( '../views/setup/SetupPageView.vue' ),
|
||||||
|
meta: {
|
||||||
|
title: 'Landing page :: Setup - myevent',
|
||||||
|
adminAuthRequired: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/admin',
|
path: '/admin',
|
||||||
name: 'admin',
|
name: 'admin',
|
||||||
@@ -130,6 +159,15 @@ const routes = [
|
|||||||
transition: 'scale'
|
transition: 'scale'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/tickets/order',
|
||||||
|
name: 'ticketOrder',
|
||||||
|
component: () => import( '../views/TicketsOrderingView.vue' ),
|
||||||
|
meta: {
|
||||||
|
title: 'Order ticket - myevent',
|
||||||
|
transition: 'scale'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/cart',
|
path: '/cart',
|
||||||
name: 'cart',
|
name: 'cart',
|
||||||
@@ -156,7 +194,12 @@ const routes = [
|
|||||||
title: 'Pay - myevent',
|
title: 'Pay - myevent',
|
||||||
transition: 'scale',
|
transition: 'scale',
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
path: '/:pathMatch(.*)*',
|
||||||
|
name: 'NotFound',
|
||||||
|
component: () => import( '@/views/404.vue')
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const router = createRouter( {
|
const router = createRouter( {
|
||||||
|
|||||||
35
src/webapp/src/views/404.vue
Normal file
35
src/webapp/src/views/404.vue
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<div class="notFound">
|
||||||
|
<h1 class="code">404</h1>
|
||||||
|
<h2 class="message">The page you are looking for was not found on the server!</h2>
|
||||||
|
<router-link to="/">Return to home page</router-link>
|
||||||
|
<a href="https://myevent.janishutz.com/docs/errors#404">More information on this error</a>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.notFound {
|
||||||
|
font-family: monospace;
|
||||||
|
color: var( --primary-color );
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code {
|
||||||
|
font-size: 2500%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
font-size: 200%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -43,8 +43,9 @@
|
|||||||
|
|
||||||
.login-app {
|
.login-app {
|
||||||
background-color: var( --background-color );
|
background-color: var( --background-color );
|
||||||
width: 40%;
|
min-height: fit-content;
|
||||||
height: 50%;
|
min-height: fit-content;
|
||||||
|
padding: 5% 20%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,16 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="cart">
|
<div class="cart">
|
||||||
<h1>Cart</h1>
|
<h1>Cart</h1>
|
||||||
|
<div v-if="cartNotEmpty" class="cart-list">
|
||||||
<h3>Your tickets</h3>
|
<h3>Your tickets</h3>
|
||||||
<ul v-for="event in tickets" class="cart-list">
|
<ul v-for="event in tickets" class="cart-list">
|
||||||
<li>{{ event.name }}
|
<li>{{ event.name }}
|
||||||
<ul v-for="ticket in event.selectedSeats">
|
<ul v-for="ticket in event.selectedSeats">
|
||||||
<li>{{ ticket.name }} ({{ ticket.category.name }}, {{ ticket.ageGroup }}) {{ event.currency }} {{ ticket.price }}</li>
|
<li>{{ ticket.name }} ({{ ticket.category.name }}, {{ ticket.ageGroup }}) {{ event.currency }} {{ ticket.price }} <span class="material-symbols-outlined deleteButton" @click="deleteEntry( ticket.name, event.name )" title="Delete ticket">delete</span></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<div class="tool-wrapper">
|
||||||
|
<h4>Total: {{ backend.currency }} {{ backend.total }}</h4>
|
||||||
<router-link to="/purchase">Purchase now</router-link>
|
<router-link to="/purchase">Purchase now</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
Cart is empty. Please add tickets <router-link to="/tickets">here</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -65,19 +73,85 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto
|
margin-right: auto
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tool-wrapper {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deleteButton {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 110%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tickets: {}
|
tickets: {},
|
||||||
|
backend: {},
|
||||||
|
cartNotEmpty: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadCart () {
|
loadCart () {
|
||||||
this.tickets = JSON.parse( sessionStorage.getItem( 'cart' ) );
|
this.cartNotEmpty = false;
|
||||||
|
let tickets = JSON.parse( sessionStorage.getItem( 'cart' ) );
|
||||||
|
|
||||||
|
for ( let event in tickets ) {
|
||||||
|
if ( Object.keys( tickets[ event ][ 'selectedSeats' ] ).length ) {
|
||||||
|
this.cartNotEmpty = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.tickets = tickets;
|
||||||
|
this.backend = JSON.parse( sessionStorage.getItem( 'backend' ) );
|
||||||
|
},
|
||||||
|
deleteEntry( id, eventName ) {
|
||||||
|
if ( confirm( 'Do you really want to delete this ticket?' ) ) {
|
||||||
|
let tickets = JSON.parse( sessionStorage.getItem( 'cart' ) );
|
||||||
|
for ( let event in tickets ) {
|
||||||
|
let ev = tickets[ event ];
|
||||||
|
if ( ev.name == eventName ) {
|
||||||
|
for ( let ticket in ev[ 'selectedSeats' ] ) {
|
||||||
|
if ( ev[ 'selectedSeats' ][ ticket ].name ) {
|
||||||
|
delete tickets[ event ][ 'selectedSeats' ][ ticket ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sessionStorage.setItem( 'cart', JSON.stringify( tickets ) );
|
||||||
|
this.sumUp();
|
||||||
|
this.loadCart();
|
||||||
|
};
|
||||||
|
},
|
||||||
|
sumUp () {
|
||||||
|
// This function calculates the total price of the tickets for this event.
|
||||||
|
let cart = sessionStorage.getItem( 'cart' ) ? JSON.parse( sessionStorage.getItem( 'cart' ) ) : {};
|
||||||
|
|
||||||
|
let price = 0;
|
||||||
|
for ( let i in cart ) {
|
||||||
|
for ( let entry in cart[ i ][ 'selectedSeats' ] ) {
|
||||||
|
price += parseInt( cart[ i ][ 'selectedSeats' ][ entry ][ 'price' ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let back = {};
|
||||||
|
|
||||||
|
back[ 'total' ] = price;
|
||||||
|
back[ 'currency' ] = this.backend.currency;
|
||||||
|
|
||||||
|
sessionStorage.setItem( 'backend', JSON.stringify( back ) );
|
||||||
|
|
||||||
|
this.total = price;
|
||||||
|
|
||||||
|
sessionStorage.setItem( 'cart', JSON.stringify( cart ) );
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
this.loadCart();
|
this.loadCart();
|
||||||
|
|||||||
@@ -46,8 +46,9 @@
|
|||||||
|
|
||||||
.login-app {
|
.login-app {
|
||||||
background-color: var( --background-color );
|
background-color: var( --background-color );
|
||||||
width: 40%;
|
min-height: fit-content;
|
||||||
height: 50%;
|
min-height: fit-content;
|
||||||
|
padding: 5% 20%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="order">
|
<div class="order">
|
||||||
<h1>Order tickets</h1>
|
<h1>Order tickets</h1>
|
||||||
<div class="order-app">
|
<div class="order-app" v-if="events">
|
||||||
<ul v-for="event in events">
|
<ul v-for="event in events">
|
||||||
<li>
|
<li>
|
||||||
<router-link to="/tickets/details" class="ticket" @click="setActiveTicket( 'test' );">
|
<router-link to="/tickets/details" class="ticket" @click="setActiveTicket( 'test' );">
|
||||||
@@ -19,6 +19,9 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="order-app" v-else>
|
||||||
|
No future events are available!
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -47,11 +47,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.login-app {
|
.login-app {
|
||||||
background-color: white;
|
background-color: var( --background-color );
|
||||||
width: 40%;
|
|
||||||
height: 50%;
|
|
||||||
min-height: fit-content;
|
min-height: fit-content;
|
||||||
min-width: fit-content;
|
min-height: fit-content;
|
||||||
|
padding: 5% 20%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="details">
|
<div class="details">
|
||||||
<!-- Load correct component depending on what the event's config is -->
|
<h1>Details</h1>
|
||||||
<seatplan ticketID="haoag"></seatplan>
|
<h3>{{ event.name }}</h3>
|
||||||
|
<p>{{ event.description }}</p>
|
||||||
|
<router-link to="/tickets/order">Order tickets</router-link>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -12,17 +14,18 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import seatplan from '@/components/seatplan.vue';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TicketsDetailsView',
|
name: 'TicketsDetailsView',
|
||||||
components: {
|
|
||||||
seatplan
|
|
||||||
},
|
|
||||||
created () {
|
created () {
|
||||||
if ( !sessionStorage.getItem( 'selectedTicket' ) ) {
|
if ( !sessionStorage.getItem( 'selectedTicket' ) ) {
|
||||||
this.$router.push( '/tickets' );
|
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' },
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
29
src/webapp/src/views/TicketsOrderingView.vue
Normal file
29
src/webapp/src/views/TicketsOrderingView.vue
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<div class="details">
|
||||||
|
<!-- Load correct component depending on what the event's config is -->
|
||||||
|
<seatplan ticketID="haoag"></seatplan>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.details {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import seatplan from '@/components/seatplan.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'TicketsDetailsView',
|
||||||
|
components: {
|
||||||
|
seatplan
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
if ( !sessionStorage.getItem( 'selectedTicket' ) ) {
|
||||||
|
this.$router.push( '/tickets' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<router-link to="/admin/events" class="bigButton">Events</router-link>
|
<router-link to="/admin/events" class="bigButton">Events</router-link>
|
||||||
<router-link to="/admin/events" class="bigButton">Plugins</router-link>
|
<router-link to="/admin/events" class="bigButton">Plugins</router-link>
|
||||||
<router-link to="/admin/events" class="bigButton">Settings</router-link>
|
<router-link to="/admin/events" class="bigButton">Settings</router-link>
|
||||||
<a href="https://myevent.janishutz.com/docs" class="bigButton" target="_blank">Documentation</a>
|
<a href="https://myevent.janishutz.com/docs/admin-panel" class="bigButton" target="_blank">Documentation</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
22
src/webapp/src/views/setup/SetupPageView.vue
Normal file
22
src/webapp/src/views/setup/SetupPageView.vue
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h3>Setting up the landing page</h3>
|
||||||
|
<p>The landing page is the page your customers see when they visit your webpage. You may select a page template <a href="https://myevent.janishutz.com/docs/homepage/templates"></a></p>
|
||||||
|
<p>You may find more infos about this part <a href="https://myevent.janishutz.com/docs/setup/setup#page-setup" target="_blank">here</a></p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
formData: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit () {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
38
src/webapp/src/views/setup/SetupPaymentsView.vue
Normal file
38
src/webapp/src/views/setup/SetupPaymentsView.vue
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h3>Setting up payment methods</h3>
|
||||||
|
<p>The root account is the most powerful account. Therefore, it should only be used if really necessary and should have a strong password. It also always requires Two Factor Authentication for added security. You may log into the root account by typing 'root' into the Email/Username field on the admin login screen.</p>
|
||||||
|
<p>You may find more infos about this part <a href="https://myevent.janishutz.com/docs/setup/setup#root-account" target="_blank">here</a></p>
|
||||||
|
<p>Password requirements:</p>
|
||||||
|
<ul style="list-style: none;">
|
||||||
|
<li>At least 15 characters long</li>
|
||||||
|
<li>At least 2 special characters</li>
|
||||||
|
<li>At least 2 numbers</li>
|
||||||
|
<li>At least 2 lower and 2 upper case letters</li>
|
||||||
|
</ul>
|
||||||
|
<form>
|
||||||
|
<label for="mail">Email address for 2FA</label><br>
|
||||||
|
<input type="email" name="mail" id="mail"><br>
|
||||||
|
<label for="password">Password</label><br>
|
||||||
|
<input type="email" name="password" id="password"><br>
|
||||||
|
<label for="password2">Confirm password</label><br>
|
||||||
|
<input type="email" name="password2" id="password2">
|
||||||
|
</form>
|
||||||
|
<button @click="submit()">Continue</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
formData: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit () {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
38
src/webapp/src/views/setup/SetupRootView.vue
Normal file
38
src/webapp/src/views/setup/SetupRootView.vue
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h3>Setting up the root account</h3>
|
||||||
|
<p>The root account is the most powerful account. Therefore, it should only be used if really necessary and should have a strong password. It also always requires Two Factor Authentication for added security. You may log into the root account by typing 'root' into the Email/Username field on the admin login screen.</p>
|
||||||
|
<p>You may find more infos about this part <a href="https://myevent.janishutz.com/docs/setup/setup#root-account" target="_blank">here</a></p>
|
||||||
|
<p>Password requirements:</p>
|
||||||
|
<ul style="list-style: none;">
|
||||||
|
<li>At least 15 characters long</li>
|
||||||
|
<li>At least 2 special characters</li>
|
||||||
|
<li>At least 2 numbers</li>
|
||||||
|
<li>At least 2 lower and 2 upper case letters</li>
|
||||||
|
</ul>
|
||||||
|
<form>
|
||||||
|
<label for="mail">Email address for 2FA</label><br>
|
||||||
|
<input type="email" name="mail" id="mail"><br>
|
||||||
|
<label for="password">Password</label><br>
|
||||||
|
<input type="email" name="password" id="password"><br>
|
||||||
|
<label for="password2">Confirm password</label><br>
|
||||||
|
<input type="email" name="password2" id="password2">
|
||||||
|
</form>
|
||||||
|
<button @click="submit()">Continue</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
formData: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit () {
|
||||||
|
this.$router.push( 'page' );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
22
src/webapp/src/views/setup/SetupStartView.vue
Normal file
22
src/webapp/src/views/setup/SetupStartView.vue
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h3>Welcome to myevent!</h3>
|
||||||
|
<p>Let's start by setting it up. We strongly encourage you to also have a look at the extensive documentation of the setup process <a href="https://myevent.janishutz.com/docs/setup/setup" target="_blank">here</a></p>
|
||||||
|
<router-link to="/setup/root">Start setup</router-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
formData: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setup () {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -3,7 +3,9 @@ The main website's pages are written in HTML & CSS whilst the doc pages are auto
|
|||||||
** DO NOT MODIFY THE DOC PAGES IN THE [dist/docs/](dist/docs/) DIRECTORY! **
|
** DO NOT MODIFY THE DOC PAGES IN THE [dist/docs/](dist/docs/) DIRECTORY! **
|
||||||
|
|
||||||
## Links in the md files in [src/](src/)
|
## Links in the md files in [src/](src/)
|
||||||
Please note that you are required to use either a link relative to the root folder with double forward slash (example: *//server/app.js*), to the website root with a single forward slash (example: */download*), a full link (example: *https://myevent.janishutz.com/docs*) or a relative link (example: *plugins/music*). If you do not follow these patterns, the website won't build or the links will not work correctly. NOTE: Don't be confused if the root folder links don't work in the Markdown, as they use specific syntax for the build script.
|
Please note that you are required to use either a link relative to the root folder with double forward slash (example: *//server/app.js*), to the website root with a single forward slash (example: */download*), to the docs root with &/ (example: *&/setup*) or simply /docs/ (example: */docs/setup*), a full link (example: *https://myevent.janishutz.com/docs*) or a relative link (example: *plugins/music*). If you do not follow these patterns, the website won't build or the links will not work correctly.
|
||||||
|
|
||||||
|
***NOTE: Don't be confused if the root folder links don't work in the Markdown, as they use specific syntax for the build script.***
|
||||||
|
|
||||||
## Folder structure, file naming and file structure
|
## Folder structure, file naming and file structure
|
||||||
Please note that the filename that is used for the md file is used to create a folder that contains an *index.html* so the *.html* file extension disappears. The build script uses the first level 1 title (marked with \# in md) as the page title and also for the navigation menu, so please choose the title appropriately and don't let it exceed 50 characters!
|
Please note that the filename that is used for the md file is used to create a folder that contains an *index.html* so the *.html* file extension disappears. The build script uses the first level 1 title (marked with \# in md) as the page title and also for the navigation menu, so please choose the title appropriately and don't let it exceed 50 characters!
|
||||||
|
|||||||
11
website/src/admin-panel.md
Normal file
11
website/src/admin-panel.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Admin panel
|
||||||
|
The admin panel is where you can change basically everything about myevent. Depending on your account's privileges, you may find more or less settings. Only the root account has access to the admin accounts page.
|
||||||
|
|
||||||
|
Here's a list of the pages available when logged in as the root user. All other users have fewer pages enabled.
|
||||||
|
- [Admin Accounts](&/admin-panel/admin-accounts)
|
||||||
|
- [Pages](&/admin-panel/pages)
|
||||||
|
- [Events](&/admin-panel/events)
|
||||||
|
- [Plugins](&/admin-panel/plugins)
|
||||||
|
- [Settings](&/admin-panel/settings)
|
||||||
|
|
||||||
|
Additionally, some settings might not be available to all admin accounts on all pages.
|
||||||
18
website/src/admin-panel/admin-accounts.md
Normal file
18
website/src/admin-panel/admin-accounts.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Admin Accounts
|
||||||
|
On this page you may add, modify or remove admin accounts. Note that in order for you to see this page, you'll need to be logged in as the user root.
|
||||||
|
|
||||||
|
## Adding an account
|
||||||
|
|
||||||
|
### Privileges
|
||||||
|
|
||||||
|
|
||||||
|
### Email
|
||||||
|
|
||||||
|
|
||||||
|
### 2FA
|
||||||
|
With this checkbox you can choose if this user needs to do two factor authentication, meaning, if the user needs to authorise the login using a link. In the [Settings](&/admin-panel/settings#2fa) you may choose between the two different 2FA modes that myevent offers.
|
||||||
|
|
||||||
|
|
||||||
|
## Modifying an account
|
||||||
|
|
||||||
|
## Removing an account
|
||||||
0
website/src/admin-panel/events.md
Normal file
0
website/src/admin-panel/events.md
Normal file
0
website/src/admin-panel/pages.md
Normal file
0
website/src/admin-panel/pages.md
Normal file
0
website/src/admin-panel/plugins.md
Normal file
0
website/src/admin-panel/plugins.md
Normal file
26
website/src/admin-panel/settings.md
Normal file
26
website/src/admin-panel/settings.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Settings
|
||||||
|
|
||||||
|
## 2FA
|
||||||
|
myevent offers two different 2fa modes:
|
||||||
|
- Standard mode: The user has to click on a link that was sent to him via email. He'll automatically be logged in as soon as the page loads.
|
||||||
|
- Enhanced mode: The user has to click on a link that was sent to him via email and then has to confirm it by entering the code that is shown to him on the 2FA page. After that he'll automatically be logged in.
|
||||||
|
|
||||||
|
In both modes, the system informs the user about the IP address that tried to log into the account.
|
||||||
|
|
||||||
|
This setting can be changed individually for admin and user accounts and 2FA can be disabled entirely. It is highly encouraged to enable this at least for the admin accounts and for user accounts set the requirement to 'User-defined' or 'Always required' instead of 'Disabled'.
|
||||||
|
|
||||||
|
## User account passwords
|
||||||
|
Here you may set password requirements for the user accounts. The system will always be offering the users to generate a password that is strong for them to facilitate the process of setting a password.
|
||||||
|
|
||||||
|
## Guest purchase
|
||||||
|
Choose if a user may purchase a ticket without creating an account. An email address is always required as the system sends the tickets via email to the customers for easier access.
|
||||||
|
|
||||||
|
## Allow overbooking
|
||||||
|
Activate this and set a percentage of overbooking, if you want to enable overbooking of the event to ensure that every single spot is occupied even if somebody does not show up. Use is strongly discouraged and currently only works with events that have no seating plan.
|
||||||
|
|
||||||
|
## Special requirements
|
||||||
|
Here you may set a special requirement that a person booking a ticket has to fulfill, like the email address has to be ending in @yourdomain.com or they need to live in a certain street / town / city / country in order for them to be allowed to buy a ticket. You may also require that they provide a certain number, code or similar. Finally, you may choose to limit the amount of tickets a single person may reserve.
|
||||||
|
|
||||||
|
|
||||||
|
## Change organisation name
|
||||||
|
This should be self explanatory, but keep in mind that this change will only take effect after the next restart of the node app.
|
||||||
7
website/src/errors.md
Normal file
7
website/src/errors.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Errors
|
||||||
|
|
||||||
|
## 404
|
||||||
|
A 404 error is returned if the page was not found on the server. This can be either due to a wrong link or a badly configured server, but is mostly user error, so a misspelled link.
|
||||||
|
|
||||||
|
## 500
|
||||||
|
An internal server error occurs when the server is unable to properly process a request, which in some cases might also return a [400](#400) error, if the server first decides that the request is unacceptable.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Payments
|
||||||
|
Including many payment methods can help the user choose the one that fits them best, but can also be overwhelming and a pain to set up. So please try to use as few different payment gateways as possible. Our recommendation is either *Stripe* or *adyen* as they are the most flexible.
|
||||||
|
|
||||||
|
## Advantages / Disadvantages of each payment gateway
|
||||||
|
|
||||||
|
### Stripe
|
||||||
|
Stripe is one of the most well known payment gateways out there, but is also fairly expensive, but easy to set up.
|
||||||
|
See [here](https://stripe.com/en-gb/pricing) for pricing information and sign up [here](https://dashboard.stripe.com/register)
|
||||||
|
|
||||||
|
### adyen
|
||||||
|
Adyen is used by small and huge businesses alike, but you have to email their support team for account creation, which is easy to do, but takes longer to complete. adyen is fairly cheap, "*only*" charging 0.10$ per transaction plus payment method costs. Detailed pricing information can be found [here](https://www.adyen.com/pricing) and you may sign up [here](https://www.adyen.com/contact/sales)
|
||||||
|
|
||||||
|
|
||||||
|
### payrexx
|
||||||
|
https://www.payrexx.com/en/pricing/
|
||||||
26
website/src/setup/installation.md
Normal file
26
website/src/setup/installation.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Installation
|
||||||
|
Let's begin with setting up myevent! If you are not technically savvy or want somebody else to set it up for you, please contact me [here](https://api.janishutz.com/contact/setup?origin=myevent&campaign=installation-docs). If you want to set it up yourself, read on below!
|
||||||
|
|
||||||
|
|
||||||
|
# Selecting a webhosting company
|
||||||
|
Choosing the right hosting provider is not easy, especially since myevent requires node.js. Therefore, we've listed a few really good options. This website here is hosted by asurahosting. *Note: I may receive a small commission when you buy webhosting using one of the links provided below. This won't affect the price you pay.*
|
||||||
|
https://clients.asurahosting.com/aff.php?aff=1997
|
||||||
|
https://www.novatrend.ch/en/
|
||||||
|
https://www.hostinger.com/
|
||||||
|
https://www.a2hosting.com/
|
||||||
|
https://www.hetzner.com/
|
||||||
|
https://www.digitalocean.com/
|
||||||
|
|
||||||
|
*Affiliate program*
|
||||||
|
https://affiliates.hostinger.com/users/signup/
|
||||||
|
https://www.a2hosting.com/about/affiliate-program/
|
||||||
|
https://www.digitalocean.com/go/affiliates
|
||||||
|
|
||||||
|
## Database
|
||||||
|
In the database, all the userdata is stored. myevent currently supports two different databases, MySQL and a custom database based on JSON. Which one to choose?
|
||||||
|
|
||||||
|
Generally MySQL, except:
|
||||||
|
- If your organisation is small and does only sell a few tickets at a time, the JSON based database works perfectly fine.
|
||||||
|
- Your web hosting plan does not includes MySQL and you've got no access to MySQL in any other way. *NOTE: Free MySQL services should NEVER be used in such an application, as most hosting plans include MySQL which is much more reliable and if you lose access to the database, you can only access the root account and all other data (and therefore all user accounts) is lost.*
|
||||||
|
|
||||||
|
MySQL generally is more difficult to set up, but we'll run you through the process here to make the process easier for you. If you chose the JSON based database, skip ahead to the next chapter.
|
||||||
@@ -1,16 +1,12 @@
|
|||||||
# Setup of myevent
|
# Setup of myevent
|
||||||
At this point we assume you've completed the initial install of myevent. If not, you may find a guide on how to do it [here](/setup/getting-started). Let's get started setting up your event management system!
|
At this point we assume you've completed the initial install of myevent. If not, you may find a guide on how to do it [here](&/setup/getting-started). Let's get started setting up your event management system!
|
||||||
|
|
||||||
## Connecting to the server
|
## Connecting to the server
|
||||||
As discussed in the previous part where we installed the system, you can connect to your server simply by opening a web browser and typing your domain name into the address field. After that you should be greeted by the myevent post-install landing page. Please click onto the button saying 'To the admin panel' and log in with the following credentials:
|
As discussed in the previous part where we installed the system, you can connect to your server simply by opening a web browser and typing your domain name into the address field. After that you should be greeted by the myevent post-install landing page. Once there, you'll need the setup key you defined during the installation. Type it into the field and hit "Start setup".
|
||||||
|
|
||||||
Username: setup
|
|
||||||
|
|
||||||
Password: myevent-setup
|
|
||||||
|
|
||||||
*Note: This is only available during the setup process of myevent and will afterwards be deactivated to ensure safety of the system.*
|
*Note: This is only available during the setup process of myevent and will afterwards be deactivated to ensure safety of the system.*
|
||||||
|
|
||||||
## Setting up the root account
|
## Root account
|
||||||
This is the most powerful account in this system. From it you can control EVERY aspect of your system.
|
This is the most powerful account in this system. From it you can control EVERY aspect of your system.
|
||||||
|
|
||||||
**Remark: You may (and definitely should) add other accounts with less privileges after completing setup and only use the root account when it is actually necessary**
|
**Remark: You may (and definitely should) add other accounts with less privileges after completing setup and only use the root account when it is actually necessary**
|
||||||
@@ -28,8 +24,25 @@ Upper / Lower case | At least 2 upper & 2 lower case letters required
|
|||||||
|
|
||||||
Please avoid using easy to guess combinations like names & birth dates of you or your relatives, zip codes & cities and obvious words like 'password', 'myevent', 'admin', 'root' and your organisation / event's name.
|
Please avoid using easy to guess combinations like names & birth dates of you or your relatives, zip codes & cities and obvious words like 'password', 'myevent', 'admin', 'root' and your organisation / event's name.
|
||||||
|
|
||||||
|
After this, the system will email you an email confirmation link using the email you've previously configured in the config.json file during installation.
|
||||||
|
|
||||||
## Page setup
|
## Page setup
|
||||||
After having set up the root account and confirmed the email address, it is now time to set the name of the webpage. For this, you'll need to enter your organisation's name and choose the offered languages. Note that for every language you select, you need to add a promotional text if you choose to add a homepage. If you selected a homepage, you have to insert a promotional text and you have to select a homepage-template from one that is available [here](/homepage/templates). You also have to upload some images at this stage.
|
After having set up the root account and confirmed the email address, it is now time to set the name of the webpage. For this, you'll need to enter your organisation's name and choose the offered languages. Note that for every language you select, you need to add a promotional text. Please select a homepage template from [here](&/homepage/templates). You also have to upload an/some image(s) at this stage, if the selected template requires (an) image(s).
|
||||||
|
|
||||||
|
|
||||||
## Payment methods
|
## Payment methods
|
||||||
Now it is time to set up some payment methods. You may find advantages / disadvantages of each payment gateway [here](/payments). It is advised to only choose one payment gateway which provides lots of different payment options, but cost of usage can also be a factor to consider. You may add more payment options by downloading a plugin through the plugin installer in the admin panel.
|
Now it is time to set up some payment methods. You may find advantages / disadvantages of each payment gateway [here](&/payments). It is advised to only choose one payment gateway which provides lots of different payment options, but cost of usage can also be a factor to consider. You may add more payment options by downloading a plugin through the plugin installer in the admin panel. *Note: You'll have to restart the node app whenever you install a new plugin!*
|
||||||
|
|
||||||
|
## Event setup
|
||||||
|
With payment methods sorted, you now have to add an event. For this, you'll need to create tickets by hitting the plus icon.
|
||||||
|
|
||||||
|
## TOS
|
||||||
|
This is an optional step. Here you may add your own terms of services (TOS), next to the ones that are given by myevent itself. Your TOS will be inserted at the top.
|
||||||
|
|
||||||
|
## Setup complete
|
||||||
|
With this, you've completed the setup of the event. We now ask you to restart the node application. You may do this by stopping the process (if logged in via SSH, press Ctrl + C, if you've got a graphical user interface for setting up the node app, it should be self explanatory) and restarting it as described [here](&/setup/installation#starting).
|
||||||
|
|
||||||
|
|
||||||
|
**Congratulations! You've now successfully set up your event management solution. You may now log into the admin panel. You can find your admin panel at /admin (example: myevent.janishutz.com/admin, replace myevent.janishutz.com with your own domain).**
|
||||||
|
|
||||||
|
*You may find documentation on the admin panel [here](&/admin-panel/)*
|
||||||
Reference in New Issue
Block a user