mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 05:14:23 +00:00
lost of progress
This commit is contained in:
@@ -29,10 +29,10 @@
|
||||
</td>
|
||||
<td v-for="place in row.content">
|
||||
<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>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -85,7 +85,7 @@ export default {
|
||||
data () {
|
||||
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' } } } },
|
||||
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: {},
|
||||
pricingCurrentlySelected: {},
|
||||
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;
|
||||
|
||||
sessionStorage.setItem( 'cart', JSON.stringify( cart ) );
|
||||
},
|
||||
closePlaceNotAvailablePopup () {
|
||||
$( '#placeNotAvailable' ).hide( 300 );
|
||||
@@ -187,7 +196,7 @@ export default {
|
||||
let seat = JSON.parse( sessionStorage.getItem( 'tempStorage' ) );
|
||||
this.seating[ seat[ 1 ][ 1 ] ][ 'content' ][ seat[ 1 ][ 0 ] ][ 'selected' ] = false;
|
||||
},
|
||||
storeSeat( ticketOption ) {
|
||||
storeSeat( ticketOption ) {
|
||||
/*
|
||||
This function stores a ticket into the event's selected seat sessionStorage.
|
||||
*/
|
||||
@@ -200,15 +209,16 @@ export default {
|
||||
|
||||
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' ] };
|
||||
data[ String( seat[ 1 ][ 1 ] ) + String( seat[ 1 ][ 0 ] ) ] = ticketData;
|
||||
|
||||
cart[ this.ticketID ?? 'default' ][ 'selectedSeats' ] = data;
|
||||
|
||||
|
||||
sessionStorage.setItem( 'cart', JSON.stringify( cart ) );
|
||||
this.selectedSeats = cart;
|
||||
$( '#overlay' ).hide( 200 );
|
||||
this.selectedSeats = cart;
|
||||
this.sumUp();
|
||||
},
|
||||
},
|
||||
|
||||
@@ -45,7 +45,36 @@ const routes = [
|
||||
meta: {
|
||||
title: 'Login :: Admin - myevent',
|
||||
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',
|
||||
@@ -130,6 +159,15 @@ const routes = [
|
||||
transition: 'scale'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/tickets/order',
|
||||
name: 'ticketOrder',
|
||||
component: () => import( '../views/TicketsOrderingView.vue' ),
|
||||
meta: {
|
||||
title: 'Order ticket - myevent',
|
||||
transition: 'scale'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/cart',
|
||||
name: 'cart',
|
||||
@@ -156,7 +194,12 @@ const routes = [
|
||||
title: 'Pay - myevent',
|
||||
transition: 'scale',
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'NotFound',
|
||||
component: () => import( '@/views/404.vue')
|
||||
},
|
||||
]
|
||||
|
||||
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 {
|
||||
background-color: var( --background-color );
|
||||
width: 40%;
|
||||
height: 50%;
|
||||
min-height: fit-content;
|
||||
min-height: fit-content;
|
||||
padding: 5% 20%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
<template>
|
||||
<div class="cart">
|
||||
<h1>Cart</h1>
|
||||
<h3>Your tickets</h3>
|
||||
<ul v-for="event in tickets" class="cart-list">
|
||||
<li>{{ event.name }}
|
||||
<ul v-for="ticket in event.selectedSeats">
|
||||
<li>{{ ticket.name }} ({{ ticket.category.name }}, {{ ticket.ageGroup }}) {{ event.currency }} {{ ticket.price }}</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<router-link to="/purchase">Purchase now</router-link>
|
||||
<div v-if="cartNotEmpty" class="cart-list">
|
||||
<h3>Your tickets</h3>
|
||||
<ul v-for="event in tickets" class="cart-list">
|
||||
<li>{{ event.name }}
|
||||
<ul v-for="ticket in event.selectedSeats">
|
||||
<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>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tool-wrapper">
|
||||
<h4>Total: {{ backend.currency }} {{ backend.total }}</h4>
|
||||
<router-link to="/purchase">Purchase now</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
Cart is empty. Please add tickets <router-link to="/tickets">here</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -65,19 +73,85 @@
|
||||
margin-left: 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>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tickets: {}
|
||||
tickets: {},
|
||||
backend: {},
|
||||
cartNotEmpty: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
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 () {
|
||||
this.loadCart();
|
||||
|
||||
@@ -46,8 +46,9 @@
|
||||
|
||||
.login-app {
|
||||
background-color: var( --background-color );
|
||||
width: 40%;
|
||||
height: 50%;
|
||||
min-height: fit-content;
|
||||
min-height: fit-content;
|
||||
padding: 5% 20%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="order">
|
||||
<h1>Order tickets</h1>
|
||||
<div class="order-app">
|
||||
<div class="order-app" v-if="events">
|
||||
<ul v-for="event in events">
|
||||
<li>
|
||||
<router-link to="/tickets/details" class="ticket" @click="setActiveTicket( 'test' );">
|
||||
@@ -19,6 +19,9 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="order-app" v-else>
|
||||
No future events are available!
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -47,11 +47,10 @@
|
||||
}
|
||||
|
||||
.login-app {
|
||||
background-color: white;
|
||||
width: 40%;
|
||||
height: 50%;
|
||||
background-color: var( --background-color );
|
||||
min-height: fit-content;
|
||||
min-width: fit-content;
|
||||
min-height: fit-content;
|
||||
padding: 5% 20%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div class="details">
|
||||
<!-- Load correct component depending on what the event's config is -->
|
||||
<seatplan ticketID="haoag"></seatplan>
|
||||
<h1>Details</h1>
|
||||
<h3>{{ event.name }}</h3>
|
||||
<p>{{ event.description }}</p>
|
||||
<router-link to="/tickets/order">Order tickets</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -12,17 +14,18 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import seatplan from '@/components/seatplan.vue';
|
||||
|
||||
export default {
|
||||
name: 'TicketsDetailsView',
|
||||
components: {
|
||||
seatplan
|
||||
},
|
||||
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' },
|
||||
}
|
||||
}
|
||||
};
|
||||
</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">Plugins</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>
|
||||
</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>
|
||||
Reference in New Issue
Block a user