Index.vue 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <script setup>
  2. import { Head } from '@inertiajs/inertia-vue3'
  3. import { includes } from 'lodash'
  4. import DashboardLayout from '@/layouts/DashboardLayout.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. <DashboardLayout>
  93. <Head title="Dashboard" />
  94. <div class="grid">
  95. <template v-for="cardStatistic in cardStatistics">
  96. <div
  97. v-if="includes(cardStatistic.roleId, $page.props.auth.user.role_id)"
  98. class="col-12 md:col-4 xl:col-3"
  99. >
  100. <Card class="h-full">
  101. <template #content>
  102. <div class="flex justify-content-between mb-3">
  103. <div>
  104. <span class="block text-500 font-medium mb-3">{{
  105. cardStatistic.title
  106. }}</span>
  107. <div
  108. v-if="cardStatistic.value"
  109. class="text-900 font-medium text-xl"
  110. >
  111. {{ cardStatistic.value }}
  112. </div>
  113. </div>
  114. <div
  115. class="flex align-items-center justify-content-center bg-orange-100 border-round"
  116. style="width: 2.5rem; height: 2.5rem"
  117. >
  118. <i
  119. class="text-orange-500 text-xl"
  120. :class="cardStatistic.icon"
  121. ></i>
  122. </div>
  123. </div>
  124. <span class="text-green-500 font-medium"
  125. >{{ cardStatistic.amount }}
  126. </span>
  127. <span class="text-500">
  128. {{ ' ' + cardStatistic.amountLabel }}</span
  129. >
  130. </template>
  131. </Card>
  132. </div>
  133. </template>
  134. </div>
  135. <div class="grid">
  136. <template v-for="barStatistic in barStatistics">
  137. <div
  138. v-if="includes(barStatistic.roleId, $page.props.auth.user.role_id)"
  139. class="col-12 md:col-6"
  140. >
  141. <Card>
  142. <template #title>
  143. <div class="flex flex-column">
  144. <span>{{ barStatistic.title }}</span>
  145. <span
  146. v-if="barStatistic.description"
  147. class="text-base font-normal"
  148. >{{ barStatistic.description }}</span
  149. >
  150. </div>
  151. </template>
  152. <template v-if="Object.keys(barStatistic.data).length" #content>
  153. <Chart
  154. type="bar"
  155. :width="600"
  156. :height="300"
  157. :data="barChart(barStatistic.data)"
  158. :options="barChartOption"
  159. />
  160. </template>
  161. </Card>
  162. </div>
  163. </template>
  164. <!-- <div v-for="barHorizontalStatistic in barHorizontalStatistics" class="col-12 md:col-6">
  165. <Card>
  166. <template #title>
  167. <div class="flex flex-column">
  168. <span>{{ barHorizontalStatistic.title }}</span>
  169. <span v-if="barHorizontalStatistic.description" class="text-base font-normal">{{
  170. barHorizontalStatistic.description
  171. }}</span>
  172. </div>
  173. </template>
  174. <template #content>
  175. <Chart
  176. type="bar"
  177. :width="600"
  178. :height="300"
  179. :data="barHorizontalChart(barHorizontalStatistic.data)"
  180. :options="barHorizontalChartOption"
  181. />
  182. </template>
  183. </Card>
  184. </div> -->
  185. <!-- <div v-for="pieStatistic in pieStatistics" class="col-12 md:col-6">
  186. <Card>
  187. <template #title>
  188. <div class="flex flex-column">
  189. <span>{{ pieStatistic.title }}</span>
  190. <span v-if="pieStatistic.description" class="text-base font-normal">{{ pieStatistic.description }}</span>
  191. </div>
  192. </template>
  193. <template #content>
  194. <Chart
  195. type="pie"
  196. :width="600"
  197. :height="300"
  198. :data="pieChart(pieStatistic.data)"
  199. :options="pieChartOption"
  200. />
  201. </template>
  202. </Card>
  203. </div> -->
  204. </div>
  205. </DashboardLayout>
  206. </template>