Improve variant capabilites
All checks were successful
Build and deploy updated apps / Build & deploy (push) Successful in 2m11s
All checks were successful
Build and deploy updated apps / Build & deploy (push) Successful in 2m11s
This commit is contained in:
parent
cf76334c38
commit
2b8a67af9b
@ -54,7 +54,7 @@
|
||||
<script setup lang="ts">
|
||||
import type {Apartment} from '@/composables/useApartments'
|
||||
|
||||
const {t, tm, rt} = useI18n()
|
||||
const {t, tm, rt} = useVariantData()
|
||||
|
||||
defineProps<{ apartment: Apartment }>()
|
||||
const { variantPath } = useVariantPath()
|
||||
|
||||
@ -38,5 +38,5 @@ const props = defineProps<{
|
||||
features: Feature[]
|
||||
}>()
|
||||
|
||||
const {t, tm, rt} = useI18n()
|
||||
const {t, tm, rt} = useVariantData()
|
||||
</script>
|
||||
|
||||
@ -73,7 +73,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const {t, tm, rt} = useI18n()
|
||||
const {t, tm, rt} = useVariantData()
|
||||
const year = new Date().getFullYear()
|
||||
const { variantPath } = useVariantPath()
|
||||
</script>
|
||||
|
||||
@ -10,15 +10,16 @@
|
||||
<!-- nav links -->
|
||||
<ul class="flex space-x-6">
|
||||
<li>
|
||||
<NuxtLink :to="variantPath('apartments')">{{ t('header.apartments') }}</NuxtLink>
|
||||
<NuxtLink :to="variantPath('apartments')">{{ rt(tm('header').apartments) }}</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink :to="variantPath('book')">{{ t('header.book') }}</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink :to="variantPath('contact')">{{ t('header.contact') }}</NuxtLink>
|
||||
<NuxtLink :to="variantPath('contact')">{{ rt(tm('header').contact) }}</NuxtLink>
|
||||
</li>
|
||||
<AppLocaleSwitcher/>
|
||||
<WVariantSwitcher/>
|
||||
</ul>
|
||||
</nav>
|
||||
</AppStripe>
|
||||
@ -26,6 +27,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const {t, tm, rt} = useI18n()
|
||||
const {t, tm, rt} = useVariantData()
|
||||
const { variantPath } = useVariantPath()
|
||||
</script>
|
||||
|
||||
@ -23,5 +23,5 @@ const props = defineProps<{
|
||||
i18nKey: string
|
||||
}>()
|
||||
|
||||
const {t, tm, rt} = useI18n()
|
||||
const {t, tm, rt} = useVariantData()
|
||||
</script>
|
||||
|
||||
@ -3,7 +3,10 @@
|
||||
"home": "Landhaus Panoramablick",
|
||||
"apartments": "Apartments & Preise",
|
||||
"book": "Buchen",
|
||||
"contact": "Kontakt"
|
||||
"contact": {
|
||||
"#su": "KontaktS",
|
||||
"#wi": "KontaktW"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"questions": "Fragen oder Wünsche?",
|
||||
@ -83,7 +86,10 @@
|
||||
"list": [
|
||||
{
|
||||
"id": "apartment-1",
|
||||
"title": "Apartment 1",
|
||||
"title": {
|
||||
"#su": "Appartment 1 (Sommer)",
|
||||
"#wi": "Appartment 1 (Winter)"
|
||||
},
|
||||
"subtitle": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
|
||||
"thumbnail": "/ap-1/1.webp",
|
||||
"highlights": [
|
||||
|
||||
@ -3,7 +3,10 @@
|
||||
"home": "Landhaus Panoramablick",
|
||||
"apartments": "Apartments & Rates",
|
||||
"book": "Book",
|
||||
"contact": "Contact"
|
||||
"contact": {
|
||||
"#su": "ContactS",
|
||||
"#wi": "ContactW"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"questions": "Fragen oder Wünsche?",
|
||||
@ -83,7 +86,10 @@
|
||||
"list": [
|
||||
{
|
||||
"id": "apartment-1",
|
||||
"title": "Apartment 1",
|
||||
"title": {
|
||||
"#su": "Appartment 1 (Summer)",
|
||||
"#wi": "Appartment 1 (Winter)"
|
||||
},
|
||||
"subtitle": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
|
||||
"thumbnail": "/ap-1/1.webp",
|
||||
"highlights": [
|
||||
|
||||
@ -27,7 +27,7 @@ export default defineNuxtConfig({
|
||||
}
|
||||
},
|
||||
websites: {
|
||||
defaultVariant: 'sumu',
|
||||
defaultVariant: 'su',
|
||||
variants: [
|
||||
{ code: 'su', name: 'Summer' },
|
||||
{ code: 'wi', name: 'Winter' }
|
||||
|
||||
@ -21,5 +21,5 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const {t, tm, rt} = useI18n()
|
||||
const {t, tm, rt} = useVariantData()
|
||||
</script>
|
||||
@ -96,7 +96,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
/*TODO form should contain link to privacy statement?*/
|
||||
const {t, tm, rt} = useI18n()
|
||||
const {t, tm, rt} = useVariantData()
|
||||
const { variantPath } = useVariantPath()
|
||||
import * as v from 'valibot'
|
||||
import type {FormSubmitEvent} from '@nuxt/ui'
|
||||
|
||||
@ -130,6 +130,6 @@ const images = [
|
||||
'/panorama.webp'
|
||||
]
|
||||
|
||||
const {t, tm, rt} = useI18n()
|
||||
const {t, tm, rt} = useVariantData()
|
||||
const { variantPath } = useVariantPath()
|
||||
</script>
|
||||
@ -26,5 +26,5 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const {t, tm, rt} = useI18n()
|
||||
const {t, tm, rt} = useVariantData()
|
||||
</script>
|
||||
@ -8,14 +8,7 @@ export default defineNuxtModule<ModuleOptions>({
|
||||
name: 'websites',
|
||||
configKey: 'websites',
|
||||
},
|
||||
defaults: {
|
||||
defaultVariant: "su",
|
||||
variants: [
|
||||
{ code: 'su', name: 'Summer' },
|
||||
{ code: 'wi', name: 'Winter' }
|
||||
]
|
||||
},
|
||||
setup(_options, _nuxt) {
|
||||
setup(options, nuxt) {
|
||||
const resolver = createResolver(import.meta.url)
|
||||
addComponentsDir({
|
||||
path: resolver.resolve('./runtime/components'),
|
||||
@ -24,5 +17,6 @@ export default defineNuxtModule<ModuleOptions>({
|
||||
global: true,
|
||||
})
|
||||
addImportsDir(resolver.resolve('./runtime/composables'))
|
||||
nuxt.options.runtimeConfig.public.websites = options
|
||||
}
|
||||
})
|
||||
|
||||
18
packages/ui/src/runtime/components/WVariantSwitcher.vue
Normal file
18
packages/ui/src/runtime/components/WVariantSwitcher.vue
Normal file
@ -0,0 +1,18 @@
|
||||
<script setup>
|
||||
const { variants, current } = useVariants()
|
||||
const switchVariantPath = useSwitchVariantPath()
|
||||
|
||||
const availableVariants = computed(() =>
|
||||
variants.filter(v => String(v.code) !== String(current.value))
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NuxtLink
|
||||
v-for="variant in availableVariants"
|
||||
:key="variant.code"
|
||||
:to="switchVariantPath(variant.code)"
|
||||
>
|
||||
{{ variant.code.toUpperCase() }}
|
||||
</NuxtLink>
|
||||
</template>
|
||||
18
packages/ui/src/runtime/composables/useSwitchVariantPath.ts
Normal file
18
packages/ui/src/runtime/composables/useSwitchVariantPath.ts
Normal file
@ -0,0 +1,18 @@
|
||||
export function useSwitchVariantPath() {
|
||||
const route = useRoute()
|
||||
return (variant) => {
|
||||
// Clone current params and replace variant
|
||||
const params = { ...route.params, variant }
|
||||
// Build a new path with the new params
|
||||
// This uses named routes (recommended). If not, fallback to direct path replace:
|
||||
if (route.name) {
|
||||
return { name: route.name, params }
|
||||
} else {
|
||||
// fallback: replace variant in path
|
||||
return route.fullPath.replace(
|
||||
`/${route.params.variant || ''}`,
|
||||
`/${variant}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
42
packages/ui/src/runtime/composables/useVariantData.ts
Normal file
42
packages/ui/src/runtime/composables/useVariantData.ts
Normal file
@ -0,0 +1,42 @@
|
||||
export function useVariantData() {
|
||||
const { t, tm, rt } = useI18n()
|
||||
const route = useRoute()
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
function vtm(key: string) {
|
||||
// Get the latest variant *each time* this runs for reactivity!
|
||||
const variant = route.params.variant || config.public.websites.defaultVariant
|
||||
const value = tm(key)
|
||||
if (value && typeof value === 'object' && value[`#${variant}`] !== undefined) {
|
||||
return value[`#${variant}`]
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
function vt(key: string) {
|
||||
try {
|
||||
return rt(vtm(key))
|
||||
} catch {
|
||||
return key
|
||||
}
|
||||
}
|
||||
|
||||
function vrt(value) {
|
||||
const variant = route.params.variant || config.public.websites.defaultVariant
|
||||
if (value && typeof value === 'object' && value[`#${variant}`]) {
|
||||
value = value[`#${variant}`]
|
||||
}
|
||||
try {
|
||||
return rt(value)
|
||||
} catch (err) {
|
||||
console.error('Exception in vrt:', err)
|
||||
return value || err
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
t: vt,
|
||||
tm: vtm,
|
||||
rt: vrt,
|
||||
}
|
||||
}
|
||||
13
packages/ui/src/runtime/composables/useVariants.ts
Normal file
13
packages/ui/src/runtime/composables/useVariants.ts
Normal file
@ -0,0 +1,13 @@
|
||||
export function useVariants() {
|
||||
const config = useRuntimeConfig()
|
||||
const route = useRoute()
|
||||
const variants = config.public.websites.variants || []
|
||||
const defaultVariant = config.public.websites.defaultVariant
|
||||
|
||||
// Make current a computed so it tracks route changes
|
||||
const current = computed(() => route.params.variant || defaultVariant)
|
||||
return {
|
||||
variants,
|
||||
current,
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user