<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>