targo-frontend/src/modules/timesheets/components/mobile/expense-dialog-list-item-mobile.vue

183 lines
7.2 KiB
Vue

<script
setup
lang="ts"
>
/* eslint-disable */
import { date, useQuasar } from 'quasar';
import { computed, ref } from 'vue';
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
import { useExpensesApi } from 'src/modules/timesheets/composables/use-expense-api';
import { useExpensesStore } from 'src/stores/expense-store';
import { getExpenseIcon } from 'src/modules/timesheets/utils/expense.util';
import type { Expense } from 'src/modules/timesheets/models/expense.models';
import ExpenseDialogFormMobile from 'src/modules/timesheets/components/mobile/expense-dialog-form-mobile.vue';
// =========== state =====================================
const expense = defineModel<Expense>({ required: true })
const q = useQuasar();
const expenses_store = useExpensesStore();
const expenses_api = useExpensesApi();
const is_showing_update_form = ref(false);
const is_showing_delete_confirm = ref(false);
// =========== computed ==================================
const approved_class = computed(() => expense.value.is_approved ? ' bg-accent text-white' : '')
const primaryColor = computed(() => q.dark.isActive ? 'blue-grey-3' : 'primary')
// =========== methods ===================================
const requestExpenseDeletion = async () => {
showDeleteConfirmation(false);
await expenses_api.deleteExpenseById(expense.value.id);
}
const onUpdateClicked = () => {
if (expense.value.is_approved) return;
expenses_store.mode = 'update';
expenses_store.current_expense = expense.value;
expenses_store.initial_expense = unwrapAndClone(expense.value);
}
const showDeleteConfirmation = (state: boolean) => {
is_showing_delete_confirm.value = state;
}
</script>
<template>
<div class="column bg-dark shadow-5 rounded-5 q-my-sm full-width">
<!-- expense deletion confirmation -->
<q-dialog
v-model="is_showing_delete_confirm"
backdrop-filter="blur(4px)"
class="z-max"
>
<div class="column rounded-5 bg-dark">
<span class="col text-uppercase text-weight-light text-h6 q-py-sm q-px-md">
{{ $t('timesheet.expense.actions.delete_confirm') }}
</span>
<div class="row col">
<q-btn
flat
dense
square
size="lg"
color="negative"
:label="$t('shared.misc.no')"
class="col"
@click="showDeleteConfirmation(false)"
/>
<q-btn
flat
dense
square
size="lg"
color="accent"
:label="$t('shared.misc.yes')"
class="col"
@click="requestExpenseDeletion"
/>
</div>
</div>
</q-dialog>
<q-expansion-item
v-model="is_showing_update_form"
hide-expand-icon
dense
group="expenses"
header-class="q-px-none"
class="rounded-5"
:class="expense.is_approved ? ' bg-accent text-white' : ''"
@before-show="onUpdateClicked()"
>
<template #header>
<div class="row full-width">
<div class="column col q-px-sm q-py-xs">
<!-- date label and delete button -->
<div class="col-auto row items-center q-pl-xs">
<q-icon
name="calendar_month"
size="sm"
class="col-auto"
/>
<span
class="col text-uppercase text-weight-light full-width q-pl-sm text-h6"
:class="approved_class"
>
{{ $d(
date.extractDate(expense.date, 'YYYY-MM-DD'),
{ month: 'long', day: 'numeric' }
) }}
</span>
<q-btn
flat
dense
icon="las la-trash"
:color="primaryColor"
size="lg"
class="col-auto bg-dark q-px-xs"
style="border-radius: 0 2px 2px 0;"
@click.stop="showDeleteConfirmation(true)"
/>
</div>
<div class="col row full-width items-center q-px-xs">
<!-- avatar type icon section -->
<q-icon
:name="getExpenseIcon(expense.type)"
size="lg"
class="col-auto q-pr-sm"
/>
<!-- amount or mileage section -->
<div class="col text-weight-bold text-h6">
<q-item-label v-if="expense.type === 'MILEAGE'">
{{ expense.mileage?.toFixed(1) }} km
</q-item-label>
<q-item-label v-else>
$ {{ expense.amount.toFixed(2) }}
</q-item-label>
</div>
</div>
<!-- attachment file -->
<div class="col-auto q-pa-xs full-width">
<q-btn
:color="expense.is_approved ? 'white' : 'accent'"
:text-color="expense.is_approved ? 'accent' : 'white'"
icon="las la-paperclip"
:label="expense.attachment_name ?? `( ${$t('shared.label.empty')} )`"
class="full-width text-lowercase q-mx-sm q-px-sm q-pb-sm inset-shadow"
/>
</div>
</div>
<q-icon
v-if="expense.is_approved"
name="verified"
color="white"
size="lg"
class="full-height q-px-none"
/>
</div>
</template>
<div class="q-px-sm">
<ExpenseDialogFormMobile
v-model="expense"
@on-update-clicked="is_showing_update_form = false"
/>
</div>
</q-expansion-item>
</div>
</template>