AddFirstBookingDiscount
This commit is contained in:
@@ -6,6 +6,15 @@
|
||||
@browse="scrollToServices"
|
||||
/>
|
||||
|
||||
<FirstBookingDiscountBanner
|
||||
:enabled="discountEnabled"
|
||||
:title="discountTitle"
|
||||
:percent="discountPercent"
|
||||
:code="discountCode"
|
||||
:mode="discountMode"
|
||||
:compact="false"
|
||||
/>
|
||||
|
||||
<HomeServicesSection
|
||||
:items="services"
|
||||
:loading="loadingServices"
|
||||
@@ -18,11 +27,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useRouter } from 'vue-router';
|
||||
import HomeFeatureBar from '@/components/home/HomeFeatureBar.vue';
|
||||
import HomeHeroSection from '@/components/home/HomeHeroSection.vue';
|
||||
import HomeServicesSection from '@/components/home/HomeServicesSection.vue';
|
||||
import FirstBookingDiscountBanner from '@/components/landing/FirstBookingDiscountBanner.vue';
|
||||
import DesktopSiteLayout from '@/layouts/DesktopSiteLayout.vue';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { useTenantStore } from '@/stores/tenant';
|
||||
@@ -42,7 +53,25 @@ const props = withDefaults(
|
||||
const router = useRouter();
|
||||
const auth = useAuthStore();
|
||||
const tenant = useTenantStore();
|
||||
const { landingBusinessId } = storeToRefs(tenant);
|
||||
const { landingBusinessId, landingBusiness } = storeToRefs(tenant);
|
||||
|
||||
const discountEnabled = computed(
|
||||
() =>
|
||||
landingBusiness.value?.promoDiscountEnabled === true &&
|
||||
!!landingBusiness.value?.promoDiscountPercent,
|
||||
);
|
||||
const discountTitle = computed(
|
||||
() => landingBusiness.value?.promoDiscountTitle?.trim() || 'تخفیف ویژه',
|
||||
);
|
||||
const discountPercent = computed(
|
||||
() => landingBusiness.value?.promoDiscountPercent ?? null,
|
||||
);
|
||||
const discountCode = computed(
|
||||
() => landingBusiness.value?.promoDiscountCode?.trim() ?? null,
|
||||
);
|
||||
const discountMode = computed(
|
||||
() => landingBusiness.value?.promoDiscountMode ?? 'first_booking',
|
||||
);
|
||||
|
||||
function scrollToServices() {
|
||||
const el = document.getElementById('services');
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<section
|
||||
v-if="enabled"
|
||||
id="club"
|
||||
class="scroll-mt-24"
|
||||
:class="compact ? 'px-5 pb-6' : 'mx-auto max-w-[1200px] px-6 pb-10 lg:px-8'"
|
||||
>
|
||||
<div
|
||||
class="flex items-center justify-between gap-3 rounded-2xl bg-brand-50 px-4 py-4 dark:bg-brand-500/10"
|
||||
>
|
||||
<div class="min-w-0 flex-1 space-y-1">
|
||||
<p class="text-xs text-landing-muted dark:text-muted">{{ title }}</p>
|
||||
<p class="text-2xl font-black text-brand-600 dark:text-brand-500">
|
||||
{{ percentLabel }}٪ تخفیف
|
||||
</p>
|
||||
<p v-if="code" class="text-xs font-medium text-landing-ink dark:text-text">
|
||||
کد تخفیف:
|
||||
<span class="font-bold" dir="ltr">{{ code }}</span>
|
||||
</p>
|
||||
<p class="text-[11px] leading-5 text-landing-muted dark:text-muted">
|
||||
{{ helperText }}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="flex h-16 w-16 shrink-0 items-center justify-center rounded-2xl bg-white shadow-sm dark:bg-surface dark:shadow-black/20"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<AppIcon name="gift" size="lg" class="text-brand-600 dark:text-brand-500" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import AppIcon from '@/components/ui/AppIcon.vue';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
enabled?: boolean;
|
||||
title?: string | null;
|
||||
percent?: number | null;
|
||||
code?: string | null;
|
||||
mode?: 'first_booking' | 'always' | null;
|
||||
compact?: boolean;
|
||||
}>(),
|
||||
{
|
||||
enabled: false,
|
||||
title: 'تخفیف ویژه',
|
||||
percent: null,
|
||||
code: null,
|
||||
mode: 'first_booking',
|
||||
compact: true,
|
||||
},
|
||||
);
|
||||
|
||||
const percentLabel = computed(() => {
|
||||
const n = props.percent ?? 0;
|
||||
return n.toLocaleString('fa-IR');
|
||||
});
|
||||
|
||||
const helperText = computed(() =>
|
||||
props.mode === 'always'
|
||||
? 'این تخفیف هنگام رزرو بهصورت خودکار روی مبلغ اعمال میشود.'
|
||||
: 'برای اولین رزرو شما در این کسبوکار بهصورت خودکار اعمال میشود.',
|
||||
);
|
||||
</script>
|
||||
@@ -70,26 +70,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="club" class="scroll-mt-24 px-5 pb-6">
|
||||
<div
|
||||
class="flex items-center justify-between gap-3 rounded-2xl bg-brand-50 px-4 py-4 dark:bg-brand-500/10"
|
||||
>
|
||||
<div class="min-w-0 flex-1 space-y-1">
|
||||
<p class="text-xs text-landing-muted dark:text-muted">اولین رزرو شما</p>
|
||||
<p class="text-2xl font-black text-brand-600 dark:text-brand-500">۱۰٪ تخفیف</p>
|
||||
<p class="text-xs font-medium text-landing-ink dark:text-text">
|
||||
کد تخفیف:
|
||||
<span class="font-bold" dir="ltr">NEW10</span>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="flex h-16 w-16 shrink-0 items-center justify-center rounded-2xl bg-white shadow-sm dark:bg-surface dark:shadow-black/20"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<AppIcon name="gift" size="lg" class="text-brand-600 dark:text-brand-500" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<FirstBookingDiscountBanner
|
||||
:enabled="discountEnabled"
|
||||
:title="discountTitle"
|
||||
:percent="discountPercent"
|
||||
:code="discountCode"
|
||||
:mode="discountMode"
|
||||
compact
|
||||
/>
|
||||
|
||||
<HomeServicesSection
|
||||
:items="services"
|
||||
@@ -115,6 +103,7 @@ import { computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import BusinessImageGallery from '@/components/business/BusinessImageGallery.vue';
|
||||
import HomeServicesSection from '@/components/home/HomeServicesSection.vue';
|
||||
import FirstBookingDiscountBanner from '@/components/landing/FirstBookingDiscountBanner.vue';
|
||||
import AppIcon from '@/components/ui/AppIcon.vue';
|
||||
import { useTenantStore } from '@/stores/tenant';
|
||||
import type { AppIconName } from '@/types/icons';
|
||||
@@ -138,17 +127,40 @@ const businessTitle = computed(() => landingBusiness.value?.title ?? '');
|
||||
const businessSubtitle = computed(() => landingBusiness.value?.subtitle?.trim() ?? '');
|
||||
const aboutText = computed(() => landingBusiness.value?.description?.trim() ?? '');
|
||||
|
||||
const quickActions: {
|
||||
id: string;
|
||||
label: string;
|
||||
icon: AppIconName;
|
||||
targetId: string;
|
||||
}[] = [
|
||||
{ id: 'services', label: 'خدمات کارواش', icon: 'car', targetId: 'services' },
|
||||
{ id: 'pricing', label: 'تعرفهها', icon: 'badge-percent', targetId: 'services' },
|
||||
{ id: 'club', label: 'باشگاه مشتریان', icon: 'sparkles', targetId: 'club' },
|
||||
{ id: 'about', label: 'درباره ما', icon: 'info', targetId: 'about' },
|
||||
];
|
||||
const discountEnabled = computed(
|
||||
() =>
|
||||
landingBusiness.value?.promoDiscountEnabled === true &&
|
||||
!!landingBusiness.value?.promoDiscountPercent,
|
||||
);
|
||||
const discountTitle = computed(
|
||||
() => landingBusiness.value?.promoDiscountTitle?.trim() || 'تخفیف ویژه',
|
||||
);
|
||||
const discountPercent = computed(
|
||||
() => landingBusiness.value?.promoDiscountPercent ?? null,
|
||||
);
|
||||
const discountCode = computed(
|
||||
() => landingBusiness.value?.promoDiscountCode?.trim() ?? null,
|
||||
);
|
||||
const discountMode = computed(
|
||||
() => landingBusiness.value?.promoDiscountMode ?? 'first_booking',
|
||||
);
|
||||
|
||||
const quickActions = computed(() => {
|
||||
const items: {
|
||||
id: string;
|
||||
label: string;
|
||||
icon: AppIconName;
|
||||
targetId: string;
|
||||
}[] = [
|
||||
{ id: 'services', label: 'خدمات', icon: 'car', targetId: 'services' },
|
||||
{ id: 'pricing', label: 'تعرفهها', icon: 'badge-percent', targetId: 'services' },
|
||||
];
|
||||
if (discountEnabled.value) {
|
||||
items.push({ id: 'club', label: 'تخفیف ویژه', icon: 'sparkles', targetId: 'club' });
|
||||
}
|
||||
items.push({ id: 'about', label: 'درباره ما', icon: 'info', targetId: 'about' });
|
||||
return items;
|
||||
});
|
||||
|
||||
function scrollTo(targetId: string) {
|
||||
const el = document.getElementById(targetId);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<footer class="border-t border-landing-line bg-landing-surface dark:border-border dark:bg-surface-2">
|
||||
<div id="club" class="sr-only" aria-hidden="true" />
|
||||
|
||||
<div class="mx-auto max-w-[1200px] px-6 py-12 lg:px-8">
|
||||
<div class="grid grid-cols-1 gap-10 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<section>
|
||||
|
||||
Reference in New Issue
Block a user