Introduce variant capabilities
All checks were successful
Build and deploy updated apps / Build & deploy (push) Successful in 2m11s

This commit is contained in:
Dominik Milacher 2025-06-14 23:28:00 +02:00
parent f3f668f20e
commit cf76334c38
14 changed files with 54 additions and 26 deletions

View File

@ -26,7 +26,7 @@
<div class="flex justify-end">
<div class="flex flex-row gap-4 ">
<UButton
to="/contact"
:to="variantPath('contact')"
size="md"
color="primary"
variant="outline"
@ -36,7 +36,7 @@
</UButton>
<UButton
to="/book"
:to="variantPath('book')"
size="md"
color="primary"
variant="solid"
@ -57,4 +57,5 @@ import type {Apartment} from '@/composables/useApartments'
const {t, tm, rt} = useI18n()
defineProps<{ apartment: Apartment }>()
const { variantPath } = useVariantPath()
</script>

View File

@ -37,7 +37,7 @@
<div class="flex flex-col gap-4 ">
<UButton
to="/contact"
:to="variantPath('contact')"
size="md"
color="primary"
variant="solid"
@ -47,7 +47,7 @@
</UButton>
<UButton
to="/book"
:to="variantPath('book')"
size="md"
color="primary"
variant="solid"
@ -63,9 +63,9 @@
<div class="pt-4 text-center text-sm text-neutral-600 flex flex-col py-4">
<span>&copy; {{ year }} Panoramablick Saalbach</span>
<div>
<NuxtLink to="/legal#imprint" :external="true" class="underline ml-2">Impressum</NuxtLink>
<NuxtLink to="/legal#privacy" :external="true" class="underline ml-2">Datenschutz</NuxtLink>
<NuxtLink to="/legal#accessability" :external="true" class="underline ml-2">Barrierefreiheit</NuxtLink>
<NuxtLink :to="variantPath('legal', 'imprint')" :external="true" class="underline ml-2">Impressum</NuxtLink>
<NuxtLink :to="variantPath('legal', 'privacy')" :external="true" class="underline ml-2">Datenschutz</NuxtLink>
<NuxtLink :to="variantPath('legal', 'accessability')" :external="true" class="underline ml-2">Barrierefreiheit</NuxtLink>
</div>
</div>
</AppStripe>
@ -75,4 +75,5 @@
<script setup lang="ts">
const {t, tm, rt} = useI18n()
const year = new Date().getFullYear()
const { variantPath } = useVariantPath()
</script>

View File

@ -3,20 +3,20 @@
<AppStripe>
<nav class="mx-auto py-4 flex items-center justify-between">
<!-- your logo / home link -->
<NuxtLink to="/" class="text-xl font-semibold">
<NuxtLink :to="variantPath('/')" class="text-xl font-semibold">
{{ t('header.home') }}
</NuxtLink>
<!-- nav links -->
<ul class="flex space-x-6">
<li>
<NuxtLink to="/apartments">{{ t('header.apartments') }}</NuxtLink>
<NuxtLink :to="variantPath('apartments')">{{ t('header.apartments') }}</NuxtLink>
</li>
<li>
<NuxtLink to="/book">{{ t('header.book') }}</NuxtLink>
<NuxtLink :to="variantPath('book')">{{ t('header.book') }}</NuxtLink>
</li>
<li>
<NuxtLink to="/contact">{{ t('header.contact') }}</NuxtLink>
<NuxtLink :to="variantPath('contact')">{{ t('header.contact') }}</NuxtLink>
</li>
<AppLocaleSwitcher/>
</ul>
@ -27,4 +27,5 @@
<script setup lang="ts">
const {t, tm, rt} = useI18n()
const { variantPath } = useVariantPath()
</script>

View File

@ -1,9 +1,9 @@
{
"header": {
"home": "Landhaus Panoramablick",
"apartments": "Apartments & Preise",
"book": "Buchen",
"contact": "Kontakt"
"apartments": "Apartments & Rates",
"book": "Book",
"contact": "Contact"
},
"footer": {
"questions": "Fragen oder Wünsche?",

View File

@ -26,9 +26,11 @@ export default defineNuxtConfig({
hotelId: "test"
}
},
generate: {
routes: [
'/legal'
websites: {
defaultVariant: 'sumu',
variants: [
{ code: 'su', name: 'Summer' },
{ code: 'wi', name: 'Winter' }
]
}
})

View File

@ -36,7 +36,7 @@
<p class="text-neutral-700 mb-4 max-w-prose">
{{ t('contact.online-1') }}
<UButton to="/book" variant="outline" trailing-icon="i-heroicons-arrow-right">{{
<UButton :to="variantPath('book')" variant="outline" trailing-icon="i-heroicons-arrow-right">{{
t('contact.online-2')
}}
</UButton>
@ -97,6 +97,7 @@
<script setup lang="ts">
/*TODO form should contain link to privacy statement?*/
const {t, tm, rt} = useI18n()
const { variantPath } = useVariantPath()
import * as v from 'valibot'
import type {FormSubmitEvent} from '@nuxt/ui'

View File

@ -27,13 +27,13 @@
</div>
<div class="mt-8 flex gap-4">
<UButton to="/apartments" color="primary" variant="solid" size="xl"
<UButton :to="variantPath('apartments')" color="primary" variant="solid" size="xl"
trailing-icon="i-heroicons-arrow-right">{{ t('button.apartments') }}
</UButton>
<UButton to="/book" color="secondary" variant="solid" size="xl" trailing-icon="i-heroicons-globe-alt">
<UButton :to="variantPath('book')" color="secondary" variant="solid" size="xl" trailing-icon="i-heroicons-globe-alt">
{{ t('button.book') }}
</UButton>
<UButton to="/contact" color="secondary" variant="solid" size="xl" trailing-icon="i-heroicons-envelope">
<UButton :to="variantPath('contact')" color="secondary" variant="solid" size="xl" trailing-icon="i-heroicons-envelope">
{{ t('button.contact') }}
</UButton>
</div>
@ -53,7 +53,7 @@
<!-- Right: Text Content -->
<AppTitleText i18n-key="landing.highlight">
<UButton :external="true" to="/contact#hosts" color="primary" variant="solid" size="xl"
<UButton :external="true" :to="variantPath('contact', 'hosts')" color="primary" variant="solid" size="xl"
trailing-icon="i-heroicons-arrow-right">
{{
t('button.hosts')
@ -98,7 +98,7 @@
<AppTitleText i18n-key="landing.apartments">
<div class="flex flex-wrap gap-4 justify-center">
<a v-for="apartment in tm('apartments.list')" :href="`/apartments#${rt(apartment.id)}`"
<a v-for="apartment in tm('apartments.list')" :href="variantPath('apartments', rt(apartment.id))"
class="relative group block w-60 h-80 overflow-hidden">
<img :src="rt(apartment.thumbnail)" alt="Image 1"
class="w-full h-full object-cover transition-transform duration-300 ease-out group-hover:scale-110"/>
@ -131,4 +131,5 @@ const images = [
]
const {t, tm, rt} = useI18n()
const { variantPath } = useVariantPath()
</script>

View File

@ -1,4 +1,4 @@
import { defineNuxtModule, createResolver, addComponentsDir } from '@nuxt/kit'
import { defineNuxtModule, createResolver, addComponentsDir, addImportsDir } from '@nuxt/kit'
// Module options TypeScript interface definition
export interface ModuleOptions {}
@ -8,7 +8,13 @@ export default defineNuxtModule<ModuleOptions>({
name: 'websites',
configKey: 'websites',
},
defaults: {},
defaults: {
defaultVariant: "su",
variants: [
{ code: 'su', name: 'Summer' },
{ code: 'wi', name: 'Winter' }
]
},
setup(_options, _nuxt) {
const resolver = createResolver(import.meta.url)
addComponentsDir({
@ -17,5 +23,6 @@ export default defineNuxtModule<ModuleOptions>({
prefix: '',
global: true,
})
},
addImportsDir(resolver.resolve('./runtime/composables'))
}
})

View File

@ -0,0 +1,14 @@
export function useVariantPath() {
const localePath = useLocalePath()
const route = useRoute()
function variantPath(page: string, anchor?: string) {
let base = [localePath('/'), route.params.variant ?? '', page].filter(Boolean).join('/')
base = base.replace(/\/{2,}/g, '/')
base = base.replace(/\/+$/, '')
base = base ? base : '/'
return anchor ? `${base}#${anchor}` : base
}
return { variantPath }
}