base structure and display
This commit is contained in:
parent
de049e9125
commit
9d96e3a6dc
22 changed files with 1210 additions and 15 deletions
|
@ -8,18 +8,30 @@
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
@apply bg-white text-black;
|
@apply bg-white text-black w-full min-h-screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
[primary] {
|
[primary] {
|
||||||
@apply bg-primary text-white;
|
@apply bg-primary text-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-link-active {
|
a {
|
||||||
|
@apply cursor-pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[primary-link] {
|
||||||
|
@apply text-xl;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[primary-link].active {
|
||||||
@apply underline;
|
@apply underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-sublink-active {
|
a[primary-sublink] {
|
||||||
|
@apply text-xl p-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[primary-sublink].active {
|
||||||
@apply bg-white text-primary;
|
@apply bg-white text-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
components/ContentBuilder.vue
Normal file
5
components/ContentBuilder.vue
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<p>Content Builder</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts"></script>
|
|
@ -1 +1,20 @@
|
||||||
<template>Footer</template>
|
<template>
|
||||||
|
<div darkgray class="h-48 min-h-fit w-full px-5 py-10 flex-col justify-center items-center flex">
|
||||||
|
<div class="self-stretch py-5 justify-center items-center gap-10 inline-flex">
|
||||||
|
<NuxtLink v-for="link in footer.links" :key="link.id" :to="link.URL" :target="link.target" class="text-base">
|
||||||
|
{{ link.text }}
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
<div class="text-base">@Copyright {{ new Date().getFullYear() }} {{ footer.copyright }}</div>
|
||||||
|
<div class="text-base">verwaltet von {{ footer.designed_developed_by }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type Global from "../types/single/global";
|
||||||
|
|
||||||
|
const { findOne } = useStrapi();
|
||||||
|
|
||||||
|
const { data: global } = await useAsyncData("global", () => findOne<Global>("global"));
|
||||||
|
const { footer } = global.value?.data as unknown as Global;
|
||||||
|
</script>
|
||||||
|
|
|
@ -1 +1,52 @@
|
||||||
<template>Header</template>
|
<template>
|
||||||
|
<div class="sticky top-0 h-fit">
|
||||||
|
<div primary class="h-24 min-h-fit w-full px-12 py-2.5 justify-between items-center gap-5 flex">
|
||||||
|
<NuxtLink to="/">
|
||||||
|
<img class="h-16 w-fit" :src="baseUrl + navbar.logo.url" />
|
||||||
|
</NuxtLink>
|
||||||
|
<div class="self-stretch p-2.5 justify-center items-center gap-7 flex">
|
||||||
|
<NuxtLink
|
||||||
|
primary-link
|
||||||
|
v-for="link in navbar.navbar_items"
|
||||||
|
:key="link.id"
|
||||||
|
:to="`/${link.URL}/${link.default_active_child}`"
|
||||||
|
:class="link.URL == params?.[0] ? 'active' : ''"
|
||||||
|
>
|
||||||
|
{{ link.name }}
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="navbar_sub_items?.length != 0"
|
||||||
|
primary
|
||||||
|
class="h-12 min-h-fit w-full px-12 border-t-2 border-white justify-center items-center gap-5 flex"
|
||||||
|
>
|
||||||
|
<NuxtLink
|
||||||
|
primary-sublink
|
||||||
|
v-for="sublink in navbar_sub_items"
|
||||||
|
:key="sublink.id"
|
||||||
|
:to="`/${params?.[0]}/${sublink.URL}`"
|
||||||
|
:class="sublink.URL == params?.[1] ? 'active' : ''"
|
||||||
|
>
|
||||||
|
{{ sublink.name }}
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type Global from "../types/single/global";
|
||||||
|
|
||||||
|
const {
|
||||||
|
params: { slug: params },
|
||||||
|
} = useRoute();
|
||||||
|
const baseUrl = useStrapiUrl().replace("/api", "");
|
||||||
|
const { findOne } = useStrapi();
|
||||||
|
|
||||||
|
const { data: global } = await useAsyncData("global", () => findOne<Global>("global"));
|
||||||
|
const { navbar } = global.value?.data as unknown as Global;
|
||||||
|
|
||||||
|
const navbar_sub_items = computed(() => {
|
||||||
|
return navbar.navbar_items.find((ni) => ni.URL == params?.[0])?.navbar_sub_items;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
3
components/NotFound.vue
Normal file
3
components/NotFound.vue
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<template>
|
||||||
|
<div class="h-[calc(100vh-18rem)] w-full flex items-center justify-center">Nicht gefunden</div>
|
||||||
|
</template>
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<Header />
|
<Header />
|
||||||
Image title
|
|
||||||
<slot />
|
<slot />
|
||||||
<Footer />
|
<Footer />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<template>
|
|
||||||
<Header />
|
|
||||||
<slot />
|
|
||||||
<Footer />
|
|
||||||
</template>
|
|
|
@ -1,6 +1,26 @@
|
||||||
<template>
|
<template>
|
||||||
Image
|
<div class="relative h-[calc(100vh-6rem)] w-full">
|
||||||
|
<NuxtPicture preload loading="lazy" class="w-full h-full object-cover" :src="baseUrl + backdrop.url" />
|
||||||
|
<img class="absolute h-40 w-fit bottom-10 left-5" :src="baseUrl + navbar.logo.url" />
|
||||||
|
</div>
|
||||||
<Header />
|
<Header />
|
||||||
<slot />
|
<slot />
|
||||||
<Footer />
|
<Footer />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type Global from "../types/single/global";
|
||||||
|
import type Homepage from "../types/single/homepage";
|
||||||
|
|
||||||
|
const {
|
||||||
|
params: { slug: params },
|
||||||
|
} = useRoute();
|
||||||
|
const baseUrl = useStrapiUrl().replace("/api", "");
|
||||||
|
const { findOne } = useStrapi();
|
||||||
|
|
||||||
|
const { data: global } = await useAsyncData("global", () => findOne<Global>("global"));
|
||||||
|
const { navbar } = global.value?.data as unknown as Global;
|
||||||
|
|
||||||
|
const { data: homepage } = await useAsyncData("homepage", () => findOne<Homepage>("homepage"));
|
||||||
|
const { backdrop } = homepage.value?.data as unknown as Homepage;
|
||||||
|
</script>
|
||||||
|
|
|
@ -28,10 +28,10 @@ export default defineNuxtConfig({
|
||||||
|
|
||||||
compatibilityDate: "2024-04-03",
|
compatibilityDate: "2024-04-03",
|
||||||
devtools: { enabled: false },
|
devtools: { enabled: false },
|
||||||
modules: ["@nuxtjs/strapi"],
|
modules: ["@nuxtjs/strapi", "@nuxt/image"],
|
||||||
|
|
||||||
strapi: {
|
strapi: {
|
||||||
url: process.env.STRAPI_URL,
|
url: process.env.STRAPI_URL,
|
||||||
prefix: "/api",
|
prefix: "/api",
|
||||||
},
|
},
|
||||||
});
|
});
|
936
package-lock.json
generated
936
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -10,6 +10,7 @@
|
||||||
"postinstall": "nuxt prepare"
|
"postinstall": "nuxt prepare"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@nuxt/image": "^1.8.1",
|
||||||
"@nuxtjs/strapi": "^1.12.0",
|
"@nuxtjs/strapi": "^1.12.0",
|
||||||
"nuxt": "^3.13.2",
|
"nuxt": "^3.13.2",
|
||||||
"vue": "latest",
|
"vue": "latest",
|
||||||
|
|
44
pages/[...slug].vue
Normal file
44
pages/[...slug].vue
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<template>
|
||||||
|
<NuxtLayout name="default">
|
||||||
|
<NotFound v-if="data.length == 0" />
|
||||||
|
<ContentBuilder v-else class="min-h-[calc(100vh-9rem)] w-full" />
|
||||||
|
</NuxtLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type Page from "../types/collection/page";
|
||||||
|
import type Global from "../types/single/global";
|
||||||
|
|
||||||
|
const {
|
||||||
|
params: { slug: params },
|
||||||
|
} = useRoute();
|
||||||
|
const baseUrl = useStrapiUrl().replace("/api", "");
|
||||||
|
const { findOne } = useStrapi();
|
||||||
|
|
||||||
|
const { data: global } = await useAsyncData("global", () => findOne<Global>("global"));
|
||||||
|
const {
|
||||||
|
navbar: { navbar_items },
|
||||||
|
} = global.value?.data as unknown as Global;
|
||||||
|
|
||||||
|
const navbar_sub_items = computed(() => {
|
||||||
|
return navbar_items.find((ni) => ni.URL == params[0])?.navbar_sub_items ?? [];
|
||||||
|
});
|
||||||
|
|
||||||
|
const active_item = computed(() => {
|
||||||
|
return navbar_items.find((ni) => ni.URL == params[0])?.page;
|
||||||
|
});
|
||||||
|
const active_sub_item = computed(() => {
|
||||||
|
return navbar_sub_items.value.find((si) => si.URL == params[1])?.page;
|
||||||
|
});
|
||||||
|
const active_page_id = computed<string>(() => {
|
||||||
|
return active_sub_item.value?.slug ?? active_item.value?.slug ?? "";
|
||||||
|
});
|
||||||
|
|
||||||
|
const { data: pages } = await useAsyncData("pages", () =>
|
||||||
|
findOne<Array<Page>>("pages", {
|
||||||
|
populate: "*",
|
||||||
|
filters: { slug: active_page_id.value },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
const data = pages.value?.data as unknown as Array<Page>;
|
||||||
|
</script>
|
|
@ -1,3 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<NuxtLayout name="landing"> index </NuxtLayout>
|
<NuxtLayout name="landing">
|
||||||
|
<ContentBuilder class="min-h-[calc(100vh-9rem)] w-full" />
|
||||||
|
</NuxtLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type Homepage from "../types/single/homepage";
|
||||||
|
|
||||||
|
const { findOne } = useStrapi();
|
||||||
|
|
||||||
|
const { data: homepage } = await useAsyncData("homepage", () => findOne<Homepage>("homepage"));
|
||||||
|
const { content } = homepage.value?.data as unknown as Homepage;
|
||||||
|
</script>
|
||||||
|
|
13
types/collection/page.ts
Normal file
13
types/collection/page.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
export default interface Page {
|
||||||
|
id: number;
|
||||||
|
documentId: string;
|
||||||
|
identifier: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
publishedAt: string;
|
||||||
|
locale: string;
|
||||||
|
slug: string;
|
||||||
|
Hero: { id: number; titel: string };
|
||||||
|
content: { __component: string; id: number; list: string; enable_detail: boolean }[];
|
||||||
|
localizations: any[];
|
||||||
|
}
|
8
types/component/footer.ts
Normal file
8
types/component/footer.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import type FooterLink from "./footerLink";
|
||||||
|
|
||||||
|
export default interface Footer {
|
||||||
|
id: number;
|
||||||
|
copyright: string;
|
||||||
|
designed_developed_by: string;
|
||||||
|
links: FooterLink[];
|
||||||
|
}
|
6
types/component/footerLink.ts
Normal file
6
types/component/footerLink.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export default interface FooterLink {
|
||||||
|
id: number;
|
||||||
|
text: string;
|
||||||
|
URL: string;
|
||||||
|
target: string;
|
||||||
|
}
|
21
types/component/image.ts
Normal file
21
types/component/image.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
export default interface Image {
|
||||||
|
id: number;
|
||||||
|
documentId: string;
|
||||||
|
name: string;
|
||||||
|
alternativeText: string | null;
|
||||||
|
caption: string | null;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
formats: any;
|
||||||
|
hash: string;
|
||||||
|
ext: string;
|
||||||
|
mime: string;
|
||||||
|
size: number;
|
||||||
|
url: string;
|
||||||
|
previewUrl: string | null;
|
||||||
|
provider: string;
|
||||||
|
provider_metadata: any;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
publishedAt: string;
|
||||||
|
}
|
8
types/component/navbar.ts
Normal file
8
types/component/navbar.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import type Image from "./image";
|
||||||
|
import type NavbarItem from "./navbarItem";
|
||||||
|
|
||||||
|
export default interface Navbar {
|
||||||
|
id: number;
|
||||||
|
logo: Image;
|
||||||
|
navbar_items: NavbarItem[];
|
||||||
|
}
|
10
types/component/navbarItem.ts
Normal file
10
types/component/navbarItem.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import type NavbarSubItem from "./navbarSubItem";
|
||||||
|
|
||||||
|
export default interface NavbarItem {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
URL: string;
|
||||||
|
default_active_child: string;
|
||||||
|
page: any;
|
||||||
|
navbar_sub_items: NavbarSubItem[];
|
||||||
|
}
|
8
types/component/navbarSubItem.ts
Normal file
8
types/component/navbarSubItem.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import type Page from "../collection/page";
|
||||||
|
|
||||||
|
export default interface NavbarSubItem {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
URL: string;
|
||||||
|
page: Page | null;
|
||||||
|
}
|
13
types/single/global.ts
Normal file
13
types/single/global.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import type Footer from "../component/footer";
|
||||||
|
import type Navbar from "../component/navbar";
|
||||||
|
|
||||||
|
export default interface Global {
|
||||||
|
id: number;
|
||||||
|
documentId: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
publishedAt: string;
|
||||||
|
locale: string;
|
||||||
|
navbar: Navbar;
|
||||||
|
footer: Footer;
|
||||||
|
}
|
12
types/single/homepage.ts
Normal file
12
types/single/homepage.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import type Image from "../component/image";
|
||||||
|
|
||||||
|
export default interface Homepage {
|
||||||
|
id: number;
|
||||||
|
documentId: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
publishedAt: string;
|
||||||
|
locale: string;
|
||||||
|
backdrop: Image;
|
||||||
|
content: Array<any>;
|
||||||
|
}
|
Loading…
Reference in a new issue