aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVidhu Kant Sharma <vidhukant@vidhukant.com>2023-12-04 15:26:36 +0530
committerVidhu Kant Sharma <vidhukant@vidhukant.com>2023-12-04 15:26:36 +0530
commit331a8da55352c736f08339ae6ca0d9e0eb690058 (patch)
treeeebd21abc445d1f05a681668d1d66bbaa6034e98
parentd5fab4fefaa3e63c1cda945cf556a0ecfdfa0170 (diff)
added table to show items of an invoice0.2.2
-rw-r--r--package.json2
-rw-r--r--src/components/invoice_items_table.vue142
-rw-r--r--src/components/item_selector.vue4
-rw-r--r--src/components/items_table.vue2
-rw-r--r--src/views/EditInvoice.vue7
-rw-r--r--src/views/HomeView.vue2
6 files changed, 152 insertions, 7 deletions
diff --git a/package.json b/package.json
index fbd1a52..8915981 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "openbills-web",
- "version": "0.2.1",
+ "version": "0.2.2",
"private": false,
"scripts": {
"dev": "vite",
diff --git a/src/components/invoice_items_table.vue b/src/components/invoice_items_table.vue
new file mode 100644
index 0000000..6a89f5a
--- /dev/null
+++ b/src/components/invoice_items_table.vue
@@ -0,0 +1,142 @@
+<script setup lang="js">
+import { ref, onMounted, toRaw } from 'vue'
+import axios from 'axios'
+import { useToast } from 'vue-toast-notification'
+
+const props = defineProps(["invoiceId"])
+
+const toast = useToast({
+ position: 'top-right'
+})
+
+const items = ref([])
+const isLoading = ref(false)
+
+const getItems = async () => {
+ items.value = []
+ isLoading.value = true
+
+ try {
+ const res = await axios.get(`/invoice/${props.invoiceId}/item`)
+ if (res.status === 200) {
+ items.value = res.data.data
+ }
+ } catch (err) {
+ toast.error('An unhandled exception occoured. Please check logs')
+ console.error(err)
+ }
+
+ isLoading.value = false
+}
+
+const handleDelete = async (id) => {
+ alert("coming soon")
+ return
+ try {
+ const res = await axios.delete(`/item/${id}`)
+ if (res.status === 200) {
+ toast.success('Successfully deleted item')
+ }
+
+ getAllItems()
+ } catch (err) {
+ toast.error('An unhandled exception occoured. Please check logs')
+ console.error(err)
+ }
+}
+
+onMounted(() => {
+ getItems()
+})
+</script>
+
+<template>
+ <div v-if="isLoading" class="w-100 d-flex justify-content-center">
+ <div class="spinner-border" role="status">
+ <span class="sr-only"></span>
+ </div>
+ </div>
+
+ <table v-else class="table table-striped table-hover">
+ <thead>
+ <tr>
+ <th scope="col">#</th>
+ <th scope="col">Item Name</th>
+ <th scope="col">Description</th>
+ <th scope="col">Brand</th>
+ <th scope="col">HSN</th>
+ <th scope="col">Unit Price</th>
+ <th scope="col">UOM</th>
+
+ <th scope="col" class="table-action-column">
+ <div class="wrapper">
+ <RouterLink to="/item/new">
+ <button class="btn btn-dark">
+ <i class="bi bi-plus-lg"></i>
+ </button>
+ </RouterLink>
+ <button class="btn btn-dark" v-on:click="getAllItems">
+ <i class="bi bi-arrow-clockwise"></i>
+ </button>
+ </div>
+ </th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <tr v-for="(item, index) in items" :key="item['id']">
+ <td scope="row">{{ index + 1 }}</td>
+ <td>{{ item.Name }}</td>
+ <td>{{ item.Description }}</td>
+ <td>{{ item.BrandName }}</td>
+ <td>{{ item.HSN }}</td>
+ <td>{{ item.UnitPrice }}</td>
+ <td>{{ item.UnitOfMeasure }}</td>
+
+ <td class="table-action-column">
+ <div class="wrapper">
+ <button class="btn" data-bs-toggle="dropdown" aria-expanded="false">
+ <i class="bi bi-caret-down-fill"></i>
+ </button>
+
+ <div class="dropdown">
+ <ul class="dropdown-menu">
+ <li>
+ <button class="dropdown-item" v-on:click="console.log('Edit: ', item.ID)">
+ Edit Item
+ </button>
+ </li>
+ <li>
+ <button class="dropdown-item" v-on:click="handleDelete(item.ID)">
+ Delete Item
+ </button>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</template>
+
+<style>
+.table-action-column .wrapper {
+ display: flex;
+ justify-content: flex-end;
+}
+
+thead .table-action-column .wrapper {
+ gap: 0.5rem;
+}
+
+tbody .table-action-column .btn {
+ opacity: 0;
+ transition: opacity 300ms;
+}
+
+tbody tr:hover .table-action-column .btn {
+ opacity: 1;
+ transition: opacity 300ms;
+}
+</style>
diff --git a/src/components/item_selector.vue b/src/components/item_selector.vue
index 9cdbeed..5dc9b84 100644
--- a/src/components/item_selector.vue
+++ b/src/components/item_selector.vue
@@ -4,7 +4,7 @@ import axios from 'axios'
import { useToast } from 'vue-toast-notification'
import InvoiceItem from "./../classes/invoice_item"
-const props = defineProps(["invoice"])
+const props = defineProps(["invoiceId"])
const emit = defineEmits(["added"])
const toast = useToast({
@@ -42,7 +42,7 @@ const submit = async (e: Event) => {
submitting.value = true
try {
- await axios.post(`/invoice/${props.invoice.ID}/item`, toRaw(item.value))
+ await axios.post(`/invoice/${props.invoiceId}/item`, toRaw(item.value))
itemSelection.value = null
item.value = new InvoiceItem()
emit("added")
diff --git a/src/components/items_table.vue b/src/components/items_table.vue
index 187ee0f..e9f103e 100644
--- a/src/components/items_table.vue
+++ b/src/components/items_table.vue
@@ -92,7 +92,7 @@ onMounted(() => {
</thead>
<tbody>
- <tr v-for="(item, index) in allItems">
+ <tr v-for="(item, index) in allItems" :key="item['id']">
<td scope="row">{{ index + 1 }}</td>
<td>{{ item.Name }}</td>
<td>{{ item.Description }}</td>
diff --git a/src/views/EditInvoice.vue b/src/views/EditInvoice.vue
index b134721..7a508f8 100644
--- a/src/views/EditInvoice.vue
+++ b/src/views/EditInvoice.vue
@@ -8,6 +8,7 @@ import Invoice from "./../classes/invoice"
import invoiceHeader from './../components/invoice_header.vue'
import itemSelector from './../components/item_selector.vue'
+import invoiceItemsTable from './../components/invoice_items_table.vue'
const toast = useToast({
position: 'top-right'
@@ -15,6 +16,7 @@ const toast = useToast({
const route = useRoute()
+const invoiceId = route.params.id
const invoice = ref(new Invoice())
const isLoading = ref(true)
@@ -22,7 +24,7 @@ const getInvoice = async () => {
isLoading.value = true
try {
- const r = await axios.get(`/invoice/${route.params.id}`)
+ const r = await axios.get(`/invoice/${invoiceId}`)
invoice.value = r.data.data
} catch (err) {
toast.error('An unhandled exception occoured. Please check logs')
@@ -43,5 +45,6 @@ onMounted(() => {
<template>
<invoiceHeader :invoice="invoice" />
- <itemSelector :invoice="invoice" @added="refreshItems()"/>
+ <itemSelector :invoiceId="invoiceId" @added="refreshItems()"/>
+ <invoiceItemsTable :invoiceId="invoiceId" />
</template>
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 0a5bf4d..6ef6440 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -16,7 +16,7 @@ const getAllDrafts = async () => {
allDrafts.value = res.data.data
}
} catch (err) {
- toast.error('An unhandled exception occoured. Please check logs')
+ //toast.error('An unhandled exception occoured. Please check logs')
console.error(err)
}