Kaynağa Gözat

feat: :sparkles: feat: ✨ feat(agendamento-sob-medida): fazendo ajuste nos bloqueio de dias e semanas para agendmaento

ajustando para que o dia ou ate mesmo a semana fiquei bloqueada para  o cliente caso ele ultrapasse o limite de dias disponiveis para agendamentos que seria no maximo 2 por semana entre cliente e prestador bloquando a semana ou o dia dependendo da forma de agendmaento

fase:dev | origin:escopo
kayo henrique 1 hafta önce
ebeveyn
işleme
cd2f074131

+ 5 - 0
src/api/providerAvailability.js

@@ -9,3 +9,8 @@ export const getProviderBlockedDays = async (providerId) => {
   const { data } = await api.get(`/provider/blocked-days/${providerId}`)
   return data.payload
 }
+
+export const getProviderSchedules = async (providerId) => {
+  const response = await api.get(`/provider/${providerId}/schedules`)
+  return response.data.payload
+}

+ 129 - 55
src/pages/search/components/SchedulingDialog.vue

@@ -132,7 +132,7 @@ import { getProviderWorkingDays, getProviderBlockedDays } from 'src/api/provider
 import { getProviderReceivedReviews } from 'src/api/review';
 import ServiceSelectionSheet from './ServiceSelectionSheet.vue';
 import ServiceTimeSelectionDialog from './ServiceTimeSelectionDialog.vue';
-import OrderSummaryDialog from './OrderSummaryDialog.vue';
+import OrderSummaryDialog from './OrderSummaryDialog.vue'
 
 const props = defineProps({
   provider: {
@@ -146,89 +146,160 @@ defineEmits([...useDialogPluginComponent.emits]);
 const { dialogRef } = useDialogPluginComponent();
 const $q = useQuasar();
 
+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 availableWeekDays = computed(() =>
+  [...new Set(workingDays.value.map((wd) => wd.day))]
+);
+
+
+const blockedDateSet = computed(() =>
+  new Set(
+    blockedDays.value
+      .filter((bd) => bd.period === 'all')
+      .map((bd) => bd.date)
+  )
+);
+
+
+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 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 count = bookings.value.filter(b => {
+    if (!b.date) return false
+
+    const normalizedDate = b.date.replace(/\//g, '-')
+
+    return normalizedDate >= start && normalizedDate <= end
+  }).length
+
+  return count >= 2
+}
+
+
+const dateOptions = (d) => {
+  const today = date.formatDate(new Date(), 'YYYY/MM/DD');
+  if (d < today) return false;
+
+  const raw = d.replace(/\//g, '-');
+  const parsed = new Date(`${raw}T12:00:00`);
+  const dayOfWeek = parsed.getDay();
+
+  const isWorkingDay = availableWeekDays.value.includes(dayOfWeek);
+  const isBlocked = blockedDateSet.value.has(raw);
+
+  if (!isWorkingDay || isBlocked) return false;
+
+if (wouldExceedWeekLimit(raw)) return false;
+
+return true;
+};
+
+
 const onDateSelected = (val) => {
   if (!val) return;
+
   selectedDate.value = null;
   const valFormatted = val.replace(/\//g, '-');
 
+
   const blocksOfDate = blockedDays.value.filter(
     (bd) => bd.date === valFormatted && bd.period !== 'all'
   );
 
+  
   const dayOfWeek = new Date(`${valFormatted}T12:00:00`).getDay();
+
   const dayPeriods = workingDays.value
     .filter((wd) => wd.day === dayOfWeek)
     .map((wd) => wd.period);
 
   const workingDayBlocks = [];
+
   if (!dayPeriods.includes('afternoon')) {
     workingDayBlocks.push({ init_hour: '14:00:00', end_hour: '20:00:00' });
   }
+
   if (!dayPeriods.includes('morning')) {
-    workingDayBlocks.push({ init_hour: '7:00:00', end_hour: '13:00:00' });
+    workingDayBlocks.push({ init_hour: '07:00:00', end_hour: '13:00:00' });
   }
 
-  const partialBlocks = [...blocksOfDate, ...workingDayBlocks];
+  
+  const existingBookingBlocks = 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 partialBlocks = [
+    ...blocksOfDate,
+    ...workingDayBlocks,
+    ...existingBookingBlocks
+  ];
+
+  // fluxo
+  $q.dialog({
+  component: ServiceSelectionSheet,
+  componentProps: {
+    provider: props.provider,
+    selectedDate: val,
+    partialBlocks
+  },
+}).onOk(({ serviceType, date: date_, provider: prov }) => {
 
   $q.dialog({
-    component: ServiceSelectionSheet,
-    componentProps: { provider: props.provider, selectedDate: val, partialBlocks },
-  }).onOk(({ serviceType, date: date_, provider: prov }) => {
-    $q.dialog({
-      component: ServiceTimeSelectionDialog,
-      componentProps: { serviceType, selectedDate: date_, provider: prov, partialBlocks },
-    }).onOk((booking) => {
-      $q.dialog({
-        component: OrderSummaryDialog,
-        componentProps: { provider: props.provider, initialBooking: booking },
-      });
-    });
-  });
-};
+    component: ServiceTimeSelectionDialog,
+    componentProps: {
+      serviceType,
+      selectedDate: date_,
+      provider: prov,
+      partialBlocks
+    },
+  }).onOk((booking) => {
 
-const selectedDate = ref(null);
-const workingDays = ref([]);
-const blockedDays = ref([]);
-const loadingAvailability = ref(true);
+    bookings.value.push(booking);
 
-const reviews = ref([]);
-const loadingReviews = ref(true);
+    $q.dialog({
+      component: OrderSummaryDialog,
+      componentProps: {
+        provider: props.provider,
+        initialBooking: booking
+      }
+    });
 
-const avatarColors = [
-  { background: '#ffd5df', color: '#932e57' },
-  { background: '#d7e8ff', color: '#2158a8' },
-  { background: '#dfd',    color: '#2a7a3b' },
-  { background: '#ffe5cc', color: '#8a4500' },
-];
+  });
 
-const avatarStyle = computed(() => {
-  const idx = (props.provider?.provider_id ?? 0) % avatarColors.length;
-  return avatarColors[idx];
 });
-
-const clientAvatarStyle = (review) => {
-  const idx = (review.id ?? 0) % avatarColors.length;
-  return avatarColors[idx];
 };
 
-const availableWeekDays = computed(() =>
-  [...new Set(workingDays.value.map((wd) => wd.day))]
-);
-
-const blockedDateSet = computed(() =>
-  new Set(blockedDays.value.map((bd) => bd.date && bd.period == 'all'))
-);
-
-const dateOptions = (d) => {
-  const today = date.formatDate(new Date(), 'YYYY/MM/DD');
-  if (d < today) return false;
-  const raw = d.replace(/\//g, '-');
-  const parsed = new Date(`${raw}T12:00:00`);
-  const dayOfWeek = parsed.getDay();
-  const isWorkingDay = availableWeekDays.value.includes(dayOfWeek);
-  const isBlocked = blockedDateSet.value.has(raw);
-  return isWorkingDay && !isBlocked;
-};
 
 const loadAvailability = async () => {
   loadingAvailability.value = true;
@@ -236,6 +307,7 @@ const loadAvailability = async () => {
     const [wd, bd] = await Promise.all([
       getProviderWorkingDays(props.provider.provider_id),
       getProviderBlockedDays(props.provider.provider_id),
+      // getProviderWeekDatesBlocks(props.provider_id, provider.client_id)
     ]);
     workingDays.value = wd ?? [];
     blockedDays.value = bd ?? [];
@@ -247,6 +319,7 @@ const loadAvailability = async () => {
   }
 };
 
+
 const loadReviews = async () => {
   loadingReviews.value = true;
   try {
@@ -260,7 +333,8 @@ const loadReviews = async () => {
 };
 
 onMounted(() => {
-  Promise.all([loadAvailability(), loadReviews()]);
+  loadAvailability();
+  loadReviews();
 });
 </script>