Compare commits

...

3 commits

14 changed files with 129 additions and 98 deletions

14
app.vue
View file

@ -3,19 +3,13 @@
</template>
<script setup lang="ts">
import calculateTitle from "./composables/calculateTitle";
import provideGlobal from "./composables/provideGlobal";
const { SEO } = await provideGlobal();
const title = await calculateTitle();
const { metaDescription, keywords } = SEO ?? {};
const { seo, title } = useGlobal();
useHead({
title: title,
title: title.value,
meta: [
{ name: "description", content: metaDescription },
{ name: "keywords", content: keywords },
{ name: "description", content: seo.value?.metaDescription },
{ name: "keywords", content: seo.value?.keywords ?? "" },
],
});
</script>

View file

@ -29,7 +29,6 @@
</template>
<script setup lang="ts">
const title = await calculateTitle();
const { footer } = await provideGlobal();
const { links, maintained_by, copyright } = footer ?? {};
const { footer, title } = useGlobal();
const { links, maintained_by, copyright } = footer.value ?? {};
</script>

View file

@ -64,8 +64,6 @@
</template>
<script setup lang="ts">
import provideGlobal from "../composables/provideGlobal";
const {
params: { slug: params },
} = useRoute();
@ -73,12 +71,12 @@ const {
const runtimeConfig = useRuntimeConfig();
const baseUrl = runtimeConfig.public.strapi.url;
const { logo, navbar } = await provideGlobal();
const { logo, navbar } = useGlobal();
const open = ref(false);
const navbar_sub_items = computed(() => {
if (!navbar) return [];
return navbar.navbar_items.find((ni) => ni.URL == params?.[0])?.navbar_sub_items;
if (!navbar.value) return [];
return navbar.value.navbar_items.find((ni) => ni.URL == params?.[0])?.navbar_sub_items;
});
</script>

View file

@ -4,10 +4,10 @@
:class="allowNavigation ? '' : 'pointer-events-none'"
:to="`${urlOverwrite ?? $route.path}/${data?.slug}`"
>
<div class="w-full h-56 relative">
<div class="w-full h-56 min-h-56 relative">
<NuxtPicture
loading="lazy"
class="w-full h-full object-cover object-center"
class="w-full h-full min-h-full object-cover object-center"
:src="data?.image?.url || logo?.url ? baseUrl + (data?.image?.url ?? logo?.url) : '/favicon.png'"
:imgAttrs="{ class: 'w-full h-full object-cover object-center' }"
/>
@ -20,11 +20,11 @@
</h1>
</div>
<div class="w-full h-44 relative bg-white px-2 py-5 flex flex-col justify-start items-start gap-2 overflow-y-auto">
<div class="w-full grow relative bg-white p-2 pb-4 flex flex-col justify-start items-start gap-2 overflow-y-auto">
<h1>
{{ data?.title }}
</h1>
<p v-if="itemDate && lookup?.show_date" class="w-full text-[#5c5c5c]">
<p class="w-full text-[#5c5c5c] line-clamp-2 overflow-hidden">
{{ itemDate }}
</p>
<p class="w-full text-[#5c5c5c] line-clamp-2 overflow-hidden">
@ -42,7 +42,7 @@ import type Lookup from "../../types/collection/lookup";
const runtimeConfig = useRuntimeConfig();
const baseUrl = runtimeConfig.public.strapi.url;
const { logo } = await provideGlobal();
const { logo } = useGlobal();
const props = defineProps({
data: Object as PropType<BaseCollection>,

View file

@ -25,7 +25,7 @@ import type SharedEmphasiseArticle from "../../types/component/shared/emphasiseA
import type Lookup from "../../types/collection/lookup";
const { find } = useStrapi();
const { data: lookup } = await useAsyncData("lookup", () =>
const { data: lookup } = await useAsyncData(() =>
find<Lookup>("collection-lookups", {
filters: {
collection: "articles",

View file

@ -113,13 +113,13 @@ const pagination = ref<Meta>({ page: 0, pageSize: 0, pageCount: 0, total: 0 });
const activeYear = ref<number>(0);
if (props.data?.lookup.list_with_date != "none") {
const { data: year } = await useAsyncData<Array<number>>("distinct-years", () =>
const { data: year } = await useAsyncData<Array<number>>(() =>
$fetch(`${baseUrl}/api/custom/${props.data?.lookup.collection}/distinct-years`)
);
years.value = year.value ?? [];
activeYear.value = years.value[0] ?? 0;
}
const { data: collections } = await useAsyncData("collection", () =>
const { data: collections } = await useAsyncData(() =>
find<BaseCollection>(props.data?.lookup.collection ?? "", {
...(props.data?.lookup?.list_with_date != "none"
? {
@ -235,7 +235,7 @@ async function changeTimedData(year: number) {
withCount: true,
},
});
console.log(data);
collection.value = data?.data;
pagination.value = (data?.meta.pagination as unknown as {
page: number;

View file

@ -1,11 +0,0 @@
import provideGlobal from "./provideGlobal";
export default async function () {
const runtimeConfig = useRuntimeConfig();
const appTitle = runtimeConfig.public.app.title;
const { SEO } = await provideGlobal();
const { metaTitle } = SEO ?? {};
return metaTitle ?? appTitle;
}

View file

@ -1,9 +0,0 @@
import type Global from "../types/single/global";
export default async function () {
const { findOne } = useStrapi();
const { data: global } = await useAsyncData("global", () => findOne<Global>("global"));
const { logo, navbar, footer, SEO } = global.value?.data ?? {};
return { logo, navbar, footer, SEO };
}

26
composables/useGlobal.ts Normal file
View file

@ -0,0 +1,26 @@
import type BaseFile from "../types/component/baseFile";
import type Footer from "../types/component/global/footer";
import type Navbar from "../types/component/global/navbar";
import type SEO from "../types/component/global/seo";
import type Global from "../types/single/global";
export const useGlobal = () => {
const global = useState<Global | null>("global");
const runtimeConfig = useRuntimeConfig();
const appTitle = runtimeConfig.public.app.title;
const logo = computed<BaseFile | null>(() => global.value?.logo ?? null);
const navbar = computed<Navbar | null>(() => global.value?.navbar ?? null);
const footer = computed<Footer | null>(() => global.value?.footer ?? null);
const seo = computed<SEO | null>(() => global.value?.SEO ?? null);
const title = computed<string>(() => seo.value?.metaTitle ?? appTitle);
return {
logo,
global,
navbar,
footer,
seo,
title,
};
};

View file

@ -1,30 +1,15 @@
import type Article from "../types/collection/article";
import type Page from "../types/collection/page";
import type { ComponentTypes } from "../types/component/baseComponent";
import type SharedList from "../types/component/shared/list";
import type Global from "../types/single/global";
export default async function () {
const { find } = useStrapi();
export const useSitemap = () => {
const { navbar, footer } = useGlobal();
const pages = useState<Page[]>("sitemap_pages");
const nuxtApp = useNuxtApp();
const { navbar, footer } = await nuxtApp.runWithContext(() => provideGlobal());
const { data: page_res } = await nuxtApp.runWithContext(() =>
useAsyncData("sitemap_pages", () =>
find<Page>("pages", {
filters: {
ref_only_access: false,
},
})
)
);
const pages = page_res.value?.data ?? [];
const sitemap = ref<sitemap>([]);
const accessableURLs: Array<{ path: string; origin: string; document?: string; hasCollection?: boolean }> = [];
for (const element of navbar?.navbar_items ?? []) {
for (const element of navbar.value?.navbar_items ?? []) {
if (!element.default_active_child) {
accessableURLs.push({
sitemap.value.push({
path: element.URL.startsWith("/") ? element.URL : `/${element.URL}`,
origin: "navbar",
document: element?.page?.documentId,
@ -33,7 +18,7 @@ export default async function () {
}
for (const subelement of element.navbar_sub_items) {
let url = `${element.URL}/${subelement.URL}`;
accessableURLs.push({
sitemap.value.push({
path: url.startsWith("/") ? url : `/${url}`,
origin: "navbar",
document: subelement?.page?.documentId,
@ -43,10 +28,10 @@ export default async function () {
}
}
for (const element of pages) {
for (const element of pages.value) {
let url = element.slug.replaceAll("~", "/");
if (!accessableURLs.find((a) => a.path == url)) {
accessableURLs.push({
if (!sitemap.value.find((a) => a.path == url)) {
sitemap.value.push({
path: url.startsWith("/") ? url : `/${url}`,
origin: "page",
document: element.documentId,
@ -55,10 +40,10 @@ export default async function () {
}
}
for (const element of footer?.links ?? []) {
for (const element of footer.value?.links ?? []) {
let url = element.URL.startsWith("/") ? element.URL : `/${element.URL}`;
if (!accessableURLs.find((a) => a.path == url) && !element.URL.startsWith("http")) {
accessableURLs.push({
if (!sitemap.value.find((a) => a.path == url) && !element.URL.startsWith("http")) {
sitemap.value.push({
path: url,
origin: "footer",
document: undefined,
@ -67,5 +52,12 @@ export default async function () {
}
}
return accessableURLs;
}
return sitemap;
};
type sitemap = Array<{
path: string;
origin: string;
document?: string;
hasCollection?: boolean;
}>;

View file

@ -22,14 +22,13 @@
</template>
<script setup lang="ts">
import provideGlobal from "../composables/provideGlobal";
import type Homepage from "../types/single/homepage";
const runtimeConfig = useRuntimeConfig();
const baseUrl = runtimeConfig.public.strapi.url;
const { findOne } = useStrapi();
const { logo } = await provideGlobal();
const { logo } = useGlobal();
const { data: homepage } = await useAsyncData("homepage", () => findOne<Homepage>("homepage"));
const { backdrop } = homepage.value?.data ?? {};

View file

@ -12,14 +12,13 @@ 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 sitemap = useSitemap();
const detail = ref<Article | Operation | Event | Vehicle | undefined>(undefined);
@ -27,10 +26,10 @@ const activePath = computed(() => {
return "/" + (Array.isArray(params) ? params.join("/") : params);
});
const activePageBySitemap = computed(() => {
return sitemap.find((s) => s.path == activePath.value);
return sitemap.value.find((s) => s.path == activePath.value);
});
const similarestPage = computed(() => {
return sitemap.reduce(
return sitemap.value.reduce(
(bestMatch, current) => {
const currentMatchLength = current.path
.split("/")
@ -49,23 +48,27 @@ const similarestPage = computed(() => {
);
});
const { data: pages } = await useAsyncData("pages", () =>
findOne<Page | Array<Page>>("pages", similarestPage.value?.document, {
populate: {
populate: "*",
content: {
const { data: pages } = await useAsyncData(
() =>
findOne<Page | Array<Page>>("pages", similarestPage.value?.document, {
populate: {
populate: "*",
content: {
populate: "*",
},
hero: {
populate: "*",
},
},
hero: {
populate: "*",
filters: {
...(!similarestPage.value?.document
? { slug: Array.isArray(params) ? params.join("~") : params, ref_only_access: false }
: {}),
},
},
filters: {
...(!similarestPage.value?.document
? { slug: Array.isArray(params) ? params.join("~") : params, ref_only_access: false }
: {}),
},
})
}),
{
default: () => null,
}
);
const page = computed(() => {
return Array.isArray(pages.value?.data) ? pages.value.data[0] : pages.value?.data;
@ -100,7 +103,7 @@ if (isCollectionDetail) {
];
for (const element of collectionOfDetail) {
const { data: details } = await useAsyncData("detail", () =>
const { data: details } = await useAsyncData(() =>
find<Article | Operation | Event | Vehicle>(element ?? "", {
populate: "*",
filters: {

15
plugins/global.ts Normal file
View file

@ -0,0 +1,15 @@
import type Global from "../types/single/global";
export default defineNuxtPlugin(async (nuxtApp) => {
const globalState = useState<Global | null>("global", () => null);
if (!globalState.value) {
const { findOne } = useStrapi();
const { data: global } = await useAsyncData("global", () => findOne<Global>("global"), {
server: true,
lazy: false,
default: () => {},
});
globalState.value = global.value?.data ?? null;
}
});

25
plugins/sitemap.ts Normal file
View file

@ -0,0 +1,25 @@
import type Page from "../types/collection/page";
import type Global from "../types/single/global";
export default defineNuxtPlugin(async (nuxtApp) => {
const pageState = useState<Page[]>("sitemap_pages", () => []);
if (!pageState.value) {
const { find } = useStrapi();
const { data: page_res } = await useAsyncData(
"sitemap_pages",
() =>
find<Page>("pages", {
filters: {
ref_only_access: false,
},
}),
{
server: true,
lazy: false,
default: () => {},
}
);
pageState.value = page_res.value?.data ?? [];
}
});