|
- <template>
- <div class="dark">
- <div v-if="reservations" class="stats">
- <h1>
- {{reservations.length}} active reservations
- </h1>
- <h2>
- {{invalidatedCount}} invalidated<br>
- {{validCount}} to go
- </h2>
- </div>
- <div class="guest-table">
- <vuetable v-if="reservations"
- :fields="fields"
- :api-mode="false"
- :data="reservations"
- :sort-order="sortOrder"
- :show-sort-icons="true"
- >
- <template v-slot:timestamp="props">
- <template v-if="props.rowData.timestamp">
- {{new Date(props.rowData.timestamp).toLocaleString('de-DE', {day:'numeric',month:'numeric',hour:'numeric',minute:'numeric'})}}
- </template>
- </template>
- <template v-slot:invalidated="props">
- <template v-if="props.rowData.invalidated">
- {{new Date(props.rowData.invalidated).toLocaleString('de-DE', {day:'numeric',month:'numeric',hour:'numeric',minute:'numeric'})}}
- </template>
- <button v-else @click="invalidate(props.rowData.token)">invalidate</button>
- </template>
- <template v-slot:actions="props">
- <button @click="cancel(props.rowData.token)">cancel</button>
- </template>
- <template v-slot:headsup_sent="props">
- <template v-if="props.rowData.headsup_sent">
- {{new Date(props.rowData.headsup_sent).toLocaleString('de-DE', {day:'numeric',month:'numeric',hour:'numeric',minute:'numeric'})}}
- </template>
- <button @click="sendHeadsup(props.rowData.id)">X</button>
- </template>
- </vuetable>
- </div>
- <label for="showSensitiveData">
- <input type="checkbox" name="showSensitiveData" id="showSensitiveData" :value="showSensitiveData" @change="showSensitiveData = !showSensitiveData">
- show sensitive data
- </label>
- <div class="add-guest-form">
-
- <form class="input-form" @submit.prevent="onAddGuest">
- <div class="input-headline">add new reservation</div>
- <input class="input-text" v-model="anzeigename" placeholder="nickname (public)" />
- <input class="input-text" v-model="name" placeholder="real name" />
- <input class="input-text" v-model="email" placeholder="email" />
- <input class="input-btn" type="submit" :value="(addGuestSending ? 'sending ...' : 'reserve')" :disabled="(addGuestSending ? true : false)" />
- <div v-if="addGuestError">
- oh no something went wrong!<br>
- {{addGuestError.detail}}
- </div>
- </form>
- <button @click="sendHeadsups">SEND ALL EMAILS</button>
-
-
-
- </div>
- <!-- {{reservations}} -->
- </div>
- </template>
-
- <script>
- import Vuetable from 'vuetable-2'
- export default {
- name: 'Reservations',
- components: {
- Vuetable
- },
- data() {
- return {
- reservations: null,
- sortOrder: [
- {
- field: 'name',
- direction: 'asc',
- }
- ],
- showSensitiveData: false,
- addGuestSending: false,
- addGuestError: null,
- anzeigename: '',
- name: '',
- email: '',
- }
- },
- computed: {
- secret () {
- return this.$route.params.secret
- },
- invalidatedCount () {
- if (this.reservations && this.reservations.length) {
- const filtered = this.reservations.filter(r => !!r.invalidated)
- return filtered.length
- }
- return null
- },
- validCount () {
- if (this.reservations && this.reservations.length) {
- const filtered = this.reservations.filter(r => !r.invalidated)
- return filtered.length
- }
- return null
- },
- fields () {
- if (this.showSensitiveData) {
- return ['id','timestamp', 'anzeigename', 'name', 'email', 'token', 'invalidated','actions', 'headsup_sent']
- } else {
- return ['id','timestamp', 'anzeigename', 'invalidated','actions', 'headsup_sent']
- }
- }
- },
- methods: {
- async getReservations() {
- const response = await fetch(`${process.env.VUE_APP_API_URL}guest/management/${this.$route.params.secret}`)
- const data = await response.json()
- this.reservations = data
- },
- async cancel(token) {
- let data = { token }
- const response = await fetch(
- `${process.env.VUE_APP_API_URL}guest/cancel`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(data),
- }
- )
- if (response.status === 200) {
- this.getReservations()
- } else {
- alert(await response.json())
- }
- },
- async invalidate(token) {
- let data = { token }
- const response = await fetch(
- `${process.env.VUE_APP_API_URL}guest/invalidate`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(data),
- }
- )
- if (response.status === 200) {
- this.getReservations()
- } else {
- alert(await response.json())
- }
- },
-
- async sendHeadsup(id) {
- let data = {
- guest_id: id,
- secret: this.secret
- }
- const response = await fetch(
- `${process.env.VUE_APP_API_URL}guest/management/send_headsup`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(data),
- }
- )
- if (response.status === 200) {
- this.getReservations()
- } else {
- alert(await response.json())
- }
-
- },
-
- async sendHeadsups() {
- let data = {
- secret: this.secret
- }
- const response = await fetch(
- `${process.env.VUE_APP_API_URL}guest/management/send_headsups`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(data),
- }
- )
- if (response.status === 200) {
- this.getReservations()
- } else {
- alert(await response.json())
- }
-
- },
-
- async onAddGuest() {
- if (this.name.length == 0) {
- return false
- }
- this.addGuestSending = true
- let data = {
- anzeigename: this.anzeigename,
- name: this.name,
- email: this.email,
- newsletter: false,
- }
- const response = await fetch(
- `${process.env.VUE_APP_API_URL}guest`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(data),
- }
- )
- if (response.status === 200) {
- this.anzeigename = ''
- this.name = ''
- this.email = ''
- this.getReservations()
- } else {
- this.getReservations()
- this.addGuestError = true
- this.addGuestError = await response.json()
- }
- this.addGuestSending = false
- return false
- },
-
-
-
- },
- mounted () {
- this.getReservations()
- },
- }
- </script>
-
- <style>
- .stats {
- display: flex;
- flex-direction: column;
- align-items: center;
- }
-
- .vuetable thead {
- background-color: rgb(255, 0, 0);
- }
-
- .vuetable-body tr {
- border-bottom: 1px dashed rgb(255, 0, 0);
- }
- .vuetable-body tr:hover {
- background-color: rgba(255, 0, 0, 0.281)
- }
-
- .vuetable-body td {
- padding: .5em;
- margin: 0;
- }
-
- .guest-table {
- display: flex;
- flex-direction: column;
- align-items: center;
- }
-
-
- .add-guest-form {
- display: flex;
- flex-direction: column;
- align-items: center;
- margin-top: 120px
- }
-
- button {
- background: #fff;
- color: #000;
- border: none;
- text-transform: uppercase;
- cursor: pointer;
- font-size: 18px;
- font-family: inherit;
- }
- button:hover {
- background: #ff0;
- color: #000;
- }
- </style>
|