Table summary of orders
This commit is contained in:
		
							
								
								
									
										18
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/App.vue
									
									
									
									
									
								
							| @@ -1,10 +1,28 @@ | ||||
| <template> | ||||
|   <Suspense> | ||||
|     <RouterView /> | ||||
|   </Suspense> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import './assets/style.scss' | ||||
| import { RouterView } from 'vue-router' | ||||
| import { watch } from 'vue' | ||||
| import { getActivePinia } from 'pinia' | ||||
|  | ||||
| const pinia = getActivePinia(); | ||||
|  | ||||
| if(pinia != undefined) { | ||||
|   watch( | ||||
|     pinia.state, | ||||
|     (state) => { | ||||
|       // persist the whole state to the local storage whenever it changes | ||||
|       localStorage.setItem('piniaState', JSON.stringify(state)) | ||||
|     }, | ||||
|     { deep: true } | ||||
|   ); | ||||
| } | ||||
|  | ||||
| </script> | ||||
|  | ||||
| <style> | ||||
|   | ||||
| @@ -49,7 +49,3 @@ async function confirmOrder() { | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
|  | ||||
| </style> | ||||
| @@ -132,7 +132,3 @@ function cancelOrder(event: Event) { | ||||
|     </div> | ||||
|   </form> | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
|  | ||||
| </style> | ||||
| @@ -10,7 +10,3 @@ | ||||
|   </div> | ||||
|  | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
|  | ||||
| </style> | ||||
| @@ -44,7 +44,3 @@ function sendLogin() { | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
|  | ||||
| </style> | ||||
| @@ -1,12 +1,13 @@ | ||||
| <script setup lang="ts"> | ||||
| import VueDatePicker from '@vuepic/vue-datepicker'; | ||||
| import { axiosInstance, type Category, type Contractor, type OrderProduct } from '@/main' | ||||
| import { axiosInstance, type Contractor, type OrderProduct } from '@/main' | ||||
| import { useCategoriesStore } from '@/stores/categories.store' | ||||
| import { useContractorsStore } from '@/stores/contractors.store' | ||||
| import { useOrdersStore } from '@/stores/orders.store' | ||||
| import { storeToRefs } from 'pinia' | ||||
| import { useSiteControlStore } from '@/stores/siteControl.store' | ||||
| import { ref } from 'vue' | ||||
| import { onBeforeUnmount, onMounted, ref, watch } from 'vue' | ||||
| import { useRoute, useRouter } from 'vue-router' | ||||
|  | ||||
| const categoriesStore = useCategoriesStore(); | ||||
| const contractorsStore = useContractorsStore(); | ||||
| @@ -17,25 +18,59 @@ const { contractor, contractors } = storeToRefs(contractorsStore); | ||||
| const { deliveryDate, uuid } = storeToRefs(ordersStore); | ||||
| const { categories } = storeToRefs(categoriesStore); | ||||
| const { showConfirmationModal, isDarkTheme } = storeToRefs(siteControlStore); | ||||
|  | ||||
| const contractorSearch = ref<string>(); | ||||
| const filteredContractors = ref<Array<Contractor>>(); | ||||
| const showContractorsDropdown = ref<boolean>(false); | ||||
| const contractorInput = ref(null); | ||||
|  | ||||
| const showErrorNotification = ref<boolean>(false); | ||||
| const errorNotificationMessage = ref<string>(); | ||||
| const route = useRoute(); | ||||
|  | ||||
| watch(contractor, (contractor) => { | ||||
|   if(contractor == undefined) { | ||||
|     contractorSearch.value = ''; | ||||
|   } else { | ||||
|     contractorSearch.value = contractor.Knt_NipE + ', ' + contractor.Knt_Nazwa1 + contractor.Knt_Nazwa2 + contractor.Knt_Nazwa3; | ||||
|   } | ||||
| }, { immediate: true }); | ||||
|  | ||||
| function createJSON(event: Event) { | ||||
|   event.preventDefault(); | ||||
|   console.log(route); | ||||
|   const json = { | ||||
|     MZN_UUID: uuid.value, | ||||
|     MZN_DataZam: new Date(Date.now()).toISOString(), | ||||
|     MZN_DataZam: new Date(Date.now()).toISOString().split('T')[0], | ||||
|     MZN_DataDos: deliveryDate.value != undefined ? deliveryDate.value.toISOString() : null, | ||||
|     MZN_PodID: contractor.value, | ||||
|     MZN_PodID: contractor.value?.Knt_KntId, | ||||
|     MZamElem: new Array<OrderProduct> | ||||
|   }; | ||||
|  | ||||
|   if(categories.value == undefined) return; | ||||
|   if(categories.value == undefined) { | ||||
|     showErrorNotification.value=true; | ||||
|     errorNotificationMessage.value = "Produkty nie zostały pobrane z bazy danych."; | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if(contractor.value == undefined) { | ||||
|     showErrorNotification.value=true; | ||||
|     errorNotificationMessage.value = "Klient nie został wybrany."; | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if(deliveryDate.value == undefined) { | ||||
|     showErrorNotification.value=true; | ||||
|     errorNotificationMessage.value = "Data dostawy nie została wybrana."; | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   for (let category of categories.value) { | ||||
|     for (let product of category.Towary) { | ||||
|       if(product.Quantity != null && product.Quantity != '') { | ||||
|         if(isNaN(Number(product.Quantity)) || isNaN(Number(product.Twr_CenaZ)) || isNaN(Number(product.Twr_Cena))) { | ||||
|           showErrorNotification.value=true; | ||||
|           errorNotificationMessage.value = "W zamówieniu znajdują się niepoprawne wartości."; | ||||
|           return; | ||||
|         } | ||||
|         const productObject : OrderProduct = { | ||||
| @@ -54,10 +89,12 @@ function createJSON(event: Event) { | ||||
|   } | ||||
|   if(json.MZamElem.length == 0) { | ||||
|     showErrorNotification.value=true; | ||||
|     errorNotificationMessage.value = "Zamówienie jest puste."; | ||||
|     return; | ||||
|   } | ||||
|   showErrorNotification.value=false; | ||||
|  | ||||
|   console.log(json); | ||||
|   console.log(JSON.stringify(json)); | ||||
|   axiosInstance.post('/zamowienie', JSON.stringify(json)).then( response => { | ||||
|     uuid.value = response.data.MZN_UUID; | ||||
|   }); | ||||
| @@ -65,12 +102,64 @@ function createJSON(event: Event) { | ||||
|  | ||||
| function setConfirmationModal(event : Event) { | ||||
|   event.preventDefault(); | ||||
|   if(uuid.value == undefined) { | ||||
|     showErrorNotification.value=true; | ||||
|     errorNotificationMessage.value = "Zamówienie nie zostało jeszcze zapisane w bazie danych."; | ||||
|     return; | ||||
|   } | ||||
|   showConfirmationModal.value = true; | ||||
| } | ||||
|  | ||||
| function cancelOrder(event: Event) { | ||||
|   event.preventDefault(); | ||||
|   axiosInstance.delete('/zamowienie/' + uuid.value); | ||||
|   siteControlStore.newOrder(); | ||||
| } | ||||
|  | ||||
| function filterContractors() { | ||||
|     if (contractorSearch.value == "") { | ||||
|       contractor.value = undefined; | ||||
|       filteredContractors.value = contractors.value; | ||||
|       return; | ||||
|     } | ||||
|     filteredContractors.value = contractors.value.filter( | ||||
|       contractor => | ||||
|       (contractor.Knt_NipE + contractor.Knt_Nazwa1 + contractor.Knt_Nazwa2 + contractor.Knt_Nazwa3).toLowerCase().includes(contractorSearch.value as string) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| function toggleContractorsDropdown() { | ||||
|   if(!showContractorsDropdown.value) { | ||||
|     showContractorsDropdown.value = true; | ||||
|     if(contractorSearch.value == undefined || contractorSearch.value == '') { | ||||
|       filteredContractors.value = contractors.value; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| function handleClickOutsideDropdown(event : Event) { | ||||
|   if(contractorInput.value != null && !contractorInput.value.contains(event.target)){ | ||||
|     showContractorsDropdown.value = false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| function selectContractorFromDropdown(selectedContractor : Contractor) { | ||||
|   console.log(selectedContractor); | ||||
|   contractor.value = selectedContractor; | ||||
|   showContractorsDropdown.value = false; | ||||
| } | ||||
|  | ||||
| onMounted(function (){ | ||||
|   document.addEventListener('click', handleClickOutsideDropdown); | ||||
| }); | ||||
|  | ||||
| onBeforeUnmount( function () { | ||||
|   document.removeEventListener('click', handleClickOutsideDropdown); | ||||
| }) | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <form class="box" @submit="createJSON"> | ||||
|   <form class="box" @submit.prevent="createJSON"> | ||||
|     <div class="mb-3"> | ||||
|       <div class="box"> | ||||
|         <div class="mb-3"> | ||||
| @@ -78,12 +167,29 @@ function setConfirmationModal(event : Event) { | ||||
|           <h1 class="subtitle is-5" v-if="uuid != undefined" ><b>{{ uuid }}</b></h1> | ||||
|         </div> | ||||
|         <div class="field mb-5"> | ||||
|           <label class="label is-small">NIP</label> | ||||
|           <label class="label is-small">Klient</label> | ||||
|           <div class="field"> | ||||
|             <div class="select is-small is-expanded" style="width: 100%"> | ||||
|               <select v-model="contractor" class="is-expanded" style="width: 100%" required> | ||||
|                 <option class="is-expanded" v-for="contractor in contractors" :key="contractor.Knt_KntId" :value="contractor">{{ contractor.Knt_NipE + ', ' + contractor.Knt_Miasto + ', ' + contractor.Knt_Nazwa1 + ' ' + contractor.Knt_Nazwa2 + ' ' + contractor.Knt_Nazwa3 }}</option> | ||||
|               </select> | ||||
|             <div ref="contractorInput" class="dropdown maxwidth" | ||||
|                  v-bind:class="{'is-active': showContractorsDropdown == true}"> | ||||
|               <div class="dropdown-trigger maxwidth" @click="toggleContractorsDropdown"> | ||||
|                 <div class="field maxwidth" @onclick.prevent="toggleContractorsDropdown"> | ||||
|                   <p class="control is-expanded has-icons-right is-small maxwidth" @onclick.prevent="toggleContractorsDropdown"> | ||||
|                     <input class="input is-small is-expanded maxwidth" type="search" | ||||
|                            v-model="contractorSearch" @input="filterContractors" /> | ||||
|                     <span class="icon is-small is-right"><i class="fas fa-search"></i></span> | ||||
|                   </p> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="dropdown-menu is-clipped has-background-info-on-scheme-invert" id="dropdown-menu" role="menu" style="max-width: calc(100vw - 3rem); box-shadow: 0px 0px 6px -1px rgba(165, 165, 165, 0.8); border-radius: 10px 10px 10px 10px; overflow-x:auto"> | ||||
|                 <div class="dropdown-content" style="max-height: 50vh; overflow-x: auto"> | ||||
|                   <a v-if="filteredContractors != undefined && filteredContractors.length == 0" class="dropdown-item is-clipped">Brak wyników</a> | ||||
|                   <a v-for="dropdownContractor in filteredContractors" v-bind:key="dropdownContractor.Knt_KntId" | ||||
|                      class="dropdown-item is-clipped" @click = "selectContractorFromDropdown(dropdownContractor)" | ||||
|                      v-bind:class = "{'has-background-info' : dropdownContractor == contractor}"> | ||||
|                     {{dropdownContractor.Knt_NipE + ', ' + dropdownContractor.Knt_Nazwa1 + dropdownContractor.Knt_Nazwa2 + dropdownContractor.Knt_Nazwa3}} | ||||
|                   </a> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
| @@ -101,9 +207,10 @@ function setConfirmationModal(event : Event) { | ||||
|         </div> | ||||
|         <button class="button is-info mt-5">Zapisz</button> | ||||
|         <button class="button is-success mt-5 ml-3" @click="setConfirmationModal">Potwierdź</button> | ||||
|         <div v-if="showErrorNotification==true" class="notification is-danger is-light mt-5"> | ||||
|         <button class="button is-danger mt-5 ml-3" @click="cancelOrder" v-bind:disabled="uuid == undefined">Anuluj</button> | ||||
|         <div v-if="showErrorNotification==true" class="notification is-danger is-bold mt-5"> | ||||
|           <button  class="delete" @click.prevent="showErrorNotification = false"></button> | ||||
|           W formularzu znajdują się pola, które nie są liczbami, lub wszystkie pola są puste. | ||||
|           {{ errorNotificationMessage }} | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| @@ -120,7 +227,7 @@ function setConfirmationModal(event : Event) { | ||||
|                   type="text" | ||||
|                   placeholder="Kwota" | ||||
|                   v-model="product.Twr_Cena" | ||||
|                   v-bind:class="{ 'is-danger has-background-danger-90': product.Twr_Cena != undefined && isNaN(Number(product.Twr_Cena)),'is-success has-background-success-85': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}" | ||||
|                   v-bind:class="{ 'is-danger has-background-danger-soft': product.Twr_Cena != undefined && isNaN(Number(product.Twr_Cena)),'is-success has-background-success-soft': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}" | ||||
|                 /> | ||||
|               </div> | ||||
|             </div> | ||||
| @@ -131,7 +238,7 @@ function setConfirmationModal(event : Event) { | ||||
|                   type="text" | ||||
|                   placeholder="Kwota" | ||||
|                   v-model="product.Twr_CenaZ" | ||||
|                   v-bind:class="{ 'is-danger has-background-danger-90': product.Twr_CenaZ != undefined && isNaN(Number(product.Twr_CenaZ)), 'is-success has-background-success-90': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity)) | ||||
|                   v-bind:class="{ 'is-danger has-background-danger-soft': product.Twr_CenaZ != undefined && isNaN(Number(product.Twr_CenaZ)), 'is-success has-background-success-soft': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity)) | ||||
|                                   }" | ||||
|                 /> | ||||
|               </div> | ||||
| @@ -139,14 +246,14 @@ function setConfirmationModal(event : Event) { | ||||
|             <div class="column"> | ||||
|               <div class="field has-addons"> | ||||
|                 <p class="control"> | ||||
|                   <span class="select is-small" v-bind:class="{ 'is-danger has-background-danger-90': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success has-background-success-90': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}"> | ||||
|                     <select v-model="product.ChosenOption" v-bind:class="{ 'is-danger has-background-danger-90': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success has-background-success-90': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}"> | ||||
|                   <span class="select is-small" v-bind:class="{ 'is-danger': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}"> | ||||
|                     <select v-model="product.ChosenOption" v-bind:class="{ 'is-danger has-background-danger-soft': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success has-background-success-soft': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}"> | ||||
|                       <option v-for="option in product.Options" :key="option">{{ option }}</option> | ||||
|                     </select> | ||||
|                   </span> | ||||
|                 </p> | ||||
|                 <p class="control is-expanded"> | ||||
|                   <input class="input is-small" type="text" placeholder="Ilość" v-model="product.Quantity" v-bind:class="{ 'is-danger has-background-danger-90': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success has-background-success-90': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}"> | ||||
|                   <input class="input is-small" type="text" placeholder="Ilość" v-model="product.Quantity" v-bind:class="{ 'is-danger has-background-danger-soft': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success has-background-success-soft': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}"> | ||||
|                 </p> | ||||
|               </div> | ||||
|             </div> | ||||
| @@ -174,7 +281,8 @@ function setConfirmationModal(event : Event) { | ||||
|     --dp-menu-border-color: var(--bulma-border); | ||||
|     --dp-border-color-hover: var(--bulma-border); | ||||
|     --dp-border-color-focus: var(--bulma-border); | ||||
|     --dp-primary-color: var(--bulma-info-00); | ||||
|     --dp-primary-color: var(--bulma-info); | ||||
|     --dp-primary-text-color: #000; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -188,4 +296,8 @@ function setConfirmationModal(event : Event) { | ||||
|     --dp-primary-text-color: #000; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .maxwidth { | ||||
|   width: 100%; | ||||
| } | ||||
| </style> | ||||
| @@ -19,14 +19,13 @@ const userStore = useUserStore(); | ||||
|  | ||||
| const { username } = storeToRefs(userStore); | ||||
|  | ||||
|  | ||||
| function makeBurger() { | ||||
|   activator.value = !activator.value | ||||
|   return activator | ||||
| } | ||||
|  | ||||
| function clickForm() { | ||||
|   siteControlStore.switchToFrom(); | ||||
|   siteControlStore.switchToForm(); | ||||
|   if(activator.value) { | ||||
|     activator.value = false; | ||||
|   } | ||||
| @@ -39,27 +38,21 @@ function clickOrders() { | ||||
|   } | ||||
| } | ||||
|  | ||||
| function clickTable() { | ||||
|   siteControlStore.switchToTable(); | ||||
|   if(activator.value) { | ||||
|     activator.value = false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| function routeLogin() { | ||||
|   axiosInstance.post('/logout'); | ||||
|   router.push("/login"); | ||||
| } | ||||
|  | ||||
| function newOrder() { | ||||
|   const {order, uuid, deliveryDate, orderDate } = storeToRefs(ordersStore); | ||||
|   const { contractor } = storeToRefs(contractorsStore); | ||||
|   contractor.value = undefined; | ||||
|   order.value = undefined; | ||||
|   uuid.value = undefined; | ||||
|   deliveryDate.value = undefined; | ||||
|   orderDate.value = undefined; | ||||
|   categoriesStore.fetchCategories(); | ||||
|   siteControlStore.switchToFrom(); | ||||
|   window.scrollTo(0, 0); | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <nav class="navbar" role="navigation" aria-label="main navigation"> | ||||
|   <nav class="navbar has-shadow" role="navigation" aria-label="main navigation"> | ||||
|     <div class="navbar-brand"> | ||||
|       <a class="navbar-item is-overflow-hidden" style="max-width: calc(100vw - 50px); white-space: nowrap; overflow: hidden"> | ||||
|         <h3 class="title is-4">Mleczarnia</h3> | ||||
| @@ -81,15 +74,17 @@ function newOrder() { | ||||
|         <a class="navbar-item" @click="clickOrders"> | ||||
|           Zamówienia | ||||
|         </a> | ||||
|         <a class="navbar-item" @click="clickTable"> | ||||
|           Tabela | ||||
|         </a> | ||||
|       </div> | ||||
|  | ||||
|       <div class="navbar-end"> | ||||
|         <div class="navbar-item"> | ||||
|           <div class="buttons"> | ||||
|             <button class="button is-info" @click="newOrder"> | ||||
|             <button class="button is-info" @click="siteControlStore.newOrder"> | ||||
|               Nowe Zamówienie | ||||
|             </button> | ||||
|             <button class="button is-light" @click="routeLogin" > | ||||
|             <button class="button is-info" @click="routeLogin" > | ||||
|               Wyloguj | ||||
|             </button> | ||||
|           </div> | ||||
| @@ -98,7 +93,3 @@ function newOrder() { | ||||
|     </div> | ||||
|   </nav> | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
|  | ||||
| </style> | ||||
| @@ -1,17 +1,18 @@ | ||||
| <script setup lang="ts"> | ||||
| import VueDatePicker from '@vuepic/vue-datepicker'; | ||||
| import { ref, watch } from 'vue' | ||||
| import { computed, ref, watch } from 'vue' | ||||
| import { useOrdersStore } from '@/stores/orders.store' | ||||
| import { storeToRefs } from 'pinia' | ||||
| import { useSiteControlStore } from '@/stores/siteControl.store' | ||||
|  | ||||
| const ordersStore = useOrdersStore(); | ||||
| const siteControlStore = useSiteControlStore(); | ||||
| const searchOrderDate = ref<Date>(); | ||||
| const searchOrderDate = ref<Array<Date>>(); | ||||
| const isOutOfBuffer = ref<boolean>(false); | ||||
| const isInBufor = ref<boolean>(false); | ||||
| const { orders } = storeToRefs(ordersStore); | ||||
| const areOrdersLoading = ref<boolean>(false); | ||||
| const { isDarkTheme } = storeToRefs(siteControlStore); | ||||
|  | ||||
| watch(isInBufor, (val) => { | ||||
|   if(val && val == isOutOfBuffer.value) { | ||||
| @@ -29,6 +30,12 @@ watch(isOutOfBuffer, (val) => { | ||||
|   immediate: true | ||||
| }); | ||||
|  | ||||
| const buffer = computed(()=>{ | ||||
|     if (!isInBufor.value && !isOutOfBuffer.value) { | ||||
|       return null; | ||||
|     } else return !!isInBufor.value; | ||||
|   }); | ||||
|  | ||||
| function viewOrder(uuid : string) { | ||||
|   siteControlStore.viewOrder(uuid); | ||||
| } | ||||
| @@ -36,10 +43,13 @@ function viewOrder(uuid : string) { | ||||
| async function fetchOrders(event : Event) { | ||||
|   event.preventDefault(); | ||||
|   areOrdersLoading.value = true; | ||||
|   if(isInBufor.value) { | ||||
|     orders.value = await ordersStore.fetchOrdersInBuffer(); | ||||
|   } else if (isOutOfBuffer.value) { | ||||
|     orders.value = await ordersStore.fetchOrdersOutOfBuffer(); | ||||
|   console.log(searchOrderDate.value); | ||||
|  | ||||
|   if(searchOrderDate.value == undefined) { | ||||
|     orders.value = await ordersStore.fetchOrdersByBuffer(buffer.value); | ||||
|   } | ||||
|   if(searchOrderDate.value != undefined) { | ||||
|     orders.value = await ordersStore.fetchOrdersByDateStartAndEnd(searchOrderDate.value[0], searchOrderDate.value[1], buffer.value); | ||||
|   } | ||||
|   areOrdersLoading.value = false; | ||||
| } | ||||
| @@ -57,7 +67,10 @@ async function fetchOrders(event : Event) { | ||||
|             <VueDatePicker v-model="searchOrderDate" | ||||
|                            :enable-time-picker="false" | ||||
|                            :clearable="true" | ||||
|                            input-class-name="input is-small"/> | ||||
|                            input-class-name="input is-small calendar-background" | ||||
|                            menu-class-name="calendar-background" | ||||
|                            v-bind:dark = "isDarkTheme" | ||||
|                             range/> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="field mb-5"> | ||||
| @@ -73,15 +86,14 @@ async function fetchOrders(event : Event) { | ||||
|             </label> | ||||
|           </div> | ||||
|         </div> | ||||
|         <button class="button is-primary is-small is-expanded" @click="fetchOrders"  :class="{ 'is-loading': areOrdersLoading }">Pobierz zamówienia</button> | ||||
|         <button class="button is-info is-small is-expanded" @click="fetchOrders"  :class="{ 'is-loading': areOrdersLoading }">Pobierz zamówienia</button> | ||||
|       </div> | ||||
|     </form> | ||||
|     <div class="box"> | ||||
|       <h1 class="is-large mb-3"><b>ZAMÓWIENIA</b></h1> | ||||
|       <div class="columns is-multiline"> | ||||
|         <div class="column is-4" v-for="order in orders" :key="order.MZN_UUID"> | ||||
|           <div class="box"> | ||||
| <!--            <h1 class="mb-3 is-size-7"><b>{{ order.MZN_UUID }}</b></h1>--> | ||||
|           <div class="box" :class="{'confirmed' : order.MZN_Bufor == 0 && order.MZN_Anulowane != 1, 'cancelled' : order.MZN_Anulowane == 1}"> | ||||
|             <label class="label is-small">Klient</label> | ||||
|             <div class="field is-small mb-3"> | ||||
|               <input class="input is-small is-static" | ||||
| @@ -122,7 +134,7 @@ async function fetchOrders(event : Event) { | ||||
|                      value="Nie" | ||||
|                      readonly/> | ||||
|             </div> | ||||
|             <button class="button is-primary is-small is-expanded" @click="viewOrder(order.MZN_UUID)" :name="order.MZN_UUID">Podgląd</button> | ||||
|             <button class="button is-info is-small is-expanded" @click="viewOrder(order.MZN_UUID)" :name="order.MZN_UUID">Podgląd</button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
| @@ -130,6 +142,34 @@ async function fetchOrders(event : Event) { | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
| <style> | ||||
| @media (prefers-color-scheme: dark){ | ||||
|   .calendar-background { | ||||
|     --dp-background-color: rgb(20, 22, 26); | ||||
|     --dp-border-color: var(--bulma-border); | ||||
|     --dp-menu-border-color: var(--bulma-border); | ||||
|     --dp-border-color-hover: var(--bulma-border); | ||||
|     --dp-border-color-focus: var(--bulma-border); | ||||
|     --dp-primary-color: var(--bulma-info); | ||||
|     --dp-primary-text-color: #000; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @media (prefers-color-scheme: light){ | ||||
|   .calendar-background { | ||||
|     --dp-border-color: var(--bulma-border); | ||||
|     --dp-menu-border-color: var(--bulma-border); | ||||
|     --dp-border-color-hover: var(--bulma-border); | ||||
|     --dp-border-color-focus: var(--bulma-border); | ||||
|     --dp-primary-color: var(--bulma-info); | ||||
|     --dp-primary-text-color: #000; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .cancelled { | ||||
|   --bulma-box-background-color: var(--bulma-danger-soft) | ||||
| } | ||||
| .confirmed { | ||||
|   --bulma-box-background-color: var(--bulma-success-soft) | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										19
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/main.ts
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| import { createApp } from 'vue'; | ||||
| import { createApp, watch } from 'vue' | ||||
| import App from './App.vue'; | ||||
| import VueDatePicker from '@vuepic/vue-datepicker'; | ||||
| import '@vuepic/vue-datepicker/dist/main.css'; | ||||
| @@ -24,10 +24,18 @@ const pinia = createPinia(); | ||||
| app.use(pinia); | ||||
| app.use(VueCookies); | ||||
| app.use(router); | ||||
| useOrdersStore(); | ||||
| useContractorsStore(); | ||||
| useCategoriesStore(); | ||||
| useSiteControlStore(); | ||||
|  | ||||
| if(localStorage.getItem('piniaState')) { | ||||
|   pinia.state.value = JSON.parse(localStorage.getItem('piniaState') as string); | ||||
| } | ||||
|  | ||||
| watch ( | ||||
|   () => pinia.state.value, | ||||
|   (state) => { | ||||
|     localStorage.setItem('piniaState', JSON.stringify(state)); | ||||
|   }, | ||||
|   {deep: true} | ||||
| ) | ||||
|  | ||||
|  | ||||
| export const axiosInstance = axios.create({ | ||||
| @@ -103,6 +111,7 @@ export interface Contractor { | ||||
|  | ||||
| export interface Order { | ||||
|   MZN_Bufor: number, | ||||
|   MZN_Anulowane: number, | ||||
|   MZN_DataDos: string, | ||||
|   MZN_DataZam: string, | ||||
|   MZN_MZNID: number, | ||||
|   | ||||
| @@ -1,22 +1,14 @@ | ||||
| import { createRouter, createWebHistory } from 'vue-router'; | ||||
|  | ||||
| import { MainView, LoginView } from '@/views'; | ||||
| import { MainView, LoginView, SummedOrdersView } from '@/views'; | ||||
|  | ||||
| export const router = createRouter({ | ||||
|   history: createWebHistory(import.meta.env.BASE_URL), | ||||
|   linkActiveClass: 'active', | ||||
|   routes: [ | ||||
|     { path: '/', component: MainView }, | ||||
|     { path: '/login', component: LoginView } | ||||
|     { path: '/login', component: LoginView }, | ||||
|     { path: '/table', component: SummedOrdersView,  }, | ||||
|   ] | ||||
| }); | ||||
|  | ||||
| router.beforeEach(async (to) => { | ||||
|   // redirect to login page if not logged in and trying to access a restricted page | ||||
|   const publicPages = ['/login']; | ||||
|   const authRequired = !publicPages.includes(to.path); | ||||
|   // | ||||
|   // if (authRequired) { | ||||
|   //   return '/login'; | ||||
|   // } | ||||
| }); | ||||
|   | ||||
| @@ -4,40 +4,52 @@ import { type Ref, ref } from 'vue' | ||||
| import { axiosInstance } from '@/main' | ||||
|  | ||||
| export const useOrdersStore = defineStore('orders', () => { | ||||
|   const orders = ref<Array<Order>>([]); | ||||
|   const orders = ref<Array<Order>>(); | ||||
|   const order = ref<Order>(); | ||||
|   const uuid = ref<string>(); | ||||
|   const deliveryDate = ref<Date>(); | ||||
|   const orderDate = ref<Date>(); | ||||
|  | ||||
|   async function fetchOrders() { | ||||
|     orders.value=[]; | ||||
|     let ordersTemp : Array<Order> = await fetchOrdersInBuffer(); | ||||
|     orders.value.push(...ordersTemp); | ||||
|     ordersTemp = await fetchOrdersOutOfBuffer(); | ||||
|     orders.value.push(...ordersTemp); | ||||
|   } | ||||
|  | ||||
|   async function fetchOrdersOutOfBuffer() : Promise<Array<Order>> { | ||||
|     const response = await axiosInstance.get('/zamowienia', {withCredentials: true}); | ||||
|     const ordersTemp : Array<Order> = response.data; | ||||
|     return ordersTemp; | ||||
|   } | ||||
|  | ||||
|   async function fetchOrdersInBuffer() : Promise<Array<Order>> { | ||||
|     const response = await axiosInstance.get('/zamowienia/bufor', {withCredentials: true}); | ||||
|   async function fetchOrdersByBuffer(inBuffer : boolean | null) { | ||||
|     let urlString = '/zamowienia'; | ||||
|     if(inBuffer != null) { | ||||
|       urlString += '?bufor=' + Number(inBuffer).toString(); | ||||
|     } | ||||
|     const response = await axiosInstance.get(urlString, {withCredentials: true}); | ||||
|     const ordersTemp : Array<Order> = response.data; | ||||
|     return ordersTemp; | ||||
|   } | ||||
|  | ||||
|   async function fetchOrder(uuid : string) { | ||||
|   async function fetchOrdersByDateStartAndEnd(dateStart : Date, dateEnd : Date, inBuffer : boolean | null) { | ||||
|     let urlString = '/zamowienia?od=' + dateStart.toISOString().split('T')[0] + '&do=' + dateEnd.toISOString().split('T')[0] | ||||
|     if(inBuffer != null) { | ||||
|       urlString += '&bufor=' + Number(inBuffer).toString(); | ||||
|     } | ||||
|     const response = await axiosInstance.get(urlString, {withCredentials: true}); | ||||
|     const ordersTemp : Array<Order> = response.data; | ||||
|     return ordersTemp; | ||||
|   } | ||||
|  | ||||
|   async function fetchOrdersByDay(date : Date, inBuffer : boolean | null) { | ||||
|     let urlString = "/zamowienia/" + date.toISOString().split("T")[0]; | ||||
|     console.log(urlString); | ||||
|     if(inBuffer != null) { | ||||
|       urlString += '?bufor=' + Number(inBuffer).toString(); | ||||
|     } | ||||
|     const response = await axiosInstance.get(urlString, {withCredentials: true}); | ||||
|     const ordersTemp : Array<Order> = response.data; | ||||
|     return ordersTemp; | ||||
|   } | ||||
|  | ||||
|   async function loadOrder(uuidString: string, confirmed: boolean, contractor: Ref<Contractor|undefined>, contractors: Ref<Array<Contractor>>, categories: Ref<Array<Category>>) { | ||||
|     const response = await axiosInstance.get('/zamowienie/' + uuidString); | ||||
|     const tempOrder = response.data; | ||||
|  | ||||
|     console.log(tempOrder); | ||||
|  | ||||
|     if(confirmed) { | ||||
| @@ -58,8 +70,14 @@ export const useOrdersStore = defineStore('orders', () => { | ||||
|       for(const category of categories.value) { | ||||
|         const product = category.Towary.find(product => (product.Twr_TwrId == orderProduct.MZE_TwrId)); | ||||
|         if(product != undefined && orderProduct.MZE_TwrCena != null) { | ||||
|           console.log(product); | ||||
|           if(orderProduct.MZE_TwrJm == product.Twr_JM) { | ||||
|             product.Twr_Cena = orderProduct.MZE_TwrCena.slice(0, -2); | ||||
|           } else if(orderProduct.Twr_Cena == product.Twr_JMZ) { | ||||
|             product.Twr_CenaZ = orderProduct.MZE_TwrCena.slice(0, -2); | ||||
|           } | ||||
|           product.Quantity = orderProduct.MZE_TwrIlosc.slice(0, -2); | ||||
|           product.ChosenOption = orderProduct.MZE_TwrJm; | ||||
|           category.isVisible = true; | ||||
|           break; | ||||
|         } | ||||
| @@ -67,5 +85,5 @@ export const useOrdersStore = defineStore('orders', () => { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return {orders, order, uuid, deliveryDate, orderDate, fetchOrders, fetchOrdersInBuffer, fetchOrdersOutOfBuffer, loadOrder} | ||||
|   return {orders, order, uuid, deliveryDate, orderDate, fetchOrders, loadOrder, fetchOrdersByDay, fetchOrdersByBuffer, fetchOrdersByDateStartAndEnd} | ||||
| }) | ||||
| @@ -4,34 +4,42 @@ import { useOrdersStore } from '@/stores/orders.store' | ||||
| import type { Order } from '@/main' | ||||
| import { useContractorsStore } from '@/stores/contractors.store' | ||||
| import { useCategoriesStore } from '@/stores/categories.store' | ||||
| import { router } from '@/router/router' | ||||
|  | ||||
| export const useSiteControlStore = defineStore('siteControl', () => { | ||||
|   const isForm = ref<boolean>(true); | ||||
|   const isOrders = ref<boolean>(false); | ||||
|   const shownComponent = ref<string>('mainForm'); | ||||
|   const showConfirmationModal = ref<boolean>(false); | ||||
|   const isDarkTheme = ref<boolean>(false); | ||||
|   const isLoading = ref<boolean>(true); | ||||
|  | ||||
|  | ||||
|   function switchToFrom() { | ||||
|     if(!isForm.value) { | ||||
|       isForm.value = true; | ||||
|       isOrders.value = false; | ||||
|   function switchToForm() { | ||||
|     shownComponent.value = "mainForm"; | ||||
|     if(router.currentRoute.value.fullPath != "/") { | ||||
|       router.push("/"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async function switchToOrders() { | ||||
|     if(!isOrders.value) { | ||||
|     if(shownComponent.value != 'orderSelector') { | ||||
|       const orderStore = useOrdersStore(); | ||||
|       const { orders } = storeToRefs(orderStore); | ||||
|       isLoading.value = true; | ||||
|       isForm.value = false; | ||||
|       isOrders.value = true; | ||||
|       shownComponent.value = "orderSelector" | ||||
|       orders.value = new Array<Order>(); | ||||
|       orders.value.push(... await orderStore.fetchOrdersInBuffer()); | ||||
|       orders.value.push(... await orderStore.fetchOrdersOutOfBuffer()); | ||||
|       orders.value = await orderStore.fetchOrders(); | ||||
|       isLoading.value = false; | ||||
|     } | ||||
|     if(router.currentRoute.value.fullPath != "/") { | ||||
|       router.push("/"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async function switchToTable() { | ||||
|     if(router.currentRoute.value.fullPath != "/table") { | ||||
|       shownComponent.value = "table" | ||||
|       router.push("/table"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function checkTheme() { | ||||
| @@ -42,15 +50,31 @@ export const useSiteControlStore = defineStore('siteControl', () => { | ||||
|     const orderStore = useOrdersStore(); | ||||
|     const contractorsStore = useContractorsStore(); | ||||
|     const categoriesStore = useCategoriesStore(); | ||||
|     isForm.value = true; | ||||
|     isOrders.value = false; | ||||
|     shownComponent.value = "mainForm"; | ||||
|     isLoading.value = true; | ||||
|     window.scrollTo(0, 0); | ||||
|     await categoriesStore.fetchCategories(); | ||||
|     const { contractor, contractors } = storeToRefs(contractorsStore); | ||||
|     const { categories } = storeToRefs(categoriesStore); | ||||
|     await orderStore.loadOrder(uuid, false, contractor, contractors, categories); | ||||
|     isLoading.value=false; | ||||
|   } | ||||
|  | ||||
|   return {isForm, isOrders, isLoading, showConfirmationModal, isDarkTheme, switchToFrom, switchToOrders, checkTheme, viewOrder}; | ||||
|   function newOrder() { | ||||
|     const ordersStore = useOrdersStore(); | ||||
|     const contractorsStore = useContractorsStore(); | ||||
|     const categoriesStore = useCategoriesStore(); | ||||
|     const { order, uuid, deliveryDate, orderDate } = storeToRefs(ordersStore); | ||||
|     const { contractor } = storeToRefs(contractorsStore); | ||||
|     contractor.value = undefined; | ||||
|     order.value = undefined; | ||||
|     uuid.value = undefined; | ||||
|     deliveryDate.value = undefined; | ||||
|     orderDate.value = undefined; | ||||
|     categoriesStore.fetchCategories(); | ||||
|     switchToForm(); | ||||
|     window.scrollTo(0, 0); | ||||
|   } | ||||
|  | ||||
|   return {isLoading, showConfirmationModal, isDarkTheme, shownComponent, switchToForm, switchToOrders, switchToTable, checkTheme, viewOrder, newOrder}; | ||||
| }) | ||||
| @@ -12,15 +12,12 @@ const schema = Yup.object().shape({ | ||||
| }); | ||||
|  | ||||
| async function onSubmit(values : any, { setErrors } : any) { | ||||
|   const { username, password, errors } = values; | ||||
|  | ||||
|   console.log(username + ' ' + password); | ||||
|   const { username, password } = values; | ||||
|  | ||||
|   const body = await axiosInstance.post('/login', { | ||||
|     username: username, | ||||
|     password: password | ||||
|   }).catch ((error) => { | ||||
|     console.log(error.response); | ||||
|     if(error.response.status == 401) { | ||||
|       setErrors({ apiError: "unauthorized" }) | ||||
|     } | ||||
| @@ -77,7 +74,3 @@ async function onSubmit(values : any, { setErrors } : any) { | ||||
|  | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
|  | ||||
| </style> | ||||
|   | ||||
| @@ -4,23 +4,24 @@ | ||||
|   <div v-if="isLoading"> | ||||
|     <LoadingComponent/> | ||||
|   </div> | ||||
|   <div v-else> | ||||
|     <div v-if="isForm"> | ||||
|   <div> | ||||
|     <div v-if="shownComponent == 'mainForm'"> | ||||
|       <MainForm | ||||
|         v-if="order == undefined || order.MZN_Bufor==1" | ||||
|       /> | ||||
|       <ConfirmedForm v-else-if="order.MZN_Bufor==0"/> | ||||
|     </div> | ||||
|     <OrdersSelector class="box is-shadowless" v-else-if="isOrders" | ||||
|     <OrdersSelector class="box is-shadowless" v-else-if="shownComponent == 'orderSelector'" | ||||
|     /> | ||||
|   </div> | ||||
|   <ConfirmationModal v-show="showConfirmationModal" @close="showConfirmationModal = false" @confirm="closeConfirmationModal" :order-uuid="uuid"></ConfirmationModal> | ||||
|   <button class="button" @click="test">test</button> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import '@/assets/base.css' | ||||
| import { useContractorsStore } from '@/stores/contractors.store' | ||||
| import { storeToRefs } from 'pinia' | ||||
| import { getActivePinia, storeToRefs } from 'pinia' | ||||
| import { useCategoriesStore } from '@/stores/categories.store' | ||||
| import { useOrdersStore } from '@/stores/orders.store' | ||||
| import { useSiteControlStore } from '@/stores/siteControl.store' | ||||
| @@ -36,7 +37,7 @@ const contractor = storeToRefs(contractorsStore).contractor; | ||||
| const categories = storeToRefs(categoriesStore).categories; | ||||
| const { uuid, order } = storeToRefs(ordersStore); | ||||
| const { username } = storeToRefs(userStore); | ||||
| const { isForm, isOrders, showConfirmationModal, isLoading } = storeToRefs(siteControlStore); | ||||
| const { isForm, isOrders, showConfirmationModal, isLoading, shownComponent } = storeToRefs(siteControlStore); | ||||
|  | ||||
|  | ||||
| async function  fetchData() { | ||||
| @@ -49,6 +50,10 @@ async function  fetchData() { | ||||
|   isLoading.value = false; | ||||
| } | ||||
|  | ||||
| function test() { | ||||
|   console.log(getActivePinia()); | ||||
| } | ||||
|  | ||||
| function closeConfirmationModal() { | ||||
|   showConfirmationModal.value = false; | ||||
|   if (uuid.value != undefined) { | ||||
| @@ -57,6 +62,7 @@ function closeConfirmationModal() { | ||||
|   } | ||||
| } | ||||
|  | ||||
| console.log(localStorage.getItem('piniaState')); | ||||
| siteControlStore.checkTheme(); | ||||
| fetchData(); | ||||
| </script> | ||||
|   | ||||
							
								
								
									
										90
									
								
								src/views/SummedOrdersView.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/views/SummedOrdersView.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| <script setup lang="ts"> | ||||
| import { useOrdersStore } from '@/stores/orders.store' | ||||
| import { storeToRefs } from 'pinia' | ||||
| import { useRoute } from 'vue-router' | ||||
| import NavBar from '@/components/NavBar.vue' | ||||
| import VueDatePicker from '@vuepic/vue-datepicker' | ||||
| import { useSiteControlStore } from '@/stores/siteControl.store' | ||||
| import { ref } from 'vue' | ||||
|  | ||||
| const ordersStore = useOrdersStore(); | ||||
| const siteControlStore = useSiteControlStore(); | ||||
|  | ||||
| const { orders } = storeToRefs(ordersStore); | ||||
| const { isDarkTheme } = storeToRefs(siteControlStore); | ||||
| const searchDate = ref<Date>(); | ||||
| const confirmedOrders = ref<boolean>(); | ||||
|  | ||||
|  | ||||
| orders.value = await ordersStore.fetchOrdersByDay(new Date(Date.now()), null); | ||||
|  | ||||
| const route = useRoute(); | ||||
| console.log(route); | ||||
|  | ||||
| async function fetchOrders() { | ||||
|   console.log((confirmedOrders.value) ? true : null); | ||||
|   orders.value = await ordersStore.fetchOrdersByDateStartAndEnd(searchDate.value != undefined ? searchDate.value : new Date(Date.now()), | ||||
|     searchDate.value != undefined ? searchDate.value : new Date(Date.now()), | ||||
|     (confirmedOrders.value) ? true : null); | ||||
| } | ||||
|  | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <NavBar/> | ||||
|   <div class="columns box is-shadowless"> | ||||
|     <div class="column box mr-3"> | ||||
|       <h1 class="title is-4 mb-3">Opcje</h1> | ||||
|       <label class="label is-small">Data dostawy</label> | ||||
|       <VueDatePicker v-model="searchDate" | ||||
|                      :enable-time-picker="false" | ||||
|                      :clearable="true" | ||||
|                      input-class-name="input is-small calendar-background" | ||||
|                      menu-class-name="calendar-background" | ||||
|                      v-bind:dark = "isDarkTheme" /> | ||||
|  | ||||
|       <div class="control mt-3"> | ||||
|         <label class="checkbox mr-5"> | ||||
|           <input type="checkbox" v-model="confirmedOrders"/> | ||||
|           Tylko potwierdzone zamówienia? | ||||
|         </label> | ||||
|       </div> | ||||
|  | ||||
|       <button class="button mt-3" @click="fetchOrders">Potwierdź</button> | ||||
|     </div> | ||||
|     <div class="column is-four-fifths is-flex is-align-content-center box is-justify-content-center"> | ||||
|       <table class="table blackBorder"> | ||||
|         <thead> | ||||
|         <tr class="has-background-grey-light"> | ||||
|           <th>Nazwa produktu</th> | ||||
|           <th>Ilość</th> | ||||
|           <th>Jednostka miary</th> | ||||
|           <th>Cena jednostkowa</th> | ||||
|           <th>Cena całkowita</th> | ||||
|         </tr> | ||||
|         </thead> | ||||
|         <tbody v-for="order in orders" :key="order.MZN_UUID"> | ||||
|         <tr class="has-background-grey-lighter"> | ||||
|           <th colspan="5"> | ||||
|             {{ order.MZN_PodNazwa1 + order.MZN_PodNazwa2 + order.MZN_PodNazwa3 + order.MZN_DataDos.toString()}} | ||||
|           </th> | ||||
|         </tr> | ||||
|         <tr v-for="product in order.MZamElem" :key="product.MZE_MZEID"> | ||||
|           <th>{{ product.MZE_TwrNazwa }}</th> | ||||
|           <th>{{ Number(product.MZE_TwrIlosc).toFixed(2) }}</th> | ||||
|           <th>{{ product.MZE_TwrJm }}</th> | ||||
|           <th>{{ Number(product.MZE_TwrCena).toFixed(2) }}</th> | ||||
|           <th>{{ (Number(product.MZE_TwrCena) * Number(product.MZE_TwrIlosc)).toFixed(2) }}</th> | ||||
|         </tr> | ||||
|         </tbody> | ||||
|       </table> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
| .blackBorder { | ||||
|   --bulma-table-cell-border-color : black; | ||||
| } | ||||
| </style> | ||||
| @@ -1,2 +1,3 @@ | ||||
| export { default as LoginView } from "./LoginView.vue"; | ||||
| export { default as MainView } from "./MainView.vue"; | ||||
| export { default as SummedOrdersView } from "./SummedOrdersView.vue" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user