AddServiceLoyalty
This commit is contained in:
@@ -54,6 +54,12 @@
|
||||
{{ formatPriceToman(selectedPrice) }} تومان
|
||||
</dd>
|
||||
</div>
|
||||
<p
|
||||
v-if="loyaltyHint"
|
||||
class="border-t border-brand-500/20 pt-1.5 text-xs leading-6 text-brand-700 dark:text-brand-400"
|
||||
>
|
||||
{{ loyaltyHint }}
|
||||
</p>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@@ -268,10 +274,21 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { createBooking, createBookingBatch, fetchAvailableSlots } from '@/api/bookings';
|
||||
import {
|
||||
createBooking,
|
||||
createBookingBatch,
|
||||
fetchAvailableSlots,
|
||||
fetchServiceLoyaltyStatus,
|
||||
} from '@/api/bookings';
|
||||
import { fetchBusinessServiceClasses } from '@/api/business-service-classes';
|
||||
import { ApiError } from '@/api/client';
|
||||
import type { Booking, Business, BusinessService, BusinessServiceClass } from '@/api/types';
|
||||
import type {
|
||||
Booking,
|
||||
Business,
|
||||
BusinessService,
|
||||
BusinessServiceClass,
|
||||
ServiceLoyaltyStatus,
|
||||
} from '@/api/types';
|
||||
import BookingOrderSummary from '@/components/booking/BookingOrderSummary.vue';
|
||||
import BusinessRatingBadge from '@/components/business/BusinessRatingBadge.vue';
|
||||
import BookingServiceClassStep from '@/components/booking/BookingServiceClassStep.vue';
|
||||
@@ -343,6 +360,7 @@ const dateTimeRef = ref<InstanceType<typeof DesktopBookingDateTime> | null>(null
|
||||
const serviceClasses = ref<BusinessServiceClass[]>([]);
|
||||
const loadingClasses = ref(true);
|
||||
const classesError = ref('');
|
||||
const loyaltyByServiceId = ref<Record<string, ServiceLoyaltyStatus>>({});
|
||||
|
||||
const classStepRequired = computed(() => {
|
||||
if (loadingClasses.value && props.business.serviceClassesEnabled) {
|
||||
@@ -414,6 +432,46 @@ const selectedDurationLabel = computed(() => {
|
||||
return `${selectedDurationMinutes.value} دقیقه`;
|
||||
});
|
||||
|
||||
const loyaltyHint = computed(() => {
|
||||
if (!auth.isLoggedIn || !selectedServices.value.length) return '';
|
||||
const parts: string[] = [];
|
||||
for (const service of selectedServices.value) {
|
||||
const status = loyaltyByServiceId.value[service.id];
|
||||
if (!status?.enabled || !status.everyN) continue;
|
||||
const title = service.serviceTemplate?.title ?? 'این خدمت';
|
||||
if (status.nextIsFree) {
|
||||
parts.push(`«${title}» در نوبت بعدی رایگان میشود.`);
|
||||
} else if (status.remainingPaidVisits != null) {
|
||||
parts.push(
|
||||
`«${title}»: ${status.remainingPaidVisits} نوبت تا رایگان بعدی (هر ${status.everyN} بار).`,
|
||||
);
|
||||
}
|
||||
}
|
||||
return parts.join(' ');
|
||||
});
|
||||
|
||||
watch(
|
||||
[selectedServiceIds, () => auth.isLoggedIn],
|
||||
async ([ids, loggedIn]) => {
|
||||
if (!loggedIn || !ids.length) {
|
||||
loyaltyByServiceId.value = {};
|
||||
return;
|
||||
}
|
||||
const next: Record<string, ServiceLoyaltyStatus> = {};
|
||||
await Promise.all(
|
||||
ids.map(async (id) => {
|
||||
try {
|
||||
next[id] = await fetchServiceLoyaltyStatus(id);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}),
|
||||
);
|
||||
loyaltyByServiceId.value = next;
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
const summaryItems = computed(() =>
|
||||
selectedServices.value.map((service) => ({
|
||||
id: service.id,
|
||||
|
||||
Reference in New Issue
Block a user