This commit introduces a 'Contact Sales' modal on the web development page, allowing users to inquire about specific service plans. - The pricing plan buttons now trigger this modal, pre-filled with the selected plan's details. - Users can add custom remarks to their inquiry. - On submission, a pre-formatted message is generated and opened in WhatsApp using a new `useWhatsAppMsgSender` composable. - Adds `NUXT_PUBLIC_WHATSAPP_NUMBER` to the runtime configuration. - Refactors content validation by introducing Zod schemas for `PricingPlan` and `Button` props to improve type safety. - Adds new i18n keys for the modal interface and message templates.
48 lines
1.2 KiB
Vue
48 lines
1.2 KiB
Vue
<template>
|
|
<UContainer>
|
|
<UPageHero :title="page?.title" :description="page?.description" />
|
|
|
|
<p class="text-muted py-4 text-center">{{ page?.remarks }}</p>
|
|
|
|
<UTabs :items="serviceTabs">
|
|
<template v-for="service in serviceTabs" :key="service.id" #[service.id]>
|
|
<UPricingPlans :plans="service.plans" />
|
|
</template>
|
|
</UTabs>
|
|
<WebDevContactSalesModal ref="webDevContactSalesModal" />
|
|
</UContainer>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import WebDevContactSalesModal from "~/components/webDev/ContactSalesModal.vue";
|
|
|
|
const { data: page } = await useLocalizedCollection("webDev");
|
|
|
|
const webDevContactSalesModal = ref<InstanceType<
|
|
typeof WebDevContactSalesModal
|
|
> | null>(null);
|
|
|
|
const serviceTabs = computed(() =>
|
|
page.value?.services.map((srv) => ({
|
|
...srv,
|
|
plans: srv.plans.map((pln) => ({
|
|
...pln,
|
|
button: {
|
|
label: "立刻咨询", // TODO: i18n 适配
|
|
onClick: () => {
|
|
webDevContactSalesModal.value?.openModal({
|
|
serviceTitle: srv.label,
|
|
planTitle: pln.title,
|
|
startingPrice: pln.price,
|
|
features: pln.features ?? [],
|
|
});
|
|
},
|
|
},
|
|
})),
|
|
slot: srv.id,
|
|
}))
|
|
);
|
|
</script>
|
|
|
|
<style></style>
|