|
|
@@ -129,7 +129,9 @@ import { ref, computed, onMounted } from 'vue';
|
|
|
import { useDialogPluginComponent, useQuasar } from 'quasar';
|
|
|
import { date } from 'quasar';
|
|
|
import { getProviderWorkingDays, getProviderBlockedDays } from 'src/api/providerAvailability';
|
|
|
+import { getClientProviderBlocks } from 'src/api/schedule';
|
|
|
import { getProviderReceivedReviews } from 'src/api/review';
|
|
|
+import { userStore } from 'src/stores/user';
|
|
|
import ServiceSelectionSheet from './ServiceSelectionSheet.vue';
|
|
|
import ServiceTimeSelectionDialog from './ServiceTimeSelectionDialog.vue';
|
|
|
import OrderSummaryDialog from './OrderSummaryDialog.vue'
|
|
|
@@ -145,17 +147,21 @@ defineEmits([...useDialogPluginComponent.emits]);
|
|
|
|
|
|
const { dialogRef } = useDialogPluginComponent();
|
|
|
const $q = useQuasar();
|
|
|
+const store = userStore();
|
|
|
|
|
|
const selectedDate = ref(null);
|
|
|
const workingDays = ref([]);
|
|
|
const blockedDays = ref([]);
|
|
|
const loadingAvailability = ref(true);
|
|
|
-
|
|
|
const reviews = ref([]);
|
|
|
const loadingReviews = ref(true);
|
|
|
|
|
|
|
|
|
const bookings = ref([]);
|
|
|
+const providerClientBlocks = ref({
|
|
|
+ existing_schedules: [],
|
|
|
+ fully_blocked_weeks: [],
|
|
|
+});
|
|
|
|
|
|
|
|
|
const availableWeekDays = computed(() =>
|
|
|
@@ -172,53 +178,55 @@ const blockedDateSet = computed(() =>
|
|
|
);
|
|
|
|
|
|
|
|
|
-const getWeekRange = (dateStr) => {
|
|
|
- const d = new Date(`${dateStr}T12:00:00`)
|
|
|
- const day = d.getDay()
|
|
|
-
|
|
|
- const start = new Date(d)
|
|
|
- start.setDate(d.getDate() - day)
|
|
|
+const normalizeDate = (dateStr) => (dateStr ?? '').replace(/\//g, '-');
|
|
|
|
|
|
- const end = new Date(start)
|
|
|
- end.setDate(start.getDate() + 6)
|
|
|
-
|
|
|
- return {
|
|
|
- start: start.toISOString().split('T')[0],
|
|
|
- end: end.toISOString().split('T')[0]
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const wouldExceedWeekLimit = (selectedDate) => {
|
|
|
- const { start, end } = getWeekRange(selectedDate)
|
|
|
+const getWeekStart = (dateStr) => {
|
|
|
+ const normalizedDate = normalizeDate(dateStr);
|
|
|
+ const d = new Date(`${normalizedDate}T12:00:00`);
|
|
|
+ d.setDate(d.getDate() - d.getDay());
|
|
|
+ return d.toISOString().split('T')[0];
|
|
|
+};
|
|
|
|
|
|
- const count = bookings.value.filter(b => {
|
|
|
- if (!b.date) return false
|
|
|
+const blockedWeekStartSet = computed(() =>
|
|
|
+ new Set(providerClientBlocks.value.fully_blocked_weeks ?? [])
|
|
|
+);
|
|
|
|
|
|
- const normalizedDate = b.date.replace(/\//g, '-')
|
|
|
+const getServerWeekCount = (selectedDate) => {
|
|
|
+ const weekStart = getWeekStart(selectedDate);
|
|
|
+ return (providerClientBlocks.value.existing_schedules ?? []).filter(
|
|
|
+ (schedule) => getWeekStart(schedule.date) === weekStart
|
|
|
+ ).length;
|
|
|
+};
|
|
|
|
|
|
- return normalizedDate >= start && normalizedDate <= end
|
|
|
- }).length
|
|
|
+const getLocalWeekCount = (selectedDate) => {
|
|
|
+ const weekStart = getWeekStart(selectedDate);
|
|
|
+ return bookings.value.filter((booking) => getWeekStart(booking.date) === weekStart).length;
|
|
|
+};
|
|
|
|
|
|
- return count >= 2
|
|
|
-}
|
|
|
+const wouldExceedWeekLimit = (selectedDate) => {
|
|
|
+ const serverCount = getServerWeekCount(selectedDate);
|
|
|
+ const localCount = getLocalWeekCount(selectedDate);
|
|
|
+ return (serverCount + localCount) >= 2;
|
|
|
+};
|
|
|
|
|
|
|
|
|
const dateOptions = (d) => {
|
|
|
const today = date.formatDate(new Date(), 'YYYY/MM/DD');
|
|
|
if (d < today) return false;
|
|
|
|
|
|
- const raw = d.replace(/\//g, '-');
|
|
|
+ const raw = normalizeDate(d);
|
|
|
const parsed = new Date(`${raw}T12:00:00`);
|
|
|
const dayOfWeek = parsed.getDay();
|
|
|
|
|
|
const isWorkingDay = availableWeekDays.value.includes(dayOfWeek);
|
|
|
const isBlocked = blockedDateSet.value.has(raw);
|
|
|
+ const isWeekBlocked = blockedWeekStartSet.value.has(getWeekStart(raw));
|
|
|
|
|
|
- if (!isWorkingDay || isBlocked) return false;
|
|
|
+ if (!isWorkingDay || isBlocked || isWeekBlocked) return false;
|
|
|
|
|
|
-if (wouldExceedWeekLimit(raw)) return false;
|
|
|
+ if (wouldExceedWeekLimit(raw)) return false;
|
|
|
|
|
|
-return true;
|
|
|
+ return true;
|
|
|
};
|
|
|
|
|
|
|
|
|
@@ -226,7 +234,7 @@ const onDateSelected = (val) => {
|
|
|
if (!val) return;
|
|
|
|
|
|
selectedDate.value = null;
|
|
|
- const valFormatted = val.replace(/\//g, '-');
|
|
|
+ const valFormatted = normalizeDate(val);
|
|
|
|
|
|
|
|
|
const blocksOfDate = blockedDays.value.filter(
|
|
|
@@ -251,18 +259,26 @@ const onDateSelected = (val) => {
|
|
|
}
|
|
|
|
|
|
|
|
|
- const existingBookingBlocks = bookings.value
|
|
|
+ const localBookingBlocks = bookings.value
|
|
|
.filter(b => b.date.replace(/\//g, '-') === valFormatted)
|
|
|
.map(b => ({
|
|
|
init_hour: `${b.slot.startHour}:00:00`,
|
|
|
end_hour: `${b.slot.endHour}:00:00`
|
|
|
}));
|
|
|
|
|
|
+ const serverBookingBlocks = (providerClientBlocks.value.existing_schedules ?? [])
|
|
|
+ .filter((schedule) => normalizeDate(schedule.date) === valFormatted)
|
|
|
+ .map((schedule) => ({
|
|
|
+ init_hour: schedule.start_time,
|
|
|
+ end_hour: schedule.end_time,
|
|
|
+ }));
|
|
|
+
|
|
|
|
|
|
const partialBlocks = [
|
|
|
...blocksOfDate,
|
|
|
...workingDayBlocks,
|
|
|
- ...existingBookingBlocks
|
|
|
+ ...localBookingBlocks,
|
|
|
+ ...serverBookingBlocks,
|
|
|
];
|
|
|
|
|
|
// fluxo
|
|
|
@@ -303,17 +319,28 @@ const onDateSelected = (val) => {
|
|
|
|
|
|
const loadAvailability = async () => {
|
|
|
loadingAvailability.value = true;
|
|
|
+
|
|
|
try {
|
|
|
- const [wd, bd] = await Promise.all([
|
|
|
+ const clientId = store.user?.client?.id;
|
|
|
+ const defaultClientBlocks = { existing_schedules: [], fully_blocked_weeks: [] };
|
|
|
+
|
|
|
+ const [wd, bd, clientBlocks] = await Promise.all([
|
|
|
getProviderWorkingDays(props.provider.provider_id),
|
|
|
getProviderBlockedDays(props.provider.provider_id),
|
|
|
- // getProviderWeekDatesBlocks(props.provider_id, provider.client_id)
|
|
|
+ clientId
|
|
|
+ ? getClientProviderBlocks(clientId, props.provider.provider_id)
|
|
|
+ : Promise.resolve(defaultClientBlocks),
|
|
|
]);
|
|
|
+
|
|
|
workingDays.value = wd ?? [];
|
|
|
blockedDays.value = bd ?? [];
|
|
|
+ providerClientBlocks.value = clientBlocks ?? defaultClientBlocks;
|
|
|
+
|
|
|
} catch {
|
|
|
workingDays.value = [];
|
|
|
blockedDays.value = [];
|
|
|
+ providerClientBlocks.value = { existing_schedules: [], fully_blocked_weeks: [] };
|
|
|
+
|
|
|
} finally {
|
|
|
loadingAvailability.value = false;
|
|
|
}
|