Index.vue 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <script setup>
  2. import { ref, watch } from 'vue'
  3. import { Inertia } from '@inertiajs/inertia'
  4. import { Head, useForm } from '@inertiajs/inertia-vue3'
  5. import throttle from 'lodash/throttle'
  6. import pickBy from 'lodash/pickBy'
  7. import AppButton from '@/components/AppButton.vue'
  8. import AppPagination from '@/components/AppPagination.vue'
  9. import AppMenu from '@/components/AppMenu.vue'
  10. import AppDropdown from '@/components/AppDropdown.vue'
  11. import AppLayout from '@/layouts/AppLayout.vue'
  12. import { IndexTable } from './TableHeader'
  13. const props = defineProps({
  14. transactions: Object,
  15. transactionsStatus: Array,
  16. filters: Object,
  17. })
  18. const filterForm = useForm({
  19. search: props.filters.search,
  20. dates: props.filters.dates,
  21. })
  22. watch(
  23. filterForm,
  24. throttle(() => {
  25. Inertia.get('/transactions', pickBy({ search: filterForm.search, dates: filterForm.dates }), {
  26. preserveState: true,
  27. })
  28. }, 300)
  29. )
  30. const transactionId = ref()
  31. const updateStatusDialog = ref(false)
  32. const updateStatusForm = useForm({
  33. transaction_status_id: null,
  34. })
  35. const updateStatusSubmit = () => {
  36. updateStatusForm.put(route('transactions.update', transactionId.value), {
  37. onSuccess: () => {
  38. updateStatusDialog.value = false
  39. },
  40. })
  41. }
  42. const updateStatusItems = ref([])
  43. const overlayMenu = ref()
  44. const overlayItems = ref([])
  45. const startPrinting = (transactionNumber) => {
  46. Inertia.get(`/thermal-printing/${transactionNumber}`)
  47. }
  48. const overlayToggle = (event, data) => {
  49. overlayItems.value =
  50. data.transactionStatusId == 4
  51. ? [
  52. {
  53. label: 'Lihat detail',
  54. icon: 'pi pi-eye',
  55. to: route('transactions.show', data.id),
  56. },
  57. {
  58. label: 'Cetak ulang',
  59. icon: 'pi pi-print',
  60. command() {
  61. startPrinting(data.transactionNumber)
  62. },
  63. },
  64. ]
  65. : [
  66. {
  67. label: 'Perbaharui status',
  68. icon: 'pi pi-refresh',
  69. command() {
  70. updateStatusDialog.value = true
  71. },
  72. },
  73. {
  74. label: 'Lihat detail',
  75. icon: 'pi pi-eye',
  76. to: route('transactions.show', data.id),
  77. },
  78. {
  79. label: 'Cetak ulang',
  80. icon: 'pi pi-print',
  81. command() {
  82. startPrinting(data.transactionNumber)
  83. },
  84. },
  85. ]
  86. updateStatusItems.value = props.transactionsStatus.filter((val) => val.value >= data.transactionStatusId)
  87. updateStatusForm.transaction_status_id = data.transactionStatusId
  88. transactionId.value = data.id
  89. overlayMenu.value.toggle(event)
  90. }
  91. </script>
  92. <template>
  93. <Head title="Daftar Transaksi" />
  94. <AppLayout>
  95. <DataTable
  96. responsiveLayout="scroll"
  97. columnResizeMode="expand"
  98. :value="transactions.data"
  99. :rowHover="true"
  100. :stripedRows="true"
  101. >
  102. <template #header>
  103. <h5>Transaksi</h5>
  104. <div class="grid">
  105. <div class="col-12 md:col-8">
  106. <div class="flex flex-column md:flex-row">
  107. <div class="flex align-items-center mr-0 md:mr-2 mb-2 md:mb-0">
  108. <InputText class="w-full md:w-16rem" placeholder="cari..." v-model="filterForm.search" />
  109. </div>
  110. <Calendar
  111. class="w-full md:w-16rem"
  112. v-model="filterForm.dates"
  113. selection-mode="range"
  114. placeholder="filter waktu..."
  115. date-format="dd/mm/yy"
  116. :show-button-bar="true"
  117. :manual-input="false"
  118. />
  119. </div>
  120. </div>
  121. <div class="col-12 md:col-4 flex justify-content-end">
  122. <AppButton
  123. label="Tambah Transaksi"
  124. class="p-button-text"
  125. icon="pi pi-pencil"
  126. :href="route('transactions.create')"
  127. />
  128. </div>
  129. </div>
  130. </template>
  131. <Column
  132. v-for="indexTable in IndexTable"
  133. :field="indexTable.field"
  134. :header="indexTable.header"
  135. :key="indexTable.field"
  136. >
  137. <template #body="{ data, field }">
  138. <template v-if="field === 'transactionStatusName'">
  139. <Badge v-if="data['transactionStatusId'] === 1" :value="data[field]"></Badge>
  140. <Badge v-else-if="data['transactionStatusId'] === 2" :value="data[field]" severity="warning"></Badge>
  141. <Badge v-else :value="data[field]" severity="success"></Badge>
  142. </template>
  143. <template v-else-if="field === 'customer'">
  144. <p class="font-bold">{{ data.customer.number }}</p>
  145. <p>{{ data.customer.name }}</p>
  146. <p>{{ data.customer.phone }}</p>
  147. </template>
  148. <template v-else-if="field === 'transactionNumber'">
  149. <p class="font-bold">{{ data[field] }}</p>
  150. <p>{{ data.dateLaundry }}</p>
  151. </template>
  152. <template v-else>
  153. {{ data[field] }}
  154. </template>
  155. </template>
  156. </Column>
  157. <Column>
  158. <template #body="slotProps">
  159. <Button
  160. icon="pi pi-angle-double-down"
  161. class="p-button-rounded p-button-text"
  162. aria-controls="overlay_menu"
  163. @click="overlayToggle($event, slotProps.data)"
  164. />
  165. <AppMenu id="overlay_menu" ref="overlayMenu" :popup="true" :model="overlayItems" />
  166. </template>
  167. </Column>
  168. </DataTable>
  169. <AppPagination :links="transactions.links" />
  170. <Dialog
  171. modal
  172. v-model:visible="updateStatusDialog"
  173. class="p-fluid"
  174. header="Perbaharui Status"
  175. :style="{ width: '450px' }"
  176. :breakpoints="{ '960px': '75vw' }"
  177. @hide="updateStatusDialog"
  178. >
  179. <div class="grid">
  180. <div class="col-12">
  181. <AppDropdown
  182. label="Perbaharui Status"
  183. placeholder="pilih satu"
  184. v-model="updateStatusForm.transaction_status_id"
  185. :error="updateStatusForm.error"
  186. :options="updateStatusItems"
  187. />
  188. </div>
  189. </div>
  190. <template #footer>
  191. <div class="flex justify-content-end">
  192. <AppButton
  193. label="Simpan"
  194. icon="pi pi-check"
  195. class="p-button-text"
  196. :disabled="updateStatusForm.processing"
  197. @click="updateStatusSubmit"
  198. />
  199. </div>
  200. </template>
  201. </Dialog>
  202. </AppLayout>
  203. </template>