DashboardProvidersClose.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <template>
  2. <div class="q-mx-md q-mb-lg">
  3. <div class="row items-center justify-between no-wrap q-mb-sm">
  4. <div class="dashboard-section-title gradient-diarista font16 fontbold">{{ $t('dashboard_client.providers_close.title') }}</div>
  5. <div class="text-text-light">
  6. <q-btn flat color="text-light" size="sm" icon="mdi-chevron-left" @click="setPeriodTypePrevious"/>
  7. <span class="font10 fontbold">{{ showCorrectLabels() }}</span>
  8. <q-btn flat color="text-light" size="sm" icon="mdi-chevron-right" @click="setPeriodTypeNext"/>
  9. </div>
  10. </div>
  11. <div class="column">
  12. <q-card
  13. v-for="p in data"
  14. :key="p.provider_id"
  15. class="card-border bg-page text-text q-mb-sm"
  16. :flat="false"
  17. >
  18. <q-card-section class="row no-wrap q-pa-sm">
  19. <div class="row no-wrap full-width">
  20. <div class="col-2">
  21. <q-avatar :style="avatarColors[p.provider_id % avatarColors.length]" class="">
  22. <img v-if="p.provider_photo" :src="p.provider_photo" style="object-fit:cover;border-radius:50%;" />
  23. <span v-else>{{ p.provider_name?.slice(0,1).toUpperCase() ?? '—' }}</span>
  24. </q-avatar>
  25. </div>
  26. <div class="col-10 row">
  27. <div class="column col-9 justify-between">
  28. <span class="text-provider-close-name font12 fontmedium">{{ getFirstName(p.provider_name) }}</span>
  29. <span class="text-provider-close-region font9 fontmedium">{{ p.district }}</span>
  30. <div class="row items-center justify-between q-pr-lg">
  31. <div class="row items-center">
  32. <q-icon name="mdi-star" color="warning" size="12px" />
  33. <span class="text-provider-close-rating font9 fontmedium">
  34. {{ p.average_rating != null ? (Number(p.average_rating).toFixed(1) + ' (' + (p.total_reviews ?? 0) + ')') : ('(' + (p.total_reviews ?? 0) + ')') }}
  35. </span>
  36. </div>
  37. <div class="row items-center">
  38. <q-icon name="mdi-broom" color="secondary" size="16px" />
  39. <span class="text-provider-close-jobs font9 fontmedium">{{ p.total_services ?? 0 }}</span>
  40. </div>
  41. <div class="row items-center">
  42. <q-icon name="mdi-map-marker-outline" color="text" size="16px" />
  43. <span class="text-provider-close-jobs font9 fontmedium">{{ (p.distance_km ?? '--') + ' km' }}</span>
  44. </div>
  45. </div>
  46. </div>
  47. <div class="column col-3 justify-between text-center items-center">
  48. <span class="text-provider-close-price font12 fontmedium">
  49. {{ showCorrectValues(p) }}
  50. </span>
  51. <div class="full-width">
  52. <q-btn
  53. unelevated rounded no-caps
  54. color="primary"
  55. size="sm"
  56. padding="3px 12px"
  57. :label="$t('dashboard_client.providers_close.schedule')"
  58. @click="goToScheduling(p)"
  59. />
  60. </div>
  61. </div>
  62. </div>
  63. </div>
  64. </q-card-section>
  65. </q-card>
  66. </div>
  67. </div>
  68. </template>
  69. <script setup>
  70. import { useQuasar } from 'quasar';
  71. import { formatCurrency } from 'src/helpers/utils';
  72. import SchedulingDialog from 'src/pages/search/components/SchedulingDialog.vue';
  73. import { ref } from 'vue';
  74. import { useI18n } from 'vue-i18n';
  75. defineProps({ data: { type: Array, default: () => [] } });
  76. const $q = useQuasar();
  77. const { t } = useI18n();
  78. const currentPeriodType = ref(8);
  79. const periodTypeMap = ref({
  80. 2: 'daily_price_2h',
  81. 4: 'daily_price_4h',
  82. 6: 'daily_price_6h',
  83. 8: 'daily_price_8h',
  84. });
  85. // eslint-disable-next-line no-unused-vars
  86. const formatDistance = (distance) => {
  87. if (distance === null || distance === undefined || distance === '') return '—';
  88. const numericDistance = Number(distance);
  89. if (!Number.isFinite(numericDistance)) return '—';
  90. return `${numericDistance.toLocaleString('pt-BR', { maximumFractionDigits: 1 })} km`;
  91. };
  92. const showCorrectValues = (p) => {
  93. switch (currentPeriodType.value) {
  94. case 8:
  95. return p.daily_price_8h ? formatCurrency(p.daily_price_8h) : t('dashboard_client.providers_close.no_price');
  96. case 6:
  97. return p.daily_price_6h ? formatCurrency(p.daily_price_6h) : t('dashboard_client.providers_close.no_price');
  98. case 4:
  99. return p.daily_price_4h ? formatCurrency(p.daily_price_4h) : t('dashboard_client.providers_close.no_price');
  100. case 2:
  101. return p.daily_price_2h ? formatCurrency(p.daily_price_2h) : t('dashboard_client.providers_close.no_price');
  102. default:
  103. return t('dashboard_client.providers_close.no_price');
  104. }
  105. };
  106. const showCorrectLabels = () => {
  107. switch (currentPeriodType.value) {
  108. case 8:
  109. return t('dashboard_client.providers_close.until_8h');
  110. case 6:
  111. return t('dashboard_client.providers_close.until_6h');
  112. case 4:
  113. return t('dashboard_client.providers_close.until_4h');
  114. case 2:
  115. return t('dashboard_client.providers_close.until_2h');
  116. default:
  117. return '';
  118. }
  119. };
  120. const setPeriodTypePrevious = () => {
  121. const previousPeriod = currentPeriodType.value - 2;
  122. if (periodTypeMap.value[previousPeriod]) {
  123. currentPeriodType.value = previousPeriod;
  124. }
  125. };
  126. const setPeriodTypeNext = () => {
  127. const nextPeriod = currentPeriodType.value + 2;
  128. if (periodTypeMap.value[nextPeriod]) {
  129. currentPeriodType.value = nextPeriod;
  130. }
  131. };
  132. const avatarColors = [
  133. { background: '#ffd5df', color: '#932e57' },
  134. { background: '#d7e8ff', color: '#2158a8' },
  135. { background: '#dfd', color: '#2a7a3b' },
  136. { background: '#ffe5cc', color: '#8a4500' },
  137. ];
  138. const getFirstName = (name) => {
  139. if (!name) return 'Prestador';
  140. return name.trim().split(' ')[0];
  141. };
  142. const goToScheduling = (provider) => {
  143. $q.dialog({
  144. component: SchedulingDialog,
  145. componentProps: { provider },
  146. });
  147. };
  148. </script>
  149. <style scoped lang="scss">
  150. </style>