Index.vue 7.0KB

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