Compare commits
3 Commits
2b8a67af9b
...
87c244f0e3
| Author | SHA1 | Date | |
|---|---|---|---|
| 87c244f0e3 | |||
| a5bf261f62 | |||
| b86bc53a48 |
@ -4,7 +4,8 @@
|
||||
|
||||
Package creation: `pnpm dlx nuxi@latest init -t module packages/ui --packageManager pnpm`. App creation: `pnpm dlx nuxi@latest init apps/panoramablick --packageManager pnpm`.
|
||||
|
||||
|
||||
Setup in the root via `pnpm install`. Running a single app in dev mode via `pnpm run dev` in that app directory.
|
||||
|
||||
This is a community-maintained example. If you experience a problem, please submit a pull request with a fix. GitHub Issues will be closed.
|
||||
|
||||
## Using this example
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<section class="w-full">
|
||||
<!-- ❶ two-column card ----------------------------->
|
||||
<div class="grid gap-8 lg:grid-cols-2 bg-white rounded-lg overflow-hidden">
|
||||
<div class="flex flex-col md:flex-row">
|
||||
<!-- ◀ left half : image carousel -->
|
||||
<AppThumbnailCarousel></AppThumbnailCarousel>
|
||||
<AppThumbnailCarousel class="basis-1/3"></AppThumbnailCarousel>
|
||||
|
||||
<!-- ▶ right half : text (top) & icons (bottom) -->
|
||||
<div class="flex flex-col h-full p-6">
|
||||
<div class="basis-2/3 flex flex-col h-full p-6">
|
||||
<!-- title + intro copy -->
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
@ -52,8 +52,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {Apartment} from '@/composables/useApartments'
|
||||
|
||||
const {t, tm, rt} = useVariantData()
|
||||
|
||||
defineProps<{ apartment: Apartment }>()
|
||||
|
||||
@ -3,10 +3,15 @@
|
||||
<AppStripe>
|
||||
<nav class="mx-auto py-4 flex items-center justify-between">
|
||||
<!-- your logo / home link -->
|
||||
<NuxtLink :to="variantPath('/')" class="text-xl font-semibold">
|
||||
{{ t('header.home') }}
|
||||
<NuxtLink :to="variantPath('/')" class="text-xl font-semibold flex items-center gap-2">
|
||||
<UIcon name="i-heroicons-home" />
|
||||
|
||||
<span class="hidden md:inline">
|
||||
{{ t('header.home') }}
|
||||
</span>
|
||||
</NuxtLink>
|
||||
|
||||
|
||||
<!-- nav links -->
|
||||
<ul class="flex space-x-6">
|
||||
<li>
|
||||
|
||||
@ -59,15 +59,22 @@
|
||||
"landing": {
|
||||
"welcome": {
|
||||
"title": "Willkommen im Landhaus Panoramablick",
|
||||
"description": "Genießen Sie erholsame Tage inmitten der Natur mit herrlichem Ausblick auf die Berge. Unser Landhaus bietet gemütliche Apartments und herzliche Gastfreundschaft."
|
||||
"description": "Genießen Sie erholsame Tage inmitten der Natur mit herrlichem Ausblick auf die Berge. Unser Landhaus bietet gemütliche Apartments und herzliche Gastfreundschaft.",
|
||||
"joker": {
|
||||
"#su": "true",
|
||||
"#wi": "false"
|
||||
}
|
||||
},
|
||||
"highlight": {
|
||||
"title": "Erleben Sie Natur hautnah",
|
||||
"description": "Unser Landhaus liegt eingebettet in idyllischer Landschaft mit atemberaubendem Ausblick. Ob Wandern, Entspannen oder die Umgebung erkunden – bei uns finden Sie Ruhe und Erholung."
|
||||
"description": "Unser Landhaus liegt eingebettet in idyllischer Landschaft mit atemberaubendem Ausblick. Ob Wandern, Entspannen oder die Umgebung erkunden – bei uns finden Sie Ruhe und Erholung.",
|
||||
"image-left": "/ap.webp",
|
||||
"image-right": "/sauna.webp"
|
||||
},
|
||||
"location": {
|
||||
"title": "Logieren Sie in bester Lage",
|
||||
"description": "Blabla asdfasdf asdf asdf asdf asddf asddf asdf asdf asdfasd ffad."
|
||||
"description": "Blabla asdfasdf asdf asdf asdf asddf asddf asdf asdf asdfasd ffad.",
|
||||
"image": "/maps.png"
|
||||
},
|
||||
"apartments": {
|
||||
"title": "Unsere Apartments",
|
||||
@ -81,7 +88,9 @@
|
||||
"apartments": {
|
||||
"highlight": {
|
||||
"title": "Das gibt es bei uns",
|
||||
"description": "Es ist alles so toll"
|
||||
"description": "Es ist alles so toll",
|
||||
"image-left": "/ap.webp",
|
||||
"image-right": "/sauna.webp"
|
||||
},
|
||||
"list": [
|
||||
{
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="w-full h-full bg-neutral-50">
|
||||
<AppFlatSection>
|
||||
<div class="flex gap-12 items-center">
|
||||
<div class="flex flex-col md:flex-row items-center gap-8">
|
||||
<!-- Left: Image Group -->
|
||||
<div class="flex flex-row gap-4 justify-center relative">
|
||||
<img src="/ap.webp" alt="Image 1" class="w-40 h-60 object-cover rounded-lg"/>
|
||||
<img src="/sauna.webp" alt="Image 2" class="w-40 h-60 object-cover rounded-lg translate-y-6"/>
|
||||
<img :src="t('apartments.highlight.image-left')" alt="Image 1" class="w-40 h-60 object-cover"/>
|
||||
<img :src="t('apartments.highlight.image-right')" class="w-40 h-60 object-cover mt-6" />
|
||||
</div>
|
||||
|
||||
<AppTitleText i18n-key="apartments.highlight">
|
||||
@ -14,7 +14,12 @@
|
||||
</div>
|
||||
</AppFlatSection>
|
||||
|
||||
<AppCardSection v-for="apartment in tm('apartments.list')" :id="rt(apartment.id)">
|
||||
<AppCardSection
|
||||
v-for="(apartment, index) in tm('apartments.list')"
|
||||
:key="apartment.id"
|
||||
:id="rt(apartment.id)"
|
||||
:padTop="index === 0"
|
||||
>
|
||||
<AppApartment :apartment="apartment"/>
|
||||
</AppCardSection>
|
||||
</div>
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
<!-- Contact‑centric layout -->
|
||||
<AppFlatSection>
|
||||
<!-- Grid: form (fixed max‑width) | host snapshots -->
|
||||
<div class="grid gap-12 lg:grid-cols-[minmax(0,480px)_1fr] items-start lg:items-center">
|
||||
<div class="flex flex-col md:flex-row gap-8 items-center">
|
||||
<!-- ─── Contact form ─── -->
|
||||
<div class="w-full max-w-xl mx-auto lg:mx-0">
|
||||
<div class="w-full md:w-auto max-w-xl mx-auto lg:mx-0">
|
||||
<h1 class="text-3xl sm:text-4xl font-bold mb-4">{{ t('contact.title') }}</h1>
|
||||
|
||||
<!-- Extended intro -->
|
||||
@ -71,7 +71,7 @@
|
||||
</div>
|
||||
|
||||
<!-- ─── Decorative host snapshots ─── -->
|
||||
<div id="hosts" class="flex flex-col gap-10 lg:self-center">
|
||||
<div id="hosts" class="flex flex-col gap-10 lg:self-center w-full md:w-auto">
|
||||
<AppHero
|
||||
:src="t('contact.heroes.parents.image')"
|
||||
:alt="t('contact.heroes.parents.title')"
|
||||
|
||||
@ -1,54 +1,70 @@
|
||||
<template>
|
||||
<section class="relative w-full">
|
||||
<div class="relative w-full">
|
||||
<UCarousel
|
||||
v-slot="{ item }"
|
||||
:items="images"
|
||||
:ui="{item: 'basis-full h-full ps-0', container: 'flex items-stretch h-150 sm:h-75 md:h-100 lg:h-150'}"
|
||||
:autoplay="{ delay: 5000 }"
|
||||
:loop="true"
|
||||
:fade="true"
|
||||
:duration="75"
|
||||
class="w-full h-full">
|
||||
<div class="w-full h-full flex items-center justify-center">
|
||||
<img :src="item" class="w-full h-full object-cover" alt="Demo Picture"/>
|
||||
</div>
|
||||
</UCarousel>
|
||||
<div class="absolute inset-0 z-10 bg-black/60">
|
||||
<div class="w-full h-full flex justify-center items-center">
|
||||
<AppStripe class="text-white">
|
||||
<div class="max-w-2xl">
|
||||
<h1 class="text-5xl max-w-4xl font-bold">{{ t('landing.welcome.title') }}</h1>
|
||||
<p class="mt-4 text-lg text-gray-200">
|
||||
{{
|
||||
t('landing.welcome.description')
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="relative w-full">
|
||||
<div class="absolute inset-0 z-0">
|
||||
<UCarousel
|
||||
v-slot="{ item }"
|
||||
:items="images"
|
||||
:ui="{item: 'basis-full h-full ps-0', container: 'flex items-stretch h-full'}"
|
||||
:autoplay="{ delay: 5000 }"
|
||||
:loop="true"
|
||||
:fade="true"
|
||||
:duration="75"
|
||||
class="w-full h-full custom-carousel">
|
||||
<div class="w-full h-full flex items-center justify-center">
|
||||
<img :src="item" class="w-full h-full object-cover" alt="Demo Picture"/>
|
||||
</div>
|
||||
</UCarousel>
|
||||
</div>
|
||||
|
||||
<div class="absolute inset-0 z-5 bg-black/60"/>
|
||||
|
||||
<div class="relative z-10">
|
||||
<AppStripe class="text-white py-4 sm:py-8 lg:py-16">
|
||||
<div class="flex flex-col md:flex-row py-6 gap-4 sm:gap-8 lg:gap-16">
|
||||
<div class="flex flex-col">
|
||||
<div>
|
||||
<h1 class="text-5xl max-w-4xl font-bold">{{ t('landing.welcome.title') }}</h1>
|
||||
<p class="mt-4 text-lg">
|
||||
{{
|
||||
t('landing.welcome.description')
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-8 flex gap-4">
|
||||
<UButton :to="variantPath('apartments')" color="primary" variant="solid" size="xl"
|
||||
trailing-icon="i-heroicons-arrow-right">{{ t('button.apartments') }}
|
||||
</UButton>
|
||||
<UButton :to="variantPath('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="variantPath('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>
|
||||
</AppStripe>
|
||||
</div>
|
||||
<div v-if="t('landing.welcome.joker') === 'true'" class="flex items-center justify-center p-8">
|
||||
<a href="https://www.saalbach.com/de/sommer/joker-card">
|
||||
<NuxtImg
|
||||
src="/joker-card.jpeg"
|
||||
alt="Joker Card"
|
||||
class="w-30 md:w-50 transform rotate-15"
|
||||
style="border-radius: .5rem"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AppStripe>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<AppFlatSection>
|
||||
<div class="flex gap-12 items-center">
|
||||
<div class="flex flex-col md:flex-row items-center gap-4">
|
||||
<!-- Left: Image Group -->
|
||||
<div class="flex flex-row gap-4 justify-center relative">
|
||||
<img src="/ap.webp" alt="Image 1" class="w-40 h-60 object-cover rounded-lg"/>
|
||||
<img src="/sauna.webp" alt="Image 2" class="w-40 h-60 object-cover rounded-lg translate-y-6"/>
|
||||
<img :src="t('landing.highlight.image-left')" alt="Image 1" class="w-40 h-60 object-cover"/>
|
||||
<img :src="t('landing.highlight.image-right')" class="w-40 h-60 object-cover mt-6" />
|
||||
</div>
|
||||
|
||||
<!-- Right: Text Content -->
|
||||
@ -64,7 +80,7 @@
|
||||
</AppFlatSection>
|
||||
|
||||
<AppCardSection>
|
||||
<div class="flex gap-12 items-center">
|
||||
<div class="flex flex-col md:flex-row items-center gap-4">
|
||||
|
||||
<!-- Left: Text (40%) -->
|
||||
<div class="basis-2/5 pr">
|
||||
@ -79,13 +95,11 @@
|
||||
<!-- Right: Image (60%) -->
|
||||
<a
|
||||
href="https://maps.app.goo.gl/FtTC8ervoBCnfU3j7"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="basis-3/5 flex justify-center overflow-hidden rounded-lg group"
|
||||
class="basis-3/5 flex justify-center overflow-hidden group"
|
||||
aria-label="Google Maps öffnen"
|
||||
>
|
||||
<img
|
||||
src="/maps.png"
|
||||
:src="t('landing.location.image')"
|
||||
alt="Vorschaubild der Lage in Google Maps"
|
||||
class="w-full h-80 object-cover transition-transform duration-300 ease-out group-hover:scale-110"
|
||||
/>
|
||||
@ -124,6 +138,13 @@
|
||||
</AppCardSection>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* TODO this is somewhat hacky, but currently no other way to style carousel inner wrapper */
|
||||
:deep(.custom-carousel > .overflow-hidden) {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script setup lang="ts">
|
||||
const images = [
|
||||
'/house.webp',
|
||||
@ -131,5 +152,5 @@ const images = [
|
||||
]
|
||||
|
||||
const {t, tm, rt} = useVariantData()
|
||||
const { variantPath } = useVariantPath()
|
||||
const {variantPath} = useVariantPath()
|
||||
</script>
|
||||
BIN
apps/panoramablick/public/joker-card.jpeg
Normal file
BIN
apps/panoramablick/public/joker-card.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
Loading…
x
Reference in New Issue
Block a user