<template> <div> <v-dialog v-model="checkValidate" max-width="290"> <v-card> <v-card-title> Willst du wirklich?? </v-card-title> <v-card-text v-if="stornoMessage"> Willst du wirklich den Betrag {{ (stornoMessage.amount / 100).toFixed(2) }}€ von {{ stornoMessage.user.firstname }} {{ stornoMessage.user.lastname }} stornieren? </v-card-text> <v-card-actions> <v-spacer /> <v-btn text @click="cancelStorno">Abbrechen</v-btn> <v-btn text @click="acceptStorno">Stornieren</v-btn> </v-card-actions> </v-card> </v-dialog> <v-dialog v-model="dialog" max-width="290"> <v-card> <v-card-title class="headline" >Transaktion ist länger als 1 Minute her!</v-card-title > <v-card-text> Da die Transaktion länger als 1 Minuter her ist, kann eine Stornierung nicht durchgeführt werden. Wende dich bitte an den Finanzer. </v-card-text> <v-card-actions> <v-spacer /> <v-btn text @click="dialog = false"> Verstanden </v-btn> </v-card-actions> </v-card> </v-dialog> <v-progress-linear v-if="loading && users.length !== 0" indeterminate /> <v-container> <AddAmountSkeleton v-if="loading && users.length === 0" /> </v-container> <v-navigation-drawer v-model="menu" right app clipped> <v-list-item-group :key="componentRenderer"> <v-list-item inactive> <v-list-item-title class="headline"> Verlauf </v-list-item-title> </v-list-item> <v-divider /> <div v-for="message in messages" three-line :key="messages.indexOf(message)" > <v-list-item three-line inactive @click="storno(message)"> <v-list-item-content> <v-progress-linear indeterminate v-if="message.loading" /> <v-list-item-title>{{ now(message.date) }}</v-list-item-title> <v-list-item-subtitle>{{ createMessage(message) }}</v-list-item-subtitle> <v-list-item-subtitle class="red--text" v-if="message.storno" >STORNIERT!!!</v-list-item-subtitle > <v-list-item-action-text v-if="under5minutes(message.date)" >Klicken um zu Stornieren </v-list-item-action-text> </v-list-item-content> </v-list-item> </div> </v-list-item-group> </v-navigation-drawer> <div v-for="user in users" :key="users.indexOf(user)"> <div v-if="isFiltered(user) && calcLastSeen(user)"> <v-container> <v-card :loading="user.loading"> <v-card-title> <v-list-item-title class="title" >{{ user.firstname }} {{ user.lastname }}</v-list-item-title > </v-card-title> <v-card-subtitle v-if="user.limit + user.amount > 0"> Nur noch {{ ((user.limit + user.amount) / 100).toFixed(2) }} € übrig!! </v-card-subtitle> <v-card-text> <v-row> <v-col cols="10"> <v-row> <v-col cols="6" xs="5" sm="4"> <v-btn class="creditBtn" block @click=" addAmount({ username: user.username, amount: 200, user: user }) " :color="color" :disabled="user.locked" >2 € </v-btn> </v-col> <v-col cols="6" xs="5" sm="4"> <v-btn class="creditBtn" block @click=" addAmount({ username: user.username, amount: 100, user: user }) " :color="color" :disabled="user.locked" >1 € </v-btn> </v-col> <v-col cols="6" xs="5" sm="4"> <v-btn class="creditBtn" block @click=" addAmount({ username: user.username, amount: 50, user: user }) " :color="color" :disabled="user.locked" >0,50 € </v-btn> </v-col> <v-col cols="6" xs="5" sm="4"> <v-btn class="creditBtn" block @click=" addAmount({ username: user.username, amount: 40, user: user }) " :color="color" :disabled="user.locked" >0,40 € </v-btn> </v-col> <v-col cols="6" xs="5" sm="4"> <v-btn class="creditBtn" block @click=" addAmount({ username: user.username, amount: 20, user: user }) " :color="color" :disabled="user.locked" >0,20 € </v-btn> </v-col> <v-col cols="6" xs="5" sm="4"> <v-btn class="creditBtn" block @click=" addAmount({ username: user.username, amount: 10, user: user }) " :color="color" :disabled="user.locked" >0,10 € </v-btn> </v-col> <v-col cols="8"> <v-text-field outlined type="number" v-model="user.value" label="Benutzerdefinierter Betrag" :disabled="user.locked" ></v-text-field> </v-col> <v-col cols="4"> <v-btn fab :color="color" @click="addAmountMore(user)" :disabled="user.locked" > <v-icon>{{ plus }}</v-icon> </v-btn> </v-col> </v-row> </v-col> <v-col align-self="center"> <v-row> <v-list-item> <v-list-item-action-text :class="getColor(user.type)" >{{ (user.amount / 100).toFixed(2) }} €</v-list-item-action-text > </v-list-item> </v-row> </v-col> </v-row> <v-alert v-if="user.locked" type="error" >{{ user.firstname }} darf nicht mehr anschreiben. {{ user.firstname }} sollte sich lieber mal beim Finanzer melden.</v-alert > </v-card-text> </v-card> <v-snackbar v-for="message in messages" :key="messages.indexOf(message)" :color="message.error ? 'error' : 'success'" bottom :timeout="0" :multi-line="true" v-model="message.visible" > {{ createMessage(message) }} </v-snackbar> </v-container> </div> </div> </div> </template> <script> import { mapGetters, mapActions } from 'vuex' import { mdiPlus } from '@mdi/js' import AddAmountSkeleton from '../user/Skeleton/AddAmountSkeleton' export default { name: 'CreditLists', components: { AddAmountSkeleton }, props: {}, data() { return { plus: mdiPlus, value: null, color: 'green accent-4', menu: true, dialog: false, componentRenderer: 0, timer: '', stornoMessage: null, checkValidate: false } }, created() { this.menu = this.menu_from_store this.getUsers() this.timer = setInterval(this.forceRender, 1000) }, methods: { ...mapActions({ addAmount: 'barUsers/addAmount', getUsers: 'barUsers/getUsers', deactivate: 'barUsers/deactivateMenu', commitStorno: 'barUsers/storno' }), forceRender() { this.componentRenderer += 1 }, getColor(type) { return type === 'credit' ? 'title green--text' : 'title red--text' }, isFiltered(user) { try { var filters = this.filter.split(' ') if (filters.length === 1) { if ( user.firstname.toLowerCase().includes(filters[0].toLowerCase()) || user.lastname.toLowerCase().includes(filters[0].toLowerCase()) ) { return true } } else if (filters.length > 1) { if ( user.firstname.toLowerCase().includes(filters[0].toLowerCase()) && user.lastname.toLowerCase().includes(filters[1].toLowerCase()) ) { return true } } return false } catch (e) { return true } }, addAmountMore(user) { this.addAmount({ username: user.username, amount: Math.round(Math.abs(user.value * 100)), user: user }) setTimeout(() => { user.value = null }, 300) }, storno(message) { if (!message.error) { if (!this.under5minutes(message.date)) this.dialog = true else { this.checkValidate = true this.stornoMessage = message } } }, acceptStorno() { this.commitStorno({ username: this.stornoMessage.user.username, amount: this.stornoMessage.amount, date: this.stornoMessage.date }) setTimeout(() => { this.cancelStorno() }, 300) }, cancelStorno() { this.stornoMessage = null this.checkValidate = null }, createMessage(message) { var text = '' if (message.error) { text = 'Konnte ' + (message.amount / 100).toFixed(2) + '€ zu ' + message.user.firstname + ' ' + message.user.lastname + ' hinzufügen.' } else { text = '' + (message.amount / 100).toFixed(2) + '€ wurde zu ' + message.user.firstname + ' ' + message.user.lastname + ' hinzugefügt.' } return text }, calcLastSeen(user) { if (user.last_seen) { let date = new Date() if (((date - user.last_seen)/1000/60/60) < 72) { return true } } return false } }, computed: { ...mapGetters({ users: 'barUsers/users', filter: 'barUsers/filter', loading: 'barUsers/usersLoading', messages: 'barUsers/messages', menu_from_store: 'barUsers/menu' }), under5minutes() { return now => { var actual = new Date() return actual - now < 60000 } }, now() { return now => { var actual = new Date() var zero = new Date(0) var date = new Date(actual - now) if (date.getFullYear() === zero.getFullYear()) { if (date.getMonth() === zero.getMonth()) { if (date.getDate() === zero.getDate()) { if (date.getHours() === zero.getDate()) { if (date.getMinutes() < 1) { return 'vor ' + date.getSeconds() + ' Sekunden' } else if (date.getMinutes() < 10) { return 'vor ' + date.getMinutes() + ' Minuten' } else { return ( (now.getHours() < 10 ? '0' : '') + now.getHours() + ':' + (now.getMinutes() < 10 ? '0' : '') + now.getMinutes() ) } } else { return ( (now.getHours() < 10 ? '0' : '') + now.getHours() + ':' + (now.getMinutes() < 10 ? '0' : '') + now.getMinutes() ) } } } } return ( now.getDate() + '.' + now.getMonth() + '.' + now.getFullYear() + ' ' + (now.getHours() < 10 ? '0' : '') + now.getHours() + ':' + (now.getMinutes() < 10 ? '0' : '') + now.getMinutes() ) } } }, watch: { menu(newValue) { if (!newValue) this.deactivate() }, menu_from_store() { this.menu = this.menu_from_store } }, beforeDestroy() { clearInterval(this.timer) } } </script> <style scoped> .creditBtn { margin: 2px; } </style>