Index.vue 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <script setup>
  2. import { Head } from '@inertiajs/inertia-vue3'
  3. import { includes } from 'lodash'
  4. import AppLayout from '@/layouts/AppLayout.vue'
  5. defineProps({
  6. cardStatistics: Array,
  7. barStatistics: Array,
  8. barHorizontalStatistics: Array,
  9. })
  10. const colors = [
  11. '#349dcf',
  12. '#00b2da',
  13. '#00c7dd',
  14. '#1fdbdb',
  15. '#57eed3',
  16. '#88ffc9',
  17. '#96ed9a',
  18. '#a8d96c',
  19. '#bbc242',
  20. '#cda91d',
  21. ]
  22. const barChart = (chartData) => {
  23. const colors = ['#349dcf', '#a8d96c']
  24. const data = {
  25. datasets: [],
  26. }
  27. let id = 0
  28. for (const key in chartData) {
  29. data.datasets.push({
  30. label: key,
  31. backgroundColor: colors[id],
  32. data: chartData[key],
  33. })
  34. id++
  35. }
  36. return data
  37. }
  38. const barChartOption = {
  39. maintainAspectRatio: false,
  40. datasetFill: false,
  41. }
  42. const barHorizontalChart = (chartData) => {
  43. const labels = []
  44. const data = []
  45. for (const obj of chartData) {
  46. labels.push([obj.label1, obj.label2])
  47. data.push(obj.data)
  48. }
  49. return {
  50. labels: labels,
  51. datasets: [
  52. {
  53. data: data,
  54. backgroundColor: colors,
  55. },
  56. ],
  57. }
  58. }
  59. const barHorizontalChartOption = {
  60. maintainAspectRatio: false,
  61. datasetFill: false,
  62. indexAxis: 'y',
  63. plugins: {
  64. legend: {
  65. display: false,
  66. },
  67. },
  68. }
  69. const pieChart = (chartData) => {
  70. const labels = []
  71. const data = []
  72. for (const key in chartData) {
  73. labels.push(key)
  74. data.push(chartData[key])
  75. }
  76. return {
  77. labels: labels,
  78. datasets: [
  79. {
  80. data: data,
  81. backgroundColor: colors,
  82. },
  83. ],
  84. }
  85. }
  86. const pieChartOption = {
  87. maintainAspectRatio: false,
  88. datasetFill: false,
  89. }
  90. </script>
  91. <template>
  92. <AppLayout>
  93. <Head title="Dashboard" />
  94. <div class="grid">
  95. <template v-for="cardStatistic in cardStatistics">
  96. <div v-if="includes(cardStatistic.roleId, $page.props.auth.user.role_id)" class="col-12 md:col-4 xl:col-3">
  97. <Card class="h-full">
  98. <template #content>
  99. <div class="flex justify-content-between mb-3">
  100. <div>
  101. <span class="block text-500 font-medium mb-3">{{ cardStatistic.title }}</span>
  102. <div v-if="cardStatistic.value" class="text-900 font-medium text-xl">{{ cardStatistic.value }}</div>
  103. </div>
  104. <div
  105. class="flex align-items-center justify-content-center bg-orange-100 border-round"
  106. style="width: 2.5rem; height: 2.5rem"
  107. >
  108. <i class="text-orange-500 text-xl" :class="cardStatistic.icon"></i>
  109. </div>
  110. </div>
  111. <span class="text-green-500 font-medium">{{ cardStatistic.amount }} </span>
  112. <span class="text-500"> {{ ' ' + cardStatistic.amountLabel }}</span>
  113. </template>
  114. </Card>
  115. </div>
  116. </template>
  117. </div>
  118. <div class="grid">
  119. <template v-for="barStatistic in barStatistics">
  120. <div v-if="includes(barStatistic.roleId, $page.props.auth.user.role_id)" class="col-12 md:col-6">
  121. <Card>
  122. <template #title>
  123. <div class="flex flex-column">
  124. <span>{{ barStatistic.title }}</span>
  125. <span v-if="barStatistic.description" class="text-base font-normal">{{
  126. barStatistic.description
  127. }}</span>
  128. </div>
  129. </template>
  130. <template v-if="Object.keys(barStatistic.data).length" #content>
  131. <Chart
  132. type="bar"
  133. :width="600"
  134. :height="300"
  135. :data="barChart(barStatistic.data)"
  136. :options="barChartOption"
  137. />
  138. </template>
  139. </Card>
  140. </div>
  141. </template>
  142. <!-- <div v-for="barHorizontalStatistic in barHorizontalStatistics" class="col-12 md:col-6">
  143. <Card>
  144. <template #title>
  145. <div class="flex flex-column">
  146. <span>{{ barHorizontalStatistic.title }}</span>
  147. <span v-if="barHorizontalStatistic.description" class="text-base font-normal">{{
  148. barHorizontalStatistic.description
  149. }}</span>
  150. </div>
  151. </template>
  152. <template #content>
  153. <Chart
  154. type="bar"
  155. :width="600"
  156. :height="300"
  157. :data="barHorizontalChart(barHorizontalStatistic.data)"
  158. :options="barHorizontalChartOption"
  159. />
  160. </template>
  161. </Card>
  162. </div> -->
  163. <!-- <div v-for="pieStatistic in pieStatistics" class="col-12 md:col-6">
  164. <Card>
  165. <template #title>
  166. <div class="flex flex-column">
  167. <span>{{ pieStatistic.title }}</span>
  168. <span v-if="pieStatistic.description" class="text-base font-normal">{{ pieStatistic.description }}</span>
  169. </div>
  170. </template>
  171. <template #content>
  172. <Chart
  173. type="pie"
  174. :width="600"
  175. :height="300"
  176. :data="pieChart(pieStatistic.data)"
  177. :options="pieChartOption"
  178. />
  179. </template>
  180. </Card>
  181. </div> -->
  182. </div>
  183. </AppLayout>
  184. </template>