Browse Source

ajustes avaliacao: max 5 files, so permite anexar foto em avaliaca negativa, nao tava exibindo foto do avaliado, pré-seleciona favorito se ja era antes

Gustavo Zanatta 1 tuần trước cách đây
mục cha
commit
b70687cd90

+ 70 - 5
src/pages/dashboard/components/schedule/ScheduleRatingDialog.vue

@@ -24,7 +24,14 @@
           class="q-mb-sm"
           size="64px"
         >
+          <img
+            v-if="photoUrl"
+            style="object-fit: cover"
+            :src="photoUrl"
+          />
+
           <span
+            v-else
             class="full-width full-height flex flex-center"
             style="border-radius: 50%"
             :style="avatarStyle"
@@ -112,7 +119,10 @@
         />
       </q-card-section>
 
-      <q-card-section class="q-pt-xs q-pb-xs q-px-lg">
+      <q-card-section
+        v-if="isNegative"
+        class="q-pt-xs q-pb-xs q-px-lg"
+      >
         <input
           ref="photoInputRef"
           accept="image/jpeg,image/png,image/webp"
@@ -142,7 +152,7 @@
           </div>
 
           <div
-            v-if="photos.length < 5"
+            v-if="photos.length < MAX_PHOTOS"
             class="photo-add"
             @click="photoInputRef.click()"
           >
@@ -206,7 +216,12 @@
 import { avatarColors } from "src/helpers/avatarColors";
 import { computed, onMounted, ref } from "vue";
 import { createReview, getImprovementTypes } from "src/api/review";
+import {
+  deleteClientFavoriteProvider,
+  getClientFavoriteProviders,
+} from "src/api/clientFavoriteProvider";
 import { getFirstName } from "src/helpers/utils";
+import { getProfileMediaUrl } from "src/helpers/profileMedia";
 import { useDialogPluginComponent, useQuasar } from "quasar";
 import { useI18n } from "vue-i18n";
 import { userStore } from "src/stores/user";
@@ -228,8 +243,12 @@ const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
 const store = userStore();
 const { t } = useI18n();
 
+const MAX_PHOTOS = 5;
+
 const checkboxValue = ref(false);
 const comment = ref(null);
+const favoriteId = ref(null);
+const isFavoriteProvider = ref(false);
 const loading = ref(false);
 const loadingTags = ref(false);
 const photoInputRef = ref(null);
@@ -245,6 +264,8 @@ const avatarStyle = computed(() => {
   return { background: c.background, color: c.color };
 });
 
+const photoUrl = computed(() => getProfileMediaUrl(props.schedule));
+
 const initials = computed(() => {
   const firstName = getFirstName(props.schedule.provider_name);
 
@@ -257,7 +278,7 @@ const isPositive = computed(() => stars.value >= 3);
 const onPhotosSelected = (event) => {
   const files = Array.from(event.target.files);
 
-  const remaining = 5 - photos.value.length;
+  const remaining = MAX_PHOTOS - photos.value.length;
 
   files.slice(0, remaining).forEach((file) => {
     photos.value.push(file);
@@ -269,13 +290,42 @@ const onPhotosSelected = (event) => {
 
 const onStarsChange = () => {
   selectedTagIds.value = [];
-  checkboxValue.value = false;
+  checkboxValue.value = isPositive.value && isFavoriteProvider.value;
+
+  if (!isNegative.value) clearPhotos();
 };
 
 const openHelp = () => {
   $q.dialog({ component: ProfileHelpDialog });
 };
 
+const clearPhotos = () => {
+  photoPreviews.value.forEach((preview) => URL.revokeObjectURL(preview));
+  photos.value = [];
+  photoPreviews.value = [];
+};
+
+const loadFavoriteState = async () => {
+  const clientId = store.user?.client?.id;
+  if (!clientId) return;
+
+  try {
+    const favorites = await getClientFavoriteProviders(clientId);
+
+    const match = (favorites ?? []).find(
+      (f) => Number(f.provider_id) === Number(props.schedule.provider_id),
+    );
+
+    isFavoriteProvider.value = !!match;
+    favoriteId.value = match?.id ?? null;
+
+    if (isPositive.value && isFavoriteProvider.value) checkboxValue.value = true;
+  } catch {
+    isFavoriteProvider.value = false;
+    favoriteId.value = null;
+  }
+};
+
 const removePhoto = (idx) => {
   URL.revokeObjectURL(photoPreviews.value[idx]);
   photos.value.splice(idx, 1);
@@ -298,9 +348,22 @@ const submit = async () => {
       block_provider: isNegative.value && checkboxValue.value,
       block_client: false,
       favorite_provider: isPositive.value && checkboxValue.value,
-      photos: photos.value,
+      photos: isNegative.value ? photos.value : [],
     });
 
+    if (
+      isPositive.value &&
+      !checkboxValue.value &&
+      isFavoriteProvider.value &&
+      favoriteId.value
+    ) {
+      try {
+        await deleteClientFavoriteProvider(favoriteId.value);
+      } catch {
+        // manter a avaliação enviada mesmo se a remoção do favorito falhar
+      }
+    }
+
     onDialogOK(true);
   } catch (error) {
     const status = error?.response?.status;
@@ -326,6 +389,8 @@ const toggleTag = (id) => {
 };
 
 onMounted(async () => {
+  loadFavoriteState();
+
   loadingTags.value = true;
 
   try {