Migrate MyE&P SPA

This commit is contained in:
Björn Fromme
2021-08-11 12:20:43 +02:00
parent b8bac586d2
commit 98a87f95f1
32 changed files with 8575 additions and 13216 deletions
+8160 -12867
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -43,6 +43,7 @@
"@tailwindcss/forms": "^0.3.3",
"autoprefixer": "^10.3.1",
"core-js": "^3.15.2",
"document-register-element": "^1.14.10",
"file-loader": "^6.2.0",
"node-sass": "^4.14.1",
"postcss": "^8.3.6",
@@ -54,6 +55,7 @@
"tailwindcss-alt": "^3.0.0",
"tinycolor2": "^1.4.1",
"vue-loader": "^15.9.7",
"vue-custom-element": "^3.3.0",
"vue-template-compiler": "^2.6.14"
}
}
@@ -1,14 +0,0 @@
// Initialize vue apps
import Vue from 'vue'
import store from './myep/store'
new Vue({
el: '#myep',
store,
components: {
MyEp: () => import('./myep/App.vue'),
},
created () {
this.$store.dispatch('init');
},
});
@@ -0,0 +1,16 @@
// Initialize vue apps
import Vue from 'vue'
import vueCustomElement from 'vue-custom-element'
import dayjs from 'dayjs'
import 'dayjs/locale/de'
import 'document-register-element/build/document-register-element'
import App from './myep/App'
Vue.filter('date', (value) => {
return dayjs(value).format('DD.MM.YY');
})
Vue.use(vueCustomElement)
Vue.config.productionTip = false
Vue.customElement('my-ep', App)
@@ -1,61 +1,59 @@
<template>
<div class="form-wrapper form--border" id="myep-main" v-show="!loading">
<div id="myep-main" v-show="!loading">
<p class="text-2xl">Adressdaten</p>
<form @submit.prevent="save()">
<div class="row">
<div class="col-xs-12 col-md-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div>
<form-group label="Gender">
<select v-model="userData.gender" class="form-control">
<select v-model="userData.gender" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
<option value="w">W</option>
<option value="m">M</option>
<option value="d">D</option>
</select>
</form-group>
<form-group label="Title">
<input type="text" v-model="userData.title" class="form-control">
<input type="text" v-model="userData.title" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="Name" :error="formErrors.lastName">
<input type="text" v-model="userData.lastName" class="form-control">
<input type="text" v-model="userData.lastName" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="Vorname" :error="formErrors.firstName">
<input type="text" v-model="userData.firstName" class="form-control">
<input type="text" v-model="userData.firstName" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="Geburtsdatum">
<span ref="picker"></span>
<div ref="picker"></div>
</form-group>
</div>
<div class="col-xs-12 col-md-6">
<div>
<form-group label="Straße" :error="formErrors.street">
<input type="text" v-model="userData.street" class="form-control">
<input type="text" v-model="userData.street" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="PLZ" :error="formErrors.zipCode">
<input type="text" v-model="userData.zipCode" class="form-control">
<input type="text" v-model="userData.zipCode" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="Stadt" :error="formErrors.city">
<input type="text" v-model="userData.city" class="form-control">
<input type="text" v-model="userData.city" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="Land" :error="formErrors.country">
<select v-model="userData.country" class="form-control">
<select v-model="userData.country" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
<option v-for="country in countries"
:value="country['code']">{{ country['name'] }}</option>
</select>
</form-group>
<form-group label="E-Mail" :error="formErrors.email">
<input type="text" v-model="userData.email" class="form-control">
<input type="text" v-model="userData.email" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="Telefon" :error="formErrors.phonePrivate">
<input type="text" v-model="userData.phonePrivate" class="form-control">
<input type="text" v-model="userData.phonePrivate" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="Mobil" :error="formErrors.phoneMobile">
<input type="text" v-model="userData.phoneMobile" class="form-control">
<input type="text" v-model="userData.phoneMobile" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
</div>
<div class="col-xs-12">
<div class="form-group">
<button type="submit" class="button" :disabled="loading">
Speichern
</button>
</div>
<div class="col-span-1 md:col-span2">
<button type="submit" class="button" :disabled="loading">
Speichern
</button>
</div>
</div>
</form>
@@ -1,6 +1,6 @@
<template>
<div id="myep" class="relative mb-16">
<nav class="w-full bg-gray-200 flex items-center justify-between mb-2 relative" v-if="isLoggedIn">
<nav class="w-full bg-gray-200 flex items-center justify-between mb-8 relative" v-if="isLoggedIn">
<span class="block text-2xl px-4">My E&P</span>
<div class="absolute z-10 top-100 left-0 w-full bg-gray-200 shadow lg:relative lg:top-auto lg:left-auto lg:w-auto lg:shadow-none lg:flex lg:space-x-4"
:class="{ 'hidden': !navVisible }">
@@ -62,6 +62,9 @@
if (this.isLoggedIn) {
this.$router.replace({ name: 'address' })
}
},
created () {
this.$store.dispatch('init')
}
}
</script>
@@ -3,14 +3,28 @@
<div class="grid lg:grid-cols-2 gap-4" v-if="initialized">
<div>
<panel title="Reisedaten">
<ul class="list-group">
<li class="list-group-item"><strong>Reise:</strong> {{ travelData.productName }}</li>
<li class="list-group-item"><strong>Zeitraum:</strong> {{ travelData.dateFrom }} - {{ travelData.dateTo }}</li>
<li class="list-group-item"><strong>Inklusivleistungen:</strong> {{ travelData.servicesIncluded.join(', ') }}</li>
<li class="list-group-item"><strong>Anmelder:</strong> {{ bookingData.applicant.firstName }} {{ bookingData.applicant.lastName }}</li>
<li class="list-group-item"><strong>Gesamtpreis:</strong> {{ totalPrice.toFixed(2) }}</li>
<li class="list-group-item"><strong>Teilnehmer:</strong> {{ participantsCount.active }}</li>
<li class="list-group-item"><strong>Stornos:</strong> {{ participantsCount.canceled }}</li>
<ul class="list-none">
<li class="p-2 border-b border-gray-200 last:border-0">
<strong>Reise:</strong> {{ travelData.productName }}
</li>
<li class="p-2 border-b border-gray-200 last:border-0">
<strong>Zeitraum:</strong> {{ travelData.dateFrom }} - {{ travelData.dateTo }}
</li>
<li class="p-2 border-b border-gray-200 last:border-0">
<strong>Inklusivleistungen:</strong> {{ travelData.servicesIncluded.join(', ') }}
</li>
<li class="p-2 border-b border-gray-200 last:border-0">
<strong>Anmelder:</strong> {{ bookingData.applicant.firstName }} {{ bookingData.applicant.lastName }}
</li>
<li class="p-2 border-b border-gray-200 last:border-0">
<strong>Gesamtpreis:</strong> {{ totalPrice.toFixed(2) }}
</li>
<li class="p-2 border-b border-gray-200 last:border-0">
<strong>Teilnehmer:</strong> {{ participantsCount.active }}
</li>
<li class="p-2 border-b border-gray-200 last:border-0">
<strong>Stornos:</strong> {{ participantsCount.canceled }}
</li>
</ul>
</panel>
<services-overview :services="services.other" :participant-data="participantData"/>
@@ -26,7 +40,10 @@
/>
</panel>
<panel title="Anmerkungen" :body="true">
<textarea class="form-textarea block w-full" rows="2" v-model="bookingData.remarks" @change="dirty = true"/>
<textarea class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full"
rows="2"
v-model="bookingData.remarks"
@change="dirty = true"/>
</panel>
</div>
</div>
@@ -39,7 +56,9 @@
</router-link>
</div>
<div class="py-4" v-if="initialized">
<h2>Teilnehmer</h2>
<h2 class="mb-4">
Teilnehmer
</h2>
<collapsible-panel :title="'#' + (index + 1) + ' ' + participant.data.lastName + ', ' + participant.data.firstName"
:class="invalidParticipantData[participant.data.id] ? 'panel-danger' : 'panel-default'" parent="#participant-list"
v-for="(participant, index) in participantData" :key="participant.data.id">
@@ -47,14 +66,14 @@
Storniert am {{ participant.data.cancellationDate }}, Stornokosten {{ participant.data.cancellationFee.toFixed(2) }}
</template>
<template v-else>
<div class="panel-body-section">
<div class="p-2 border-b border-gray-200">
<participant-data-form :participant="participant"
:mutable="mutableFields.participantData.mutable"
:countries="countries"
v-on:updated="onParticipantDataUpdated($event, index)"
/>
</div>
<div class="lg:flex lg:space-x-1 space-y-1 lg:space-y-0 py-4">
<div class="flex flex-col space-y-1 md:flex-row md:space-y-0 md:space-x-1 py-4 border-b border-gray-200 p-2">
<participant-address-form :participant="participant"
:countries="countries"
:mutable="mutableFields.participantData.mutable"
@@ -86,7 +105,7 @@
v-show="showPickups"
/>
</div>
<div class="grid lg:grid-cols-2 gap-4">
<div class="grid lg:grid-cols-2 gap-4 p-2">
<table class="table table-condensed text-sm mb-0">
<tbody>
<tr>
@@ -117,7 +136,7 @@
</tr>
</tbody>
</table>
<textarea rows="2" class="form-textarea block w-full"
<textarea rows="2" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full"
v-model="participant.data.accommodationRequest"
@change="dirty = true"
placeholder="Anmerkungen"
@@ -1,43 +1,50 @@
<template>
<div id="myep-main" v-show="!loading">
<h1>Mein Profil</h1>
<h1 class="mb-4">
Mein Profil
</h1>
<form @submit.prevent="save()">
<div class="row">
<div class="col-xs-12 col-md-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 mb-4">
<div>
<template v-for="selectionGroup in crmData.selectionGroups"
v-if="hasVisibleSelections(selectionGroup)">
<h3>{{ selectionGroup.name}}</h3>
<div class="checkbox" v-for="selection in selectionGroup.selections"
<h3 class="mb-2">
{{ selectionGroup.name}}
</h3>
<div class="mb-2"
v-for="selection in selectionGroup.selections"
v-if="selection.changeable === true && isSelectionVisible(selection)">
<label :class="{ disabled: !selection.changeable}">
<input type="checkbox" class="form-control" v-model="selection.value"
<label class="inline-flex items-center" :class="{ 'opacity-50': !selection.changeable}">
<input type="checkbox"
class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 text-ep-secondary sbw:text-sbw-secondary"
v-model="selection.value"
:disabled="!selection.changeable"/>
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
{{ selection.name }}
<span class="ml-2">
{{ selection.name }}
</span>
</label>
</div>
</template>
</div>
<div class="col-xs-12 col-md-6">
<div class="checkbox" v-for="action in crmData.actions" v-if="action.changeable === true">
<label :class="{ disabled: !action.changeable}">
<input type="checkbox" class="form-control"
v-model="action.value" :disabled="!action.changeable"/>
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
{{ action.name }}
<div>
<div class="mb-2"
v-for="action in crmData.actions"
v-if="action.changeable === true">
<label class="inline-flex items-center" :class="{ 'opacity-50': !action.changeable}">
<input type="checkbox"
class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 text-ep-secondary sbw:text-sbw-secondary"
v-model="action.value"
:disabled="!action.changeable"/>
<span class="ml-2">
{{ action.name }}
</span>
</label>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<button type="submit" class="button" :disabled="loading">
Speichern
</button>
</div>
</div>
</div>
<button type="submit" class="button" :disabled="loading">
Speichern
</button>
</form>
</div>
</template>
@@ -109,9 +116,3 @@
}
}
</script>
<style scoped>
label.disabled {
opacity: 0.5;
}
</style>
@@ -1,39 +1,71 @@
<template>
<div id="myep-main" v-show="!loading">
<h1>Meine Buchungen</h1>
<div class="table-responsive">
<table class="table table-striped table-condensed">
<h1 class="mb-4">
Meine Buchungen
</h1>
<div class="w-full max-w-full overflow-x-scroll">
<table class="min-w-full border border-gray-200 border-collapse mb-8 text-sm">
<thead>
<tr>
<th class="text-left align-top">Buchungsdatum</th>
<th class="text-left align-top">Reisedatum</th>
<th class="text-left align-top">Reise</th>
<th class="text-left align-top">Vorgang</th>
<th class="text-center align-top">Preis</th>
<th class="text-center align-top">offen</th>
<th class="text-left align-top">Status</th>
<th></th>
<th class="px-2 py-1 border border-gray-200 text-left">
Buchungsdatum
</th>
<th class="px-2 py-1 border border-gray-200 text-left">
Reisedatum
</th>
<th class="px-2 py-1 border border-gray-200 text-left">
Reise
</th>
<th class="px-2 py-1 border border-gray-200 text-left">
Vorgang
</th>
<th class="px-2 py-1 border border-gray-200 text-center">
Preis
</th>
<th class="px-2 py-1 border border-gray-200 text-center">
offen
</th>
<th class="px-2 py-1 border border-gray-200 text-left">
Status
</th>
<th class="px-2 py-1 border border-gray-200"></th>
</tr>
</thead>
<tbody>
<tr v-for="event of events">
<td class="text-left align-top">{{ formatBookingDate(event.dateBooking) }}</td>
<td class="text-left align-top">{{ event.dateTravel | date }}</td>
<td class="text-left align-top">{{ event.product }}</td>
<td class="text-left align-top">{{ event.bookingNumber }}</td>
<td class="text-right align-top whitespace-nowrap">{{ formatCurrency(event.price) }}</td>
<td class="text-right align-top whitespace-nowrap" :class="{ 'text-red-500': hasOutstandingPayment(event) }">{{ calculateBalance(event) }}</td>
<td class="text-left align-top">{{ status[event.status] }}</td>
<td class="flex space-x-1">
<a :href="getDownloadUrl(event, 'confirmation')" target="_blank" class="button button--action button--small">
Bestätigung
</a>
<a :href="getDownloadUrl(event, 'documents')" target="_blank" class="button button--secondary button--small" v-if="event.documents">
Reiseinfos
</a>
<router-link :to="{ name: 'bookingEdit', params: { id: event.id } }" v-if="event.editable" class="button button--small">
bearbeiten
</router-link>
<tr v-for="event of events" class="even:bg-gray-200">
<td class="px-2 py-1 border border-gray-200">
{{ formatBookingDate(event.dateBooking) }}
</td>
<td class="px-2 py-1 border border-gray-200">
{{ event.dateTravel | date }}
</td>
<td class="px-2 py-1 border border-gray-200">
{{ event.product }}
</td>
<td class="px-2 py-1 border border-gray-200">
{{ event.bookingNumber }}
</td>
<td class="px-2 py-1 border border-gray-200 whitespace-nowrap">
{{ formatCurrency(event.price) }}
</td>
<td class="px-2 py-1 border border-gray-200 whitespace-nowrap" :class="{ 'text-red-500': hasOutstandingPayment(event) }">
{{ calculateBalance(event) }}
</td>
<td class="px-2 py-1 border border-gray-200">
{{ status[event.status] }}
</td>
<td class="px-2 py-1 border border-gray-200">
<div class="grid grid-cols-1 xl:grid-cols-3 gap-2 w-32 xl:w-auto">
<a :href="getDownloadUrl(event, 'confirmation')" target="_blank" class="button button--action button--small">
Bestätigung
</a>
<router-link :to="{ name: 'bookingEdit', params: { id: event.id } }" v-if="event.editable" class="button button--small">
bearbeiten
</router-link>
<a :href="getDownloadUrl(event, 'documents')" target="_blank" class="button button--secondary button--small" v-if="event.documents">
Reiseinfos
</a>
</div>
</td>
</tr>
</tbody>
@@ -1,41 +1,49 @@
<template>
<div class="form-wrapper form--border" id="myep-main">
<h1>Login MyE&amp;P</h1>
<div id="myep-main">
<h1 class="mb-4">
Login MyE&amp;P
</h1>
<form @submit.prevent="submit()">
<div class="row">
<div class="col-xs-12 col-md-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div>
<form-group label="E-Mail" :error="formErrors.email">
<input type="text" v-model="email" class="form-control">
<input type="email" v-model="email" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="Passwort" v-if="loginMode">
<input type="password" v-model="password" class="form-control">
<input type="password" v-model="password" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<div class="form-group">
<div class="btn-group">
<button type="submit" class="button" :disabled="loading">
{{ loginMode ? 'Login' : 'Passwort erneuern' }}
</button>
<button class="button button--secondary" @click.prevent="toggleMode()">
{{ loginMode ? 'Passwort vergessen?' : 'Zum Login' }}
</button>
<router-link to="register" class="button button--secondary">Registrieren</router-link>
</div>
<div class="flex flex-col lg:flex-row space-y-2 lg:space-y-0 lg:space-x-2 mt-4">
<button type="submit" class="button" :disabled="loading">
{{ loginMode ? 'Login' : 'Passwort erneuern' }}
</button>
<button class="button button--secondary" @click.prevent="toggleMode()">
{{ loginMode ? 'Passwort vergessen?' : 'Zum Login' }}
</button>
<router-link to="register" class="button button--secondary">Registrieren</router-link>
</div>
</div>
<div class="col-xs-12 col-md-6">
<h3>Neu!</h3>
<p>
<div>
<h3 class="mb-2">
Neu!
</h3>
<p class="mb-4">
Melde dich jetzt bei MyEP an und du kannst jederzeit auf deine aktuellen Buchungen zugreifen und
diese abändern. Egal ob du einen Kurs oder eine Skipasserweiterung hinzufügen/entfernen möchtest,
oder das vegetarische Essen auswählen willst. Im neuen Portal ist das nun kostenlos bis 7 Tage vor
Reisebeginn möglich!
</p>
<h3>Noch keine Zugangsdaten?</h3>
<p>Dann gib deine E-Mail ein, mit der Du gebucht hast und klicke auf "Passwort vergessen"! Und wir
senden dir ein E-Mail mit einem Passwort-Link!</p>
<p>Ein LogIn ist nur möglich wenn Eure Daten schon durch eine Buchung oder Anfrage bei uns
<h3 class="mb-2">
Noch keine Zugangsdaten?
</h3>
<p class="mb-2">
Dann gib deine E-Mail ein, mit der Du gebucht hast und klicke auf "Passwort vergessen"! Und wir
senden dir ein E-Mail mit einem Passwort-Link!
</p>
<p>
Ein LogIn ist nur möglich wenn Eure Daten schon durch eine Buchung oder Anfrage bei uns
angelegt wurden. Wenn Ihr auch Kunde werden möchtet, dann schickt uns Eure Interessen über unser
<a href="https://www.ep-reisen.de/skireisen/unternehmen/kontakt/kontaktformular/" title="Kontaktformular">Kontaktformular</a>.</p>
<a href="https://www.ep-reisen.de/skireisen/unternehmen/kontakt/kontaktformular/" title="Kontaktformular">Kontaktformular</a>.
</p>
</div>
</div>
</form>
@@ -1,16 +1,12 @@
<template>
<div class="form-wrapper form--border" id="myep-main" v-show="!loading">
<h1>Newsletter</h1>
<div class="row">
<div class="col-xs-12">
<p v-html="statusMessage"></p>
<div class="form-group">
<button type="submit" class="button" :disabled="loading" @click.prevent="toggleReqistration()">
{{ userData.newsletter ? 'Abmelden' : 'Anmelden' }}
</button>
</div>
</div>
</div>
<div id="myep-main" v-show="!loading">
<h1 class="mb-4">
Newsletter
</h1>
<p class="mb-8" v-html="statusMessage"></p>
<button type="submit" class="button" :disabled="loading" @click.prevent="toggleReqistration()">
{{ userData.newsletter ? 'Abmelden' : 'Anmelden' }}
</button>
</div>
</template>
@@ -1,48 +1,34 @@
<template>
<div class="form-wrapper form--border" id="myep-main">
<h1>Registrierung MyE&amp;P</h1>
<div id="myep-main">
<h1 class="mb-4">
Registrierung MyE&amp;P
</h1>
<form @submit.prevent="register()">
<div class="row">
<div class="col-xs-12 col-md-6">
<form-group label="Vorname" :error="formErrors.firstName">
<input type="text" v-model="userData.firstName" class="form-control">
</form-group>
</div>
<div class="col-xs-12 col-md-6">
<form-group label="Name" :error="formErrors.lastName">
<input type="text" v-model="userData.lastName" class="form-control">
</form-group>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-4 mb-4">
<form-group label="Vorname" :error="formErrors.firstName">
<input type="text" v-model="userData.firstName" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="Name" :error="formErrors.lastName">
<input type="text" v-model="userData.lastName" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="E-Mail" :error="formErrors.email">
<input type="text" v-model="userData.email" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
</form-group>
<form-group label="Gender" :error="formErrors.gender">
<select v-model="userData.gender" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full">
<option value="M">M</option>
<option value="W">W</option>
<option value="D">D</option>
</select>
</form-group>
</div>
<div class="row">
<div class="col-xs-12 col-md-6">
<form-group label="E-Mail" :error="formErrors.email">
<input type="text" v-model="userData.email" class="form-control">
</form-group>
</div>
<div class="col-xs-12 col-md-6">
<form-group label="Gender" :error="formErrors.gender">
<select v-model="userData.gender" class="form-control">
<option value="M">M</option>
<option value="W">W</option>
<option value="D">D</option>
</select>
</form-group>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-6">
<div class="form-group">
<div class="btn-group">
<button type="submit" class="button" :disabled="loading">
Registrieren
</button>
<router-link to="login" class="button button--secondary">
Zum Login
</router-link>
</div>
</div>
</div>
<div class="flex flex-col lg:flex-row space-y-2 lg:space-y-0 lg:space-x-2">
<button type="submit" class="button" :disabled="loading">
Registrieren
</button>
<router-link to="login" class="button button--secondary">
Zum Login
</router-link>
</div>
</form>
</div>
@@ -1,7 +1,14 @@
<template>
<div class="relative" v-if="mutable && selectableAccommodations.length > 0">
<button class="btn btn-primary btn-sm w-full lg:w-auto" type="button" @click.prevent="visible = !visible">
Zimmer <span class="glyphicon" :class="{ 'glyphicon-chevron-up': visible, 'glyphicon-chevron-down': !visible }"></span>
<button class="button button--primary button--small w-full"
type="button"
@click.prevent="visible = !visible">
<span>
Zimmer
</span>
<svg class="w-4 h-4 transform" :class="{ 'rotate-180': visible }">
<use href="#icon-chevron-down"></use>
</svg>
</button>
<ul class="absolute top-100 left-0 z-10 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs divide-y" v-show="visible">
<li v-for="accommodation in selectableAccommodations" :key="accommodation.id" class="py-1">
@@ -1,42 +1,43 @@
<template>
<div class="panel">
<div class="panel-heading">
<h3 class="panel-title">
<a role="button" href="#" class="flex items-center justify-between" @click.prevent="expanded = !expanded">
<span>{{ title }}</span>
<i class="fa fa-chevron-right transform" :class="{ 'rotate-90': expanded }"></i>
</a>
<div class="border border-gray-200 rounded mb-4">
<div class="bg-gray-200 p-2">
<h3 class="text-base font-bold">
<a role="button" href="#" class="flex items-center justify-between"
@click.prevent="expanded = !expanded">
<span>{{ title }}</span>
<svg class="w-6 h-6 transform" :class="{ 'rotate-180': expanded }">
<use href="#icon-chevron-down"></use>
</svg>
</a>
</h3>
</div>
<div :class="{ 'hidden': !expanded }">
<div class="panel-body">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CollapsiblePanel',
data () {
return {
export default {
name: 'CollapsiblePanel',
data() {
return {
id: null,
expanded: false,
}
},
props: {
parent: {
type: String,
required: true,
},
title: {
type: String,
required: true,
}
},
mounted () {
this.id = this._uid
}
},
props: {
parent: {
type: String,
required: true,
},
title: {
type: String,
required: true,
}
},
mounted() {
this.id = this._uid
}
}
</script>
@@ -1,17 +1,10 @@
<template>
<panel title="Gebuchte Kontingente" :body="true">
<table class="table table-condensed">
<colgroup>
<col style="width: 75%">
<col style="width: 25%">
</colgroup>
<tbody>
<tr v-for="contingent in contingents" :key="contingent.id">
<th>{{ contingent.room }}</th>
<td>{{ contingent.count }}</td>
</tr>
</tbody>
</table>
<panel title="Gebuchte Kontingente">
<ul class="list-none">
<li class="p-2 border-b border-gray-200 last:border-0" v-for="contingent in contingents" :key="contingent.id">
{{ contingent.room }}: {{ contingent.count }}
</li>
</ul>
</panel>
</template>
@@ -1,8 +1,12 @@
<template>
<div class="form-group" :class="{'has-error': error }">
<label class="control-label">{{ label }}:</label>
<div class="mb-4">
<label class="block mb-1" :class="{ 'text-red-500': error }">
{{ label }}:
</label>
<slot></slot>
<span class="help-block">{{ error }}</span>
<span class="block text-sm mt-1" v-show="error">
{{ error }}
</span>
</div>
</template>
@@ -20,4 +24,4 @@
}
}
}
</script>
</script>
@@ -1,53 +1,15 @@
<template>
<panel title="Änderungen möglich bis" :body="true">
<table class="table table-condensed mb-0">
<colgroup>
<col style="width: 75%">
<col style="width: 25%">
</colgroup>
<tbody>
<tr>
<th>Unterkunft</th>
<td>
<span class="label" :class="mutableFields.accommodation.mutable ? 'label-success' : 'label-danger'">
{{ mutableFields.accommodation.mutable ? mutableFields.accommodation.until : 'keine Änderung möglich' }}
</span>
</td>
</tr>
<tr>
<th>Teilnehmer</th>
<td>
<span class="label" :class="mutableFields.participantData.mutable ? 'label-success' : 'label-danger'">
{{ mutableFields.participantData.mutable ? mutableFields.participantData.until : 'keine Änderung möglich' }}
</span>
</td>
</tr>
<tr>
<th>Leistungen</th>
<td>
<span class="label" :class="mutableFields.services.mutable ? 'label-success' : 'label-danger'">
{{ mutableFields.services.until ? mutableFields.services.until : 'keine Änderung möglich' }}
</span>
</td>
</tr>
<tr>
<th>Beförderung</th>
<td>
<span class="label" :class="mutableFields.transportation.mutable ? 'label-success' : 'label-danger'">
{{ mutableFields.transportation.until ? mutableFields.transportation.until : 'keine Änderung möglich' }}
</span>
</td>
</tr>
<tr>
<th>Zustiege</th>
<td>
<span class="label" :class="mutableFields.pickup.mutable ? 'label-success' : 'label-danger'">
{{ mutableFields.pickup.until ? mutableFields.pickup.until : 'keine Änderung möglich' }}
</span>
</td>
</tr>
</tbody>
</table>
<panel title="Änderungen möglich bis">
<ul class="list-none">
<li class="p-2 border-b border-gray-200 last:border-0" v-for="field in fields" :key="field.prop">
<strong>
{{ field.label }}:
</strong>
<span class="px-2 py-1 text-white" :class="mutableFields[field.prop].mutable ? 'bg-green-500' : 'bg-red-500'">
{{ mutableFields[field.prop].mutable ? mutableFields[field.prop].until : 'keine Änderung möglich' }}
</span>
</li>
</ul>
</panel>
</template>
@@ -56,6 +18,17 @@
export default {
name: 'MutableFields',
data() {
return {
fields: [
{ prop: 'accommodation', label: 'Unterkunft' },
{ prop: 'participantData', label: 'Teilnehmer' },
{ prop: 'services', label: 'Leistungen' },
{ prop: 'transportation', label: 'Beförderung' },
{ prop: 'pickup', label: 'Zustiege' },
]
}
},
components: {
Panel
},
@@ -1,10 +1,12 @@
<template>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ title }}</h3>
<div class="border border-gray-200 rounded mb-4">
<div class="bg-gray-200 p-2">
<h3 class="text-base font-bold">
{{ title }}
</h3>
</div>
<template v-if="body">
<div class="panel-body">
<div class="bg-white p-2">
<slot></slot>
</div>
</template>
@@ -1,33 +1,40 @@
<template>
<div class="relative">
<button class="btn btn-primary btn-sm w-full lg:w-auto" type="button" @click.prevent="visible = !visible">
Adresse/Telefon <span class="glyphicon" :class="{ 'glyphicon-chevron-up': visible, 'glyphicon-chevron-down': !visible }"></span>
<button class="button button--primary button--small w-full"
type="button"
@click.prevent="visible = !visible">
<span>
Adresse/Telefon
</span>
<svg class="w-4 h-4 transform" :class="{ 'rotate-180': visible }">
<use href="#icon-chevron-down"></use>
</svg>
</button>
<div class="absolute top-100 left-0 z-10 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs space-y-2" v-show="visible">
<input class="form-input w-full" type="text" placeholder="Straße"
<input class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full" type="text" placeholder="Straße"
v-model="participant.data.street" :disabled="!mutable"
@change="$emit('updated', participant)"
>
<input class="form-input w-full" type="text" placeholder="PLZ"
<input class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full" type="text" placeholder="PLZ"
v-model="participant.data.zipCode" :disabled="!mutable"
@change="$emit('updated', participant)"
>
<input class="form-input w-full" type="text" placeholder="Ort"
<input class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full" type="text" placeholder="Ort"
v-model="participant.data.city" :disabled="!mutable"
@change="$emit('updated', participant)"
>
<select class="form-select w-full"
<select class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full"
v-model="participant.data.country" :disabled="!mutable"
@change="$emit('updated', participant)"
>
<option value="">Land...</option>
<option v-for="country in countries" :key="country.code" :value="country.code">{{ country.name }}</option>
</select>
<input class="form-input w-full" type="text" placeholder="Telefon"
<input class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full" type="text" placeholder="Telefon"
v-model="participant.data.phonePrivate" :disabled="!mutable"
@change="$emit('updated', participant)"
>
<input class="form-input w-full" type="text" placeholder="Mobil"
<input class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full" type="text" placeholder="Mobil"
v-model="participant.data.phoneMobile" :disabled="!mutable"
@change="$emit('updated', participant)"
>
@@ -1,18 +1,18 @@
<template>
<div class="lg:flex lg:space-x-1 space-y-1 lg:space-y-0">
<input class="form-input w-full lg:w-1/6" type="text" placeholder="Nachname"
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-1">
<input class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full" type="text" placeholder="Nachname"
v-model="participant.data.lastName" :disabled="!mutable"
@change="$emit('updated', participant)"
>
<input class="form-input w-full lg:w-1/6" type="text" placeholder="Vorname"
<input class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full" type="text" placeholder="Vorname"
v-model="participant.data.firstName" :disabled="!mutable"
@change="$emit('updated', participant)"
>
<input class="form-input w-full lg:w-1/6" type="text" placeholder="E-Mail"
<input class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full" type="text" placeholder="E-Mail"
v-model="participant.data.email" :disabled="!mutable"
@change="$emit('updated', participant)"
>
<select class="form-select w-full lg:w-1/6"
<select class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full"
v-model="participant.data.gender" :disabled="!mutable"
@change="$emit('updated', participant)"
>
@@ -20,14 +20,14 @@
<option value="M">männlich</option>
<option value="D">divers</option>
</select>
<select class="form-select w-full lg:w-1/6"
<select class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full"
v-model="participant.data.nationality" :disabled="!mutable"
@change="$emit('updated', participant)"
>
<option value="">Nationalität...</option>
<option v-for="country in countries" :key="country.code" :value="country.code">{{ country.adjective }}</option>
</select>
<input type="date" class="form-input w-full lg:w-1/6" placeholder="Geburtsdatum"
<input type="date" class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full" placeholder="Geburtsdatum"
v-model="participant.data.dateOfBirth" :disabled="!mutable"
@change="$emit('updated', participant)"
>
@@ -1,7 +1,12 @@
<template>
<div class="relative" v-if="hasSelectedRentals">
<button class="btn btn-secondary btn-sm w-full lg:w-auto" @click.prevent="visible = !visible">
Größen <span class="glyphicon" :class="{ 'glyphicon-chevron-up': visible, 'glyphicon-chevron-down': !visible }"></span>
<button class="button button--primary button--small" @click.prevent="visible = !visible">
<span>
Größen
</span>
<svg class="w-4 h-4 transform" :class="{ 'rotate-180': visible }">
<use href="#icon-chevron-down"></use>
</svg>
</button>
<div class="absolute top-100 left-0 z-10 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs space-y-2" v-show="visible">
<input class="form-input w-full" type="text" placeholder="Körpergröße"
@@ -1,12 +1,18 @@
<template>
<div class="relative">
<button class="btn btn-primary btn-sm w-full lg:w-auto" @click.prevent="visible = !visible">
Zustieg <span class="glyphicon" :class="{ 'glyphicon-chevron-up': visible, 'glyphicon-chevron-down': !visible }"></span>
<button class="button button--primary button--small" @click.prevent="visible = !visible">
<span>
Zustieg
</span>
<svg class="w-4 h-4 transform" :class="{ 'rotate-180': visible }">
<use href="#icon-chevron-down"></use>
</svg>
</button>
<div class="absolute top-100 left-0 z-10 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs" v-show="visible">
<div class="py-1" v-for="pickup in pickups" :key="pickup.id">
<label class="inline-flex items-center text-sm">
<input type="radio" class="form-radio"
<input type="radio"
class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 text-ep-secondary sbw:text-sbw-secondary"
:name="'pickup-' + participant.data.id"
v-model="pickupId"
:value="pickup.busproId"
@@ -1,12 +1,18 @@
<template>
<div class="relative" v-if="hasServices">
<button class="btn btn-primary btn-sm w-full lg:w-auto" type="button" @click.prevent="visible = !visible">
{{ subType.label }} <span class="glyphicon" :class="{ 'glyphicon-chevron-up': visible, 'glyphicon-chevron-down': !visible }"></span>
<button class="button button--primary button--small" type="button" @click.prevent="visible = !visible">
<span>
{{ subType.label }}
</span>
<svg class="w-4 h-4 transform" :class="{ 'rotate-180': visible }">
<use href="#icon-chevron-down"></use>
</svg>
</button>
<div class="absolute top-100 left-0 z-10 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs" v-show="visible">
<div class="py-1" v-for="service in availableServices" :key="service.id">
<label class="inline-flex items-center text-sm">
<input type="checkbox" class="form-checkbox"
<input type="checkbox"
class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 text-ep-secondary sbw:text-sbw-secondary"
v-model="participant.serviceIds"
:value="service.id"
:disabled="false === isServiceSelectable(service)"
@@ -1,11 +1,11 @@
<template>
<panel title="Gebuchte Zusatzleistungen">
<ul class="list-group" v-show="hasServiceAssignments">
<li class="list-group-item" v-for="(assignment, serviceId) in serviceAssignments">
<ul class="list-none" v-show="hasServiceAssignments">
<li class="p-2 border-b border-gray-200 last:border-0" v-for="(assignment, serviceId) in serviceAssignments">
{{ services[serviceId].name }}: {{ assignment.length }}
</li>
</ul>
<div class="panel-body" v-show="!hasServiceAssignments">
<div class="bg-white p-2" v-show="!hasServiceAssignments">
<span>keine</span>
</div>
</panel>
@@ -1,14 +1,18 @@
<template>
<div v-if="hasServices">
<label v-for="service in services" :key="service.id" class="flex items-center mb-1">
<input type="checkbox" class="form-checkbox"
<div class="flex flex-col space-y-2" v-if="hasServices">
<label class="flex items-center"
v-for="service in services" :key="service.id">
<input type="checkbox"
class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 text-ep-secondary sbw:text-sbw-secondary"
v-model="selectedTransportationIds"
:value="service.id"
:disabled="isServiceUnavailable(service) || !mutable"
@change="selectService(service, $event)"
>
<span class="ml-2">{{ service.name }}</span>
@change="selectService(service, $event)"/>
<span class="ml-2">
{{ service.name }}
</span>
</label>
</div>
</template>
@@ -14,16 +14,16 @@ const guard = (to, from, next) => {
}
};
import Address from '../myep/Address'
import Events from '../myep/Events'
import Login from '../myep/Login'
import CrmData from '../myep/CrmData'
import Newsletter from '../myep/Newsletter'
import Registration from '../myep/Registration'
import Address from '../Address'
import Events from '../Events'
import Login from '../Login'
import CrmData from '../CrmData'
import Newsletter from '../Newsletter'
import Registration from '../Registration'
// Lazy load some components when they become required
const Teamer = () => import('../myep/Teamer')
const BookingEdit = () => import('../myep/BookingEdit')
const Teamer = () => import('../Teamer')
const BookingEdit = () => import('../BookingEdit')
export default new VueRouter({
routes: [
@@ -1,9 +1,15 @@
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import authenticatedClient from "../api";
import authenticatedClient from '../api'
Vue.use(Vuex);
const configElement = document.getElementById('appconfig')
const config = JSON.parse(configElement.innerHTML)
axios.defaults.baseURL = config.myEpApiBaseUrl
authenticatedClient.defaults.baseURL = config.myEpApiBaseUrl
Vue.use(Vuex)
const defaultUserData = {
isTeamer: false,
@@ -42,13 +48,13 @@ export default new Vuex.Store({
}
},
initConfig(state) {
const configElement = document.getElementById('appconfig');
state.config = JSON.parse(configElement.innerHTML);
axios.defaults.baseURL = state.config.myEpApiBaseUrl;
state.config = config
},
setUserData(state, data) {
data.watchList = [...state.userData.watchList, ...data.watchList];
state.userData = data;
if (state.userData.watchList) {
data.watchList = [...state.userData.watchList, ...data.watchList]
}
state.userData = data
},
login(state, data) {
state.authToken = data.token;
@@ -1,7 +1,7 @@
.button {
@apply inline-block px-4 py-2 md:px-8;
@apply uppercase text-center outline-none focus:outline-none;
@apply transition-colors;
@apply inline-flex items-center justify-center px-4 py-2 md:px-8;
@apply uppercase leading-none;
@apply transition-colors outline-none focus:outline-none;
@apply bg-ep-secondary text-white;
&--active,
@@ -22,4 +22,8 @@
@apply bg-white border-ep-secondary text-ep-secondary;
}
}
&--small {
@apply px-2 py-1 md:px-4 text-sm;
}
}
@@ -1,10 +1,9 @@
<f:format.raw>
<script type="application/json" id="appconfig">
{
"loaderUrl": "{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif', absolute: 1)}",
"myEpApiBaseUrl": "{settings.myEpApiEndpointUrl}",
"paCode": <f:if condition='{context.paCode}'><f:then>"{context.paCode}"</f:then><f:else>null</f:else></f:if>,
"externalDomains": {settings.domainsToTrack -> v:iterator.explode() -> f:format.json() -> f:format.raw()}
}
</script>
</f:format.raw>
<script type="application/json" id="appconfig">
{
"loaderUrl": "<f:format.raw>{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif', absolute: 1)}</f:format.raw>",
"myEpApiBaseUrl": "<f:format.raw>{settings.myEpApiEndpointUrl}</f:format.raw>",
"paCode": <f:if condition='{context.paCode}'><f:then>"{context.paCode}"</f:then><f:else>null</f:else></f:if>,
"externalDomains": <f:format.raw>{settings.domainsToTrack -> v:iterator.explode() -> f:format.json() -> f:format.raw()}</f:format.raw>
}
</script>
@@ -17,7 +17,7 @@
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.name">
<span x-bind:class="formErrors.name ? 'text-red-500' : 'text-gray-700'">Name*</span>
<f:form.textfield class="border-gray-400 focus:border-gray-800 mt-1 w-full" property="name"/>
<f:form.textfield class="border-gray-400 focus:border-gray-800 ring-0 focus:ring-0 mt-1 w-full" property="name"/>
<div class="text-red-500 mt-2" x-show="formErrors.name" x-html="formErrors.name"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.firstName">
+1
View File
@@ -97,6 +97,7 @@ module.exports = {
variants: {
extend: {
backgroundColor: [ 'sbw', 'sbw-hover', 'snz', 'snz-hover', 'uch', 'uch-hover', 'even', 'odd' ],
borderWidth: [ 'even', 'odd', 'first', 'last' ],
textColor: [ 'sbw', 'sbw-hover', 'snz', 'snz-hover', 'uch', 'uch-hover' ],
borderColor: [ 'sbw','snz', 'uch' ],
display: ['group-hover'],
+1
View File
@@ -9,6 +9,7 @@ Encore
.setOutputPath('./public/typo3conf/ext/ep_theme/Resources/Public/')
.setPublicPath('/typo3conf/ext/ep_theme/Resources/Public/')
.addEntry('main', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/main.js')
.addEntry('myep', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/myep.js')
.addStyleEntry('rte', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/scss/rte.scss')
.addExternals({
jquery: 'jQuery',