flaschengeist-frontend/src/components/baruser/CreditLists.vue

466 lines
15 KiB
Vue

<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-if="!user.locked">
<v-col cols="10">
<v-row>
<v-col cols="6" xs="5" sm="4">
<v-btn
class="creditBtn"
block
@click="addingAmount(user, 200)"
:color="color"
:disabled="user.locked"
>2 €
</v-btn>
</v-col>
<v-col cols="6" xs="5" sm="4">
<v-btn
class="creditBtn"
block
@click="addingAmount(user, 100)"
:color="color"
:disabled="user.locked"
>1 €
</v-btn>
</v-col>
<v-col cols="6" xs="5" sm="4">
<v-btn
class="creditBtn"
block
@click="addingAmount(user, 50)"
: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="addingAmount(user, 40)"
: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="addingAmount(user, 20)"
: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="addingAmount(user, 10)"
: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-content class="text-center">
<v-list-item-action-text :class="getColor(user.type)"
>{{
(user.amount / 100).toFixed(2)
}}
</v-list-item-action-text>
<v-list-item-action-text v-if="user.toSetAmount">
- {{(user.toSetAmount / 100).toFixed(2)}}
</v-list-item-action-text>
</v-list-item-content>
</v-list-item>
</v-row>
</v-col>
</v-row>
<v-row>
<v-col class="hidden-sm-and-down" cols="8">
<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-col>
<v-col align-self="center" v-if="user.locked">
<v-row>
<v-list-item>
<v-list-item-content class="text-center">
<v-list-item-action-text :class="getColor(user.type)"
>{{
(user.amount / 100).toFixed(2)
}}
</v-list-item-action-text
>
</v-list-item-content>
</v-list-item>
</v-row>
</v-col>
</v-row>
</v-card-text>
</v-card>
<v-snackbar
color="success"
bottom
:timeout="0"
:multi-line="true"
:value="messages.length > 0 ? messages[0].visible : test"
vertical
>
<v-list-item v-for="message in messages"
:key="messages.indexOf(message)"
style="background-color: #4CAF50;"
v-show="message.visible">
<v-list-item-content>
<v-list-item-title style="color: white">
{{ createMessage(message) }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</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,
test: null
}
},
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'
}),
addingAmount(user, amount) {
clearTimeout(user.timeout)
user.toSetAmount = user.toSetAmount ? user.toSetAmount + amount : amount
user.timeout = setTimeout(() => {
this.addAmount({username: user.username,
amount: user.toSetAmount,
user: user})
setTimeout(() => {
user.toSetAmount = null
}, 300)
}, 2000)
},
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>