From bd3abb6733fc63d27a53196158a4f938880a8334 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:18:07 +0300 Subject: [PATCH 01/13] Add get in touch block --- .../public/images/cms/blocks/get_in_touch.jpg | Bin 0 -> 207933 bytes .../src/lib/data/blockify/getInTouch.js | 17 ++++++++ .../src/lib/data/blockify/index.js | 2 + .../src/pages/[...slugs].page.js | 3 ++ .../src/payload/blocks/GetInTouch.js | 37 ++++++++++++++++++ .../src/payload/collections/Pages.js | 10 ++++- 6 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 apps/codeforafrica/public/images/cms/blocks/get_in_touch.jpg create mode 100644 apps/codeforafrica/src/lib/data/blockify/getInTouch.js create mode 100644 apps/codeforafrica/src/payload/blocks/GetInTouch.js diff --git a/apps/codeforafrica/public/images/cms/blocks/get_in_touch.jpg b/apps/codeforafrica/public/images/cms/blocks/get_in_touch.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ca1fb2b1efc889d88f37779e0f26056d7f5353fa GIT binary patch literal 207933 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%0ALa?cw4XNpq<=ev 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 Tre?t!G}^}-%=!SYuRZ?@ocQOk literal 0 HcmV?d00001 diff --git a/apps/codeforafrica/src/lib/data/blockify/getInTouch.js b/apps/codeforafrica/src/lib/data/blockify/getInTouch.js new file mode 100644 index 000000000..7f31cd472 --- /dev/null +++ b/apps/codeforafrica/src/lib/data/blockify/getInTouch.js @@ -0,0 +1,17 @@ +function getInTouch(block) { + const { + actionButton: { href, label }, + ...other + } = block; + + return { + ...other, + action: { + href, + content: label, + }, + slug: "get-in-touch", + }; +} + +export default getInTouch; diff --git a/apps/codeforafrica/src/lib/data/blockify/index.js b/apps/codeforafrica/src/lib/data/blockify/index.js index 8b522d11e..421e56d59 100644 --- a/apps/codeforafrica/src/lib/data/blockify/index.js +++ b/apps/codeforafrica/src/lib/data/blockify/index.js @@ -1,7 +1,9 @@ +import getInTouch from "./getInTouch"; import hero from "./hero"; const propsifyBlockBySlug = { hero, + "get-in-touch": getInTouch, }; async function blockify(blocks) { diff --git a/apps/codeforafrica/src/pages/[...slugs].page.js b/apps/codeforafrica/src/pages/[...slugs].page.js index 4557ba5fa..2c9bbd26f 100644 --- a/apps/codeforafrica/src/pages/[...slugs].page.js +++ b/apps/codeforafrica/src/pages/[...slugs].page.js @@ -1,6 +1,8 @@ import React from "react"; import { SWRConfig } from "swr"; +import GetInTouch from "../components/GetInTouch/GetInTouch"; + import CustomPageHeader from "@/codeforafrica/components/CustomPageHeader"; import FeaturedProjects from "@/codeforafrica/components/FeaturedProjects"; import GetInvolved from "@/codeforafrica/components/GetInvolved"; @@ -13,6 +15,7 @@ import { getPageServerSideProps } from "@/codeforafrica/lib/data"; const componentsBySlugs = { hero: Hero, + "get-in-touch": GetInTouch, "page-header": PageHeader, "custom-page-header": CustomPageHeader, "meet-our-team": MeetOurTeam, diff --git a/apps/codeforafrica/src/payload/blocks/GetInTouch.js b/apps/codeforafrica/src/payload/blocks/GetInTouch.js new file mode 100644 index 000000000..ce6dbf253 --- /dev/null +++ b/apps/codeforafrica/src/payload/blocks/GetInTouch.js @@ -0,0 +1,37 @@ +import link from "../fields/links/link"; + +const GetInTouch = { + slug: "get-in-touch", + imageURL: "/images/cms/blocks/get_in_touch.jpg", + imageAltText: "Display Get In Touch Call to Action", + fields: [ + { + name: "title", + label: "Title", + required: true, + type: "text", + }, + { + name: "subtitle", + label: "Sub Title", + required: true, + type: "text", + }, + { + name: "actionButton", + label: "Action Button", + type: "group", + fields: [ + { + name: "label", + label: "Label", + type: "text", + required: true, + }, + link({}), + ], + }, + ], +}; + +export default GetInTouch; diff --git a/apps/codeforafrica/src/payload/collections/Pages.js b/apps/codeforafrica/src/payload/collections/Pages.js index a8e034e7b..cc609c0e7 100644 --- a/apps/codeforafrica/src/payload/collections/Pages.js +++ b/apps/codeforafrica/src/payload/collections/Pages.js @@ -1,5 +1,6 @@ import CustomPageHeader from "../blocks/CustomPageHeader"; import Error from "../blocks/Error"; +import GetInTouch from "../blocks/GetInTouch"; import Hero from "../blocks/Hero"; import OurPartners from "../blocks/OurPartners"; import PageHeader from "../blocks/PageHeader"; @@ -37,7 +38,14 @@ const Pages = { // each other e.g. while alphabecially CustomPageHeader should be with C, // it's functiaonally equivalent with PageHeader so we keep it next to // PageHeader - blocks: [Error, Hero, PageHeader, CustomPageHeader, OurPartners], + blocks: [ + Error, + GetInTouch, + Hero, + PageHeader, + CustomPageHeader, + OurPartners, + ], admin: { initCollapsed: true, }, From b247ecf2ac18a43be666c523054c17c942b081b4 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:26:19 +0300 Subject: [PATCH 02/13] common action button extraction function --- .../src/components/GetInTouch/GetInTouch.js | 4 ++-- .../src/lib/data/blockify/getInTouch.js | 14 ++++++-------- apps/codeforafrica/src/lib/data/rest/index.js | 2 +- apps/codeforafrica/src/lib/data/utils/index.js | 4 +++- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/codeforafrica/src/components/GetInTouch/GetInTouch.js b/apps/codeforafrica/src/components/GetInTouch/GetInTouch.js index 71c01065b..e79914832 100644 --- a/apps/codeforafrica/src/components/GetInTouch/GetInTouch.js +++ b/apps/codeforafrica/src/components/GetInTouch/GetInTouch.js @@ -8,7 +8,7 @@ import TwoToneBackground from "@/codeforafrica/components/TwoToneBackground"; const GetInTouch = React.forwardRef(function GetInTouch(props, ref) { const { - action: { href, content }, + action: { href, label }, subtitle, title, sx, @@ -59,7 +59,7 @@ const GetInTouch = React.forwardRef(function GetInTouch(props, ref) { }, }} > - {content} + {label} diff --git a/apps/codeforafrica/src/lib/data/blockify/getInTouch.js b/apps/codeforafrica/src/lib/data/blockify/getInTouch.js index 7f31cd472..bb5efccea 100644 --- a/apps/codeforafrica/src/lib/data/blockify/getInTouch.js +++ b/apps/codeforafrica/src/lib/data/blockify/getInTouch.js @@ -1,15 +1,13 @@ +import { actionFromActionButton } from "@/codeforafrica/lib/data/utils"; + function getInTouch(block) { - const { - actionButton: { href, label }, - ...other - } = block; + const { actionButton, ...other } = block; + + const action = actionFromActionButton({ ...actionButton }); return { ...other, - action: { - href, - content: label, - }, + action, slug: "get-in-touch", }; } diff --git a/apps/codeforafrica/src/lib/data/rest/index.js b/apps/codeforafrica/src/lib/data/rest/index.js index 80c11bb13..b74fd48d6 100644 --- a/apps/codeforafrica/src/lib/data/rest/index.js +++ b/apps/codeforafrica/src/lib/data/rest/index.js @@ -37,6 +37,6 @@ export const api = { export async function getPageStaticProps(context) { const props = await getPageProps(api, context); return { - props, + props: props || {}, }; } diff --git a/apps/codeforafrica/src/lib/data/utils/index.js b/apps/codeforafrica/src/lib/data/utils/index.js index 28917e671..9f7b65630 100644 --- a/apps/codeforafrica/src/lib/data/utils/index.js +++ b/apps/codeforafrica/src/lib/data/utils/index.js @@ -1,5 +1,7 @@ export function imageFromMedia({ alt = null, url = null }) { return { alt, src: url }; } - +export function actionFromActionButton({ href, label, newTab = false }) { + return { href, label, newTab }; +} export default undefined; From 916de995db92be3292383bd9385b3bcd7a96fcd1 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:29:06 +0300 Subject: [PATCH 03/13] regenerate snapshots --- apps/codeforafrica/src/components/GetInTouch/GetInTouch.snap.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/codeforafrica/src/components/GetInTouch/GetInTouch.snap.js b/apps/codeforafrica/src/components/GetInTouch/GetInTouch.snap.js index c1d6a05e7..5d282a7c4 100644 --- a/apps/codeforafrica/src/components/GetInTouch/GetInTouch.snap.js +++ b/apps/codeforafrica/src/components/GetInTouch/GetInTouch.snap.js @@ -36,6 +36,7 @@ exports[` renders unchanged 1`] = ` viewbox="0 0 24 24" /> + Get in touch From 8da42a00d5bba5b1614cf1450f7cf3e2559df481 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Tue, 19 Sep 2023 10:50:39 +0300 Subject: [PATCH 04/13] Update after PR Review --- .../src/lib/data/blockify/getInTouch.js | 15 --------------- apps/codeforafrica/src/lib/data/blockify/index.js | 2 -- apps/codeforafrica/src/lib/data/rest/index.js | 9 ++++++++- apps/codeforafrica/src/lib/data/utils/index.js | 3 --- .../src/payload/blocks/GetInTouch.js | 2 +- 5 files changed, 9 insertions(+), 22 deletions(-) delete mode 100644 apps/codeforafrica/src/lib/data/blockify/getInTouch.js diff --git a/apps/codeforafrica/src/lib/data/blockify/getInTouch.js b/apps/codeforafrica/src/lib/data/blockify/getInTouch.js deleted file mode 100644 index bb5efccea..000000000 --- a/apps/codeforafrica/src/lib/data/blockify/getInTouch.js +++ /dev/null @@ -1,15 +0,0 @@ -import { actionFromActionButton } from "@/codeforafrica/lib/data/utils"; - -function getInTouch(block) { - const { actionButton, ...other } = block; - - const action = actionFromActionButton({ ...actionButton }); - - return { - ...other, - action, - slug: "get-in-touch", - }; -} - -export default getInTouch; diff --git a/apps/codeforafrica/src/lib/data/blockify/index.js b/apps/codeforafrica/src/lib/data/blockify/index.js index 421e56d59..8b522d11e 100644 --- a/apps/codeforafrica/src/lib/data/blockify/index.js +++ b/apps/codeforafrica/src/lib/data/blockify/index.js @@ -1,9 +1,7 @@ -import getInTouch from "./getInTouch"; import hero from "./hero"; const propsifyBlockBySlug = { hero, - "get-in-touch": getInTouch, }; async function blockify(blocks) { diff --git a/apps/codeforafrica/src/lib/data/rest/index.js b/apps/codeforafrica/src/lib/data/rest/index.js index b74fd48d6..63517ea4b 100644 --- a/apps/codeforafrica/src/lib/data/rest/index.js +++ b/apps/codeforafrica/src/lib/data/rest/index.js @@ -36,7 +36,14 @@ export const api = { export async function getPageStaticProps(context) { const props = await getPageProps(api, context); + if (!props) { + return { + props: { + title: "Page not found", + }, + }; + } return { - props: props || {}, + props, }; } diff --git a/apps/codeforafrica/src/lib/data/utils/index.js b/apps/codeforafrica/src/lib/data/utils/index.js index 9f7b65630..9449588da 100644 --- a/apps/codeforafrica/src/lib/data/utils/index.js +++ b/apps/codeforafrica/src/lib/data/utils/index.js @@ -1,7 +1,4 @@ export function imageFromMedia({ alt = null, url = null }) { return { alt, src: url }; } -export function actionFromActionButton({ href, label, newTab = false }) { - return { href, label, newTab }; -} export default undefined; diff --git a/apps/codeforafrica/src/payload/blocks/GetInTouch.js b/apps/codeforafrica/src/payload/blocks/GetInTouch.js index ce6dbf253..92d2ea922 100644 --- a/apps/codeforafrica/src/payload/blocks/GetInTouch.js +++ b/apps/codeforafrica/src/payload/blocks/GetInTouch.js @@ -18,7 +18,7 @@ const GetInTouch = { type: "text", }, { - name: "actionButton", + name: "action", label: "Action Button", type: "group", fields: [ From 9eed46a4aa637ca9fbdd92957841b3b23a14ec6c Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Tue, 19 Sep 2023 10:52:47 +0300 Subject: [PATCH 05/13] Remove unnecessary spaces --- apps/codeforafrica/src/lib/data/utils/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/codeforafrica/src/lib/data/utils/index.js b/apps/codeforafrica/src/lib/data/utils/index.js index 9449588da..28917e671 100644 --- a/apps/codeforafrica/src/lib/data/utils/index.js +++ b/apps/codeforafrica/src/lib/data/utils/index.js @@ -1,4 +1,5 @@ export function imageFromMedia({ alt = null, url = null }) { return { alt, src: url }; } + export default undefined; From 385640d52c64be4dd296a6871b173852e049e7a7 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Tue, 19 Sep 2023 10:54:37 +0300 Subject: [PATCH 06/13] Correct component import --- apps/codeforafrica/src/pages/[...slugs].page.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/codeforafrica/src/pages/[...slugs].page.js b/apps/codeforafrica/src/pages/[...slugs].page.js index 2c9bbd26f..3e81c0b3e 100644 --- a/apps/codeforafrica/src/pages/[...slugs].page.js +++ b/apps/codeforafrica/src/pages/[...slugs].page.js @@ -1,10 +1,9 @@ import React from "react"; import { SWRConfig } from "swr"; -import GetInTouch from "../components/GetInTouch/GetInTouch"; - import CustomPageHeader from "@/codeforafrica/components/CustomPageHeader"; import FeaturedProjects from "@/codeforafrica/components/FeaturedProjects"; +import GetInTouch from "@/codeforafrica/components/GetInTouch"; import GetInvolved from "@/codeforafrica/components/GetInvolved"; import Hero from "@/codeforafrica/components/Hero"; import MeetOurTeam from "@/codeforafrica/components/MeetOurTeam"; From 8c38f4c64837dcbc8cfe7c0aa45f66a02f5605e6 Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Tue, 19 Sep 2023 12:19:47 +0300 Subject: [PATCH 07/13] Remove ghostCMS and netlify --- .../codeforafrica-deploy-review-app.yml | 2 - Dockerfile.codeforafrica | 6 +- apps/codeforafrica/src/lib/api.ghost/ghost.js | 9 - apps/codeforafrica/src/lib/api.ghost/index.js | 45 -- apps/codeforafrica/src/lib/api.ghost/posts.js | 147 ---- .../src/lib/api.netlify-cms/getBadges.js | 10 - .../src/lib/api.netlify-cms/getBody.js | 11 - .../lib/api.netlify-cms/getCollectionData.js | 10 - .../src/lib/api.netlify-cms/getContactForm.js | 15 - .../src/lib/api.netlify-cms/getDonors.js | 10 - .../src/lib/api.netlify-cms/getGetInTouch.js | 8 - .../api.netlify-cms/getGuidingPrinciples.js | 9 - .../src/lib/api.netlify-cms/getImpactList.js | 18 - .../src/lib/api.netlify-cms/getJoinUs.js | 10 - .../lib/api.netlify-cms/getNewsAndStories.js | 17 - .../src/lib/api.netlify-cms/getOffices.js | 27 - .../getOurGuidingPrinciples.js | 30 - .../src/lib/api.netlify-cms/getOurImpact.js | 23 - .../src/lib/api.netlify-cms/getOurMission.js | 18 - .../src/lib/api.netlify-cms/getOurOffices.js | 9 - .../api.netlify-cms/getOurOpportunities.js | 12 - .../src/lib/api.netlify-cms/getOurPartners.js | 37 - .../src/lib/api.netlify-cms/getOurProjects.js | 12 - .../src/lib/api.netlify-cms/getOurStories.js | 9 - .../src/lib/api.netlify-cms/getOurTeam.js | 9 - .../src/lib/api.netlify-cms/getPartners.js | 13 - .../src/lib/api.netlify-cms/getProjectTeam.js | 9 - .../src/lib/api.netlify-cms/getProjects.js | 62 -- .../lib/api.netlify-cms/getRelatedProjects.js | 11 - .../src/lib/api.netlify-cms/getTeam.js | 15 - .../src/lib/api.netlify-cms/index.js | 47 -- .../sections/getMeetOurTeam.js | 19 - .../api.netlify-cms/sections/getSettings.js | 9 - .../src/lib/api.netlify-cms/seo.js | 29 - .../src/lib/api.netlify-cms/utils.js | 44 - apps/codeforafrica/src/lib/index.js | 757 ------------------ 36 files changed, 1 insertion(+), 1527 deletions(-) delete mode 100644 apps/codeforafrica/src/lib/api.ghost/ghost.js delete mode 100644 apps/codeforafrica/src/lib/api.ghost/index.js delete mode 100644 apps/codeforafrica/src/lib/api.ghost/posts.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getBadges.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getBody.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getCollectionData.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getContactForm.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getDonors.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getGetInTouch.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getGuidingPrinciples.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getImpactList.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getJoinUs.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getNewsAndStories.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getOffices.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getOurGuidingPrinciples.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getOurImpact.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getOurMission.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getOurOffices.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getOurOpportunities.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getOurPartners.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getOurProjects.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getOurStories.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getOurTeam.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getPartners.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getProjectTeam.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getProjects.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getRelatedProjects.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/getTeam.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/index.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/sections/getMeetOurTeam.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/sections/getSettings.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/seo.js delete mode 100644 apps/codeforafrica/src/lib/api.netlify-cms/utils.js delete mode 100644 apps/codeforafrica/src/lib/index.js diff --git a/.github/workflows/codeforafrica-deploy-review-app.yml b/.github/workflows/codeforafrica-deploy-review-app.yml index 7eec5f81e..0d2f232e6 100644 --- a/.github/workflows/codeforafrica-deploy-review-app.yml +++ b/.github/workflows/codeforafrica-deploy-review-app.yml @@ -57,8 +57,6 @@ jobs: MONGODB_URL=${{ secrets.CODEFORAFRICA_MONGO_URL }}/${{ env.APP_NAME }} NEXT_PUBLIC_APP_URL=${{ env.NEXT_PUBLIC_APP_URL }} PAYLOAD_SECRET=${{ secrets.CODEFORAFRICA_PAYLOAD_SECRET_KEY }} - GHOST_URL=${{ secrets.GHOST_URL }} - GHOST_API_KEY=${{ secrets.GHOST_API_KEY }} NEXT_PUBLIC_APP_LOGO_URL=${{ secrets.NEXT_PUBLIC_APP_CFA_LOGO_URL }} NEXT_PUBLIC_APP_NAME=${{ secrets.NEXT_PUBLIC_APP_CFA_NAME }} cache-from: type=local,src=/tmp/.buildx-cache diff --git a/Dockerfile.codeforafrica b/Dockerfile.codeforafrica index 0cb590d89..9ae89ad8f 100644 --- a/Dockerfile.codeforafrica +++ b/Dockerfile.codeforafrica @@ -33,9 +33,7 @@ RUN pnpm install --recursive --offline --frozen-lockfile ARG PORT=3000 \ MONGODB_URL \ PAYLOAD_SECRET \ - NEXT_PUBLIC_APP_URL=http://localhost:3000 \ - GHOST_URL \ - GHOST_API_KEY + NEXT_PUBLIC_APP_URL=http://localhost:3000 RUN pnpm build-next --filter=codeforafrica @@ -62,8 +60,6 @@ ENV NODE_ENV=production \ PAYLOAD_CONFIG_PATH=${PAYLOAD_CONFIG_PATH} \ PAYLOAD_SECRET=${PAYLOAD_SECRET} \ MONGODB_URL=${MONGODB_URL} \ - GHOST_URL=${GHOST_URL} \ - GHOST_API_KEY=${GHOST_API_KEY} \ NEXT_PUBLIC_APP_LOGO_URL=${NEXT_PUBLIC_APP_LOGO_URL} \ NEXT_PUBLIC_APP_NAME=${NEXT_PUBLIC_APP_NAME} \ NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL} diff --git a/apps/codeforafrica/src/lib/api.ghost/ghost.js b/apps/codeforafrica/src/lib/api.ghost/ghost.js deleted file mode 100644 index df8241647..000000000 --- a/apps/codeforafrica/src/lib/api.ghost/ghost.js +++ /dev/null @@ -1,9 +0,0 @@ -import GhostContentAPI from "@tryghost/content-api"; - -export default function initializeContentAPI() { - return new GhostContentAPI({ - url: process.env.GHOST_URL, - key: process.env.GHOST_API_KEY, - version: process.env.GHOST_API_VERSION || "v5.0", - }); -} diff --git a/apps/codeforafrica/src/lib/api.ghost/index.js b/apps/codeforafrica/src/lib/api.ghost/index.js deleted file mode 100644 index a5dc694a8..000000000 --- a/apps/codeforafrica/src/lib/api.ghost/index.js +++ /dev/null @@ -1,45 +0,0 @@ -import { getAllPosts, getPost } from "@/codeforafrica/lib/api.ghost/posts"; -import equalsIgnoreCase from "@/codeforafrica/utils/equalsIgnoreCase"; - -export async function getAllOpportunities() { - const allPosts = await getAllPosts(); - return allPosts.filter((post) => - equalsIgnoreCase(post.primaryTag.name, "opportunities"), - ); -} - -export async function getAllOpportunitiesTags() { - const opportunities = await getAllOpportunities(); - const tags = opportunities.flatMap((post) => post.tags); - return ["All", ...new Set(tags)]; -} - -export async function getOpportnity(slug) { - return getPost(slug); -} - -export async function getAllStories() { - const allPosts = await getAllPosts(); - return allPosts.filter((post) => - equalsIgnoreCase(post.primaryTag.name, "stories"), - ); -} - -export async function getAllStoriesTags() { - const stories = await getAllStories(); - const tags = stories.flatMap((post) => post.tags); - return ["All", ...new Set(tags)]; -} - -export async function getStory(slug) { - return getPost(slug); -} - -export async function getRelatedStoriesByTags(tags, story = {}) { - const stories = await getAllStories(); - return stories.filter( - (s) => - s.id !== story.id && - s.tags.some((t) => tags.find((st) => equalsIgnoreCase(t, st))), - ); -} diff --git a/apps/codeforafrica/src/lib/api.ghost/posts.js b/apps/codeforafrica/src/lib/api.ghost/posts.js deleted file mode 100644 index 6f43cde8c..000000000 --- a/apps/codeforafrica/src/lib/api.ghost/posts.js +++ /dev/null @@ -1,147 +0,0 @@ -import { promises as fs } from "fs"; -import { join } from "path"; - -import camelcaseKeys from "camelcase-keys"; - -import initializeContentAPI from "@/codeforafrica/lib/api.ghost/ghost"; -import equalsIgnoreCase from "@/codeforafrica/utils/equalsIgnoreCase"; - -const cacheDir = join(process.cwd(), "public/data"); - -function transformPost(post) { - const { - customExcerpt, - excerpt: originalExcerpt, - featureImage, - featureImageAlt, - featureImageCaption, - metaDescription, - metaTitle, - primaryAuthor, - primaryTag, - publishedAt: publishedAtRaw, - slug, - tags: originalTags, - title, - twitterDescription, - twitterImage, - twitterTitle, - ogDescription, - ogImage, - ogTitle, - updatedAt, - ...other - } = camelcaseKeys(post, { deep: true }); - - const excerpt = customExcerpt || originalExcerpt || null; - const href = `/${primaryTag.slug}/${slug}`; - const publishedAt = new Date(publishedAtRaw).toLocaleDateString("en", { - year: "numeric", - month: "short", - day: "numeric", - }); - const tags = originalTags - .filter((t) => !equalsIgnoreCase(t.name, primaryTag.name)) - .map((tag) => tag.name); - - const seo = { - title: metaTitle || title, - description: metaDescription || excerpt, - openGraph: { - type: "article", - article: { - publishedTime: publishedAtRaw, - modifiedTime: updatedAt, - tags, - }, - }, - twitter: { - handle: primaryAuthor.twitter, - }, - }; - // seo will be merged with individual story page seo. This means "empty" - // values should be excluded. - const computedOgDescription = ogDescription || twitterDescription; - if (computedOgDescription) { - seo.openGraph.description = computedOgDescription; - } - const computedOgTitle = ogTitle || twitterTitle; - if (computedOgTitle) { - seo.openGraph.title = computedOgTitle; - } - const computedOgImage = ogImage || twitterImage || featureImage; - if (computedOgImage) { - seo.openGraph.images = [ - { - url: computedOgImage, - alt: - featureImageAlt || - featureImageCaption || - computedOgTitle || - seo.title, - }, - ]; - } - - return { - excerpt, - featureImage, - href, - primaryTag, - publishedAt, - slug, - tags, - seo, - title, - primaryAuthor, - ...other, - }; -} - -async function cachePosts(posts) { - const cacheFile = join(cacheDir, "posts.json"); - const data = { - date: new Date().toISOString(), - posts, - }; - await fs.writeFile(cacheFile, JSON.stringify(data)); -} - -async function getCachedPosts() { - try { - const cacheFile = join(cacheDir, "posts.json"); - const data = await fs.readFile(cacheFile, "utf8"); - return JSON.parse(data); - } catch (error) { - return null; - } -} - -export async function getAllPosts() { - // Check if we have a cached version of the posts - const cachedPosts = await getCachedPosts(); - if (cachedPosts) { - // check if the cache is older than 5 mins - // is 5 mins a good cache age? - // TODO: make this configurable - const cacheAge = new Date() - new Date(cachedPosts.date); - if (cacheAge < 300000) { - return cachedPosts.posts; - } - } - // If not, fetch from Ghost - const api = initializeContentAPI(); - const posts = await api.posts.browse({ - include: "authors,tags", - limit: "all", - }); - const allPosts = posts.map(transformPost); - // Cache the posts - await cachePosts(allPosts); - return allPosts; -} - -export async function getPost(slug) { - const allPost = await getAllPosts(); - return allPost.find((p) => p.slug === slug); -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getBadges.js b/apps/codeforafrica/src/lib/api.netlify-cms/getBadges.js deleted file mode 100644 index 38db75923..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getBadges.js +++ /dev/null @@ -1,10 +0,0 @@ -import { join } from "path"; - -import getCollectionData from "./getCollectionData"; - -const badgesDir = join(process.cwd(), "content/badges"); - -export default function getBadges(fields) { - const badges = getCollectionData(badgesDir, fields); - return badges; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getBody.js b/apps/codeforafrica/src/lib/api.netlify-cms/getBody.js deleted file mode 100644 index 711d77fb2..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getBody.js +++ /dev/null @@ -1,11 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -function getBody(page) { - const { content } = getCollectionBySlug("content/pages", page, [ - "content", - ]).items; - - return { content }; -} - -export default getBody; diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getCollectionData.js b/apps/codeforafrica/src/lib/api.netlify-cms/getCollectionData.js deleted file mode 100644 index 554e6301a..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getCollectionData.js +++ /dev/null @@ -1,10 +0,0 @@ -import { getCollectionSlugs, getCollectionBySlug } from "./utils"; - -export default function getCollectionData(collectionDir, fields) { - const slugs = getCollectionSlugs(collectionDir); - const collections = slugs.map((slug) => { - const collection = getCollectionBySlug(collectionDir, slug, fields); - return fields?.length ? collection.items : collection.data; - }); - return collections; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getContactForm.js b/apps/codeforafrica/src/lib/api.netlify-cms/getContactForm.js deleted file mode 100644 index f30853e50..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getContactForm.js +++ /dev/null @@ -1,15 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -const FIELD_NAME = "contact-form"; - -function getContactForm() { - const contactForm = getCollectionBySlug("content/pages", "contact", [ - FIELD_NAME, - "slug", - ]).items[FIELD_NAME]; - const { "embed-code": embedCode, slug } = contactForm || {}; - - return { embedCode, slug }; -} - -export default getContactForm; diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getDonors.js b/apps/codeforafrica/src/lib/api.netlify-cms/getDonors.js deleted file mode 100644 index e9573225c..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getDonors.js +++ /dev/null @@ -1,10 +0,0 @@ -import { join } from "path"; - -import getCollectionData from "./getCollectionData"; - -const donorsDir = join(process.cwd(), "content/donors"); - -export default function getDonors(fields) { - const donors = getCollectionData(donorsDir, fields); - return donors; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getGetInTouch.js b/apps/codeforafrica/src/lib/api.netlify-cms/getGetInTouch.js deleted file mode 100644 index c9fb5a508..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getGetInTouch.js +++ /dev/null @@ -1,8 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -const FIELD_NAME = "get-in-touch"; - -export default function getGetInTouch() { - return getCollectionBySlug("content/pages", "about", [FIELD_NAME, "slug"]) - .items[FIELD_NAME]; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getGuidingPrinciples.js b/apps/codeforafrica/src/lib/api.netlify-cms/getGuidingPrinciples.js deleted file mode 100644 index 3814964ed..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getGuidingPrinciples.js +++ /dev/null @@ -1,9 +0,0 @@ -import { join } from "path"; - -import getCollectionData from "./getCollectionData"; - -const dir = join(process.cwd(), "content/guiding-principles"); - -export default function getGuidingPrinciples(fields) { - return getCollectionData(dir, fields); -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getImpactList.js b/apps/codeforafrica/src/lib/api.netlify-cms/getImpactList.js deleted file mode 100644 index 71b547ebe..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getImpactList.js +++ /dev/null @@ -1,18 +0,0 @@ -import { join } from "path"; - -import getCollectionData from "./getCollectionData"; - -const impactDir = join(process.cwd(), "content/impact"); - -function getImpactList() { - return getCollectionData(impactDir, [ - "id", - "slug", - "title", - "value", - "image", - "content", - ]); -} - -export default getImpactList; diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getJoinUs.js b/apps/codeforafrica/src/lib/api.netlify-cms/getJoinUs.js deleted file mode 100644 index fcd77e8a1..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getJoinUs.js +++ /dev/null @@ -1,10 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -const FIELD_NAME = "join-our-slack"; - -function getJoinUs() { - return getCollectionBySlug("content/pages", "contact", [FIELD_NAME, "slug"]) - .items[FIELD_NAME]; -} - -export default getJoinUs; diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getNewsAndStories.js b/apps/codeforafrica/src/lib/api.netlify-cms/getNewsAndStories.js deleted file mode 100644 index 147f6f33a..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getNewsAndStories.js +++ /dev/null @@ -1,17 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -const FIELD_NAME = "news-stories"; - -function getNewsAndStories(page) { - const { - "articles-count": count, - title, - slug, - } = getCollectionBySlug("content/pages", page, [FIELD_NAME, "slug"]).items[ - FIELD_NAME - ]; - - return { count, title, slug }; -} - -export default getNewsAndStories; diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getOffices.js b/apps/codeforafrica/src/lib/api.netlify-cms/getOffices.js deleted file mode 100644 index 3fabd374c..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getOffices.js +++ /dev/null @@ -1,27 +0,0 @@ -import { join } from "path"; - -import getCollectionData from "./getCollectionData"; - -const officesDir = join(process.cwd(), "content/offices"); - -export default function getOffices(fields) { - const offices = getCollectionData(officesDir, fields); - return offices.map((office) => { - const lat = office.location.latitude; - const lng = office.location.longitude; - return { - map: { - center: { - lat, - lng, - }, - position: { - lat, - lng, - }, - }, - content: office.content, - title: office.name, - }; - }); -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getOurGuidingPrinciples.js b/apps/codeforafrica/src/lib/api.netlify-cms/getOurGuidingPrinciples.js deleted file mode 100644 index c5c6ad594..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getOurGuidingPrinciples.js +++ /dev/null @@ -1,30 +0,0 @@ -import { join } from "path"; - -import getGuidingPrinciples from "./getGuidingPrinciples"; -import { getCollectionBySlug } from "./utils"; - -const pagesDir = join(process.cwd(), "content/pages"); - -const FIELD_NAME = "guiding-principles"; - -function getOurGuidingPrinciples() { - const { - title, - "guiding-principle-list": principleIds, - slug, - } = getCollectionBySlug(pagesDir, "about", [FIELD_NAME, "slug"]).items[ - FIELD_NAME - ]; - const allPrinciples = getGuidingPrinciples([ - "id", - "title", - "icon", - "content", - ]); - - const list = - principleIds?.map((id) => allPrinciples.find((p) => p.id === id)) ?? null; - return { title, list, slug }; -} - -export default getOurGuidingPrinciples; diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getOurImpact.js b/apps/codeforafrica/src/lib/api.netlify-cms/getOurImpact.js deleted file mode 100644 index ca7c8aca4..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getOurImpact.js +++ /dev/null @@ -1,23 +0,0 @@ -import { join } from "path"; - -import getImpactList from "./getImpactList"; -import { getCollectionBySlug } from "./utils"; - -const pageDir = join(process.cwd(), "content/pages"); -const FIELD_NAME = "our-impact"; - -export default function geOurImpact(page = "index") { - const { - "our-impact": { - action = null, - "impact-list": impactIds, - title = null, - slug = null, - }, - } = getCollectionBySlug(pageDir, page, [FIELD_NAME, "slug"]).items; - const impact = getImpactList(); - // Need to maintain order of how impact were selected in ourImpact - const list = impactIds?.map((id) => impact.find((i) => i.id === id)) ?? null; - - return { action, list, title, slug }; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getOurMission.js b/apps/codeforafrica/src/lib/api.netlify-cms/getOurMission.js deleted file mode 100644 index 18507a1a8..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getOurMission.js +++ /dev/null @@ -1,18 +0,0 @@ -import { join } from "path"; - -import { getCollectionBySlug } from "./utils"; - -import marked from "@/codeforafrica/lib/marked"; - -const pagesDir = join(process.cwd(), "content/pages"); -const FIELD_NAME = "our-mission"; - -export default function getOurMission() { - const { "our-mission": ourMission } = getCollectionBySlug(pagesDir, "about", [ - FIELD_NAME, - "slug", - ]).items; - ourMission.description = marked(ourMission.description); - - return ourMission; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getOurOffices.js b/apps/codeforafrica/src/lib/api.netlify-cms/getOurOffices.js deleted file mode 100644 index e9572e71c..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getOurOffices.js +++ /dev/null @@ -1,9 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -const FIELD_NAME = "our-offices"; - -export default function getOurOffices(page = "contact") { - return getCollectionBySlug("content/pages", page, [FIELD_NAME, "slug"]).items[ - FIELD_NAME - ]; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getOurOpportunities.js b/apps/codeforafrica/src/lib/api.netlify-cms/getOurOpportunities.js deleted file mode 100644 index 756ff319d..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getOurOpportunities.js +++ /dev/null @@ -1,12 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -const FIELD_NAME = "opportunities"; - -export default function getOurOpportunities(page = "opportunities") { - const { slug } = getCollectionBySlug("content/pages", page, [ - FIELD_NAME, - "slug", - ]).items[FIELD_NAME]; - - return { slug }; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getOurPartners.js b/apps/codeforafrica/src/lib/api.netlify-cms/getOurPartners.js deleted file mode 100644 index 1fc920666..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getOurPartners.js +++ /dev/null @@ -1,37 +0,0 @@ -import { join } from "path"; - -import getPartners from "./getPartners"; -import { getCollectionBySlug } from "./utils"; - -import marked from "@/codeforafrica/lib/marked"; - -const pageDir = join(process.cwd(), "content/pages"); -const FIELD_NAME = "our-partners"; - -export default function geOurPartners(page = "index") { - const { - "our-partners": { - slug, - title: originalTitle, - "partners-list": partnersIds, - action = null, - }, - } = getCollectionBySlug(pageDir, page, [FIELD_NAME, "slug"]).items; - const title = marked.parseInline(originalTitle); - const allPartners = getPartners([ - "id", - "slug", - "name", - "content", - "href", - "logo", - "links", - ]); - // Need to maintain order of how partners were selected in ourPartners - const list = - page === "index" - ? partnersIds?.map((id) => allPartners.find((p) => p.id === id)) ?? null - : allPartners; - - return { slug, partners: { title, list, action } }; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getOurProjects.js b/apps/codeforafrica/src/lib/api.netlify-cms/getOurProjects.js deleted file mode 100644 index ccfc31d56..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getOurProjects.js +++ /dev/null @@ -1,12 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -const FIELD_NAME = "projects"; - -export default function geOurProjects(page = "index") { - const { slug } = getCollectionBySlug("content/pages", page, [ - FIELD_NAME, - "slug", - ]).items[FIELD_NAME]; - - return { slug }; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getOurStories.js b/apps/codeforafrica/src/lib/api.netlify-cms/getOurStories.js deleted file mode 100644 index 7a14ae72f..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getOurStories.js +++ /dev/null @@ -1,9 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -const FIELD_NAME = "stories"; - -export default function getOurStories(page = "stories") { - return getCollectionBySlug("content/pages", page, [FIELD_NAME, "slug"]).items[ - FIELD_NAME - ]; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getOurTeam.js b/apps/codeforafrica/src/lib/api.netlify-cms/getOurTeam.js deleted file mode 100644 index 950473562..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getOurTeam.js +++ /dev/null @@ -1,9 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -export default function geOurPartners() { - const { - "our-team": { title, slug }, - } = getCollectionBySlug("content/pages", "about", ["our-team", "slug"]).items; - - return { title, slug }; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getPartners.js b/apps/codeforafrica/src/lib/api.netlify-cms/getPartners.js deleted file mode 100644 index fcebeb226..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getPartners.js +++ /dev/null @@ -1,13 +0,0 @@ -import { join } from "path"; - -import getCollectionData from "./getCollectionData"; - -const partnersDir = join(process.cwd(), "content/partners"); - -export default function getPartners(fields) { - const partners = getCollectionData(partnersDir, fields); - return partners.map(({ slug = null, ...other }) => { - const href = slug ? `/about/partners/${slug}` : null; - return { ...other, slug, href }; - }); -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getProjectTeam.js b/apps/codeforafrica/src/lib/api.netlify-cms/getProjectTeam.js deleted file mode 100644 index 7aba99fef..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getProjectTeam.js +++ /dev/null @@ -1,9 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -const FIELD_NAME = "team"; - -export default function getProjectTeam(page = "our-work-individual") { - return getCollectionBySlug("content/pages", page, [FIELD_NAME, "slug"]).items[ - FIELD_NAME - ]; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getProjects.js b/apps/codeforafrica/src/lib/api.netlify-cms/getProjects.js deleted file mode 100644 index e6d72b3ad..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getProjects.js +++ /dev/null @@ -1,62 +0,0 @@ -import { join } from "path"; - -import getBadges from "./getBadges"; -import getDonors from "./getDonors"; -import getPartners from "./getPartners"; -import getTeam from "./getTeam"; -import { getCollectionSlugs, getCollectionBySlug } from "./utils"; - -import marked from "@/codeforafrica/lib/marked"; - -const projectsDir = join(process.cwd(), "content/projects"); - -export default function getProjects(fields) { - const slugs = getCollectionSlugs(projectsDir); - return slugs.map((_slug) => { - const collection = getCollectionBySlug(projectsDir, _slug, fields); - const project = collection.items; - if (project.badges?.length) { - const badges = getBadges(["id", "name", "content", "date"]); - project.badges = project.badges.map((id) => - badges.find((badge) => badge.id === id), - ); - } - if (project.partners?.length) { - const partners = getPartners([ - "id", - "slug", - "name", - "content", - "href", - "logo", - ]); - project.partners = { - title: "Partners", - list: project.partners.map((id) => - partners.find((partner) => partner.id === id), - ), - }; - } - if (project.donors?.length) { - const donors = getDonors(); - project.donors = { - title: "Donors", - list: project.donors.map((id) => - donors.find((donor) => donor.id === id), - ), - }; - } - - if (project.team?.length) { - const team = getTeam(); - project.team = { - title: "Team", - list: project.team.map((id) => team.find((m) => m.id === id)), - }; - } - - project.subtitle = marked(project.subtitle); - project.href = `/projects/${project.slug}`; - return project; - }); -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getRelatedProjects.js b/apps/codeforafrica/src/lib/api.netlify-cms/getRelatedProjects.js deleted file mode 100644 index 9a6cffb57..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getRelatedProjects.js +++ /dev/null @@ -1,11 +0,0 @@ -import { getCollectionBySlug } from "./utils"; - -const FIELD_NAME = "related-projects"; - -function getRelatedProjects(page) { - return getCollectionBySlug("content/pages", page, [FIELD_NAME, "slug"]).items[ - FIELD_NAME - ]; -} - -export default getRelatedProjects; diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/getTeam.js b/apps/codeforafrica/src/lib/api.netlify-cms/getTeam.js deleted file mode 100644 index 2f9f8672e..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/getTeam.js +++ /dev/null @@ -1,15 +0,0 @@ -import { join } from "path"; - -import getCollectionData from "./getCollectionData"; - -const teamDir = join(process.cwd(), "content/team"); - -export default function getTeam(fields) { - const teams = getCollectionData(teamDir, fields); - return teams - .filter((member) => !member.deactivated) - .map(({ slug = null, ...other }) => { - const href = slug ? `/about/members/${slug}` : null; - return { ...other, slug, href }; - }); -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/index.js b/apps/codeforafrica/src/lib/api.netlify-cms/index.js deleted file mode 100644 index 0a8fc7a61..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/index.js +++ /dev/null @@ -1,47 +0,0 @@ -import getBody from "./getBody"; -import getContactForm from "./getContactForm"; -import getGetInTouch from "./getGetInTouch"; -import getJoinUs from "./getJoinUs"; -import getNewsAndStories from "./getNewsAndStories"; -import getOffices from "./getOffices"; -import getOurGuidingPrinciples from "./getOurGuidingPrinciples"; -import getOurImpact from "./getOurImpact"; -import getOurMission from "./getOurMission"; -import getOurOffices from "./getOurOffices"; -import getOurOpportunities from "./getOurOpportunities"; -import getOurPartners from "./getOurPartners"; -import getOurProjects from "./getOurProjects"; -import getOurStories from "./getOurStories"; -import getOurTeam from "./getOurTeam"; -import getPartners from "./getPartners"; -import getCmsProjects from "./getProjects"; -import getProjectTeam from "./getProjectTeam"; -import getRelatedProjects from "./getRelatedProjects"; -import getTeam from "./getTeam"; -import getMeetOurTeam from "./sections/getMeetOurTeam"; -import getSeo from "./seo"; - -export { - getBody, - getContactForm, - getCmsProjects, - getGetInTouch, - getJoinUs, - getMeetOurTeam, - getNewsAndStories, - getOffices, - getOurGuidingPrinciples, - getOurImpact, - getOurMission, - getOurOffices, - getOurOpportunities, - getOurPartners, - getOurProjects, - getOurStories, - getSeo, - getRelatedProjects, - getOurTeam, - getPartners, - getProjectTeam, - getTeam, -}; diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/sections/getMeetOurTeam.js b/apps/codeforafrica/src/lib/api.netlify-cms/sections/getMeetOurTeam.js deleted file mode 100644 index 63ea47092..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/sections/getMeetOurTeam.js +++ /dev/null @@ -1,19 +0,0 @@ -import { join } from "path"; - -import { getCollectionBySlug } from "../utils"; - -import marked from "@/codeforafrica/lib/marked"; - -const indexPageDir = join(process.cwd(), "content/pages"); - -export default function getMeetOurTeam( - page = "index", - fields = ["meet-our-team", "slug"], -) { - const meetOurTeam = getCollectionBySlug(indexPageDir, page, fields).items[ - "meet-our-team" - ]; - meetOurTeam.logo = meetOurTeam.image?.src; - meetOurTeam.description = marked(meetOurTeam.description); - return meetOurTeam; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/sections/getSettings.js b/apps/codeforafrica/src/lib/api.netlify-cms/sections/getSettings.js deleted file mode 100644 index dc11d88b5..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/sections/getSettings.js +++ /dev/null @@ -1,9 +0,0 @@ -import { join } from "path"; - -import { getCollectionBySlug } from "../utils"; - -const settingsPageDir = join(process.cwd(), "content/settings"); - -export default function getSettings(section) { - return getCollectionBySlug(settingsPageDir, section).data; -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/seo.js b/apps/codeforafrica/src/lib/api.netlify-cms/seo.js deleted file mode 100644 index f5d91c099..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/seo.js +++ /dev/null @@ -1,29 +0,0 @@ -import { deepmerge } from "@mui/utils"; -import camelcaseKeys from "camelcase-keys"; - -import getSettings from "./sections/getSettings"; -import { getCollectionBySlug } from "./utils"; - -// 1. Since getCollectionBySlug creates a new object on every call, -// we don't need to clone when deep-merging. -// -// 2. If we have meta (at site or page seo level), it's title and description -// should override that level's title and description. - -function createSeo(pageSeo) { - const { - seo: { meta, ...siteSeo }, - site: { title, description }, - } = getSettings("general"); - - const seo = deepmerge(siteSeo, { title, description, ...meta, ...pageSeo }); - return camelcaseKeys(seo); -} - -export default function getSeo(page, pageSeo) { - const { - seo: { meta, ...seo }, - } = getCollectionBySlug("content/pages", page, ["seo"]).items; - - return createSeo(deepmerge({ ...seo, ...meta }, pageSeo)); -} diff --git a/apps/codeforafrica/src/lib/api.netlify-cms/utils.js b/apps/codeforafrica/src/lib/api.netlify-cms/utils.js deleted file mode 100644 index 490ba3cda..000000000 --- a/apps/codeforafrica/src/lib/api.netlify-cms/utils.js +++ /dev/null @@ -1,44 +0,0 @@ -import fs from "fs"; -import { join } from "path"; - -import matter from "gray-matter"; - -import marked from "@/codeforafrica/lib/marked"; - -export function getCollectionSlugs(collectionDir) { - return fs.readdirSync(collectionDir); -} - -export function getCollectionBySlug(collectionDir, slug, fields) { - const realSlug = slug.replace(/\.md$/, ""); - const fullPath = join(collectionDir, `${realSlug}.md`); - const fileContents = fs.readFileSync(fullPath, "utf8"); - const { data, content } = matter(fileContents); - - const markedContent = marked(content); - - data.slug = realSlug; - data.content = markedContent; - - const items = fields?.reduce((acc, curr) => { - if (curr === "content") { - acc.content = markedContent; - } else if (curr === "slug") { - acc.slug = realSlug; - } else { - // The slug field above works for folder-based collections e.g. impact - // but not for file-based collections e.g. get-in-touch in about. - // Since field names are guaranteed to be unique (in page) and are set - // in config, we can set the slug to be field name in file-based - // collections - let currData = data[curr] || null; - if (currData?.constructor === Object && fields.includes("slug")) { - currData = { slug: curr, ...currData }; - } - acc[curr] = currData; - } - return acc; - }, {}); - - return { items, data }; // return data which can be used as default incase of no fields -} diff --git a/apps/codeforafrica/src/lib/index.js b/apps/codeforafrica/src/lib/index.js deleted file mode 100644 index e61fdec30..000000000 --- a/apps/codeforafrica/src/lib/index.js +++ /dev/null @@ -1,757 +0,0 @@ -import fuse from "./api.fuse"; -import { - getBody, - getContactForm, - getCmsProjects, - getGetInTouch, - getJoinUs, - getMeetOurTeam, - getNewsAndStories, - getOffices, - getOurGuidingPrinciples, - getOurImpact, - getOurMission, - getOurOffices, - getOurOpportunities, - getOurPartners, - getOurProjects, - getOurStories, - getOurTeam, - getPartners, - getProjectTeam, - getRelatedProjects, - getTeam, - getSeo, -} from "./api.netlify-cms"; - -import { - getAllOpportunities, - getAllOpportunitiesTags, - getAllStories, - getAllStoriesTags, - getStory, - getRelatedStoriesByTags, -} from "@/codeforafrica/lib/api.ghost"; -import equalsIgnoreCase from "@/codeforafrica/utils/equalsIgnoreCase"; - -export const partners = getPartners([ - "id", - "slug", - "name", - "content", - "href", - "logo", - "links", -]); - -export const projects = getCmsProjects([ - "tag", - "name", - "slug", - "tagLine", - "icon", - "title", - "subtitle", - "content", - "thumbnail", - "href", - "externalHref", - "badges", - "partners", - "donors", - "team", - "links", -]); - -function getRandomInt(max) { - return Math.floor(Math.random() * max); -} - -function getRandomStartIndex(length, size) { - const max = length >= size ? length - size : length; - return getRandomInt(max); -} - -const meetOurTeam = getMeetOurTeam(); - -export const team = getTeam(); - -const DEFAULT_REVALIDATE = 3 * 60; // 3 minutes - -const ALL_TAG = "All"; - -function getProjectTags(options = { includeAll: true }) { - const tags = Array.from( - new Set(projects?.flatMap((a) => a.tag || [])), - ).sort(); - if (options?.includeAll) { - return [ALL_TAG, ...tags]; - } - return tags; -} - -function paginateResults(items, page, pageSize) { - // We need to initialize to null for serialization. - let count = null; - let results = []; - let pageNumber = null; - let pageSizeNumber = null; - if (items?.length) { - // Need to ensure page, pageSize are numbers and not strings - pageNumber = Number.parseInt(page, 10) || 1; - pageSizeNumber = Number.parseInt(pageSize, 10) || 6; - count = Math.ceil(items.length / pageSizeNumber); - results = items.slice( - (pageNumber - 1) * pageSizeNumber, - pageNumber * pageSizeNumber, - ); - } - return { - pagination: { - count, - page: pageNumber, - pageSize: pageSizeNumber, - }, - results, - }; -} - -function prioritiseFeaturedStory(stories) { - const index = stories.findIndex((s) => s.featured); - // If we have a featured story and it's not the first story, - if (index > 0) { - // we need to "push" the featured story to the top of list. - const featuredStory = stories[index]; - return [featuredStory, ...stories.filter((_, i) => i !== index)]; - } - return stories; -} - -export async function getStories(options) { - const { - tag: originalTag, - page = 1, - "page-size": pageSize = 10, - q, - } = options || {}; - const tag = originalTag || ALL_TAG; - - let stories = await getAllStories(); - if (equalsIgnoreCase(tag, ALL_TAG) && page === 1 && !q) { - stories = prioritiseFeaturedStory(stories); - } else { - if (!equalsIgnoreCase(tag, ALL_TAG)) { - stories = stories.filter((s) => - s.tags.some((t) => equalsIgnoreCase(t, tag)), - ); - } - if (q && stories.length) { - stories = fuse - .stories(stories) - .search(q) - .map((p) => p.item); - } - } - - return paginateResults(stories, page, pageSize); -} - -async function getProcessedNewsAndStories() { - const { title, count = 4, slug } = getNewsAndStories("index"); - const allStories = await getAllStories(); - const articles = prioritiseFeaturedStory(allStories).slice(0, count); - - return { title, articles, slug }; -} - -async function getHomePageStaticProps() { - const seo = getSeo("index"); - return { - props: { - seo, - sections: [ - { - ...getOurProjects(), - projects, - tags: getProjectTags({ includeAll: false }), - }, - { ...meetOurTeam }, - { - ...(await getProcessedNewsAndStories()), - }, - { - ...getOurPartners(), - }, - { - ...getOurImpact(), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -export function getProjects(options) { - const { tag: originalTag, page, "page-size": pageSize, q } = options || {}; - const tag = originalTag || ALL_TAG; - - let found = projects.filter( - (p) => equalsIgnoreCase(tag, ALL_TAG) || equalsIgnoreCase(tag, p.tag), - ); - if (found.length && q) { - found = fuse - .projects(found) - .search(q) - .map((p) => p.item); - } - - return paginateResults(found, page, pageSize); -} - -export async function getOpportunities(options) { - const { tag: originalTag, page, "page-size": pageSize, q } = options || {}; - const tag = originalTag || ALL_TAG; - - let opportunities = await getAllOpportunities(); - if (!equalsIgnoreCase(tag, ALL_TAG)) { - opportunities = opportunities.filter((opportunity) => { - return opportunity.tags.some((t) => equalsIgnoreCase(t, tag)); - }); - } - if (opportunities.length && q) { - opportunities = fuse - .opportunities(opportunities) - .search(q) - .map((p) => p.item); - } - - return paginateResults(opportunities, page, pageSize); -} - -async function getOpportunitiesPageStaticProps() { - const allOpportunities = await getAllOpportunities(); - const tags = await getAllOpportunitiesTags(); - const seo = getSeo("opportunities"); - - return { - props: { - seo, - sections: [ - { - ...getOurOpportunities(), - opportunities: paginateResults(allOpportunities), - tags, - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -async function getOpportunityPageStaticProps(params) { - const actualSlug = params.slug.split("/")[2]; - const foundOpportunity = await getStory(actualSlug); - - if (foundOpportunity) { - const { seo: pageSeo, ...opportunity } = foundOpportunity; - const seo = getSeo("opportunities-individual", pageSeo); - - return { - props: { - seo, - opportunity, - }, - revalidate: DEFAULT_REVALIDATE, - }; - } - return { notFound: true }; -} - -function getImprintPageStaticProps() { - const seo = getSeo("imprint"); - - return { - props: { - seo, - ...getBody("imprint"), - sections: [], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -function getPrivacyPageStaticProps() { - const seo = getSeo("privacy-policy"); - - return { - props: { - seo, - ...getBody("privacy-policy"), - sections: [], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -async function getProjectPageStaticProps(params) { - const project = projects.find(({ href }) => - equalsIgnoreCase(href, params?.slug), - ); - - if (project) { - const { title, count = 3, slug } = getNewsAndStories("our-work-individual"); - const relatedStories = await getRelatedStoriesByTags([project.name]); - const relatedProjects = getRelatedProjects("our-work-individual"); - const seo = getSeo("our-work-individual", { - title: project.name, - description: - // subtitle could contain html content - project.subtitle.replace(/<[^>]*>/g, "").trim() || project.title, - }); - const startIndex = getRandomStartIndex(projects.length, 3); - - return { - props: { - seo, - project, - sections: [ - { - ...getProjectTeam(), - team: project?.team?.list || null, - }, - { - slug, - title, - articles: relatedStories.slice(0, count), - }, - { - ...relatedProjects, - projects: projects - .filter((p) => p.slug !== project.slug) - .slice(startIndex, startIndex + 3), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; - } - return { notFound: true }; -} - -function getProjectsPageStaticProps() { - const seo = getSeo("our-work"); - - return { - props: { - seo, - sections: [ - { - ...getOurProjects("our-work"), - tags: getProjectTags(), - projects: getProjects(), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -async function getStoriesPageStaticProps() { - const articles = await getAllStories(); - const tags = await getAllStoriesTags(); - const seo = getSeo("stories"); - - return { - props: { - seo, - sections: [ - { - ...getOurStories(), - articles: paginateResults(articles), - tags, - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -async function getStoryPageStaticProps(slug) { - const actualSlug = slug.slug.split("/")[2]; - const story = await getStory(actualSlug); - const relatedArticles = await getRelatedStoriesByTags(story.tags, story); - - if (story) { - const { - title, - count = 3, - slug: articlesSlug, - } = getNewsAndStories("stories-individual"); - const { seo: pageSeo, ...article } = story; - const seo = getSeo("stories-individual", pageSeo); - - return { - props: { - seo, - article, - sections: [ - { - slug: articlesSlug, - title, - articles: relatedArticles?.slice(0, count) ?? null, - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; - } - return { notFound: true }; -} - -function getMembersFieldTags(options = { includeAll: true }) { - let countries = Array.from( - new Set(team?.flatMap((m) => m.country || [])), - ).sort(); - let teams = Array.from(new Set(team?.flatMap((m) => m.team || []))).sort(); - if (options?.includeAll) { - countries = [ALL_TAG, ...countries]; - teams = [ALL_TAG, ...teams]; - } - return [ - { field: "Country", tags: countries }, - { field: "Team", tags: teams }, - ]; -} - -export function getMembers(options) { - const { - field, - page, - "page-size": pageSize = 18, - q, - tag: originalTag, - } = options || {}; - const tag = originalTag || ALL_TAG; - - let found = team.filter( - (m) => - equalsIgnoreCase(tag, ALL_TAG) || - (field && equalsIgnoreCase(tag, m[field])), - ); - if (found.length && q) { - found = fuse - .members(found) - .search(q) - .map((p) => p.item); - } - - return paginateResults(found, page, pageSize); -} - -function getAboutImpactPageStaticProps() { - const seo = getSeo("about-impact"); - - return { - props: { - seo, - unit: "impact", - crumbs: [{ href: "/about", label: "About us" }, { label: "Impact" }], - sections: [ - { - ...getOurImpact("about"), - }, - { - ...getGetInTouch(), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -function getAboutMemberPageStaticProps(params) { - const member = team.find(({ href }) => equalsIgnoreCase(href, params?.slug)); - - if (member) { - const relatedProjects = getRelatedProjects("about-members-individual"); - const seo = getSeo("about-members-individual", { - title: member.name, - description: member.title, - }); - - return { - props: { - seo, - member, - sections: [ - { - ...relatedProjects, - projects: projects.filter((p) => - p.team?.list?.find((m) => m.id === member.id), - ), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; - } - return { notFound: true }; -} - -function getAboutMembersPageStaticProps() { - const seo = getSeo("about-members"); - - return { - props: { - seo, - unit: "members", - crumbs: [{ href: "/about", label: "About us" }, { label: "Members" }], - sections: [ - { - ...getOurTeam(), - pathname: "/about/members", - tags: getMembersFieldTags(), - team: getMembers(), - }, - { - ...getGetInTouch(), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -function getAboutPageStaticProps() { - const seo = getSeo("about"); - - return { - props: { - seo, - sections: [ - { - ...getOurMission(), - }, - { - ...getOurGuidingPrinciples(), - }, - - { - ...getOurTeam(), - tags: getMembersFieldTags(), - team: getMembers(), - }, - { - ...getOurPartners("about"), - }, - { - ...getOurImpact("about"), - }, - { - ...getGetInTouch(), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -function getAboutPartnerPageStaticProps(params) { - const partner = partners.find(({ slug }) => - equalsIgnoreCase(`/about/partners/${slug}`, params?.slug), - ); - - if (partner) { - const relatedProjects = getRelatedProjects("about-partners-individual"); - const seo = getSeo("about-partners-individual", { - title: partner.name, - // TODO(kilemens): Add short description to each partner - }); - - return { - props: { - seo, - partner: { ...partner, image: partner.logo, title: "Partner" }, - sections: [ - { - ...relatedProjects, - projects: projects.filter((p) => - p.partners?.list?.find((l) => l.id === partner.id), - ), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; - } - return { notFound: true }; -} - -function getAboutPartnersPageStaticProps() { - const seo = getSeo("about-partners"); - - return { - props: { - seo, - unit: "partners", - crumbs: [{ href: "/about", label: "About us" }, { label: "Partners" }], - sections: [ - { - ...getOurPartners("about"), - }, - { - ...getGetInTouch(), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -function getContactPageStaticProps() { - const seo = getSeo("contact"); - - return { - props: { - seo, - sections: [ - { - ...getContactForm(), - }, - { - ...getJoinUs(), - }, - { - ...getOurOffices(), - addresses: getOffices(), - map: { - apiKey: process.env.GOOGLE_API_KEY ?? null, - zoom: 20, - zoomControl: false, - mapTypeControl: false, - scaleControl: false, - streetViewControl: false, - rotateControl: false, - fullscreenControl: false, - }, - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -async function getProcessedRecentStories(page) { - const allStories = await getAllStories(); - const { title, count = 3, slug } = getNewsAndStories(page); - const articles = allStories.slice(0, count); - return { title, articles, slug }; -} - -async function getErrorPageStaticProps() { - const seo = getSeo("error"); - - return { - props: { - seo, - sections: [ - { - ...(await getProcessedRecentStories("error")), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -async function get404PageStaticProps() { - const seo = getSeo("404"); - - return { - props: { - seo, - sections: [ - { - ...(await getProcessedRecentStories("404")), - }, - ], - }, - revalidate: DEFAULT_REVALIDATE, - }; -} - -export async function getPageStaticProps(params) { - switch (params?.slug) { - case "/": { - return getHomePageStaticProps(params); - } - case "/about": { - return getAboutPageStaticProps(params); - } - case "/about/members": { - return getAboutMembersPageStaticProps(params); - } - case "/about/partners": { - return getAboutPartnersPageStaticProps(params); - } - case "/about/impact": { - return getAboutImpactPageStaticProps(); - } - case "/contact": { - return getContactPageStaticProps(params); - } - case "/imprint": { - return getImprintPageStaticProps(params); - } - case "/opportunities": { - return getOpportunitiesPageStaticProps(params); - } - case "/privacy": { - return getPrivacyPageStaticProps(params); - } - case "/projects": { - return getProjectsPageStaticProps(params); - } - case "/stories": { - return getStoriesPageStaticProps(params); - } - case "/404": { - return get404PageStaticProps(); - } - case "/_error": { - return getErrorPageStaticProps(); - } - default: - if (params?.slug?.startsWith("/about/members/")) { - return getAboutMemberPageStaticProps(params); - } - if (params?.slug?.startsWith("/about/partners/")) { - return getAboutPartnerPageStaticProps(params); - } - if (params?.slug?.startsWith("/opportunities/")) { - return getOpportunityPageStaticProps(params); - } - if (params?.slug?.startsWith("/projects/")) { - return getProjectPageStaticProps(params); - } - if (params?.slug?.startsWith("/stories/")) { - return getStoryPageStaticProps(params); - } - return { notFound: true }; - } -} - -export async function getPageStaticPaths(primaryTag) { - const posts = - primaryTag === "stories" - ? await getAllStories() - : await getAllOpportunities(); - - // filter out items with slug to remove pagination - const actualPosts = posts.filter((post) => post.slug); - const path = actualPosts.map((post) => ({ - params: { slug: post.slug }, - })); - - return path; -} From f3c6cb3b7ac59332d97d46ee2c186c339e688789 Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Tue, 19 Sep 2023 12:57:11 +0300 Subject: [PATCH 08/13] Fix failing build --- .../TeamMembers/TeamMembers.snap.js | 127 +- .../TeamMembers/TeamMembers.test.js | 3 +- .../src/pages/api/admin/config.js | 2029 ----------------- .../src/pages/api/admin/config.yml.page.js | 29 - .../src/pages/api/members/index.page.js | 20 - .../codeforafrica/src/pages/api/oauth/auth.js | 37 - .../src/pages/api/oauth/auth.page.js | 7 - .../src/pages/api/oauth/callback.js | 14 - .../src/pages/api/oauth/callback.page.js | 41 - .../src/pages/api/opportunities/index.page.js | 20 - .../src/pages/api/projects/index.page.js | 20 - .../src/pages/api/stories/index.page.js | 20 - 12 files changed, 2 insertions(+), 2365 deletions(-) delete mode 100644 apps/codeforafrica/src/pages/api/admin/config.js delete mode 100644 apps/codeforafrica/src/pages/api/admin/config.yml.page.js delete mode 100644 apps/codeforafrica/src/pages/api/members/index.page.js delete mode 100644 apps/codeforafrica/src/pages/api/oauth/auth.js delete mode 100644 apps/codeforafrica/src/pages/api/oauth/auth.page.js delete mode 100644 apps/codeforafrica/src/pages/api/oauth/callback.js delete mode 100644 apps/codeforafrica/src/pages/api/oauth/callback.page.js delete mode 100644 apps/codeforafrica/src/pages/api/opportunities/index.page.js delete mode 100644 apps/codeforafrica/src/pages/api/projects/index.page.js delete mode 100644 apps/codeforafrica/src/pages/api/stories/index.page.js diff --git a/apps/codeforafrica/src/components/TeamMembers/TeamMembers.snap.js b/apps/codeforafrica/src/components/TeamMembers/TeamMembers.snap.js index d89212ffe..be1521b9b 100644 --- a/apps/codeforafrica/src/components/TeamMembers/TeamMembers.snap.js +++ b/apps/codeforafrica/src/components/TeamMembers/TeamMembers.snap.js @@ -1,128 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[` renders unchanged 1`] = ` - -`; +exports[` renders unchanged 1`] = `
`; diff --git a/apps/codeforafrica/src/components/TeamMembers/TeamMembers.test.js b/apps/codeforafrica/src/components/TeamMembers/TeamMembers.test.js index 018bcc6cf..be9d86367 100644 --- a/apps/codeforafrica/src/components/TeamMembers/TeamMembers.test.js +++ b/apps/codeforafrica/src/components/TeamMembers/TeamMembers.test.js @@ -3,7 +3,6 @@ import React from "react"; import TeamMembers from "./TeamMembers"; -import { team } from "@/codeforafrica/lib"; import theme from "@/codeforafrica/theme"; // eslint-disable-next-line testing-library/render-result-naming-convention @@ -11,7 +10,7 @@ const render = createRender({ theme }); const defaultProps = { title: "Team", - team: team.slice(0, 3), + team: [], }; describe("", () => { diff --git a/apps/codeforafrica/src/pages/api/admin/config.js b/apps/codeforafrica/src/pages/api/admin/config.js deleted file mode 100644 index c6bcbd32e..000000000 --- a/apps/codeforafrica/src/pages/api/admin/config.js +++ /dev/null @@ -1,2029 +0,0 @@ -const APP_DIRECTORY = process.env.NEXT_PUBLIC_APP_DIRECTORY; - -const seoFields = { - label: "SEO", - name: "seo", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - required: false, - }, - { - label: "Description", - name: "description", - widget: "string", - required: false, - pattern: ["^.{1,150}$", "Must be up to 156 characters"], - }, - { - label: "Title Template", - name: "title-template", - widget: "string", - hint: "Uses title template from Settings | General if not provided", - required: false, - }, - { - label: "Meta data", - name: "meta", - widget: "object", - hint: "Search engines support", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - required: false, - hint: "Uses page title if not provided", - pattern: ["^.{1,70}$", "Must be up to 70 characters"], - }, - { - label: "Description", - name: "description", - widget: "text", - required: false, - hint: "Uses page description if not provided", - pattern: ["^.{1,150}$", "Must be up to 156 characters"], - }, - ], - }, - { - label: "Open Graph", - name: "open-graph", - hint: "Facebook, Slack, and other social media platforms", - widget: "object", - fields: [ - { - label: "Title", - hint: "Uses page title if not provided", - name: "title", - widget: "string", - required: false, - }, - { - label: "Description", - name: "description", - widget: "string", - hint: "Uses page description if not provided", - required: false, - }, - { - label: "Images", - name: "images", - widget: "list", - min: 1, - max: 1, - required: false, - fields: [ - { - name: "url", - label: "URL", - widget: "string", - }, - { - name: "width", - label: "Width", - widget: "string", - }, - { - name: "height", - label: "Height", - widget: "string", - }, - { - name: "alt", - label: "Alt Text", - widget: "string", - }, - ], - }, - ], - }, - { - label: "Twitter", - name: "twitter", - widget: "object", - fields: [ - { - label: "Handle", - name: "handle", - hint: "@username of content creator", - widget: "string", - required: false, - default: "@Code4Africa", - }, - ], - }, - ], -}; - -module.exports = { - backend: { - name: "github", - branch: "main", - repo: "CodeForAfrica/ui", - proxy_url: "http://localhost:8081/api/v1", // Set proxy to work on local repo - }, - media_folder: `${APP_DIRECTORY}public/images`, - public_folder: "/images", - local_backend: true, - collections: [ - { - name: "pages", - label: "Pages", - files: [ - { - label: "Index", - name: "index", - file: `${APP_DIRECTORY}content/pages/index.md`, - fields: [ - { - label: "Hero", - name: "hero", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "markdown", - }, - { - label: "Messages", - name: "messages", - widget: "list", - min: 3, - max: 3, - }, - { - label: "Subtitle", - name: "subtitle", - widget: "text", - }, - { - label: "Image", - name: "image", - widget: "object", - fields: [ - { - label: "Src", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - ], - }, - { - label: "Projects", - name: "projects", - widget: "object", - collapsed: true, - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - ], - }, - { - label: "Meet Our Team", - name: "meet-our-team", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Description", - name: "description", - widget: "markdown", - }, - { - label: "Href", - name: "href", - widget: "string", - }, - { - label: "Image", - name: "image", - widget: "object", - fields: [ - { - label: "Src", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - ], - }, - { - label: "Our partners", - name: "our-partners", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "markdown", - }, - { - label: "Action", - name: "action", - widget: "object", - fields: [ - { - name: "content", - widget: "string", - }, - { - name: "href", - widget: "string", - }, - ], - }, - { - label: "Partners", - name: "partners-list", - widget: "relation", - collection: "partners", - search_fields: ["name"], - value_field: "id", - display_fields: ["name"], - multiple: true, - }, - ], - }, - { - label: "News and stories", - name: "news-stories", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Number of stories", - name: "articles-count", - hint: "Including the featured story", - widget: "number", - value_type: "int", - min: 3, - }, - ], - }, - { - label: "Our Impact", - name: "our-impact", - widget: "object", - fields: [ - { - label: "Impact", - name: "impact-list", - widget: "relation", - collection: "impact", - search_fields: ["title"], - value_field: "id", - display_fields: ["title"], - multiple: true, - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "About", - name: "about", - file: `${APP_DIRECTORY}content/pages/about.md`, - fields: [ - { - label: "Hero", - name: "hero", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "text", - }, - { - label: "Background Image", - name: "image", - widget: "object", - fields: [ - { - label: "Source", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - ], - }, - { - label: "Our Mission", - name: "our-mission", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - name: "description", - widget: "markdown", - }, - ], - }, - { - label: "Guiding Principles", - name: "guiding-principles", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Guiding Principles", - name: "guiding-principle-list", - label_singular: "Guiding Principle", - widget: "relation", - collection: "guiding-principles", - search_fields: ["title"], - value_field: "id", - display_fields: ["title"], - multiple: true, - }, - ], - }, - { - label: "Our team", - name: "our-team", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - ], - }, - { - label: "Our partners", - name: "our-partners", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Partners", - name: "partners-list", - widget: "relation", - collection: "partners", - search_fields: ["name"], - value_field: "id", - display_fields: ["name"], - multiple: true, - }, - ], - }, - { - label: "Our Impact", - name: "our-impact", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Impact", - name: "impact-list", - widget: "relation", - collection: "impact", - search_fields: ["title"], - value_field: "id", - display_fields: ["title"], - multiple: true, - }, - ], - }, - { - label: "Get in touch", - name: "get-in-touch", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "string", - }, - { - label: "Action", - name: "action", - widget: "object", - fields: [ - { - name: "content", - widget: "string", - }, - { - name: "href", - widget: "string", - }, - ], - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "About | Impact", - name: "about-impact", - file: `${APP_DIRECTORY}content/pages/about-impact.md`, - fields: [ - { - ...seoFields, - }, - ], - }, - { - label: "About | Members", - name: "about-members", - file: `${APP_DIRECTORY}content/pages/about-members.md`, - fields: [ - { - ...seoFields, - }, - ], - }, - { - label: "About | Members | Individual member", - name: "about-members-individual", - file: `${APP_DIRECTORY}content/pages/about-members-individual.md`, - fields: [ - { - label: "Related Projects", - name: "related-projects", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "About | Partners", - name: "about-partners", - file: `${APP_DIRECTORY}content/pages/about-partners.md`, - fields: [ - { - ...seoFields, - }, - ], - }, - { - label: "About | Partners | Individual partner", - name: "about-partners-individual", - file: `${APP_DIRECTORY}content/pages/about-partners-individual.md`, - fields: [ - { - label: "Related Projects", - name: "related-projects", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "Contact Us", - name: "contact", - file: `${APP_DIRECTORY}content/pages/contact.md`, - fields: [ - { - label: "Hero", - name: "hero", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "string", - }, - ], - }, - { - label: "Contact form", - name: "contact-form", - widget: "object", - fields: [ - { - label: "Mailchimp code", - name: "embed-code", - widget: "code", - allow_language_selection: false, - default_language: "html", - output_code_only: true, - }, - ], - }, - { - label: "Join our Slack", - name: "join-our-slack", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "string", - }, - { - label: "Action", - name: "action", - widget: "object", - fields: [ - { - label: "Label", - name: "label", - widget: "string", - }, - { - label: "Link", - name: "href", - widget: "string", - }, - ], - }, - ], - }, - { - label: "Our offices", - name: "our-offices", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "Our Work", - name: "our-work", - file: `${APP_DIRECTORY}content/pages/our-work.md`, - fields: [ - { - label: "Hero", - name: "hero", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "string", - }, - ], - }, - { - label: "Projects", - name: "projects", - widget: "object", - collapsed: true, - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "Our Work | Individual work", - name: "our-work-individual", - file: `${APP_DIRECTORY}content/pages/our-work-individual.md`, - fields: [ - { - label: "Team", - name: "team", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - ], - }, - { - label: "Related Stories", - name: "news-stories", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Number of stories", - name: "articles-count", - widget: "number", - value_type: "int", - min: 3, - }, - ], - }, - { - label: "Related Projects", - name: "related-projects", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "Opportunities", - name: "opportunities", - file: `${APP_DIRECTORY}content/pages/opportunities.md`, - fields: [ - { - label: "Hero", - name: "hero", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "string", - }, - ], - }, - { - label: "Opportunities", - name: "opportunities", - widget: "object", - collapsed: true, - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "Opportunities | Individual opportunity", - name: "opportunities-individual", - file: `${APP_DIRECTORY}content/pages/opportunities-individual.md`, - fields: [ - { - ...seoFields, - }, - ], - }, - { - label: "Stories", - name: "stories", - file: `${APP_DIRECTORY}content/pages/stories.md`, - fields: [ - { - label: "Stories", - name: "stories", - widget: "object", - collapsed: true, - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "Stories | Individual story", - name: "stories-individual", - file: `${APP_DIRECTORY}content/pages/stories-individual.md`, - fields: [ - { - label: "Related Stories", - name: "news-stories", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Number of stories", - name: "articles-count", - widget: "number", - value_type: "int", - min: 3, - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "Imprint", - name: "imprint", - file: `${APP_DIRECTORY}content/pages/imprint.md`, - fields: [ - { - label: "Hero", - name: "hero", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "string", - }, - ], - }, - { - label: "Body", - name: "body", - widget: "markdown", - }, - { - ...seoFields, - }, - ], - }, - { - label: "Privacy Policy", - name: "privacy-policy", - file: `${APP_DIRECTORY}content/pages/privacy-policy.md`, - fields: [ - { - label: "Hero", - name: "hero", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "string", - }, - ], - }, - { - label: "Body", - name: "body", - widget: "markdown", - }, - { - ...seoFields, - }, - ], - }, - { - label: "404", - name: "404", - file: `${APP_DIRECTORY}content/pages/404.md`, - fields: [ - { - label: "Hero", - name: "hero", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "markdown", - }, - ], - }, - { - label: "News and stories", - name: "news-stories", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Number of stories", - name: "articles-count", - widget: "number", - value_type: "int", - min: 3, - }, - ], - }, - { - ...seoFields, - }, - ], - }, - { - label: "Error", - name: "error", - file: `${APP_DIRECTORY}content/pages/error.md`, - fields: [ - { - label: "Hero", - name: "hero", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "markdown", - }, - ], - }, - { - label: "News and stories", - name: "news-stories", - widget: "object", - collapsed: true, - summary: "{{fields.title}}", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Number of stories", - name: "articles-count", - widget: "number", - value_type: "int", - min: 3, - }, - ], - }, - { - ...seoFields, - }, - ], - }, - ], - }, - { - label: "Data | Badges", - name: "badges", - label_singular: "Badge", - folder: `${APP_DIRECTORY}content/badges`, - create: true, - fields: [ - { - label: "Id", - name: "id", - widget: "uuid", - }, - { - label: "Name", - name: "name", - widget: "string", - }, - { - label: "Description", - name: "body", - widget: "markdown", - }, - { - label: "Date", - name: "date", - widget: "datetime", - format: "MMMM Do YYYY", - }, - ], - }, - { - name: "donors", - label: "Data | Donors", - label_singular: "Donor", - folder: `${APP_DIRECTORY}content/donors`, - create: true, - identifier_field: "name", - fields: [ - { - label: "Id", - name: "id", - widget: "uuid", - }, - { - label: "Name", - name: "name", - widget: "string", - }, - { - label: "Logo", - name: "logo", - widget: "object", - fields: [ - { - label: "Source", - name: "src", - widget: "image", - required: false, - }, - ], - }, - ], - }, - { - label: "Data | Guiding Principles", - name: "guiding-principles", - label_singular: "Guiding Principle", - folder: `${APP_DIRECTORY}content/guiding-principles`, - create: true, - identifier_field: "title", - fields: [ - { - label: "Id", - name: "id", - widget: "uuid", - }, - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Description", - name: "body", - widget: "markdown", - }, - { - label: "Icon", - name: "icon", - widget: "object", - fields: [ - { - label: "Source", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - ], - }, - { - label: "Data | Impact", - name: "impact", - label_singular: "Impact", - folder: `${APP_DIRECTORY}content/impact`, - create: true, - identifier_field: "title", - fields: [ - { - label: "Id", - name: "id", - widget: "uuid", - }, - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Value", - name: "value", - widget: "string", - }, - { - label: "Description", - name: "body", - widget: "markdown", - }, - { - label: "Image", - name: "image", - widget: "object", - fields: [ - { - label: "Source", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - ], - }, - { - label: "Data | Offices", - name: "offices-addresses", - label_singular: "Office", - folder: `${APP_DIRECTORY}content/offices`, - create: true, - identifier_field: "name", - fields: [ - { - label: "Id", - name: "id", - widget: "uuid", - }, - { - label: "Name", - name: "name", - widget: "string", - }, - { - label: "Address", - name: "body", - widget: "markdown", - }, - { - label: "Location", - name: "location", - widget: "object", - fields: [ - { - label: "Latitude", - name: "latitude", - widget: "number", - value_type: "float", - }, - { - label: "Longitude", - name: "longitude", - widget: "number", - value_type: "float", - }, - ], - }, - ], - }, - { - name: "partners", - label: "Data | Partners", - folder: `${APP_DIRECTORY}content/partners`, - create: true, - identifier_field: "name", - label_singular: "Partner", - fields: [ - { - label: "Id", - name: "id", - widget: "uuid", - }, - { - label: "Name", - name: "name", - widget: "string", - }, - { - label: "Description", - name: "body", - widget: "markdown", - }, - { - label: "Href", - name: "href", - widget: "string", - required: false, - }, - { - label: "Logo", - name: "logo", - widget: "object", - fields: [ - { - label: "Source", - name: "src", - widget: "image", - }, - ], - }, - - { - label: "Links", - name: "links", - widget: "object", - fields: [ - { - label: "Facebook", - name: "facebook", - widget: "string", - required: false, - }, - { - label: "Twitter", - name: "twitter", - widget: "string", - required: false, - }, - { - label: "LinkedIn", - name: "linkedIn", - widget: "string", - required: false, - }, - { - label: "Instagram", - name: "instagram", - widget: "string", - required: false, - }, - { - label: "Github", - name: "github", - widget: "string", - required: false, - }, - { - label: "Slack", - name: "slack", - widget: "string", - required: false, - }, - ], - }, - ], - }, - { - label: "Data | Projects", - name: "projects", - folder: `${APP_DIRECTORY}content/projects`, - create: true, - label_singular: "Project", - identifier_field: "name", - fields: [ - { - label: "Id", - name: "id", - widget: "uuid", - }, - { - label: "Name", - name: "name", - widget: "string", - }, - { - label: "Tag Line", - name: "tagLine", - widget: "string", - }, - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Subtitle", - name: "subtitle", - widget: "markdown", - }, - { - label: "Description", - name: "body", - widget: "markdown", - }, - { - label: "Tag", - name: "tag", - widget: "string", - }, - { - label: "Icon", - name: "icon", - widget: "object", - fields: [ - { - label: "Source", - name: "src", - widget: "image", - }, - ], - }, - { - label: "Thumbnail", - name: "thumbnail", - widget: "object", - fields: [ - { - label: "Source", - name: "src", - widget: "image", - }, - ], - }, - { - label: "External URL", - name: "externalHref", - widget: "string", - }, - { - label: "Badges", - name: "badges", - widget: "relation", - label_singular: "Badge", - collection: "badges", - search_fields: ["name"], - value_field: "id", - display_fields: ["name"], - multiple: true, - }, - { - name: "partners", - label: "Partners", - widget: "relation", - label_singular: "Partner", - collection: "partners", - search_fields: ["name"], - value_field: "id", - display_fields: ["name"], - multiple: true, - }, - { - name: "donors", - label: "Donors", - widget: "relation", - label_singular: "Donor", - collection: "donors", - search_fields: ["name"], - value_field: "id", - display_fields: ["name"], - multiple: true, - }, - { - name: "team", - label: "Team", - widget: "relation", - label_singular: "Team Member", - collection: "team", - search_fields: ["name"], - value_field: "id", - display_fields: ["name"], - multiple: true, - }, - { - name: "links", - label: "Links", - label_singular: "Link", - widget: "list", - summary: "{{content}} - {{href}}", - fields: [ - { - label: "slug", - name: "slug", - widget: "string", - }, - { - label: "Content", - name: "content", - widget: "string", - }, - { - label: "Href", - name: "href", - widget: "string", - }, - { - label: "Icon", - name: "icon", - widget: "object", - fields: [ - { - label: "Source", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - ], - }, - ], - }, - { - label: "Data | Team", - name: "team", - label_singular: "Team Member", - folder: `${APP_DIRECTORY}content/team`, - create: true, - identifier_field: "name", - fields: [ - { - label: "Id", - name: "id", - widget: "uuid", - }, - { - label: "Name", - name: "name", - widget: "string", - }, - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Description", - name: "body", - widget: "markdown", - }, - { - label: "Thumbnail", - name: "thumbnail", - widget: "object", - fields: [ - { - label: "Source", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - { - name: "links", - label: "Links", - widget: "object", - label_singular: "Link", - collapsed: true, - fields: [ - { - label: "Twitter", - name: "twitter", - widget: "string", - required: false, - }, - { - label: "Github", - name: "github", - widget: "string", - required: false, - }, - { - label: "LinkedIn", - name: "linkedin", - widget: "string", - required: false, - }, - { - label: "Facebook", - name: "facebook", - widget: "string", - required: false, - }, - { - label: "Instagram", - name: "instagram", - widget: "string", - required: false, - }, - { - label: "Slack", - name: "slack", - widget: "string", - required: false, - }, - ], - }, - { - label: "Country", - name: "country", - widget: "string", - }, - { - label: "Team", - name: "team", - widget: "string", - }, - { - label: "Deactivated", - name: "deactivated", - widget: "boolean", - default: false, - }, - ], - }, - { - name: "settings", - label: "Settings", - files: [ - { - name: "general", - label: "General", - file: `${APP_DIRECTORY}content/settings/general.md`, - fields: [ - { - label: "Site", - name: "site", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - hint: "The name of the site", - }, - { - label: "Description", - name: "description", - widget: "text", - required: false, - hint: "Helps with search results and when shared in social media platforms", - }, - ], - }, - { - label: "SEO", - name: "seo", - widget: "object", - fields: [ - { - label: "Title Template", - name: "title-template", - widget: "string", - hint: '"pre/suffix that should be included with every page. It replaces %s with your title string e.g. "%s | CfA" template will render "About | CfA" in about page with title "About"', - }, - { - label: "Meta data", - name: "meta", - widget: "object", - hint: "Search engines support", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - required: false, - hint: "Uses page title if not provided", - pattern: ["^.{1,70}$", "Must be up to 70 characters"], - }, - { - label: "Description", - name: "description", - widget: "text", - required: false, - hint: "Uses page description if not provided", - pattern: ["^.{1,150}$", "Must be up to 156 characters"], - }, - ], - }, - { - label: "Open Graph", - name: "open-graph", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - required: false, - hint: "Uses page title if not provided", - }, - { - label: "Description", - name: "description", - widget: "string", - required: false, - hint: "Uses page description if not provided", - }, - { - label: "Images", - name: "images", - widget: "list", - max: 1, - min: 1, - required: false, - fields: [ - { - name: "url", - label: "URL", - widget: "string", - }, - { - name: "width", - label: "Width", - widget: "string", - }, - { - name: "height", - label: "Height", - widget: "string", - }, - { - name: "alt", - label: "Alt Text", - widget: "string", - }, - ], - }, - ], - }, - { - label: "Twitter", - name: "twitter", - widget: "object", - fields: [ - { - label: "@Site", - name: "site", - widget: "string", - required: false, - default: "@Code4Africa", - }, - { - label: "Card Type", - name: "cardType", - widget: "hidden", - default: "summary_large_image", - }, - ], - }, - ], - }, - ], - }, - { - label: "Header", - name: "header", - file: `${APP_DIRECTORY}content/settings/header.md`, - fields: [ - { - label: "Logo", - name: "logo", - widget: "object", - fields: [ - { - label: "Src", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - { - label: "Main Navigation", - name: "main-navigation", - label_singular: "Navigation item", - widget: "list", - fields: [ - { - label: "Label", - name: "content", - widget: "string", - }, - { - label: "Href", - name: "href", - widget: "string", - }, - ], - }, - { - label: "Social Media Link", - name: "social-media-link", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Href", - name: "href", - widget: "string", - }, - { - label: "Mobile Icon", - name: "mobile-icon", - widget: "object", - fields: [ - { - label: "Src", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - { - label: "Desktop Icon", - name: "desktop-icon", - widget: "object", - fields: [ - { - label: "Src", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - ], - }, - ], - }, - { - label: "Footer", - name: "footer", - file: `${APP_DIRECTORY}content/settings/footer.md`, - fields: [ - { - label: "Logo", - name: "logo", - widget: "object", - fields: [ - { - label: "Src", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - { - label: "Description", - name: "description", - widget: "markdown", - }, - { - label: "Stay in touch", - name: "stay-in-touch", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Links", - name: "links", - label_singular: "Link", - widget: "list", - fields: [ - { - label: "Label", - name: "label", - widget: "string", - }, - { - label: "Href", - name: "href", - widget: "string", - }, - { - label: "Icon", - name: "icon", - widget: "object", - fields: [ - { - label: "Src", - name: "src", - widget: "image", - }, - { - label: "Height", - name: "height", - widget: "string", - required: false, - }, - { - label: "Width", - name: "width", - widget: "string", - required: false, - }, - ], - }, - ], - }, - ], - }, - { - label: "Main Navigation", - name: "main-navigation", - label_singular: "Navigation item", - widget: "list", - fields: [ - { - label: "Label", - name: "content", - widget: "string", - }, - { - label: "Href", - name: "href", - widget: "string", - }, - ], - }, - { - label: "Secondary Navigation", - name: "secondary-navigation", - label_singular: "Navigation item", - widget: "list", - fields: [ - { - label: "Label", - name: "content", - widget: "string", - }, - { - label: "Href", - name: "href", - widget: "string", - }, - ], - }, - { - label: "Newsletter subscription", - name: "newsletter-subscription", - widget: "object", - fields: [ - { - label: "Title", - name: "title", - widget: "string", - }, - { - label: "Mailchimp code", - name: "embed-code", - widget: "code", - allow_language_selection: false, - default_language: "html", - output_code_only: true, - }, - ], - }, - ], - }, - ], - }, - ], -}; diff --git a/apps/codeforafrica/src/pages/api/admin/config.yml.page.js b/apps/codeforafrica/src/pages/api/admin/config.yml.page.js deleted file mode 100644 index 8ddba0207..000000000 --- a/apps/codeforafrica/src/pages/api/admin/config.yml.page.js +++ /dev/null @@ -1,29 +0,0 @@ -import yaml from "js-yaml"; - -import config from "./config"; - -import site from "@/codeforafrica/utils/site"; - -export default function handler(req, res) { - if (req.method === "GET") { - if (process.env.NODE_ENV === "production") { - // Set production configurations - config.backend.name = "github"; - config.backend.repo = process.env.GITHUB_BACKEND_REPO; - config.backend.base_url = site.url.replace(/\/+$/, ""); - config.backend.auth_endpoint = process.env.GITHUB_AUTH_ENDPOINT; - config.publish_mode = "editorial_workflow"; - // Remove dev configurations - config.local_backend = undefined; - config.backend.proxy_url = undefined; - } - config.logo_url = site.logoUrl; - const configFile = yaml.dump(config); - - res.setHeader("Content-Type", "text/yaml"); - res.setHeader("Content-Disposition", "attachment; filename=config.yml"); - res.send(configFile); - } - - return res.status(405).end(); -} diff --git a/apps/codeforafrica/src/pages/api/members/index.page.js b/apps/codeforafrica/src/pages/api/members/index.page.js deleted file mode 100644 index b24614719..000000000 --- a/apps/codeforafrica/src/pages/api/members/index.page.js +++ /dev/null @@ -1,20 +0,0 @@ -import { getMembers } from "@/codeforafrica/lib"; - -const QUERY_PARAM_NAMES = ["field", "page", "page-size", "q", "tag"]; - -export default function handler(req, res) { - if (req.method === "GET") { - const { query: originalQuery } = req; - const query = Object.keys(originalQuery).reduce((acc, key) => { - const paramName = key.toLocaleLowerCase(); - if (QUERY_PARAM_NAMES.includes(key)) { - acc[paramName] = originalQuery[key]; - } - return acc; - }, {}); - const projects = getMembers(query); - return res.status(200).json(projects); - } - - return res.status(405).end(); -} diff --git a/apps/codeforafrica/src/pages/api/oauth/auth.js b/apps/codeforafrica/src/pages/api/oauth/auth.js deleted file mode 100644 index 84d325f5c..000000000 --- a/apps/codeforafrica/src/pages/api/oauth/auth.js +++ /dev/null @@ -1,37 +0,0 @@ -import { nanoid } from "nanoid"; -import { AuthorizationCode } from "simple-oauth2"; - -import site from "@/codeforafrica/utils/site"; - -const config = { - cms: { - oauth: { - redirectUrl: `${site.environmentUrl.replace( - /\/+$/, - "", - )}/api/oauth/callback`, - scope: "user, repo", - }, - }, -}; - -const client = new AuthorizationCode({ - client: { - id: process.env.OAUTH_CLIENT_ID, - secret: process.env.OAUTH_CLIENT_SECRET, - }, - auth: { - tokenHost: "https://github.com", - authorizePath: "/login/oauth/authorize", - }, -}); - -// Authorization uri definition -const authorizationUri = client.authorizeURL({ - redirect_uri: config.cms.oauth.redirectUrl, - scope: config.cms.oauth.scope, - state: nanoid(), -}); - -// Initial page redirecting to Github -export default authorizationUri; diff --git a/apps/codeforafrica/src/pages/api/oauth/auth.page.js b/apps/codeforafrica/src/pages/api/oauth/auth.page.js deleted file mode 100644 index 103b8b60c..000000000 --- a/apps/codeforafrica/src/pages/api/oauth/auth.page.js +++ /dev/null @@ -1,7 +0,0 @@ -import authorizationUri from "./auth"; - -// Initial page redirecting to Github -export default async (req, res) => { - res.writeHead(302, { Location: authorizationUri }); - res.end(); -}; diff --git a/apps/codeforafrica/src/pages/api/oauth/callback.js b/apps/codeforafrica/src/pages/api/oauth/callback.js deleted file mode 100644 index ddd71ba55..000000000 --- a/apps/codeforafrica/src/pages/api/oauth/callback.js +++ /dev/null @@ -1,14 +0,0 @@ -import { AuthorizationCode } from "simple-oauth2"; - -const client = new AuthorizationCode({ - client: { - id: process.env.OAUTH_CLIENT_ID, - secret: process.env.OAUTH_CLIENT_SECRET, - }, - auth: { - tokenHost: "https://github.com", - tokenPath: "/login/oauth/access_token", - }, -}); - -export default client; diff --git a/apps/codeforafrica/src/pages/api/oauth/callback.page.js b/apps/codeforafrica/src/pages/api/oauth/callback.page.js deleted file mode 100644 index 18aecebcd..000000000 --- a/apps/codeforafrica/src/pages/api/oauth/callback.page.js +++ /dev/null @@ -1,41 +0,0 @@ -import client from "./callback"; - -const oauthProvider = "github"; - -export default async (req, res) => { - const { code, state } = req.query; - const tokenParams = { - code, - state, - }; - - let status = "error"; - let content; - try { - const accessToken = await client.getToken(tokenParams); - status = "success"; - content = { - token: accessToken.token.access_token, - provider: oauthProvider, - }; - } catch (error) { - content = JSON.stringify(error); - } - - const script = ` - `; - return res.end(script); -}; diff --git a/apps/codeforafrica/src/pages/api/opportunities/index.page.js b/apps/codeforafrica/src/pages/api/opportunities/index.page.js deleted file mode 100644 index 2f29f9448..000000000 --- a/apps/codeforafrica/src/pages/api/opportunities/index.page.js +++ /dev/null @@ -1,20 +0,0 @@ -import { getOpportunities } from "@/codeforafrica/lib"; - -const QUERY_PARAM_NAMES = ["tag", "page", "q"]; - -export default async function handler(req, res) { - if (req.method === "GET") { - const { query: originalQuery } = req; - const query = Object.keys(originalQuery).reduce((acc, key) => { - const paramName = key.toLocaleLowerCase(); - if (QUERY_PARAM_NAMES.includes(key)) { - acc[paramName] = originalQuery[key]; - } - return acc; - }, {}); - const projects = await getOpportunities(query); - return res.status(200).json(projects); - } - - return res.status(405).end(); -} diff --git a/apps/codeforafrica/src/pages/api/projects/index.page.js b/apps/codeforafrica/src/pages/api/projects/index.page.js deleted file mode 100644 index 952bdc3ba..000000000 --- a/apps/codeforafrica/src/pages/api/projects/index.page.js +++ /dev/null @@ -1,20 +0,0 @@ -import { getProjects } from "@/codeforafrica/lib"; - -const QUERY_PARAM_NAMES = ["tag", "page", "q"]; - -export default function handler(req, res) { - if (req.method === "GET") { - const { query: originalQuery } = req; - const query = Object.keys(originalQuery).reduce((acc, key) => { - const paramName = key.toLocaleLowerCase(); - if (QUERY_PARAM_NAMES.includes(key)) { - acc[paramName] = originalQuery[key]; - } - return acc; - }, {}); - const projects = getProjects(query); - return res.status(200).json(projects); - } - - return res.status(405).end(); -} diff --git a/apps/codeforafrica/src/pages/api/stories/index.page.js b/apps/codeforafrica/src/pages/api/stories/index.page.js deleted file mode 100644 index 99bd73cc9..000000000 --- a/apps/codeforafrica/src/pages/api/stories/index.page.js +++ /dev/null @@ -1,20 +0,0 @@ -import { getStories } from "@/codeforafrica/lib"; - -const QUERY_PARAM_NAMES = ["field", "page", "page-size", "q", "tag"]; - -export default async function handler(req, res) { - if (req.method === "GET") { - const { query: originalQuery } = req; - const query = Object.keys(originalQuery).reduce((acc, key) => { - const paramName = key.toLocaleLowerCase(); - if (QUERY_PARAM_NAMES.includes(key)) { - acc[paramName] = originalQuery[key]; - } - return acc; - }, {}); - const stories = await getStories(query); - return res.status(200).json(stories); - } - - return res.status(405).end(); -} From 57f54246a75337472b1da47859cf165b1045ee29 Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Wed, 20 Sep 2023 11:44:10 +0300 Subject: [PATCH 09/13] Update tests --- .../codeforafrica/src/components/TeamMembers/TeamMembers.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/codeforafrica/src/components/TeamMembers/TeamMembers.test.js b/apps/codeforafrica/src/components/TeamMembers/TeamMembers.test.js index be9d86367..fcff42135 100644 --- a/apps/codeforafrica/src/components/TeamMembers/TeamMembers.test.js +++ b/apps/codeforafrica/src/components/TeamMembers/TeamMembers.test.js @@ -10,7 +10,6 @@ const render = createRender({ theme }); const defaultProps = { title: "Team", - team: [], }; describe("", () => { From d9ea2b65fb86969c275405145965c96b641e9e7e Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Wed, 20 Sep 2023 12:19:22 +0300 Subject: [PATCH 10/13] Reviewed changes --- apps/codeforafrica/src/lib/data/rest/index.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apps/codeforafrica/src/lib/data/rest/index.js b/apps/codeforafrica/src/lib/data/rest/index.js index 63517ea4b..80c11bb13 100644 --- a/apps/codeforafrica/src/lib/data/rest/index.js +++ b/apps/codeforafrica/src/lib/data/rest/index.js @@ -36,13 +36,6 @@ export const api = { export async function getPageStaticProps(context) { const props = await getPageProps(api, context); - if (!props) { - return { - props: { - title: "Page not found", - }, - }; - } return { props, }; From 1c5b61c955e2a5b7e1885b827f7bba0de4c55300 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Wed, 20 Sep 2023 12:20:03 +0300 Subject: [PATCH 11/13] Reviewed changes --- .../codeforafrica/src/payload/blocks/GetInTouch.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/apps/codeforafrica/src/payload/blocks/GetInTouch.js b/apps/codeforafrica/src/payload/blocks/GetInTouch.js index 92d2ea922..d8e52942e 100644 --- a/apps/codeforafrica/src/payload/blocks/GetInTouch.js +++ b/apps/codeforafrica/src/payload/blocks/GetInTouch.js @@ -13,23 +13,15 @@ const GetInTouch = { }, { name: "subtitle", - label: "Sub Title", + label: "Subtitle", required: true, type: "text", }, { name: "action", - label: "Action Button", + label: "Action", type: "group", - fields: [ - { - name: "label", - label: "Label", - type: "text", - required: true, - }, - link({}), - ], + fields: [link({})], }, ], }; From 20bb17c72a3cf3a3ed9a70f021b3d2650aae8d82 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Wed, 20 Sep 2023 12:21:47 +0300 Subject: [PATCH 12/13] Remove unnecessary params --- apps/codeforafrica/src/payload/blocks/GetInTouch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/codeforafrica/src/payload/blocks/GetInTouch.js b/apps/codeforafrica/src/payload/blocks/GetInTouch.js index d8e52942e..3b5f28a9e 100644 --- a/apps/codeforafrica/src/payload/blocks/GetInTouch.js +++ b/apps/codeforafrica/src/payload/blocks/GetInTouch.js @@ -21,7 +21,7 @@ const GetInTouch = { name: "action", label: "Action", type: "group", - fields: [link({})], + fields: [link()], }, ], }; From 2de0d04f473b4871d0ff3a658ef053355aab9acc Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:04:48 +0300 Subject: [PATCH 13/13] Use link group --- .../src/payload/blocks/GetInTouch.js | 9 ++----- .../src/payload/fields/links/linkGroup.js | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 apps/codeforafrica/src/payload/fields/links/linkGroup.js diff --git a/apps/codeforafrica/src/payload/blocks/GetInTouch.js b/apps/codeforafrica/src/payload/blocks/GetInTouch.js index 3b5f28a9e..b50433007 100644 --- a/apps/codeforafrica/src/payload/blocks/GetInTouch.js +++ b/apps/codeforafrica/src/payload/blocks/GetInTouch.js @@ -1,4 +1,4 @@ -import link from "../fields/links/link"; +import linkGroup from "../fields/links/linkGroup"; const GetInTouch = { slug: "get-in-touch", @@ -17,12 +17,7 @@ const GetInTouch = { required: true, type: "text", }, - { - name: "action", - label: "Action", - type: "group", - fields: [link()], - }, + linkGroup({ overrides: { name: "action", label: "Action" } }), ], }; diff --git a/apps/codeforafrica/src/payload/fields/links/linkGroup.js b/apps/codeforafrica/src/payload/fields/links/linkGroup.js new file mode 100644 index 000000000..3931937bf --- /dev/null +++ b/apps/codeforafrica/src/payload/fields/links/linkGroup.js @@ -0,0 +1,24 @@ +import { deepmerge } from "@mui/utils"; + +import link from "./link"; + +/** + * group field consisting of a link field. + */ +function linkGroup({ linkConfig, overrides = {} } = {}) { + const generatedLinkGroup = { + name: "link", + label: { + en: "Link", + fr: "Lien", + pt: "Link", + }, + type: "group", + required: true, + fields: [link(linkConfig)], + }; + + return deepmerge(generatedLinkGroup, overrides); +} + +export default linkGroup;