140 lines
3.3 KiB
Vue
140 lines
3.3 KiB
Vue
<script setup>
|
|
import { onMounted, ref, computed } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { toCurrency } from 'filters/index';
|
|
|
|
const { t } = useI18n();
|
|
|
|
const props = defineProps({
|
|
quantity: {
|
|
type: Number,
|
|
required: true,
|
|
},
|
|
price: {
|
|
type: Number,
|
|
required: true,
|
|
},
|
|
discount: {
|
|
type: Number,
|
|
required: false,
|
|
default: 0,
|
|
},
|
|
mana: {
|
|
type: Number,
|
|
required: true,
|
|
},
|
|
promise: {
|
|
type: Function,
|
|
required: true,
|
|
},
|
|
data: {
|
|
type: Object,
|
|
required: false,
|
|
default: null,
|
|
},
|
|
});
|
|
|
|
const emit = defineEmits(['onUpdate']);
|
|
|
|
const discount = ref(0); // eslint-disable-line vue/no-dupe-keys
|
|
let canceller;
|
|
|
|
onMounted(() => {
|
|
if (props.discount) {
|
|
discount.value = props.discount;
|
|
}
|
|
});
|
|
|
|
const total = computed(() => {
|
|
const amount = props.price * props.quantity;
|
|
const appliedDiscount = (discount.value * amount) / 100;
|
|
|
|
return amount - appliedDiscount;
|
|
});
|
|
|
|
const newAmount = computed(() => `${t('New amount')}: ${toCurrency(total.value)}`);
|
|
|
|
const isLoading = ref(false);
|
|
async function save({ set }) {
|
|
isLoading.value = true;
|
|
const response = {
|
|
...props.data,
|
|
...{
|
|
discount: parseInt(discount.value),
|
|
},
|
|
};
|
|
if (props.promise) {
|
|
canceller = new AbortController();
|
|
Object.assign(response, { canceller });
|
|
|
|
await props.promise(response);
|
|
}
|
|
|
|
if (set) set();
|
|
emit('onUpdate', response);
|
|
isLoading.value = false;
|
|
}
|
|
|
|
function cancel({ cancel }) {
|
|
if (canceller) {
|
|
canceller.abort();
|
|
canceller = null;
|
|
}
|
|
|
|
discount.value = props.discount;
|
|
if (isLoading.value === true) isLoading.value = false;
|
|
if (cancel) cancel();
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<QPopupEdit
|
|
v-model="discount"
|
|
v-slot="scope"
|
|
:title="t('Update discount')"
|
|
@cancel="cancel"
|
|
>
|
|
<QBanner class="bg-primary text-center q-mb-md" rounded dense>
|
|
{{ t('Mana') }} {{ toCurrency(props.mana) }}
|
|
</QBanner>
|
|
<QInput
|
|
v-model="scope.value"
|
|
type="number"
|
|
dense
|
|
autofocus
|
|
@keyup.enter="save(scope)"
|
|
@update:model-value="discount = scope.value"
|
|
@focus="($event) => $event.target.select()"
|
|
min="0"
|
|
max="100"
|
|
:disable="isLoading"
|
|
:hint="newAmount"
|
|
:rules="[
|
|
(value) => value.length > 0 || t('Enter a value'),
|
|
(value) => (value >= 0 && value <= 100) || t('Invalid discount amount'),
|
|
]"
|
|
/>
|
|
<QCardActions class="q-px-none q-mt-sm" align="right">
|
|
<QBtn :label="t('Cancel')" color="primary" flat @click="cancel(scope)" />
|
|
<QBtn
|
|
:label="t('Update')"
|
|
color="primary"
|
|
:loading="isLoading"
|
|
unelevated
|
|
@click="save(scope)"
|
|
/>
|
|
</QCardActions>
|
|
</QPopupEdit>
|
|
</template>
|
|
|
|
<i18n>
|
|
es:
|
|
New amount: Nuevo importe
|
|
Update discount: Actualizar descuento
|
|
Mana: Maná
|
|
Enter a value: Introduce un valor
|
|
Invalid discount amount: Cantidad de descuento incorrecta
|
|
Cancel: Cancelar
|
|
Update: Actualizar
|
|
</i18n>
|