mirror of
https://github.com/beak-insights/felicity-lims.git
synced 2025-02-23 16:33:11 +08:00
190 lines
6.7 KiB
Vue
190 lines
6.7 KiB
Vue
<script setup lang="ts">
|
|
import { ref, watch, defineAsyncComponent, onMounted, computed } from "vue";
|
|
import { ADD_VOUCHER_CODE, EDIT_VOUCHER_CODE } from '@/graphql/operations/billing.mutations';
|
|
import { storeToRefs } from "pinia"
|
|
import { useBillingStore } from "@/stores";
|
|
import { useApiUtil } from "@/composables";
|
|
import { IVoucherCode } from "@/models/billing";
|
|
import { useField, useForm } from "vee-validate";
|
|
import { object, string, boolean, number } from "yup";
|
|
|
|
const LoadingMessage = defineAsyncComponent(
|
|
() => import("@/components/ui/spinners/FelLoadingMessage.vue")
|
|
)
|
|
|
|
const modal = defineAsyncComponent(
|
|
() => import("@/components/ui/FelModal.vue")
|
|
)
|
|
|
|
const props = defineProps({
|
|
voucherUid: String
|
|
})
|
|
|
|
const { withClientMutation } = useApiUtil();
|
|
let billingStore = useBillingStore();
|
|
const { fetchingVoucherCodes } = storeToRefs(billingStore);
|
|
|
|
const codes = computed<IVoucherCode[]>(() => {
|
|
const vouchers = billingStore.getVouchers;
|
|
const index = vouchers?.findIndex(item => item.uid === props.voucherUid);
|
|
if(index > -1) {
|
|
return vouchers[index]?.codes
|
|
};
|
|
return [] as IVoucherCode[];
|
|
})
|
|
|
|
onMounted(() => billingStore.fetchVoucherCodes(props.voucherUid!))
|
|
watch(() => props.voucherUid, _ =>{
|
|
billingStore.fetchVoucherCodes(props.voucherUid!)
|
|
})
|
|
|
|
let showModal = ref<boolean>(false);
|
|
const codeSchema = object({
|
|
uid: string().nullable(),
|
|
voucherUid: string().required(),
|
|
code: string().required("Code is Required"),
|
|
usageLimit: number().required("Usage Limit is Required"),
|
|
used: string().nullable(),
|
|
isActive: boolean().default(true),
|
|
});
|
|
|
|
const { handleSubmit, errors, setFieldValue } = useForm({
|
|
validationSchema: codeSchema,
|
|
initialValues: {
|
|
"isActive": true,
|
|
"voucherUid": props.voucherUid
|
|
} as any,
|
|
});
|
|
|
|
const { value: uid } = useField("uid");
|
|
const { value: voucherUid } = useField("voucherUid");
|
|
const { value: code } = useField<string>("code");
|
|
const { value: usageLimit } = useField("usageLimit");
|
|
const { value: used } = useField("used");
|
|
const { value: isActive } = useField("isActive");
|
|
|
|
const submitVoucherForm = handleSubmit((values) => {
|
|
if (!values.uid) addVoucherCode(values as IVoucherCode);
|
|
if (values.uid) updateVoucherCode(values as IVoucherCode);
|
|
});
|
|
|
|
let editCode = (vcode: IVoucherCode) => {
|
|
setFieldValue("uid", vcode.uid)
|
|
setFieldValue("code", vcode.code)
|
|
setFieldValue("usageLimit", vcode.usageLimit)
|
|
setFieldValue("used", vcode.used)
|
|
setFieldValue("isActive", vcode.isActive)
|
|
showModal.value = true
|
|
};
|
|
|
|
const newVoucherCode = () => {
|
|
setFieldValue("uid", undefined)
|
|
setFieldValue("voucherUid", props.voucherUid)
|
|
setFieldValue("code", undefined)
|
|
setFieldValue("usageLimit", undefined)
|
|
setFieldValue("used", undefined)
|
|
setFieldValue("isActive", true)
|
|
showModal.value = true
|
|
}
|
|
|
|
const addVoucherCode = (vcode: IVoucherCode) => {
|
|
delete vcode['uid'];
|
|
withClientMutation(ADD_VOUCHER_CODE, { payload: vcode },"createVoucherCode")
|
|
.then((result) => billingStore.addVoucherCode(result))
|
|
.finally(() => (showModal.value = false));
|
|
};
|
|
|
|
const updateVoucherCode = (vocher: IVoucherCode) => {
|
|
delete vocher['uid'];
|
|
delete vocher['used'];
|
|
withClientMutation(EDIT_VOUCHER_CODE, { uid: uid?.value, payload: vocher },"updateVoucherCode")
|
|
.then((result) => billingStore.updateVoucherCode(result))
|
|
.finally(() => (showModal.value = false));
|
|
};
|
|
</script>
|
|
|
|
<style lang="css" scoped>
|
|
.voucher-scroll {
|
|
min-height: 500px;
|
|
}
|
|
</style>
|
|
|
|
<template>
|
|
<div class="mt-4">
|
|
<div v-if="fetchingVoucherCodes">
|
|
<LoadingMessage message="Fetching voucher codes ..." />
|
|
</div>
|
|
<section v-else>
|
|
<div class="flex justify-between">
|
|
<h4 class="text-gray-800 text-l font-semibold">Voucher Codes</h4>
|
|
<button
|
|
class="px-4 my-2 p-1 text-sm border-sky-800 border text-dark-700 transition-colors duration-150 rounded-sm focus:outline-none hover:bg-sky-800 hover:text-gray-100"
|
|
@click="newVoucherCode">
|
|
Add Voucher Code
|
|
</button>
|
|
</div>
|
|
<hr>
|
|
<div class="grid grid-cols-5 gap-2 mt-2">
|
|
<div
|
|
v-for="vcode in codes" :key="vcode.uid"
|
|
class="col-span-1 bg-white rounded-sm shadow-sm hover:shadow-md duration-500 px-2 py-2">
|
|
<div class="font-semibold text-gray-800 flex justify-between items-center">
|
|
<h5>{{ vcode.code }}</h5>
|
|
<div class="text-sm text-gray-500 flex-grow text-right">{{ vcode.used }} of {{ vcode.usageLimit }}</div>
|
|
<a class="ml-2 pl-2 text-gray-400 border-l-2 border-l-gray-400" @click="editCode(vcode)">
|
|
<font-awesome-icon class="text-xs hover:text-gray-800" icon="pen" />
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
|
|
<modal v-if="showModal" @close="showModal = false" :contentWidth="'w-3/6'">
|
|
<template v-slot:header>
|
|
<h3>Voucher Code Form</h3>
|
|
</template>
|
|
<template v-slot:body>
|
|
<form>
|
|
<div class="grid grid-cols-2 gap-x-4 mb-4">
|
|
<label class="block col-span-1 mb-2">
|
|
<span class="text-gray-700">Voucher Code</span>
|
|
<input
|
|
:class="['form-input mt-1 block w-full', {'border-red-500 animate-pulse': errors.code }]"
|
|
type="text"
|
|
v-model="code"
|
|
placeholder="Code ..."
|
|
/>
|
|
</label>
|
|
<label class="block col-span-1 mb-2">
|
|
<span class="text-gray-700">Usage Limit</span>
|
|
<input
|
|
:class="['form-input mt-1 block w-full', {'border-red-500 animate-pulse': errors.usageLimit }]"
|
|
type="number"
|
|
min="1"
|
|
v-model="usageLimit"
|
|
/>
|
|
</label>
|
|
</div>
|
|
<div class="grid grid-cols-2 gap-x-4 mb-4">
|
|
<label class="block col-span-1 mb-2">
|
|
<span class="text-gray-700">Is Active</span>
|
|
<input
|
|
class="form-checkbox ml-4"
|
|
type="checkbox"
|
|
v-model="isActive"
|
|
checked
|
|
/>
|
|
</label>
|
|
</div>
|
|
|
|
<hr />
|
|
<button type="submit"
|
|
class="-mb-4 border border-sky-800 bg-sky-800 text-white rounded-sm px-2 py-1 mt-2 transition-colors duration-500 ease select-none hover:bg-sky-800 focus:outline-none focus:shadow-outline"
|
|
@click.prevent="submitVoucherForm">
|
|
Save Voucher
|
|
</button>
|
|
</form>
|
|
</template>
|
|
</modal>
|
|
</template>
|