diff options
Diffstat (limited to 'src/components/new_item.vue')
-rw-r--r-- | src/components/new_item.vue | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/src/components/new_item.vue b/src/components/new_item.vue new file mode 100644 index 0000000..0df7249 --- /dev/null +++ b/src/components/new_item.vue @@ -0,0 +1,163 @@ +<script setup lang="ts"> +import { ref, toRaw, onMounted } from 'vue' +import axios from 'axios' +import { useToast } from 'vue-toast-notification' +import Item from './../classes/item' + +const toast = useToast({ + position: 'top-right' +}) + +const isLoading = ref(true) +const item = ref(new Item()) +const itemBrand = ref({ id: 0, name: '' }) +const allBrands = ref([]) + +const getAllBrands = async () => { + allBrands.value = [] + isLoading.value = true + + try { + const r = await axios.get('/brand') + if (r.status === 200) { + allBrands.value = r.data.data + } else if (r.status === 204) { + toast.warning('No brands found') + } + } catch (err) { + toast.error('An unhandled exception occoured. Please check logs') + console.error(err) + } + + isLoading.value = false +} + +const submit = async (e) => { + e.preventDefault() + try { + const i = toRaw(item.value) + i.brandid = toRaw(itemBrand.value).ID + i.unitprice = i.unitprice.toString() + i.gstpercentage = i.gstpercentage.toString() + + await axios.post('/item', i) + toast.success('Successfully added a new item.') + // TODO: refresh items list + } catch (err) { + const statusCode = err.request.status + const res = JSON.parse(err.request.response) + + switch (statusCode) { + case (400, 409): + toast.error(res.error) + break + default: + console.error(err) + toast.error('An unhandled exception occoured. Please check logs') + } + } +} + +onMounted(() => { + getAllBrands() +}) +</script> + +<template> + <form class="row g-3" v-on:submit="submit"> + <div class="col-md-4"> + <label for="item-name-input" class="form-label">Item Name</label> + <input + type="text" + class="form-control" + id="item-name-input" + placeholder="Item Name" + v-model="item.name" + /> + </div> + <div class="col-md-6"> + <label for="item-description-input" class="form-label">Description</label> + <input + type="text" + class="form-control" + id="item-description-input" + placeholder="Item Description" + v-model="item.description" + /> + </div> + <div class="col-md-2"> + <label for="item-hsn-input" class="form-label">HSN</label> + <input + type="text" + class="form-control" + id="item-hsn-input" + placeholder="Item HSN" + v-model="item.hsn" + /> + </div> + + <div class="col-md-3"> + <label for="item-unitprice-input" class="form-label">Unit Price</label> + <input + type="number" + class="form-control" + id="item-unitprice-input" + placeholder="Unit Price" + v-model="item.unitprice" + /> + </div> + <div class="col-md-3"> + <label for="item-gst-input" class="form-label">GST %</label> + <input + type="number" + class="form-control" + id="item-gst-input" + placeholder="Default GST %" + v-model="item.gstpercentage" + /> + </div> + <div class="col-md-3"> + <label for="item-uom-input" class="form-label">Unit of Measurement (UOM)</label> + <input + type="text" + class="form-control" + id="item-uom-input" + placeholder="Unit of Measurement" + v-model="item.unitofmeasure" + /> + </div> + <div class="col-md-3"> + <label for="item-brand-input" class="form-label">Brand</label> + <select + class="form-select" + aria-label="Default select example" + id="item-brand-input" + v-model="itemBrand" + > + <option selected disabled value="0">Select Brand</option> + + <option v-for="brand in allBrands" :value="brand"> + {{ brand.Name }} + </option> + </select> + </div> + + <div class="col-12"> + <div class="form-check"> + <input + class="form-check-input" + type="checkbox" + id="gridCheck" + v-model="item.hasdecimalquantity" + /> + <label class="form-check-label" for="gridCheck"> + Quantity can contain decimal places + </label> + </div> + </div> + + <div class="col-12"> + <input type="submit" value="Add New Item" class="btn btn-primary" /> + </div> + </form> +</template> |