Add a method to get all web pages

This commit is contained in:
itsfinniii
2026-03-15 11:23:47 +01:00
parent c1b89c5823
commit 6dcac27de8
13 changed files with 687 additions and 1 deletions

View File

@@ -0,0 +1,318 @@
import { createDirectusConnection } from "@/lib/directus";
import { print } from 'graphql';
import { formatDate } from "@/lib/dates";
import getAllPages from "@/graphql/pages/getAllPages.graphql";
export async function getAllWebpages(): Promise<WebPage[]> {
const client = await createDirectusConnection();
const result = await client.query(print(getAllPages), {
date: formatDate(new Date(), "%Y-%M-%D")
});
let pages: WebPage[] = [];
result["Pages"].forEach((pageRecord: any) => {
let dates: string[] = [
pageRecord["date_created"],
pageRecord["date_updated"],
pageRecord["search_engine"][0]["date_created"],
pageRecord["search_engine"][0]["date_updated"]
];
const searchEngine = pageRecord["search_engine"][0];
let components: WebpageComponent[] = [];
pageRecord["components"].forEach((componentRecord: any) => {
const component = componentRecord["item"];
switch (componentRecord["item"]["__typename"]) {
case "Hero":
let heroComponent: HeroComponent = {
component: "Hero",
id: component["hero_id"],
title: component["hero_title"],
text: component["hero_text"],
backgroundImage: {
url: component["background_image"]["filename_disk"],
width: component["background_image"]["width"],
height: component["background_image"]["height"]
}
};
components.push(heroComponent);
dates.push(component["hero_created"]);
dates.push(component["hero_updated"]);
dates.push(component["background_image"]["created_on"]);
break;
case "Text_With_Side_Image":
let textWithImageComponent: TextWithImageComponent = {
component: "TextWithImage",
id: component["twsi_id"],
title: component["twsi_title"],
text: component["twsi_text"],
imageSide: component["twsi_image_side"],
image: {
url: component["image"]["filename_disk"],
width: component["image"]["width"],
height: component["image"]["height"]
}
};
components.push(textWithImageComponent);
dates.push(component["twsi_created"]);
dates.push(component["twsi_updated"]);
dates.push(component["image"]["created_on"]);
break;
case "Wall_Of_Text":
let wallOfTextComponent: WallOfTextComponent = {
component: "WallOfText",
id: component["wot_id"],
title: component["wot_title"],
text: component["wot_text"]
};
components.push(wallOfTextComponent);
dates.push(component["wot_created"]);
dates.push(component["wot_updated"]);
break;
case "Frequently_Asked_Questions":
let faqComponent: FrequentlyAskedQuestionsComponent = {
component: "FrequentlyAskedQuestions",
id: component["faq_id"],
title: component["faq_title"],
text: component["faq_text"],
questions: []
};
component["questions"].forEach((faqQuestionRecord: any) => {
faqComponent.questions.push({
id: faqQuestionRecord["id"],
question: faqQuestionRecord["question"],
answer: faqQuestionRecord["answer"]
});
dates.push(faqQuestionRecord["date_created"]);
dates.push(faqQuestionRecord["date_updated"]);
});
components.push(faqComponent);
dates.push(component["faq_created"]);
dates.push(component["faq_updated"]);
break;
case "Upcoming_Events":
let upcomingEventsComponent: UpcomingEventsComponent = {
component: "UpcomingEvents",
id: component["ue_id"],
title: component["ue_title"],
text: component["ue_text"],
events: []
};
component["events"].forEach((eventRecord: any) => {
upcomingEventsComponent.events.push({
id: eventRecord["id"],
title: eventRecord["title"],
description: eventRecord["description"],
location: eventRecord["location"],
mapLocation: [
eventRecord["map_location"]["coordinates"][1],
eventRecord["map_location"]["coordinates"][0]
],
startDate: eventRecord["start_date"],
endDate: eventRecord["end_date"]
});
dates.push(eventRecord["date_created"]);
dates.push(eventRecord["date_updated"]);
});
components.push(upcomingEventsComponent);
dates.push(component["ue_created"]);
dates.push(component["ue_updated"]);
break;
case "Equipment_Table":
let equipmentTableComponent: EquipmentTableComponent = {
component: "EquipmentTable",
id: component["et_id"],
title: component["et_title"],
text: component["et_text"],
items: []
};
component["items"].forEach((itemRecord: any) => {
equipmentTableComponent.items.push({
id: itemRecord["id"],
title: itemRecord["title"],
text: itemRecord["text"],
icon: {
url: itemRecord["icon"]["filename_disk"],
width: itemRecord["icon"]["width"],
height: itemRecord["icon"]["height"]
}
});
dates.push(itemRecord["date_created"]);
dates.push(itemRecord["date_updated"]);
dates.push(itemRecord["icon"]["created_on"]);
});
components.push(equipmentTableComponent);
dates.push(component["et_created"]);
dates.push(component["et_updated"]);
break;
case "Review_List":
let reviewsComponent: ReviewListComponent = {
component: "Reviews",
id: component["rl_id"],
title: component["rl_title"],
text: component["rl_text"],
reviews: []
};
component["reviews"].forEach((reviewRecord: any) => {
reviewsComponent.reviews.push({
id: reviewRecord["id"],
name: reviewRecord["name"],
review: reviewRecord["review"],
stars: reviewRecord["stars"],
date: reviewRecord["date"],
thumbnail: {
url: reviewRecord["thumbnail"]["filename_disk"],
width: reviewRecord["thumbnail"]["width"],
height: reviewRecord["thumbnail"]["height"]
}
});
dates.push(reviewRecord["date_created"]);
dates.push(reviewRecord["date_updated"]);
dates.push(reviewRecord["thumbnail"]["created_on"]);
});
components.push(reviewsComponent);
dates.push(component["rl_created"]);
dates.push(component["rl_updated"]);
break;
case "Contact":
let contactComponent: ContactComponent = {
component: "Contact",
id: component["c_id"],
title: component["c_title"],
text: component["c_text"],
methods: []
};
component["methods"].forEach((contactMethodRecord: any) => {
contactComponent.methods.push({
id: contactMethodRecord["id"],
title: contactMethodRecord["title"],
text: contactMethodRecord["text"],
color: contactMethodRecord["color"],
icon: {
url: contactMethodRecord["icon"]["filename_disk"],
width: contactMethodRecord["icon"]["width"],
height: contactMethodRecord["icon"]["height"]
}
});
dates.push(contactMethodRecord["date_created"]);
dates.push(contactMethodRecord["date_updated"]);
dates.push(contactMethodRecord["icon"]["created_on"]);
});
components.push(contactComponent);
dates.push(component["c_created"]);
dates.push(component["c_updated"]);
break;
case "Last_Blogs":
let lastBlogsComponent: LastBlogsComponent = {
component: "LastBlogs",
id: component["lb_id"],
title: component["lb_title"],
readMoreButtonText: component["lb_read_more_button_text"],
amount: component["lb_amount"]
};
components.push(lastBlogsComponent);
dates.push(component["lb_created"]);
dates.push(component["lb_updated"]);
break;
case "Last_Projects":
let lastProjectsComponent: LastProjectsComponent = {
component: "LastProjects",
id: component["lp_id"],
title: component["lp_title"],
readMoreButtonText: component["lp_read_more_button_text"],
amount: component["lp_amount"]
};
components.push(lastProjectsComponent);
dates.push(component["lp_created"]);
dates.push(component["lp_updated"]);
break;
case "Last_Galleries":
let lastGalleriesComponent: LastGalleriesComponent = {
component: "LastGalleries",
id: component["lg_id"],
title: component["lg_title"],
readMoreButtonText: component["lg_read_more_button_text"],
amount: component["lg_amount"]
};
components.push(lastGalleriesComponent);
dates.push(component["lg_created"]);
dates.push(component["lg_updated"]);
break;
default:
break;
}
});
let lastModified: Date;
if (dates.filter(e => e !== null).length === 0) {
lastModified = new Date();
}
else {
const sortedDates: string[] = dates.sort((a: string, b: string) => {
return new Date(b).getTime() - new Date(a).getTime();
});
lastModified = new Date(sortedDates[0]);
}
let page: WebPage = {
id: pageRecord["id"],
lastModified: lastModified,
url: pageRecord["url"],
searchEngine: {
title: searchEngine["title"],
description: searchEngine["description"],
canonical: searchEngine["canonical"],
allowCrawlers: searchEngine["allow_crawler"],
priority: searchEngine["priority"],
thumbnail: {
url: searchEngine["thumbnail"]["filename_disk"],
height: searchEngine["thumbnail"]["height"],
width: searchEngine["thumbnail"]["width"]
}
},
components: components
}
pages.push(page);
});
return pages;
}

View File

@@ -0,0 +1,216 @@
query getAllPages($date: String!) {
Pages(filter: { status: { _eq: "published" } }) {
id,
date_created,
date_updated,
status,
url,
search_engine {
id,
date_created,
date_updated,
title,
description,
thumbnail {
id,
created_on,
filename_disk,
width,
height
},
canonical,
allow_crawler,
priority
},
components {
id,
__typename,
item {
__typename,
...on Hero {
hero_id: id,
hero_created: date_created,
hero_updated: date_updated,
hero_title: title,
hero_text: subtext,
background_image {
id,
created_on,
filename_disk,
width,
height
}
hero_image: background_image {
id,
created_on,
filename_disk,
width,
height
}
background_image {
id,
created_on,
filename_disk,
width,
height
}
}
...on Text_With_Side_Image {
twsi_id: id,
twsi_created: date_created,
twsi_updated: date_updated,
twsi_title: title,
twsi_text: text,
image {
id,
created_on,
filename_disk,
width,
height
},
twsi_image_side: image_side
}
...on Wall_Of_Text {
wot_id: id,
wot_created: date_created,
wot_updated: date_updated,
wot_title: title,
wot_text: text
}
...on Frequently_Asked_Questions {
faq_id: id,
faq_created: date_created,
faq_updated: date_updated,
faq_title: title,
faq_text: text,
questions {
id,
date_created,
date_updated,
question,
answer
}
}
...on Upcoming_Events {
ue_id: id,
ue_created: date_created,
ue_updated: date_updated,
ue_title: title,
ue_text: text,
events(filter: { start_date: { _gte: $date } }) {
id,
date_created,
date_updated,
title,
description,
location,
map_location,
start_date,
end_date
}
}
...on Equipment_Table {
et_id: id,
et_created: date_created,
et_updated: date_updated,
et_title: title,
et_text: text,
items {
id,
date_created,
date_updated,
title,
text,
icon {
id,
created_on,
filename_disk,
width,
height
}
}
}
...on Review_List {
rl_id: id,
rl_created: date_created,
rl_updated: date_updated,
rl_title: title,
rl_text: text,
reviews(sort: ["date"], filter: { status: { _eq: "published" } }) {
id,
date_created,
date_updated,
name,
review,
date,
stars,
thumbnail {
id,
created_on,
filename_disk,
width,
height
}
}
}
...on Contact {
c_id: id,
c_created: date_created,
c_updated: date_updated,
c_title: title,
c_text: text,
methods {
id,
date_created,
date_updated,
title,
text,
icon {
id,
created_on,
filename_disk,
width,
height
},
color
}
}
...on Last_Blogs {
lb_id: id,
lb_created: date_created,
lb_updated: date_updated,
lb_title: title,
lb_read_more_button_text: read_more_button_text,
lb_amount: amount
}
...on Last_Projects {
lp_id: id,
lp_created: date_created,
lp_updated: date_updated,
lp_title: title,
lp_read_more_button_text: read_more_button_text,
lp_amount: amount
}
...on Last_Galleries {
lg_id: id,
lg_created: date_created,
lg_updated: date_updated,
lg_title: title,
lg_read_more_button_text: read_more_button_text,
lg_amount: amount
}
}
}
}
}

View File

@@ -1,10 +1,11 @@
---
import { getAllWebpages } from "@/content/pages/pages";
import { getAllAlbums } from "@/content/photos/albums";
import { getSettings } from "@/content/settings/settings"
import WebpageLayout from "@/layouts/WebpageLayout.astro";
const settings = await getSettings();
const albums = await getAllAlbums(settings);
const webpages = await getAllWebpages();
---
<WebpageLayout>

16
astro/src/types/components/contact.d.ts vendored Normal file
View File

@@ -0,0 +1,16 @@
type ContactComponent = {
component: "Contact";
id: string;
title: string;
text: string;
methods: ContactMethod[];
}
type ContactMethod = {
id: string;
title: string;
text: string;
color: string;
icon: PhotoProps;
}

View File

@@ -0,0 +1,15 @@
type EquipmentTableComponent = {
component: "EquipmentTable";
id: string;
title: string;
text: string;
items: EquipmentTableItem[];
}
type EquipmentTableItem = {
id: string;
title: string;
text: string;
icon: PhotoProps;
}

18
astro/src/types/components/events.d.ts vendored Normal file
View File

@@ -0,0 +1,18 @@
type UpcomingEventsComponent = {
component: "UpcomingEvents";
id: string;
title: string;
text: string;
events: UpcomingEvent[];
}
type UpcomingEvent = {
id: string;
title: string;
description: string;
location: string;
mapLocation: [number, number];
startDate: Date;
endDate: Date;
}

14
astro/src/types/components/faq.d.ts vendored Normal file
View File

@@ -0,0 +1,14 @@
type FrequentlyAskedQuestionsComponent = {
component: "FrequentlyAskedQuestions";
id: string;
title: string;
text: string;
questions: FrequentlyAskedQuestion[];
}
type FrequentlyAskedQuestion = {
id: string;
question: string;
answer: string;
}

8
astro/src/types/components/hero.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
type HeroComponent = {
component: "Hero";
id: string;
title: string;
text: string;
backgroundImage: PhotoProps;
}

View File

@@ -0,0 +1,26 @@
type LastBlogsComponent = {
component: "LastBlogs";
id: string;
title: string;
readMoreButtonText: string;
amount: number;
}
type LastProjectsComponent = {
component: "LastProjects";
id: string;
title: string;
readMoreButtonText: string;
amount: number;
}
type LastGalleriesComponent = {
component: "LastGalleries";
id: string;
title: string;
readMoreButtonText: string;
amount: number;
}

17
astro/src/types/components/reviews.d.ts vendored Normal file
View File

@@ -0,0 +1,17 @@
type ReviewListComponent = {
component: "Reviews";
id: string;
title: string;
text: string;
reviews: Review[];
}
type Review = {
id: string;
name: string;
review: string;
date: string;
stars: number;
thumbnail: PhotoProps;
}

View File

@@ -0,0 +1,9 @@
type TextWithImageComponent = {
component: "TextWithImage";
id: string;
title: string;
text: string;
image: PhotoProps;
imageSide: "left" | "right";
}

View File

@@ -0,0 +1,7 @@
type WallOfTextComponent = {
component: "WallOfText";
id: string;
title: string;
text: string;
}

21
astro/src/types/pages/page.d.ts vendored Normal file
View File

@@ -0,0 +1,21 @@
type WebPage = {
id: string;
lastModified: Date;
url: string;
searchEngine: SearchEngine;
components: WebpageComponent[];
}
type WebpageComponent =
ContactComponent |
EquipmentTableComponent |
UpcomingEventsComponent |
FrequentlyAskedQuestionsComponent |
HeroComponent |
LastBlogsComponent |
LastProjectsComponent |
LastGalleriesComponent |
ReviewListComponent |
TextWithImageComponent |
WallOfTextComponent;