lost of progress

This commit is contained in:
2023-04-21 16:03:21 +02:00
parent 13924e3abb
commit 8d751026b6
26 changed files with 483 additions and 47 deletions

View File

@@ -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();
},
},

View File

@@ -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( {

View 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>

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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>

View File

@@ -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;

View File

@@ -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>

View 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>

View File

@@ -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>

View 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>

View 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>

View 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>

View 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>