diff --git a/apps/codeforafrica/payload.config.ts b/apps/codeforafrica/payload.config.ts index 454a7d0f8..f152e0df2 100644 --- a/apps/codeforafrica/payload.config.ts +++ b/apps/codeforafrica/payload.config.ts @@ -3,6 +3,7 @@ import path from "path"; import { buildConfig } from "payload/config"; import Media from "./src/payload/collections/Media"; import Pages from "./src/payload/collections/Pages"; +import Partners from "./src/payload/collections/Partners"; import Settings from "./src/payload/globals/Settings"; import { CollectionConfig, GlobalConfig } from "payload/types"; import dotenv from "dotenv"; @@ -29,7 +30,7 @@ const adapter = s3Adapter({ export default buildConfig({ serverURL: appURL, - collections: [Pages, Media] as CollectionConfig[], + collections: [Pages, Media, Partners] as CollectionConfig[], globals: [Settings] as GlobalConfig[], admin: { css: path.resolve(__dirname, "./src/payload/admin/scss/custom.scss"), @@ -69,5 +70,5 @@ export default buildConfig({ generateURL: (docs) => docs.reduce((url, doc) => `${url}/${doc.slug}`, ""), }), - ], + ] as any[], }); diff --git a/apps/codeforafrica/src/components/OurPartners/OurPartners.js b/apps/codeforafrica/src/components/OurPartners/OurPartners.js index e52d99096..682f9ec9e 100644 --- a/apps/codeforafrica/src/components/OurPartners/OurPartners.js +++ b/apps/codeforafrica/src/components/OurPartners/OurPartners.js @@ -4,7 +4,7 @@ import { Button, Grid } from "@mui/material"; import React from "react"; const OurPartners = React.forwardRef(function OurPartners(props, ref) { - const { partners: { title, action, list: partners } = {}, sx } = props; + const { sx, partners, title, action } = props; if (!partners?.length) { return null; @@ -22,17 +22,18 @@ const OurPartners = React.forwardRef(function OurPartners(props, ref) { {title} - {partners.map(({ logo, name, href }) => { + {partners.map(({ logo, id, link: { href } }) => { + const { alt } = logo; const Wrapper = href?.length ? Link : React.Fragment; const wrapperProps = href?.length ? { href } : undefined; return ( - +
true, + }, + + fields: [ + { + name: "name", + label: { + en: "Name", + fr: "Nom", + pt: "Nome", + }, + type: "text", + required: true, + localized: true, + }, + slug({ fieldToUse: "name" }), + image({ + overrides: { + name: "logo", + required: true, + }, + }), + richText({ + name: "description", + label: { + en: "Description", + fr: "La description", + pt: "Descrição", + }, + localized: true, + required: true, + }), + socialLinks({ + name: "connect", + label: "Social Media Links", + required: false, + }), + ], + hooks: { + afterRead: [nestCollectionUnderPage("partners")], + }, +}; +export default Partners; diff --git a/apps/codeforafrica/src/payload/fields/socialLinks.js b/apps/codeforafrica/src/payload/fields/socialLinks.js new file mode 100644 index 000000000..214e75895 --- /dev/null +++ b/apps/codeforafrica/src/payload/fields/socialLinks.js @@ -0,0 +1,69 @@ +import { deepmerge } from "@mui/utils"; +import { array } from "payload/dist/fields/validations"; + +import url from "./url"; + +const socialMediaOptions = [ + "Facebook", + "Twitter", + "Instagram", + "Linkedin", + "Github", + "Slack", +]; + +function socialLinks(overrides) { + const defaults = { + name: "links", + type: "array", + label: "Links", + labels: { + singular: "Link", + plural: "Links", + }, + minRows: 1, + admin: { + className: "array-field-nested", + components: { + RowLabel: ({ data, index }) => { + let label = ""; + if (data.platform) { + label = data.platform; + } + if (data.url) { + label = label ? `${label} (${data.url})` : data.url; + } + if (!label) { + label = `Link ${String(index).padStart(2, "0")}`; + } + return label; + }, + }, + initCollapsed: true, + }, + fields: [ + { + name: "platform", + type: "select", + label: "Platform", + options: socialMediaOptions, + required: true, + validate: (val, options) => { + const { data } = options || {}; + if (data?.links?.filter((l) => l.platform === val)?.length > 1) { + return "Please select a unique platform"; + } + return array(val, options); + }, + }, + url({ + overrides: { + required: true, + }, + }), + ], + }; + return deepmerge(defaults, overrides); +} + +export default socialLinks; diff --git a/apps/codeforafrica/src/payload/globals/Settings/EngagementTab.js b/apps/codeforafrica/src/payload/globals/Settings/EngagementTab.js index fe17ec4db..169af1404 100644 --- a/apps/codeforafrica/src/payload/globals/Settings/EngagementTab.js +++ b/apps/codeforafrica/src/payload/globals/Settings/EngagementTab.js @@ -1,68 +1,4 @@ -import { array } from "payload/dist/fields/validations"; - -import url from "../../fields/url"; - -const socialMediaOptions = [ - "Facebook", - "Twitter", - "Instagram", - "Linkedin", - "Github", - "Slack", -]; - -function socialLinks() { - return { - name: "links", - type: "array", - label: "Links", - labels: { - singular: "Link", - plural: "Links", - }, - minRows: 1, - admin: { - className: "array-field-nested", - components: { - RowLabel: ({ data, index }) => { - let label = ""; - if (data.platform) { - label = data.platform; - } - if (data.url) { - label = label ? `${label} (${data.url})` : data.url; - } - if (!label) { - label = `Link ${String(index).padStart(2, "0")}`; - } - return label; - }, - }, - initCollapsed: true, - }, - fields: [ - { - name: "platform", - type: "select", - label: "Platform", - options: socialMediaOptions, - required: true, - validate: (val, options) => { - const { data } = options || {}; - if (data?.links?.filter((l) => l.platform === val)?.length > 1) { - return "Please select a unique platform"; - } - return array(val, options); - }, - }, - url({ - overrides: { - required: true, - }, - }), - ], - }; -} +import socialLinks from "../../fields/socialLinks"; const EngagementTab = { label: "Engagement", diff --git a/apps/codeforafrica/src/payload/utils/findAndFormatPagePath.js b/apps/codeforafrica/src/payload/utils/findAndFormatPagePath.js new file mode 100644 index 000000000..d6ccca9e5 --- /dev/null +++ b/apps/codeforafrica/src/payload/utils/findAndFormatPagePath.js @@ -0,0 +1,22 @@ +import formatPagePath from "./formatPagePath"; + +async function findAndFormatPagePath(payload, slug) { + const collection = "pages"; + const options = { + collection, + where: { + slug: { + equals: slug, + }, + }, + limit: 0, + }; + const { docs } = await payload.find(options); + + if (docs?.length) { + return formatPagePath(collection, docs[0]); + } + return undefined; +} + +export default findAndFormatPagePath; diff --git a/apps/codeforafrica/src/payload/utils/nestCollectionUnderPage.js b/apps/codeforafrica/src/payload/utils/nestCollectionUnderPage.js new file mode 100644 index 000000000..0e5dcd09e --- /dev/null +++ b/apps/codeforafrica/src/payload/utils/nestCollectionUnderPage.js @@ -0,0 +1,21 @@ +import findAndFormatPagePath from "./findAndFormatPagePath"; + +function nestCollectionUnderPage(pageSlug) { + return async function nestCollectionItemUnderParentPage({ + doc, + req: { payload }, + }) { + let href = null; + try { + const pagePath = await findAndFormatPagePath(payload, pageSlug); + if (pagePath) { + href = `${pagePath}/${doc.slug}`; + } + } catch (error) { + // Handle Errors + } + return { ...doc, link: { href } }; + }; +} + +export default nestCollectionUnderPage;