|
|
@@ -81,9 +81,11 @@
|
|
|
color="pink-4"
|
|
|
dense
|
|
|
flat
|
|
|
- icon="mdi-heart-outline"
|
|
|
+ :icon="isFavorite ? 'mdi-heart' : 'mdi-heart-outline'"
|
|
|
+ :loading="favoriteLoading"
|
|
|
round
|
|
|
size="sm"
|
|
|
+ @click="toggleFavorite"
|
|
|
/>
|
|
|
|
|
|
<q-btn
|
|
|
@@ -203,6 +205,11 @@ import { date } from 'quasar';
|
|
|
import { getClientProviderBlocks } from 'src/api/schedule';
|
|
|
import { getProviderBlockedDays, getProviderWorkingDays } from 'src/api/providerAvailability';
|
|
|
import { getProviderReceivedReviews } from 'src/api/review';
|
|
|
+import {
|
|
|
+ createClientFavoriteProvider,
|
|
|
+ deleteClientFavoriteProvider,
|
|
|
+ getClientFavoriteProviders,
|
|
|
+} from 'src/api/clientFavoriteProvider';
|
|
|
import { useDialogPluginComponent, useQuasar } from 'quasar';
|
|
|
import { useI18n } from 'vue-i18n';
|
|
|
import { useScheduleCartStore } from 'src/stores/scheduleCart';
|
|
|
@@ -232,6 +239,9 @@ const blockedDays = ref([]);
|
|
|
const loadingAvailability = ref(true);
|
|
|
const reviews = ref([]);
|
|
|
const loadingReviews = ref(true);
|
|
|
+const isFavorite = ref(false);
|
|
|
+const favoriteId = ref(null);
|
|
|
+const favoriteLoading = ref(false);
|
|
|
|
|
|
const avatarColors = [
|
|
|
{ background: '#ffd5df', color: '#932e57' },
|
|
|
@@ -361,6 +371,59 @@ const loadReviews = async () => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+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.provider.provider_id)
|
|
|
+ );
|
|
|
+
|
|
|
+ isFavorite.value = !!match;
|
|
|
+ favoriteId.value = match?.id ?? null;
|
|
|
+ } catch {
|
|
|
+ isFavorite.value = false;
|
|
|
+ favoriteId.value = null;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const toggleFavorite = async () => {
|
|
|
+ if (favoriteLoading.value) return;
|
|
|
+
|
|
|
+ const clientId = store.user?.client?.id;
|
|
|
+ if (!clientId) {
|
|
|
+ $q.notify({ type: 'negative', message: t('scheduling_page.favorite_error') });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ favoriteLoading.value = true;
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (isFavorite.value) {
|
|
|
+ if (favoriteId.value) {
|
|
|
+ await deleteClientFavoriteProvider(favoriteId.value);
|
|
|
+ }
|
|
|
+ isFavorite.value = false;
|
|
|
+ favoriteId.value = null;
|
|
|
+ $q.notify({ type: 'positive', message: t('scheduling_page.favorite_removed') });
|
|
|
+ } else {
|
|
|
+ const created = await createClientFavoriteProvider({
|
|
|
+ client_id: clientId,
|
|
|
+ provider_id: props.provider.provider_id,
|
|
|
+ });
|
|
|
+ isFavorite.value = true;
|
|
|
+ favoriteId.value = created?.id ?? null;
|
|
|
+ $q.notify({ type: 'positive', message: t('scheduling_page.favorite_added') });
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+ $q.notify({ type: 'negative', message: t('scheduling_page.favorite_error') });
|
|
|
+ } finally {
|
|
|
+ favoriteLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
const normalizeDate = (dateStr) => (dateStr ?? '').replace(/\//g, '-');
|
|
|
|
|
|
const onDateSelected = (val) => {
|
|
|
@@ -468,6 +531,7 @@ const wouldExceedWeekLimit = (selectedDate) => {
|
|
|
onMounted(() => {
|
|
|
loadAvailability();
|
|
|
loadReviews();
|
|
|
+ loadFavoriteState();
|
|
|
});
|
|
|
</script>
|
|
|
|