version update to nuxt4
This commit is contained in:
parent
7f1770d442
commit
ef84942e38
41 changed files with 5134 additions and 4946 deletions
134
app/pages/[...slug].vue
Normal file
134
app/pages/[...slug].vue
Normal file
|
@ -0,0 +1,134 @@
|
|||
<template>
|
||||
<NuxtLayout name="default">
|
||||
<NotFound v-if="notFound" />
|
||||
<ContentBuilder v-else-if="showContentBuilder" :hero="page?.hero" :content="page?.content" />
|
||||
<CollectionDetail v-else :data="detail" />
|
||||
</NuxtLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type Article from "~~/types/collection/article";
|
||||
import type Event from "~~/types/collection/event";
|
||||
import type Operation from "~~/types/collection/operation";
|
||||
import type Vehicle from "~~/types/collection/vehicle";
|
||||
import type Page from "~~/types/collection/page";
|
||||
|
||||
const {
|
||||
params: { slug: params },
|
||||
} = useRoute();
|
||||
const { findOne, find } = useStrapi();
|
||||
|
||||
const sitemap = useSitemap();
|
||||
|
||||
const detail = ref<Article | Operation | Event | Vehicle | undefined>(undefined);
|
||||
|
||||
const activePath = computed(() => {
|
||||
return "/" + (Array.isArray(params) ? params.join("/") : params);
|
||||
});
|
||||
const activePageBySitemap = computed(() => {
|
||||
return sitemap.value.find((s) => s.path == activePath.value);
|
||||
});
|
||||
const similarestPage = computed(() => {
|
||||
return sitemap.value.reduce(
|
||||
(bestMatch, current) => {
|
||||
const currentMatchLength = current.path
|
||||
.split("/")
|
||||
.filter(
|
||||
(segment, index) => segment != "" && segment.trim() == activePath.value.split("/")[index]?.trim()
|
||||
).length;
|
||||
const bestMatchLength = bestMatch.path
|
||||
.split("/")
|
||||
.filter(
|
||||
(segment, index) => segment != "" && segment.trim() == activePath.value.split("/")[index]?.trim()
|
||||
).length;
|
||||
|
||||
if (currentMatchLength > bestMatchLength) {
|
||||
return current;
|
||||
} else {
|
||||
return bestMatch;
|
||||
}
|
||||
},
|
||||
{ path: "", origin: "", hasCollection: false }
|
||||
);
|
||||
});
|
||||
|
||||
const { data: pages } = await useAsyncData(
|
||||
activePath,
|
||||
() =>
|
||||
findOne<Page | Array<Page>>("pages", similarestPage.value?.document, {
|
||||
populate: {
|
||||
content: {
|
||||
populate: "*",
|
||||
},
|
||||
hero: {
|
||||
populate: "*",
|
||||
},
|
||||
},
|
||||
filters: !similarestPage.value?.document
|
||||
? {
|
||||
slug: { $eq: Array.isArray(params) ? params.join("~") : params ?? "" },
|
||||
ref_only_access: { $eq: false },
|
||||
}
|
||||
: {},
|
||||
}),
|
||||
{
|
||||
default: () => null,
|
||||
watch: [activePath],
|
||||
}
|
||||
);
|
||||
const page = computed(() => {
|
||||
return Array.isArray(pages.value?.data) ? pages.value.data[0] : pages.value?.data;
|
||||
});
|
||||
|
||||
const isCollectionDetail = computed(() => {
|
||||
return activePath.value != similarestPage.value.path && similarestPage.value.hasCollection;
|
||||
});
|
||||
|
||||
const notFound = computed(() => {
|
||||
if (isCollectionDetail.value && detail.value) return !detail.value;
|
||||
else
|
||||
return (
|
||||
!page.value ||
|
||||
(page.value && !(page.value.content.length != 0 || page.value.hero.title || page.value.hero.banner))
|
||||
);
|
||||
});
|
||||
|
||||
const showContentBuilder = computed(() => {
|
||||
if (isCollectionDetail.value && detail.value) return !detail.value;
|
||||
else return page.value && (page.value.content.length != 0 || page.value.hero.title || page.value.hero.banner);
|
||||
});
|
||||
|
||||
if (isCollectionDetail) {
|
||||
let collectionOfDetail = [
|
||||
...new Set(
|
||||
page.value?.content
|
||||
.filter((c) => c.__component == "shared.list")
|
||||
.filter((c) => c.lookup.enable_detail)
|
||||
.map((c) => c.lookup.collection)
|
||||
),
|
||||
];
|
||||
|
||||
for (const element of collectionOfDetail) {
|
||||
const detailKey = `detail-${element}-${activePath.value.substring(activePath.value.lastIndexOf("/") + 1)}`;
|
||||
const { data: details } = await useAsyncData(
|
||||
detailKey,
|
||||
() =>
|
||||
find<Article | Operation | Event | Vehicle>(element ?? "", {
|
||||
populate: "*",
|
||||
filters: {
|
||||
slug: {
|
||||
$eq: activePath.value.substring(activePath.value.lastIndexOf("/") + 1),
|
||||
},
|
||||
},
|
||||
}),
|
||||
{
|
||||
watch: [activePath],
|
||||
}
|
||||
);
|
||||
if (details.value?.data[0]) {
|
||||
detail.value = details.value?.data[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
14
app/pages/index.vue
Normal file
14
app/pages/index.vue
Normal file
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<NuxtLayout name="landing">
|
||||
<ContentBuilder :content="content" />
|
||||
</NuxtLayout>
|
||||
</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 ?? {};
|
||||
</script>
|
15
app/pages/sitemap.vue
Normal file
15
app/pages/sitemap.vue
Normal file
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<NuxtLayout name="default">
|
||||
<div class="min-h-[calc(100vh-9rem)] w-full">
|
||||
<div class="container mx-auto py-12 px-2 min-h-[50vh] flex flex-col gap-2">
|
||||
<NuxtLink v-for="item in sitemap" :key="item.path" :to="`${item.path}`">
|
||||
{{ item.path }} {{ item.hasCollection ? "(...)" : "" }}
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</NuxtLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const sitemap = useSitemap();
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue