<template> <div> <q-card flat square> <q-card-section class="row items-center justify-between" horizontal> <div class="col-5 text-left q-px-sm"> <div :class="{ 'text-negative': isNegative() }" class="text-weight-bold text-h6"> <span v-if="isNegative()">-</span>{{ transaction.amount.toFixed(2) }} € </div> <div class="text-caption">{{ text }}</div> <div class="text-caption">{{ timeStr }}</div> </div> <div class="col-5 q-px-sm text-center"> <div class="text-subtitle1" v-if="isReversed">Storniert</div> </div> <div class="col-2 q-pr-sm" style="text-align: right"> <q-btn :color="isReversed ? 'positive' : 'negative'" aria-label="Reverse transaction" :icon="!isReversed ? 'mdi-trash-can' : 'mdi-check-bold'" size="sm" round :disable="!canReverse" @click="reverse" /> </div> </q-card-section> </q-card> <q-separator /> </div> </template> <script lang="ts"> import { ref, computed, defineComponent, onUnmounted, onMounted, PropType } from 'vue'; import { hasPermission } from 'src/utils/permission'; import { formatDateTime } from 'src/utils/datetime'; import { mapGetters, Store, useStore } from 'vuex'; import { StateInterface } from 'src/store'; export default defineComponent({ name: 'Transaction', props: { transaction: { required: true, type: Object as PropType<FG.Transaction>, }, }, emits: { 'update:transaction': (t: FG.Transaction) => !!t }, watch: { transaction: 'refreshText' }, setup(props, { emit }) { const now = ref(Date.now()); const ival = setInterval(() => (now.value = Date.now()), 1000); const store = useStore<Store<StateInterface>>(); const userGetters = mapGetters('users', ['currentUser']); const text = ref(''); onUnmounted(() => clearInterval(ival)); onMounted(() => refreshText()); const isNegative = () => props.transaction.sender_id === (<FG.User>userGetters.currentUser())?.userid; const refreshText = async () => { if (isNegative()) { text.value = 'Anschreiben'; if (props.transaction.receiver_id !== null) { const user = <FG.User>await store.dispatch('user/getUser', { userid: props.transaction.receiver_id, }); text.value = `Gesendet an ${user.display_name}`; } } else { text.value = 'Gutschrift'; if (props.transaction.sender_id !== null) { const user = <FG.User>await store.dispatch('user/getUser', { userid: props.transaction.sender_id, }); text.value = `Bekommen von ${user.display_name}`; } } }; const isReversed = computed( () => props.transaction.reversal_id != undefined || props.transaction.original_id != undefined ); const canReverse = computed( () => !isReversed.value && (hasPermission('balance_reversal') || (props.transaction.sender_id === (<FG.User>userGetters.currentUser())?.userid && now.value - props.transaction.time.getTime() < 10000)) ); function reverse() { if (canReverse.value) store .dispatch('balance/revert', props.transaction) .then(() => { emit('update:transaction', props.transaction); }) .catch((error) => console.log(error)); } const timeStr = computed(() => { const elapsed = (now.value - props.transaction.time.getTime()) / 1000; if (elapsed < 60) return `Vor ${elapsed.toFixed()} s`; return formatDateTime(props.transaction.time, elapsed > 12 * 60 * 60, true, true) + ' Uhr'; }); return { timeStr, reverse, isNegative, text, refreshText, canReverse, isReversed }; }, }); </script>