117 lines
3.5 KiB
Vue
117 lines
3.5 KiB
Vue
<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";
|
|
import provideGlobal from "../composables/provideGlobal";
|
|
|
|
const {
|
|
params: { slug: params },
|
|
} = useRoute();
|
|
const { findOne, find } = useStrapi();
|
|
|
|
const sitemap = await calculateSitemap();
|
|
|
|
const detail = ref<Article | Operation | Event | Vehicle | undefined>(undefined);
|
|
|
|
const activePath = computed(() => {
|
|
return "/" + (Array.isArray(params) ? params.join("/") : params);
|
|
});
|
|
const activePageBySitemap = computed(() => {
|
|
return sitemap.find((s) => s.path == activePath.value);
|
|
});
|
|
const similarestPage = computed(() => {
|
|
return sitemap.reduce(
|
|
(bestMatch, current) => {
|
|
const currentMatchLength = current.path
|
|
.split("/")
|
|
.filter((segment, index) => segment != "" && segment == activePath.value.split("/")[index]).length;
|
|
const bestMatchLength = bestMatch.path
|
|
.split("/")
|
|
.filter((segment, index) => segment != "" && segment == activePath.value.split("/")[index]).length;
|
|
|
|
if (currentMatchLength > bestMatchLength) {
|
|
return current;
|
|
} else {
|
|
return bestMatch;
|
|
}
|
|
},
|
|
{ path: "", origin: "", hasCollection: false }
|
|
);
|
|
});
|
|
|
|
const { data: pages } = await useAsyncData("pages", () =>
|
|
findOne<Page | Array<Page>>("pages", similarestPage.value?.document, {
|
|
populate: {
|
|
populate: "*",
|
|
content: {
|
|
populate: "*",
|
|
},
|
|
hero: {
|
|
populate: "*",
|
|
},
|
|
},
|
|
filters: {
|
|
...(!similarestPage.value?.document
|
|
? { slug: Array.isArray(params) ? params.join("~") : params, ref_only_access: false }
|
|
: {}),
|
|
},
|
|
})
|
|
);
|
|
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 { data: details } = await useAsyncData("detail", () =>
|
|
find<Article | Operation | Event | Vehicle>(element ?? "", {
|
|
populate: "*",
|
|
filters: {
|
|
slug: activePath.value.substring(activePath.value.lastIndexOf("/") + 1),
|
|
},
|
|
})
|
|
);
|
|
if (details.value?.data[0]) {
|
|
detail.value = details.value?.data[0];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
</script>
|