|
|
@@ -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 {
|