diff --git a/apps/charterafrica/src/lib/data/common/getPageUrl.js b/apps/charterafrica/src/lib/data/common/getPageUrl.js deleted file mode 100644 index 132ddea99..000000000 --- a/apps/charterafrica/src/lib/data/common/getPageUrl.js +++ /dev/null @@ -1,13 +0,0 @@ -const getPageUrl = async (api, slug) => { - const { docs } = await api.getCollection("pages", { - where: { - slug: { - equals: slug, - }, - }, - }); - const breadcrumbs = docs[0]?.breadcrumbs || []; - return breadcrumbs[breadcrumbs.length - 1]?.url; -}; - -export default getPageUrl; diff --git a/apps/charterafrica/src/lib/data/common/processPageContributors.js b/apps/charterafrica/src/lib/data/common/processPageContributors.js index e66449145..696495864 100644 --- a/apps/charterafrica/src/lib/data/common/processPageContributors.js +++ b/apps/charterafrica/src/lib/data/common/processPageContributors.js @@ -1,4 +1,3 @@ -import getPageUrl from "@/charterafrica/lib/data/common/getPageUrl"; import { allCountries } from "@/charterafrica/lib/data/json/countries"; import { CONTRIBUTORS_COLLECTION, @@ -13,7 +12,6 @@ const orQueryBuilder = (fields, search) => { }; export async function getContributors(page, api, context) { - const { breadcrumbs } = page; const { locale, query: { page: pageNumber = 1, limit = 12, search, sort = "fullName" } = {}, @@ -38,17 +36,8 @@ export async function getContributors(page, api, context) { }, ); const results = docs.map((person) => { - let href = null; - const pageUrl = breadcrumbs[breadcrumbs.length - 1]?.url; - if (pageUrl) { - const { slug } = person; - href = `${pageUrl}/${slug}`; - } return { ...person, - link: { - href, - }, description: person.description || " ", name: person.fullName || person.externalId || null, image: person.avatarUrl ?? null, @@ -89,20 +78,12 @@ async function processPagePerson(page, api, context) { }, }); - const pageUrl = await getPageUrl(api, "tools"); const tools = toolDocs.map((tool) => { - let href = null; - if (pageUrl) { - href = `${pageUrl}/${tool.slug}`; - } return { ...tool, image: tool.avatarUrl ?? null, description: tool?.description || " ", name: tool.name || " ", - link: { - href, - }, }; }); diff --git a/apps/charterafrica/src/lib/data/common/processPageOrganisations.js b/apps/charterafrica/src/lib/data/common/processPageOrganisations.js index 88de6a072..2cc87c3bb 100644 --- a/apps/charterafrica/src/lib/data/common/processPageOrganisations.js +++ b/apps/charterafrica/src/lib/data/common/processPageOrganisations.js @@ -1,4 +1,3 @@ -import getPageUrl from "@/charterafrica/lib/data/common/getPageUrl"; import { allCountries } from "@/charterafrica/lib/data/json/countries"; import { ORGANIZATION_COLLECTION } from "@/charterafrica/payload/utils/collections"; import queryString from "@/charterafrica/utils/ecosystem/queryString"; @@ -24,24 +23,15 @@ async function processPageSingleOrganisation(page, api, context) { if (!docs?.length) { return null; } - const organisation = docs[0] || {}; - const pageUrl = await getPageUrl(api, "tools"); - const tools = organisation.tools.map((tool) => { - let href = null; - if (pageUrl) { - href = `${pageUrl}/${tool.slug}`; - } - return { + const organisation = docs[0] || {}; + const tools = + organisation.tools?.map((tool) => ({ ...tool, - link: { - href, - }, image: tool.avatarUrl ?? null, description: tool?.description || " ", name: tool.name || " ", - }; - }); + })) ?? []; const block = blocks.findIndex( ({ slug: bSlug }) => bSlug === "our-organisations", ); @@ -73,7 +63,6 @@ async function processPageSingleOrganisation(page, api, context) { } export async function getOrganisations(page, api, context) { - const { breadcrumbs } = page; const { locale, query: { page: pageNumber = 1, limit = 12, search, sort = "name" } = {}, @@ -97,17 +86,8 @@ export async function getOrganisations(page, api, context) { }, ); const results = docs.map((tool) => { - let href = null; - const pageUrl = breadcrumbs[breadcrumbs.length - 1]?.url; - if (pageUrl) { - const { slug } = tool; - href = `${pageUrl}/${slug}`; - } return { ...tool, - link: { - href, - }, image: tool.avatarUrl ?? null, description: tool?.description || " ", name: tool.name ?? tool?.externalId ?? null, diff --git a/apps/charterafrica/src/lib/data/common/processPageTools.js b/apps/charterafrica/src/lib/data/common/processPageTools.js index b30a0ae93..6b007b2f2 100644 --- a/apps/charterafrica/src/lib/data/common/processPageTools.js +++ b/apps/charterafrica/src/lib/data/common/processPageTools.js @@ -1,4 +1,3 @@ -import getPageUrl from "@/charterafrica/lib/data/common/getPageUrl"; import { allCountries } from "@/charterafrica/lib/data/json/countries"; import { TOOL_COLLECTION, @@ -36,13 +35,9 @@ async function processPageSingleTool(page, api, context) { if (!docs?.length) { return null; } + const tool = docs[0]; - const contributorPage = await getPageUrl(api, "contributors"); - const contributors = tool?.contributors?.map((person) => ({ - ...person, - link: { href: `${contributorPage}/${person.slug}` }, - name: person.name || person?.fullName || person.username || null, - })); + const contributors = tool.toolContributors; const { docs: orgDocs } = await api.getCollection(ORGANIZATION_COLLECTION, { locale, where: { @@ -53,23 +48,14 @@ async function processPageSingleTool(page, api, context) { }); const tools = []; const filterLabels = labelsPerLocale[locale]; - const organisationPage = await getPageUrl(api, "organisations"); - const organisation = orgDocs?.[0] - ? { - ...orgDocs?.[0], - link: { href: `${organisationPage}/${orgDocs?.[0].slug}` }, - } - : null; + const organisation = orgDocs?.[0] ?? null; + return { ...page, blocks: [ { ...tool, slug: "tool", - link: { - href: tool.link, - label: "", - }, contribute: { href: getRepoLink(tool), label: filterLabels.contribute, @@ -111,7 +97,6 @@ async function processPageSingleTool(page, api, context) { } export async function getTools(page, api, context) { - const { breadcrumbs } = page; const { locale, query: { page: pageNumber = 1, limit = 12, search, sort = "name" } = {}, @@ -138,21 +123,12 @@ export async function getTools(page, api, context) { }); const results = docs.map((tool) => { - let href = null; - const pageUrl = breadcrumbs[breadcrumbs.length - 1]?.url; - if (pageUrl) { - const { slug } = tool; - href = `${pageUrl}/${slug}`; - } return { ...tool, topicLabel: "Topic", exploreText: "Explore", contributorsCount: tool?.contributors?.length ?? null, description: tool.description ?? " ", - link: { - href, - }, image: tool.avatarUrl ?? null, }; }); diff --git a/apps/charterafrica/src/payload/collections/Contributors.js b/apps/charterafrica/src/payload/collections/Contributors.js index 5eb44260d..d2215920e 100644 --- a/apps/charterafrica/src/payload/collections/Contributors.js +++ b/apps/charterafrica/src/payload/collections/Contributors.js @@ -3,6 +3,15 @@ import dateField from "../fields/dateField"; import slug from "../fields/slug"; import source from "../fields/source"; import { CONTRIBUTORS_COLLECTION } from "../utils/collections"; +import nestCollectionUnderPage from "../utils/nestCollectionUnderPage"; + +function useFullNameOrExternalId({ doc }) { + if (doc) { + const name = doc.name ?? doc.fullName ?? doc.externalId ?? null; + return { ...doc, name }; + } + return doc; +} const Contributors = { slug: CONTRIBUTORS_COLLECTION, @@ -152,6 +161,12 @@ const Contributors = { }, }, ], + hooks: { + afterRead: [ + nestCollectionUnderPage("contributors"), + useFullNameOrExternalId, + ], + }, }; export default Contributors; diff --git a/apps/charterafrica/src/payload/collections/Organisations.js b/apps/charterafrica/src/payload/collections/Organisations.js index b0d023350..286ae7a6a 100644 --- a/apps/charterafrica/src/payload/collections/Organisations.js +++ b/apps/charterafrica/src/payload/collections/Organisations.js @@ -4,6 +4,7 @@ import slug from "../fields/slug"; import source from "../fields/source"; import supporter from "../fields/supporter"; import { ORGANIZATION_COLLECTION, TOOL_COLLECTION } from "../utils/collections"; +import nestCollectionUnderPage from "../utils/nestCollectionUnderPage"; const Organisations = { slug: ORGANIZATION_COLLECTION, @@ -266,6 +267,9 @@ const Organisations = { }, }, ], + hooks: { + afterRead: [nestCollectionUnderPage("organisations")], + }, }; export default Organisations; diff --git a/apps/charterafrica/src/payload/collections/Tools.js b/apps/charterafrica/src/payload/collections/Tools.js index 493acfd39..dcfaa3027 100644 --- a/apps/charterafrica/src/payload/collections/Tools.js +++ b/apps/charterafrica/src/payload/collections/Tools.js @@ -8,6 +8,7 @@ import slug from "../fields/slug"; import source from "../fields/source"; import supporter from "../fields/supporter"; import { TOOL_COLLECTION, CONTRIBUTORS_COLLECTION } from "../utils/collections"; +import nestCollectionUnderPage from "../utils/nestCollectionUnderPage"; const Tools = { slug: TOOL_COLLECTION, @@ -307,8 +308,12 @@ const Tools = { dateField({ name: "deletedAt", }), + source(), ], + hooks: { + afterRead: [nestCollectionUnderPage("tools")], + }, }; export default Tools; diff --git a/apps/charterafrica/src/payload/utils/findAndFormatPagePath.js b/apps/charterafrica/src/payload/utils/findAndFormatPagePath.js new file mode 100644 index 000000000..d6ccca9e5 --- /dev/null +++ b/apps/charterafrica/src/payload/utils/findAndFormatPagePath.js @@ -0,0 +1,22 @@ +import formatPagePath from "./formatPagePath"; + +async function findAndFormatPagePath(payload, slug) { + const collection = "pages"; + const options = { + collection, + where: { + slug: { + equals: slug, + }, + }, + limit: 0, + }; + const { docs } = await payload.find(options); + + if (docs?.length) { + return formatPagePath(collection, docs[0]); + } + return undefined; +} + +export default findAndFormatPagePath; diff --git a/apps/charterafrica/src/payload/utils/nestCollectionUnderPage.js b/apps/charterafrica/src/payload/utils/nestCollectionUnderPage.js new file mode 100644 index 000000000..2747d5193 --- /dev/null +++ b/apps/charterafrica/src/payload/utils/nestCollectionUnderPage.js @@ -0,0 +1,23 @@ +import findAndFormatPagePath from "./findAndFormatPagePath"; + +function nestCollectionUnderPage(pageSlug) { + // TODO(kilemensi): Think of a way of nesting title and breadcrumbs as well + // i.e. full SEO + return async function nestCollectionItemUnderParentPage({ + doc, + req: { payload }, + }) { + let href = null; + try { + const pagePath = await findAndFormatPagePath(payload, pageSlug); + if (pagePath) { + href = `${pagePath}/${doc.slug}`; + } + } catch (error) { + // TODO(kilemensi): Add Sentry to payload & report errors + } + return { ...doc, link: { href } }; + }; +} + +export default nestCollectionUnderPage;