Skip to content

Commit

Permalink
Merge pull request #581 from CodeForAfrica/feature/cfa-partners-cms
Browse files Browse the repository at this point in the history
Migrate partners to Payload
  • Loading branch information
koechkevin authored Sep 14, 2023
2 parents 67f97e8 + af4d23d commit a8f7d53
Show file tree
Hide file tree
Showing 9 changed files with 236 additions and 73 deletions.
5 changes: 3 additions & 2 deletions apps/codeforafrica/payload.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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"),
Expand Down Expand Up @@ -69,5 +70,5 @@ export default buildConfig({
generateURL: (docs) =>
docs.reduce((url, doc) => `${url}/${doc.slug}`, ""),
}),
],
] as any[],
});
11 changes: 6 additions & 5 deletions apps/codeforafrica/src/components/OurPartners/OurPartners.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -22,17 +22,18 @@ const OurPartners = React.forwardRef(function OurPartners(props, ref) {
{title}
</RichTypography>
<Grid container columns={10} justifyContent="flex-start">
{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 (
<Grid item xs={5} sm={2} key={name}>
<Grid item xs={5} sm={2} key={id}>
<Wrapper {...wrapperProps}>
<Figure
ImageProps={{
alt: name,
...logo,
alt,
src: logo.url,
}}
sx={{
filter: "grayscale(100%) opacity(50%)",
Expand Down
44 changes: 44 additions & 0 deletions apps/codeforafrica/src/payload/blocks/OurPartners.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const Partners = {
slug: "our-partners",
labels: {
singular: {
en: "Partners",
fr: "Partenaires",
pt: "Parceiros",
},
plural: {
en: "Partners",
fr: "Partenaires",
pt: "Parceiros",
},
},
fields: [
{
name: "title",
label: {
en: "Title",
fr: "Titre",
pt: "Título",
},
type: "text",
localized: true,
required: true,
},
{
name: "partners",
label: {
en: "Partners",
fr: "Les partenaires",
pt: "Parceiros",
},
type: "relationship",
relationTo: "partners",
hasMany: true,
admin: {
isSortable: true,
},
},
],
};

export default Partners;
3 changes: 2 additions & 1 deletion apps/codeforafrica/src/payload/collections/Pages.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import CustomPageHeader from "../blocks/CustomPageHeader";
import Error from "../blocks/Error";
import Hero from "../blocks/Hero";
import OurPartners from "../blocks/OurPartners";
import PageHeader from "../blocks/PageHeader";
import fullTitle from "../fields/fullTitle";
import slug from "../fields/slug";
Expand Down Expand Up @@ -36,7 +37,7 @@ 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],
blocks: [Error, Hero, PageHeader, CustomPageHeader, OurPartners],
admin: {
initCollapsed: true,
},
Expand Down
68 changes: 68 additions & 0 deletions apps/codeforafrica/src/payload/collections/Partners.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import image from "../fields/image";
import richText from "../fields/richText";
import slug from "../fields/slug";
import socialLinks from "../fields/socialLinks";
import nestCollectionUnderPage from "../utils/nestCollectionUnderPage";

const Partners = {
slug: "partners",
labels: {
singular: {
en: "Partner",
fr: "Partenaire",
pt: "Parceiro",
},
plural: {
en: "Partners",
fr: "Partenaires",
pt: "Parceiros",
},
},
admin: {
useAsTitle: "name",
defaultColumns: ["name", "logo"],
},
access: {
read: () => 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;
69 changes: 69 additions & 0 deletions apps/codeforafrica/src/payload/fields/socialLinks.js
Original file line number Diff line number Diff line change
@@ -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;
66 changes: 1 addition & 65 deletions apps/codeforafrica/src/payload/globals/Settings/EngagementTab.js
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
22 changes: 22 additions & 0 deletions apps/codeforafrica/src/payload/utils/findAndFormatPagePath.js
Original file line number Diff line number Diff line change
@@ -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;
21 changes: 21 additions & 0 deletions apps/codeforafrica/src/payload/utils/nestCollectionUnderPage.js
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit a8f7d53

Please sign in to comment.