From 6dcac27de8d3eda792daa1b4896ba3a5dd55b134 Mon Sep 17 00:00:00 2001 From: itsfinniii <102350242+itsfinniii@users.noreply.github.com> Date: Sun, 15 Mar 2026 11:23:47 +0100 Subject: [PATCH] Add a method to get all web pages --- astro/src/content/pages/pages.ts | 318 ++++++++++++++++++ astro/src/graphql/pages/getAllPages.graphql | 216 ++++++++++++ astro/src/pages/index.astro | 3 +- astro/src/types/components/contact.d.ts | 16 + astro/src/types/components/equipment.d.ts | 15 + astro/src/types/components/events.d.ts | 18 + astro/src/types/components/faq.d.ts | 14 + astro/src/types/components/hero.d.ts | 8 + astro/src/types/components/lastContent.d.ts | 26 ++ astro/src/types/components/reviews.d.ts | 17 + astro/src/types/components/textWithImage.d.ts | 9 + astro/src/types/components/wallOfText.d.ts | 7 + astro/src/types/pages/page.d.ts | 21 ++ 13 files changed, 687 insertions(+), 1 deletion(-) create mode 100644 astro/src/content/pages/pages.ts create mode 100644 astro/src/graphql/pages/getAllPages.graphql create mode 100644 astro/src/types/components/contact.d.ts create mode 100644 astro/src/types/components/equipment.d.ts create mode 100644 astro/src/types/components/events.d.ts create mode 100644 astro/src/types/components/faq.d.ts create mode 100644 astro/src/types/components/hero.d.ts create mode 100644 astro/src/types/components/lastContent.d.ts create mode 100644 astro/src/types/components/reviews.d.ts create mode 100644 astro/src/types/components/textWithImage.d.ts create mode 100644 astro/src/types/components/wallOfText.d.ts create mode 100644 astro/src/types/pages/page.d.ts diff --git a/astro/src/content/pages/pages.ts b/astro/src/content/pages/pages.ts new file mode 100644 index 0000000..26cc4d2 --- /dev/null +++ b/astro/src/content/pages/pages.ts @@ -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 { + 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; +} diff --git a/astro/src/graphql/pages/getAllPages.graphql b/astro/src/graphql/pages/getAllPages.graphql new file mode 100644 index 0000000..32a8436 --- /dev/null +++ b/astro/src/graphql/pages/getAllPages.graphql @@ -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 + } + } + } + } +} \ No newline at end of file diff --git a/astro/src/pages/index.astro b/astro/src/pages/index.astro index ccc1036..61395d5 100644 --- a/astro/src/pages/index.astro +++ b/astro/src/pages/index.astro @@ -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(); --- diff --git a/astro/src/types/components/contact.d.ts b/astro/src/types/components/contact.d.ts new file mode 100644 index 0000000..79237b4 --- /dev/null +++ b/astro/src/types/components/contact.d.ts @@ -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; +} diff --git a/astro/src/types/components/equipment.d.ts b/astro/src/types/components/equipment.d.ts new file mode 100644 index 0000000..3ec8254 --- /dev/null +++ b/astro/src/types/components/equipment.d.ts @@ -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; +} diff --git a/astro/src/types/components/events.d.ts b/astro/src/types/components/events.d.ts new file mode 100644 index 0000000..10b840d --- /dev/null +++ b/astro/src/types/components/events.d.ts @@ -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; +} diff --git a/astro/src/types/components/faq.d.ts b/astro/src/types/components/faq.d.ts new file mode 100644 index 0000000..af7f828 --- /dev/null +++ b/astro/src/types/components/faq.d.ts @@ -0,0 +1,14 @@ +type FrequentlyAskedQuestionsComponent = { + component: "FrequentlyAskedQuestions"; + + id: string; + title: string; + text: string; + questions: FrequentlyAskedQuestion[]; +} + +type FrequentlyAskedQuestion = { + id: string; + question: string; + answer: string; +} diff --git a/astro/src/types/components/hero.d.ts b/astro/src/types/components/hero.d.ts new file mode 100644 index 0000000..4350e06 --- /dev/null +++ b/astro/src/types/components/hero.d.ts @@ -0,0 +1,8 @@ +type HeroComponent = { + component: "Hero"; + + id: string; + title: string; + text: string; + backgroundImage: PhotoProps; +} diff --git a/astro/src/types/components/lastContent.d.ts b/astro/src/types/components/lastContent.d.ts new file mode 100644 index 0000000..04843bb --- /dev/null +++ b/astro/src/types/components/lastContent.d.ts @@ -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; +} diff --git a/astro/src/types/components/reviews.d.ts b/astro/src/types/components/reviews.d.ts new file mode 100644 index 0000000..36387a6 --- /dev/null +++ b/astro/src/types/components/reviews.d.ts @@ -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; +} diff --git a/astro/src/types/components/textWithImage.d.ts b/astro/src/types/components/textWithImage.d.ts new file mode 100644 index 0000000..19ff6ce --- /dev/null +++ b/astro/src/types/components/textWithImage.d.ts @@ -0,0 +1,9 @@ +type TextWithImageComponent = { + component: "TextWithImage"; + + id: string; + title: string; + text: string; + image: PhotoProps; + imageSide: "left" | "right"; +} diff --git a/astro/src/types/components/wallOfText.d.ts b/astro/src/types/components/wallOfText.d.ts new file mode 100644 index 0000000..d3ba905 --- /dev/null +++ b/astro/src/types/components/wallOfText.d.ts @@ -0,0 +1,7 @@ +type WallOfTextComponent = { + component: "WallOfText"; + + id: string; + title: string; + text: string; +} diff --git a/astro/src/types/pages/page.d.ts b/astro/src/types/pages/page.d.ts new file mode 100644 index 0000000..5a70e27 --- /dev/null +++ b/astro/src/types/pages/page.d.ts @@ -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;