diff --git a/apps/codeforafrica/payload.config.ts b/apps/codeforafrica/payload.config.ts index f152e0df2..bb14cf4e7 100644 --- a/apps/codeforafrica/payload.config.ts +++ b/apps/codeforafrica/payload.config.ts @@ -1,6 +1,7 @@ import path from "path"; import { buildConfig } from "payload/config"; +import Impact from "./src/payload/collections/Impact"; import Media from "./src/payload/collections/Media"; import Pages from "./src/payload/collections/Pages"; import Partners from "./src/payload/collections/Partners"; @@ -30,7 +31,7 @@ const adapter = s3Adapter({ export default buildConfig({ serverURL: appURL, - collections: [Pages, Media, Partners] as CollectionConfig[], + collections: [Impact, Pages, Media, Partners] as CollectionConfig[], globals: [Settings] as GlobalConfig[], admin: { css: path.resolve(__dirname, "./src/payload/admin/scss/custom.scss"), diff --git a/apps/codeforafrica/public/images/cms/blocks/our_impact.jpg b/apps/codeforafrica/public/images/cms/blocks/our_impact.jpg new file mode 100644 index 000000000..b01b4a6c4 Binary files /dev/null and b/apps/codeforafrica/public/images/cms/blocks/our_impact.jpg differ diff --git a/apps/codeforafrica/src/components/GetInvolved/GetInvolved.snap.js b/apps/codeforafrica/src/components/GetInvolved/GetInvolved.snap.js index a9a53805f..072057c34 100644 --- a/apps/codeforafrica/src/components/GetInvolved/GetInvolved.snap.js +++ b/apps/codeforafrica/src/components/GetInvolved/GetInvolved.snap.js @@ -47,11 +47,6 @@ exports[` renders unchanged 1`] = ` > 15000 -
- In 10 years, 15 000 trainees have learned new skills and knowledge within the civic tech and media space. -
diff --git a/apps/codeforafrica/src/components/ImpactCard/ImpactCard.js b/apps/codeforafrica/src/components/ImpactCard/ImpactCard.js index 706f313fa..258c52b54 100644 --- a/apps/codeforafrica/src/components/ImpactCard/ImpactCard.js +++ b/apps/codeforafrica/src/components/ImpactCard/ImpactCard.js @@ -4,6 +4,8 @@ import { styled } from "@mui/material/styles"; import PropTypes from "prop-types"; import React from "react"; +import RichText from "@/codeforafrica/components/RichText"; + const ImpactCardRoot = styled(Card, { slot: "Root", })(({ theme: { breakpoints } }) => ({ @@ -19,7 +21,7 @@ const ImpactCardRoot = styled(Card, { })); const ImpactCard = React.forwardRef(function ImpactCard(props, ref) { - const { image, title, value, content } = props; + const { image, title, value, description } = props; if (!(image && title)) { return null; @@ -72,22 +74,21 @@ const ImpactCard = React.forwardRef(function ImpactCard(props, ref) { > {value} - - {content} - + /> ); }); ImpactCard.propTypes = { - content: PropTypes.string, + description: PropTypes.arrayOf(PropTypes.shape({})), title: PropTypes.string, value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), image: PropTypes.shape({ @@ -97,7 +98,7 @@ ImpactCard.propTypes = { }; ImpactCard.defaultProps = { - content: undefined, + description: undefined, title: undefined, value: undefined, image: undefined, diff --git a/apps/codeforafrica/src/components/ImpactCard/ImpactCard.snap.js b/apps/codeforafrica/src/components/ImpactCard/ImpactCard.snap.js index dc3be107d..9eb352a88 100644 --- a/apps/codeforafrica/src/components/ImpactCard/ImpactCard.snap.js +++ b/apps/codeforafrica/src/components/ImpactCard/ImpactCard.snap.js @@ -36,9 +36,13 @@ exports[` renders unchanged 1`] = ` 15000
- In 10 years, 15 000 trainees have learned new skills and knowledge within the civic tech and media space. + + Our team makes an impact in more than 20 countries where members are present. +
diff --git a/apps/codeforafrica/src/components/ImpactCard/ImpactCard.test.js b/apps/codeforafrica/src/components/ImpactCard/ImpactCard.test.js index 2f4928027..236b04831 100644 --- a/apps/codeforafrica/src/components/ImpactCard/ImpactCard.test.js +++ b/apps/codeforafrica/src/components/ImpactCard/ImpactCard.test.js @@ -14,8 +14,16 @@ const defaultProps = { image: { src: "/images/Type=layout,%20Size=32,%20Color=1020E1.svg", }, - content: - "In 10 years, 15 000 trainees have learned new skills and knowledge within the civic tech and media space.", + description: [ + { + children: [ + { + text: "Our team makes an impact in more than 20 countries where members are present.", + children: null, + }, + ], + }, + ], }; describe("", () => { diff --git a/apps/codeforafrica/src/components/ImpactCardList/ImpactCardList.snap.js b/apps/codeforafrica/src/components/ImpactCardList/ImpactCardList.snap.js index bcd507074..ad09c8d89 100644 --- a/apps/codeforafrica/src/components/ImpactCardList/ImpactCardList.snap.js +++ b/apps/codeforafrica/src/components/ImpactCardList/ImpactCardList.snap.js @@ -41,11 +41,6 @@ exports[` renders unchanged 1`] = ` > 15000 -
- In 10 years, 15 000 trainees have learned new skills and knowledge within the civic tech and media space. -
diff --git a/apps/codeforafrica/src/components/OurImpact/OurImpact.js b/apps/codeforafrica/src/components/OurImpact/OurImpact.js index 1471f87e6..0fe03d9e5 100644 --- a/apps/codeforafrica/src/components/OurImpact/OurImpact.js +++ b/apps/codeforafrica/src/components/OurImpact/OurImpact.js @@ -7,9 +7,9 @@ import React from "react"; import ImpactCardList from "@/codeforafrica/components/ImpactCardList"; const OurImpact = React.forwardRef(function OurImpact(props, ref) { - const { list, title, sx } = props; + const { impacts, title, sx } = props; - if (!list?.length) { + if (!impacts?.length) { return null; } return ( @@ -36,19 +36,19 @@ const OurImpact = React.forwardRef(function OurImpact(props, ref) { {title} )} - + ); }); OurImpact.propTypes = { - list: PropTypes.arrayOf(PropTypes.shape({})), + impacts: PropTypes.arrayOf(PropTypes.shape({})), title: PropTypes.string, }; OurImpact.defaultProps = { - list: undefined, + impacts: undefined, title: undefined, }; diff --git a/apps/codeforafrica/src/lib/data/blockify/index.js b/apps/codeforafrica/src/lib/data/blockify/index.js index 8155c7807..c22c42108 100644 --- a/apps/codeforafrica/src/lib/data/blockify/index.js +++ b/apps/codeforafrica/src/lib/data/blockify/index.js @@ -1,9 +1,11 @@ import hero from "./hero"; import meetOurTeam from "./meetOurTeam"; +import ourImpact from "./our-impact"; const propsifyBlockBySlug = { hero, "meet-our-team": meetOurTeam, + "our-impact": ourImpact, }; async function blockify(blocks) { diff --git a/apps/codeforafrica/src/lib/data/blockify/our-impact.js b/apps/codeforafrica/src/lib/data/blockify/our-impact.js new file mode 100644 index 000000000..c5e53b4e9 --- /dev/null +++ b/apps/codeforafrica/src/lib/data/blockify/our-impact.js @@ -0,0 +1,22 @@ +import { imageFromMedia } from "@/codeforafrica/lib/data/utils"; + +function ourImpact(block) { + const { impacts, ...other } = block; + const ourImpacts = impacts.map((impact) => { + const { icon: media, title, ...rest } = impact; + const image = imageFromMedia({ alt: title, ...media }); + return { + ...rest, + image, + title, + }; + }); + + return { + ...other, + impacts: ourImpacts, + slug: "our-impact", + }; +} + +export default ourImpact; diff --git a/apps/codeforafrica/src/lib/data/common/index.js b/apps/codeforafrica/src/lib/data/common/index.js index 67af24ffa..5f3c6878d 100644 --- a/apps/codeforafrica/src/lib/data/common/index.js +++ b/apps/codeforafrica/src/lib/data/common/index.js @@ -44,12 +44,111 @@ function getPageSlug({ params }) { return params?.slugs?.[pageSlugIndex] || "index"; } +function getDefaultErrorPageProps(slug = "404") { + if (slug === "500") { + return { + title: "Server Error. ", + subtitle: [ + { + children: [ + { + text: "Don't worry!, you can head back to our ", + children: null, + }, + { + type: "link", + newTab: false, + url: "/", + children: [ + { + text: "homepage", + children: null, + }, + ], + href: "/", + }, + { + text: "check out our most recent ", + children: null, + }, + { + type: "link", + newTab: false, + url: "/projects", + children: [ + { + text: "projects", + children: null, + }, + ], + href: "/projects", + }, + { + text: ", or read below some of the contents produced by our amazing team while the technical team is working on fixing the issue.", + children: null, + }, + ], + }, + ], + }; + } + + return { + title: "Whoops! This page got lost in conversation! ", + subtitle: [ + { + children: [ + { + text: "Don't worry!, you can head back to our ", + children: null, + }, + { + type: "link", + newTab: false, + url: "/", + children: [ + { + text: "homepage", + children: null, + }, + ], + href: "/", + }, + { + text: "check out our most recent ", + children: null, + }, + { + type: "link", + newTab: false, + url: "/projects", + children: [ + { + text: "projects", + children: null, + }, + ], + href: "/projects", + }, + { + text: ", or read below some of the contents produced by our amazing team.", + children: null, + }, + ], + }, + ], + }; +} + export async function getPageProps(api, context) { const slug = getPageSlug(context); const { docs: [page], } = await api.findPage(slug); if (!page) { + if (["404", "500"].includes(slug)) { + return getDefaultErrorPageProps(slug); + } return null; } diff --git a/apps/codeforafrica/src/pages/[...slugs].page.js b/apps/codeforafrica/src/pages/[...slugs].page.js index 4557ba5fa..4c0ed596f 100644 --- a/apps/codeforafrica/src/pages/[...slugs].page.js +++ b/apps/codeforafrica/src/pages/[...slugs].page.js @@ -7,6 +7,7 @@ import GetInvolved from "@/codeforafrica/components/GetInvolved"; import Hero from "@/codeforafrica/components/Hero"; import MeetOurTeam from "@/codeforafrica/components/MeetOurTeam"; import NewsAndStories from "@/codeforafrica/components/NewsAndStories"; +import OurImpact from "@/codeforafrica/components/OurImpact"; import OurPartners from "@/codeforafrica/components/OurPartners"; import PageHeader from "@/codeforafrica/components/PageHeader"; import { getPageServerSideProps } from "@/codeforafrica/lib/data"; @@ -17,7 +18,8 @@ const componentsBySlugs = { "custom-page-header": CustomPageHeader, "meet-our-team": MeetOurTeam, "news-stories": NewsAndStories, - "our-impact": GetInvolved, + "get-involved": GetInvolved, + "our-impact": OurImpact, "our-partners": OurPartners, projects: FeaturedProjects, }; diff --git a/apps/codeforafrica/src/pages/_error.page.js b/apps/codeforafrica/src/pages/_error.page.js index 5440bc17e..cd3527600 100644 --- a/apps/codeforafrica/src/pages/_error.page.js +++ b/apps/codeforafrica/src/pages/_error.page.js @@ -6,7 +6,7 @@ function CustomError(props) { } export async function getStaticProps(context) { - return getPageStaticProps(context, "/_error"); + return getPageStaticProps({ ...context, params: { slugs: ["500"] } }); } export default CustomError; diff --git a/apps/codeforafrica/src/pages/_error.test.js b/apps/codeforafrica/src/pages/_error.test.js index 945005169..f15c14783 100644 --- a/apps/codeforafrica/src/pages/_error.test.js +++ b/apps/codeforafrica/src/pages/_error.test.js @@ -9,7 +9,7 @@ import theme from "@/codeforafrica/theme"; const render = createRender({ theme }); const defaultProps = { - sections: [], + blocks: [], }; describe("/404", () => { diff --git a/apps/codeforafrica/src/payload/blocks/OurImpact.js b/apps/codeforafrica/src/payload/blocks/OurImpact.js new file mode 100644 index 000000000..d50570fdf --- /dev/null +++ b/apps/codeforafrica/src/payload/blocks/OurImpact.js @@ -0,0 +1,20 @@ +import impacts from "../fields/impacts"; + +const OurImpact = { + slug: "our-impact", + imageURL: "/images/cms/blocks/our_impact.jpg", + imageAltText: "Show Our Impact", + fields: [ + { + name: "title", + label: "Title", + type: "text", + required: true, + }, + impacts({ + minRows: 1, + }), + ], +}; + +export default OurImpact; diff --git a/apps/codeforafrica/src/payload/collections/Impact.js b/apps/codeforafrica/src/payload/collections/Impact.js new file mode 100644 index 000000000..b09291ac9 --- /dev/null +++ b/apps/codeforafrica/src/payload/collections/Impact.js @@ -0,0 +1,39 @@ +import image from "../fields/image"; +import richText from "../fields/richText"; + +const Impact = { + slug: "impact", + admin: { + useAsTitle: "title", + defaultColumns: ["title", "value"], + }, + access: { + read: () => true, + }, + fields: [ + { + name: "title", + label: "Title", + type: "text", + required: true, + }, + richText({ + name: "description", + }), + { + name: "value", + label: "Value", + type: "number", + required: true, + min: 1, + }, + image({ + overrides: { + name: "icon", + label: "Icon", + required: true, + }, + }), + ], +}; +export default Impact; diff --git a/apps/codeforafrica/src/payload/collections/Pages.js b/apps/codeforafrica/src/payload/collections/Pages.js index 6aabde359..27d62c4cc 100644 --- a/apps/codeforafrica/src/payload/collections/Pages.js +++ b/apps/codeforafrica/src/payload/collections/Pages.js @@ -2,6 +2,7 @@ import CustomPageHeader from "../blocks/CustomPageHeader"; import Error from "../blocks/Error"; import Hero from "../blocks/Hero"; import MeetOurTeam from "../blocks/MeetOurTeam"; +import OurImpact from "../blocks/OurImpact"; import OurPartners from "../blocks/OurPartners"; import PageHeader from "../blocks/PageHeader"; import fullTitle from "../fields/fullTitle"; @@ -41,6 +42,7 @@ const Pages = { blocks: [ Error, Hero, + OurImpact, PageHeader, CustomPageHeader, MeetOurTeam, diff --git a/apps/codeforafrica/src/payload/fields/impacts.js b/apps/codeforafrica/src/payload/fields/impacts.js new file mode 100644 index 000000000..314363295 --- /dev/null +++ b/apps/codeforafrica/src/payload/fields/impacts.js @@ -0,0 +1,14 @@ +import { deepmerge } from "@mui/utils"; + +const impacts = (overrides) => + deepmerge( + { + name: "impacts", + type: "relationship", + relationTo: "impact", + hasMany: true, + }, + overrides, + ); + +export default impacts;