From 1555c162f3ca542a449f5d4f19621cdbe70d21d9 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Wed, 2 Oct 2024 08:18:31 +0300 Subject: [PATCH 01/67] chore: Include SEO fields in application specific pages and post collections --- apps/civicsignalblog/payload.config.ts | 7 +++++-- .../src/payload/lib/data/common/applications.js | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/civicsignalblog/payload.config.ts b/apps/civicsignalblog/payload.config.ts index 0e56691e8..e5a5db309 100644 --- a/apps/civicsignalblog/payload.config.ts +++ b/apps/civicsignalblog/payload.config.ts @@ -17,12 +17,14 @@ import Authors from "./src/payload/collections/Research/Authors"; import Media from "./src/payload/collections/Research/Media"; import Pages from "./src/payload/collections/Research/Pages"; import CivicSignalPages from "./src/payload/collections/Main/Pages"; +import MediaData from "./src/payload/collections/Main/MediaData"; import Posts from "./src/payload/collections/Research/Posts"; import Publication from "./src/payload/globals/Publication"; import Research from "./src/payload/globals/Site/research"; import Main from "./src/payload/globals/Site/main"; import Tags from "./src/payload/collections/Research/Tags"; import Users from "./src/payload/collections/Users"; +import { applicationPages } from "./src/payload/lib/data/common/applications"; import { defaultLocale, locales } from "./src/payload/utils/locales"; const dev = process.env.NODE_ENV !== "production"; @@ -66,6 +68,7 @@ export default buildConfig({ Posts, Tags, CivicSignalPages, + MediaData, Users, ] as CollectionConfig[], globals: [Publication, Research, Main] as GlobalConfig[], @@ -137,7 +140,7 @@ export default buildConfig({ dsn: process?.env?.NEXT_PUBLIC_SENTRY_DSN, }), seo({ - collections: ["pages", "posts"], + collections: [...applicationPages, "posts"], globals: ["settings-site"], uploadsCollection: "media", generateTitle: ({ doc }: any) => doc?.title?.value as string, @@ -145,7 +148,7 @@ export default buildConfig({ doc?.slug?.value ? `${appURL}/${doc.slug.value}` : undefined, } as any), nestedDocs({ - collections: ["pages"], + collections: applicationPages, generateLabel: (_, doc) => doc.title as string, generateURL: (docs) => docs.reduce((url, doc) => `${url}/${doc.slug}`, ""), diff --git a/apps/civicsignalblog/src/payload/lib/data/common/applications.js b/apps/civicsignalblog/src/payload/lib/data/common/applications.js index 9478b1608..ce78f5b58 100644 --- a/apps/civicsignalblog/src/payload/lib/data/common/applications.js +++ b/apps/civicsignalblog/src/payload/lib/data/common/applications.js @@ -19,4 +19,7 @@ const applications = Object.entries(applicationLabels).map( }), ); +// We'll iterate over applicationLabels once we have all the pages defined +export const applicationPages = [`${MAIN}-pages`, `${RESEARCH}-pages`]; + export default applications; From a13a620521f4c0c2290fc96262c704d6fe0fdc95 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Wed, 2 Oct 2024 09:05:40 +0300 Subject: [PATCH 02/67] feat: Implement MediaData Collection --- .../src/payload/collections/Main/MediaData.js | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 apps/civicsignalblog/src/payload/collections/Main/MediaData.js diff --git a/apps/civicsignalblog/src/payload/collections/Main/MediaData.js b/apps/civicsignalblog/src/payload/collections/Main/MediaData.js new file mode 100644 index 000000000..133efdd95 --- /dev/null +++ b/apps/civicsignalblog/src/payload/collections/Main/MediaData.js @@ -0,0 +1,43 @@ +import { slateEditor } from "@payloadcms/richtext-slate"; + +import canRead from "#civicsignalblog/payload/access/applications/main"; +import image from "#civicsignalblog/payload/fields/image"; +import richText from "#civicsignalblog/payload/fields/richText"; + +const MediaData = { + slug: "media-data", + access: { + read: canRead, + }, + admin: { + defaultColumns: ["title", "updatedAt"], + enableRichTextLink: false, + group: "Publication", + useAsTitle: "title", + }, + fields: [ + { + name: "title", + type: "text", + required: true, + localized: true, + }, + image({ + overrides: { + name: "mediaDataImage", + required: true, + localized: true, + }, + }), + richText({ + name: "description", + editor: slateEditor({ + admin: { + elements: ["link"], + }, + }), + }), + ], +}; + +export default MediaData; From dcc287fe44f89aa842890e9390a07cda5838b9a1 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Wed, 2 Oct 2024 09:06:20 +0300 Subject: [PATCH 03/67] feat: Implement PageHeader block for Research and WebTools Pages --- .../cms/blocks/web_tools_page_header.png | Bin 0 -> 49257 bytes .../src/payload/blocks/Research/PageHeader.js | 19 +++++++++++ .../src/payload/blocks/WebTools/PageHeader.js | 30 ++++++++++++++++++ .../src/payload/collections/Main/Pages.js | 16 ++-------- .../src/payload/collections/Research/Pages.js | 2 +- 5 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 apps/civicsignalblog/public/images/cms/blocks/web_tools_page_header.png create mode 100644 apps/civicsignalblog/src/payload/blocks/Research/PageHeader.js create mode 100644 apps/civicsignalblog/src/payload/blocks/WebTools/PageHeader.js diff --git a/apps/civicsignalblog/public/images/cms/blocks/web_tools_page_header.png b/apps/civicsignalblog/public/images/cms/blocks/web_tools_page_header.png new file mode 100644 index 0000000000000000000000000000000000000000..3457e6555b1d3750fea8558ed48ecdca12a086f2 GIT binary patch literal 49257 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 Gh|Y5i*R(9zdqK^j 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 Vz6cL@R$K#qv^Dh9D^;yS{tJSl)4l)z literal 0 HcmV?d00001 diff --git a/apps/civicsignalblog/src/payload/blocks/Research/PageHeader.js b/apps/civicsignalblog/src/payload/blocks/Research/PageHeader.js new file mode 100644 index 000000000..37d810022 --- /dev/null +++ b/apps/civicsignalblog/src/payload/blocks/Research/PageHeader.js @@ -0,0 +1,19 @@ +const PageHeader = { + slug: "page-header", + imageURL: "/images/cms/blocks/page_header.jpg", + imageAltText: "Header for content pages such as contact page.", + fields: [ + { + name: "title", + required: true, + type: "text", + }, + { + name: "subtitle", + required: true, + type: "text", + }, + ], +}; + +export default PageHeader; diff --git a/apps/civicsignalblog/src/payload/blocks/WebTools/PageHeader.js b/apps/civicsignalblog/src/payload/blocks/WebTools/PageHeader.js new file mode 100644 index 000000000..009e70c0f --- /dev/null +++ b/apps/civicsignalblog/src/payload/blocks/WebTools/PageHeader.js @@ -0,0 +1,30 @@ +import { slateEditor } from "@payloadcms/richtext-slate"; + +import richText from "#civicsignalblog/payload/fields/richText"; + +const PageHeader = { + slug: "webtools-page-header", + labels: { + singular: "Page Header", + plural: "Page Headers", + }, + imageURL: "/images/cms/blocks/web_tools_page_header.png", + imageAltText: "Header for web tools pages", + fields: [ + { + name: "title", + required: true, + type: "text", + }, + richText({ + name: "description", + editor: slateEditor({ + admin: { + elements: ["link"], + }, + }), + }), + ], +}; + +export default PageHeader; diff --git a/apps/civicsignalblog/src/payload/collections/Main/Pages.js b/apps/civicsignalblog/src/payload/collections/Main/Pages.js index 20fc0f9ec..6009b88ca 100644 --- a/apps/civicsignalblog/src/payload/collections/Main/Pages.js +++ b/apps/civicsignalblog/src/payload/collections/Main/Pages.js @@ -1,10 +1,5 @@ import canRead from "#civicsignalblog/payload/access/applications/main"; -import CustomPageHeader from "#civicsignalblog/payload/blocks/CustomPageHeader"; -import Error from "#civicsignalblog/payload/blocks/Error"; -import FeaturedStories from "#civicsignalblog/payload/blocks/FeaturedStories"; -import LongForm from "#civicsignalblog/payload/blocks/LongForm"; -import PageHeader from "#civicsignalblog/payload/blocks/PageHeader"; -import Posts from "#civicsignalblog/payload/blocks/Posts"; +import PageHeader from "#civicsignalblog/payload/blocks/WebTools/PageHeader"; import { MAIN } from "#civicsignalblog/payload/lib/data/common/applications"; import pages from "#civicsignalblog/payload/utils/createPagesCollection"; @@ -13,14 +8,7 @@ const Pages = pages({ label: "Pages", group: "Publication", defaultColumns: ["fullTitle", "updatedAt"], - blocks: [ - Error, - FeaturedStories, - PageHeader, - Posts, - CustomPageHeader, - LongForm, - ], + blocks: [PageHeader], access: { read: canRead, }, diff --git a/apps/civicsignalblog/src/payload/collections/Research/Pages.js b/apps/civicsignalblog/src/payload/collections/Research/Pages.js index b12f8f5c2..e59bb0c6f 100644 --- a/apps/civicsignalblog/src/payload/collections/Research/Pages.js +++ b/apps/civicsignalblog/src/payload/collections/Research/Pages.js @@ -3,8 +3,8 @@ import CustomPageHeader from "#civicsignalblog/payload/blocks/CustomPageHeader"; import Error from "#civicsignalblog/payload/blocks/Error"; import FeaturedStories from "#civicsignalblog/payload/blocks/FeaturedStories"; import LongForm from "#civicsignalblog/payload/blocks/LongForm"; -import PageHeader from "#civicsignalblog/payload/blocks/PageHeader"; import Posts from "#civicsignalblog/payload/blocks/Posts"; +import PageHeader from "#civicsignalblog/payload/blocks/Research/PageHeader"; import { RESEARCH } from "#civicsignalblog/payload/lib/data/common/applications"; import pages from "#civicsignalblog/payload/utils/createPagesCollection"; From 90ace97b9eed967e372b890c3fa28dc8b68218e2 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Thu, 3 Oct 2024 14:26:42 +0300 Subject: [PATCH 04/67] chore: Rename common applications and allow non authenticated users to read content from the CMS --- .../src/payload/access/canAccessApplication.js | 4 +++- .../src/payload/lib/data/common/applications.js | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/civicsignalblog/src/payload/access/canAccessApplication.js b/apps/civicsignalblog/src/payload/access/canAccessApplication.js index faf206265..63023cc33 100644 --- a/apps/civicsignalblog/src/payload/access/canAccessApplication.js +++ b/apps/civicsignalblog/src/payload/access/canAccessApplication.js @@ -1,7 +1,9 @@ export default function canAccessApplication(user, searchString) { + // We are using this condition to only control what a user can see at a given time if (user) { const app = user.currentApp || user.defaultApp; return app === searchString.toLowerCase(); } - return false; + // For APIs coming from external apps we are not going to use any restriction in reading + return true; } diff --git a/apps/civicsignalblog/src/payload/lib/data/common/applications.js b/apps/civicsignalblog/src/payload/lib/data/common/applications.js index ce78f5b58..dfbbe9e74 100644 --- a/apps/civicsignalblog/src/payload/lib/data/common/applications.js +++ b/apps/civicsignalblog/src/payload/lib/data/common/applications.js @@ -1,7 +1,7 @@ -export const MAIN = "main"; +export const MAIN = "tools"; export const EXPLORER = "explorer"; -export const TOPIC_MAPPER = "topic-mapper"; -export const SOURCE_MAPPER = "source-manager"; +export const TOPIC_MAPPER = "topics"; +export const SOURCE_MAPPER = "sources"; export const RESEARCH = "research"; const applicationLabels = { From c59dc96b1333cfaab4a4126fe0ed44ba32ff2e01 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Fri, 4 Oct 2024 12:40:49 +0300 Subject: [PATCH 05/67] chore: Add Document upload feature for Media Data --- .../src/payload/collections/Main/MediaData.js | 7 +++++++ .../src/payload/fields/document.js | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 apps/civicsignalblog/src/payload/fields/document.js diff --git a/apps/civicsignalblog/src/payload/collections/Main/MediaData.js b/apps/civicsignalblog/src/payload/collections/Main/MediaData.js index 133efdd95..3ad0d0309 100644 --- a/apps/civicsignalblog/src/payload/collections/Main/MediaData.js +++ b/apps/civicsignalblog/src/payload/collections/Main/MediaData.js @@ -1,6 +1,7 @@ import { slateEditor } from "@payloadcms/richtext-slate"; import canRead from "#civicsignalblog/payload/access/applications/main"; +import document from "#civicsignalblog/payload/fields/document"; import image from "#civicsignalblog/payload/fields/image"; import richText from "#civicsignalblog/payload/fields/richText"; @@ -29,6 +30,12 @@ const MediaData = { localized: true, }, }), + document({ + overrides: { + name: "mediaDataDocument", + required: true, + }, + }), richText({ name: "description", editor: slateEditor({ diff --git a/apps/civicsignalblog/src/payload/fields/document.js b/apps/civicsignalblog/src/payload/fields/document.js new file mode 100644 index 000000000..0c3cc8043 --- /dev/null +++ b/apps/civicsignalblog/src/payload/fields/document.js @@ -0,0 +1,19 @@ +import { deepmerge } from "@mui/utils"; + +function document({ overrides = undefined } = {}) { + const documentResult = { + name: "document", + type: "upload", + relationTo: "media", + filterOptions: { + mimeType: { contains: "application/pdf" }, // Restricts to PDF files + }, + admin: { + description: "Upload PDF files only", + }, + }; + + return deepmerge(documentResult, overrides); +} + +export default document; From d968728e80556c92637a0a4936c9fb1efeaed72c Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Tue, 8 Oct 2024 08:38:17 +0300 Subject: [PATCH 06/67] feat: Add ResourceList Block to civicsignal tools pages --- .../images/cms/blocks/resource_list.png | Bin 0 -> 51366 bytes .../payload/blocks/WebTools/ResourceList.js | 24 ++++++++++++++++++ .../src/payload/collections/Main/Pages.js | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 apps/civicsignalblog/public/images/cms/blocks/resource_list.png create mode 100644 apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js diff --git a/apps/civicsignalblog/public/images/cms/blocks/resource_list.png b/apps/civicsignalblog/public/images/cms/blocks/resource_list.png new file mode 100644 index 0000000000000000000000000000000000000000..9c7ed4a4a668bec2bf82584157da6e26dadc884a GIT binary patch literal 51366 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�=nDqK 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�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 GLK6VnXzXMF literal 0 HcmV?d00001 diff --git a/apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js b/apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js new file mode 100644 index 000000000..404dff968 --- /dev/null +++ b/apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js @@ -0,0 +1,24 @@ +const PageHeader = { + slug: "webtools-resource-list", + labels: { + singular: "Resource List", + plural: "Resource Lists", + }, + imageURL: "/images/cms/blocks/resource_list.png", + imageAltText: "A list of resrouces to display", + fields: [ + { + name: "resourceListType", + type: "select", + hasMany: false, + options: [ + { + label: "Media Data", + value: "media_data", + }, + ], + }, + ], +}; + +export default PageHeader; diff --git a/apps/civicsignalblog/src/payload/collections/Main/Pages.js b/apps/civicsignalblog/src/payload/collections/Main/Pages.js index 6009b88ca..6e4505f01 100644 --- a/apps/civicsignalblog/src/payload/collections/Main/Pages.js +++ b/apps/civicsignalblog/src/payload/collections/Main/Pages.js @@ -1,5 +1,6 @@ import canRead from "#civicsignalblog/payload/access/applications/main"; import PageHeader from "#civicsignalblog/payload/blocks/WebTools/PageHeader"; +import ResourceList from "#civicsignalblog/payload/blocks/WebTools/ResourceList"; import { MAIN } from "#civicsignalblog/payload/lib/data/common/applications"; import pages from "#civicsignalblog/payload/utils/createPagesCollection"; @@ -8,7 +9,7 @@ const Pages = pages({ label: "Pages", group: "Publication", defaultColumns: ["fullTitle", "updatedAt"], - blocks: [PageHeader], + blocks: [PageHeader, ResourceList], access: { read: canRead, }, From 9b587334fd917afb3f18ae1afc3d41b96f84e8b4 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Tue, 8 Oct 2024 14:31:39 +0300 Subject: [PATCH 07/67] Update apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js Co-authored-by: Clemence Kyara --- .../civicsignalblog/src/payload/blocks/WebTools/ResourceList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js b/apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js index 404dff968..13be1e792 100644 --- a/apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js +++ b/apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js @@ -5,7 +5,7 @@ const PageHeader = { plural: "Resource Lists", }, imageURL: "/images/cms/blocks/resource_list.png", - imageAltText: "A list of resrouces to display", + imageAltText: "A list of resources to display", fields: [ { name: "resourceListType", From 87182e3856ee4db04940e5aed2d49c34771a0e98 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Tue, 15 Oct 2024 11:43:34 +0300 Subject: [PATCH 08/67] feat: Add API key authentication in users collection --- .../src/payload/access/canAccessApplication.js | 8 +++++--- apps/civicsignalblog/src/payload/access/roles.js | 2 ++ apps/civicsignalblog/src/payload/collections/Users.js | 1 + apps/civicsignalblog/src/payload/globals/Site/main.js | 4 ++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/apps/civicsignalblog/src/payload/access/canAccessApplication.js b/apps/civicsignalblog/src/payload/access/canAccessApplication.js index 63023cc33..452785db2 100644 --- a/apps/civicsignalblog/src/payload/access/canAccessApplication.js +++ b/apps/civicsignalblog/src/payload/access/canAccessApplication.js @@ -1,9 +1,11 @@ +import { ROLE_APP } from "./roles"; + export default function canAccessApplication(user, searchString) { // We are using this condition to only control what a user can see at a given time if (user) { const app = user.currentApp || user.defaultApp; - return app === searchString.toLowerCase(); + // The assumption is that one account with ROLE_APP will be used to access all the app content + return app === searchString.toLowerCase() || user.roles.includes(ROLE_APP); } - // For APIs coming from external apps we are not going to use any restriction in reading - return true; + return false; } diff --git a/apps/civicsignalblog/src/payload/access/roles.js b/apps/civicsignalblog/src/payload/access/roles.js index d060bbf8e..825078e46 100644 --- a/apps/civicsignalblog/src/payload/access/roles.js +++ b/apps/civicsignalblog/src/payload/access/roles.js @@ -1,7 +1,9 @@ export const ROLE_ADMIN = "admin"; export const ROLE_EDITOR = "editor"; +export const ROLE_APP = "app"; export const ROLE_DEFAULT = ROLE_EDITOR; export const ROLE_OPTIONS = [ { label: "Admin", value: ROLE_ADMIN }, + { label: "Application", value: ROLE_APP }, { label: "Editor", value: ROLE_EDITOR }, ]; diff --git a/apps/civicsignalblog/src/payload/collections/Users.js b/apps/civicsignalblog/src/payload/collections/Users.js index 05e4dc624..780f24f14 100644 --- a/apps/civicsignalblog/src/payload/collections/Users.js +++ b/apps/civicsignalblog/src/payload/collections/Users.js @@ -32,6 +32,7 @@ const Users = { }, auth: { verify: true, + useAPIKey: true, }, fields: [ { diff --git a/apps/civicsignalblog/src/payload/globals/Site/main.js b/apps/civicsignalblog/src/payload/globals/Site/main.js index 733c873e9..c2f063386 100644 --- a/apps/civicsignalblog/src/payload/globals/Site/main.js +++ b/apps/civicsignalblog/src/payload/globals/Site/main.js @@ -13,6 +13,10 @@ const Main = settings({ access: { read: canRead, }, + auth: { + verify: true, + useAPIKey: true, + }, tabs: [GeneralTab, NavigationTab, EngagementTab], }); From 3c0468cb6ebb0ae69832995547754ec7866f3465 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Tue, 15 Oct 2024 13:37:34 +0300 Subject: [PATCH 09/67] refractor: Use shared page header and add RichText support to ResearchBlog PageHeader --- .../images/cms/blocks/resource_list.png | Bin 51366 -> 0 bytes .../src/components/PageHeader/PageHeader.js | 13 ++++++-- .../src/payload/blocks/PageHeader.js | 19 ++++++++--- .../src/payload/blocks/Research/PageHeader.js | 19 ----------- .../src/payload/blocks/WebTools/PageHeader.js | 30 ------------------ .../payload/blocks/WebTools/ResourceList.js | 24 -------------- .../src/payload/collections/Main/Pages.js | 5 ++- .../src/payload/collections/Research/Pages.js | 2 +- 8 files changed, 28 insertions(+), 84 deletions(-) delete mode 100644 apps/civicsignalblog/public/images/cms/blocks/resource_list.png delete mode 100644 apps/civicsignalblog/src/payload/blocks/Research/PageHeader.js delete mode 100644 apps/civicsignalblog/src/payload/blocks/WebTools/PageHeader.js delete mode 100644 apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js diff --git a/apps/civicsignalblog/public/images/cms/blocks/resource_list.png b/apps/civicsignalblog/public/images/cms/blocks/resource_list.png deleted file mode 100644 index 9c7ed4a4a668bec2bf82584157da6e26dadc884a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51366 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�=nDqK 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�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 GLK6VnXzXMF diff --git a/apps/civicsignalblog/src/components/PageHeader/PageHeader.js b/apps/civicsignalblog/src/components/PageHeader/PageHeader.js index d96a6b5a8..339b64e2b 100644 --- a/apps/civicsignalblog/src/components/PageHeader/PageHeader.js +++ b/apps/civicsignalblog/src/components/PageHeader/PageHeader.js @@ -4,6 +4,8 @@ import React from "react"; import TwoToneBackground from "../TwoToneBackground"; +import RichText from "@/civicsignalblog/components/RichText"; + const PageHeader = React.forwardRef(function PageHeader(props, ref) { const { title, subtitle } = props; @@ -31,9 +33,14 @@ const PageHeader = React.forwardRef(function PageHeader(props, ref) { > {title} - - {subtitle} - + ); diff --git a/apps/civicsignalblog/src/payload/blocks/PageHeader.js b/apps/civicsignalblog/src/payload/blocks/PageHeader.js index 37d810022..c61108b38 100644 --- a/apps/civicsignalblog/src/payload/blocks/PageHeader.js +++ b/apps/civicsignalblog/src/payload/blocks/PageHeader.js @@ -1,5 +1,13 @@ +import { slateEditor } from "@payloadcms/richtext-slate"; + +import richText from "#civicsignalblog/payload/fields/richText"; + const PageHeader = { slug: "page-header", + labels: { + singular: "Page Header", + plural: "Page Headers", + }, imageURL: "/images/cms/blocks/page_header.jpg", imageAltText: "Header for content pages such as contact page.", fields: [ @@ -8,11 +16,14 @@ const PageHeader = { required: true, type: "text", }, - { + richText({ name: "subtitle", - required: true, - type: "text", - }, + editor: slateEditor({ + admin: { + elements: ["link"], + }, + }), + }), ], }; diff --git a/apps/civicsignalblog/src/payload/blocks/Research/PageHeader.js b/apps/civicsignalblog/src/payload/blocks/Research/PageHeader.js deleted file mode 100644 index 37d810022..000000000 --- a/apps/civicsignalblog/src/payload/blocks/Research/PageHeader.js +++ /dev/null @@ -1,19 +0,0 @@ -const PageHeader = { - slug: "page-header", - imageURL: "/images/cms/blocks/page_header.jpg", - imageAltText: "Header for content pages such as contact page.", - fields: [ - { - name: "title", - required: true, - type: "text", - }, - { - name: "subtitle", - required: true, - type: "text", - }, - ], -}; - -export default PageHeader; diff --git a/apps/civicsignalblog/src/payload/blocks/WebTools/PageHeader.js b/apps/civicsignalblog/src/payload/blocks/WebTools/PageHeader.js deleted file mode 100644 index 009e70c0f..000000000 --- a/apps/civicsignalblog/src/payload/blocks/WebTools/PageHeader.js +++ /dev/null @@ -1,30 +0,0 @@ -import { slateEditor } from "@payloadcms/richtext-slate"; - -import richText from "#civicsignalblog/payload/fields/richText"; - -const PageHeader = { - slug: "webtools-page-header", - labels: { - singular: "Page Header", - plural: "Page Headers", - }, - imageURL: "/images/cms/blocks/web_tools_page_header.png", - imageAltText: "Header for web tools pages", - fields: [ - { - name: "title", - required: true, - type: "text", - }, - richText({ - name: "description", - editor: slateEditor({ - admin: { - elements: ["link"], - }, - }), - }), - ], -}; - -export default PageHeader; diff --git a/apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js b/apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js deleted file mode 100644 index 13be1e792..000000000 --- a/apps/civicsignalblog/src/payload/blocks/WebTools/ResourceList.js +++ /dev/null @@ -1,24 +0,0 @@ -const PageHeader = { - slug: "webtools-resource-list", - labels: { - singular: "Resource List", - plural: "Resource Lists", - }, - imageURL: "/images/cms/blocks/resource_list.png", - imageAltText: "A list of resources to display", - fields: [ - { - name: "resourceListType", - type: "select", - hasMany: false, - options: [ - { - label: "Media Data", - value: "media_data", - }, - ], - }, - ], -}; - -export default PageHeader; diff --git a/apps/civicsignalblog/src/payload/collections/Main/Pages.js b/apps/civicsignalblog/src/payload/collections/Main/Pages.js index 6e4505f01..f5a3efa43 100644 --- a/apps/civicsignalblog/src/payload/collections/Main/Pages.js +++ b/apps/civicsignalblog/src/payload/collections/Main/Pages.js @@ -1,6 +1,5 @@ import canRead from "#civicsignalblog/payload/access/applications/main"; -import PageHeader from "#civicsignalblog/payload/blocks/WebTools/PageHeader"; -import ResourceList from "#civicsignalblog/payload/blocks/WebTools/ResourceList"; +import PageHeader from "#civicsignalblog/payload/blocks/PageHeader"; import { MAIN } from "#civicsignalblog/payload/lib/data/common/applications"; import pages from "#civicsignalblog/payload/utils/createPagesCollection"; @@ -9,7 +8,7 @@ const Pages = pages({ label: "Pages", group: "Publication", defaultColumns: ["fullTitle", "updatedAt"], - blocks: [PageHeader, ResourceList], + blocks: [PageHeader], access: { read: canRead, }, diff --git a/apps/civicsignalblog/src/payload/collections/Research/Pages.js b/apps/civicsignalblog/src/payload/collections/Research/Pages.js index e59bb0c6f..b12f8f5c2 100644 --- a/apps/civicsignalblog/src/payload/collections/Research/Pages.js +++ b/apps/civicsignalblog/src/payload/collections/Research/Pages.js @@ -3,8 +3,8 @@ import CustomPageHeader from "#civicsignalblog/payload/blocks/CustomPageHeader"; import Error from "#civicsignalblog/payload/blocks/Error"; import FeaturedStories from "#civicsignalblog/payload/blocks/FeaturedStories"; import LongForm from "#civicsignalblog/payload/blocks/LongForm"; +import PageHeader from "#civicsignalblog/payload/blocks/PageHeader"; import Posts from "#civicsignalblog/payload/blocks/Posts"; -import PageHeader from "#civicsignalblog/payload/blocks/Research/PageHeader"; import { RESEARCH } from "#civicsignalblog/payload/lib/data/common/applications"; import pages from "#civicsignalblog/payload/utils/createPagesCollection"; From 5ec8a10c0a8f8e969fef9a99ac5173f892bb63b7 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Tue, 15 Oct 2024 14:51:37 +0300 Subject: [PATCH 10/67] chore: Update Jest snapshots after adding RichText support in PageHeader --- .../components/PageHeader/PageHeader.snap.js | 19 +++++++++++++++---- .../components/PageHeader/PageHeader.test.js | 11 ++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/apps/civicsignalblog/src/components/PageHeader/PageHeader.snap.js b/apps/civicsignalblog/src/components/PageHeader/PageHeader.snap.js index 6fe4aa58c..c324dcd58 100644 --- a/apps/civicsignalblog/src/components/PageHeader/PageHeader.snap.js +++ b/apps/civicsignalblog/src/components/PageHeader/PageHeader.snap.js @@ -13,11 +13,22 @@ exports[` renders unchanged 1`] = ` > Contact -

- Let’s start something together! -

+

+ Let's + + start + + something + + together + +

+ diff --git a/apps/civicsignalblog/src/components/PageHeader/PageHeader.test.js b/apps/civicsignalblog/src/components/PageHeader/PageHeader.test.js index 983b3da9b..e447ac4fd 100644 --- a/apps/civicsignalblog/src/components/PageHeader/PageHeader.test.js +++ b/apps/civicsignalblog/src/components/PageHeader/PageHeader.test.js @@ -10,7 +10,16 @@ const render = createRender({ theme }); const defaultProps = { title: "Contact", - subtitle: "Let’s start something together!", + subtitle: [ + { + children: [ + { text: "Let's", children: null }, + { children: null, bold: true, text: " start " }, + { children: null, text: "something" }, + { children: null, bold: true, text: " together" }, + ], + }, + ], }; describe("", () => { From 2b1c09d1bacc2cf56642f98af49a56016d9ef498 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Wed, 16 Oct 2024 16:31:33 +0300 Subject: [PATCH 11/67] chore: Use RichText component from @commons-ui/payload --- apps/civicsignalblog/package.json | 1 + .../components/Footer/FooterDescription.js | 3 +- .../LongFormRichText/LongFormRichText.js | 3 +- .../src/components/PageHeader/PageHeader.js | 3 +- .../src/components/RichText/RichText.js | 114 ------------------ .../src/components/RichText/RichText.snap.js | 31 ----- .../src/components/RichText/RichText.test.js | 64 ---------- .../src/components/RichText/index.js | 3 - pnpm-lock.yaml | 3 + 9 files changed, 7 insertions(+), 218 deletions(-) delete mode 100644 apps/civicsignalblog/src/components/RichText/RichText.js delete mode 100644 apps/civicsignalblog/src/components/RichText/RichText.snap.js delete mode 100644 apps/civicsignalblog/src/components/RichText/RichText.test.js delete mode 100644 apps/civicsignalblog/src/components/RichText/index.js diff --git a/apps/civicsignalblog/package.json b/apps/civicsignalblog/package.json index c137ae533..778831acc 100644 --- a/apps/civicsignalblog/package.json +++ b/apps/civicsignalblog/package.json @@ -41,6 +41,7 @@ "@aws-sdk/lib-storage": "catalog:", "@commons-ui/core": "workspace:*", "@commons-ui/next": "workspace:*", + "@commons-ui/payload": "workspace:*", "@emotion/cache": "catalog:", "@emotion/react": "catalog:", "@emotion/server": "catalog:", diff --git a/apps/civicsignalblog/src/components/Footer/FooterDescription.js b/apps/civicsignalblog/src/components/Footer/FooterDescription.js index 2b53e2dd0..92f200ef0 100644 --- a/apps/civicsignalblog/src/components/Footer/FooterDescription.js +++ b/apps/civicsignalblog/src/components/Footer/FooterDescription.js @@ -1,11 +1,10 @@ /* eslint-env browser */ import { Figure, Link } from "@commons-ui/next"; +import { RichText } from "@commons-ui/payload"; import { Stack } from "@mui/material"; import PropTypes from "prop-types"; import React from "react"; -import RichText from "@/civicsignalblog/components/RichText"; - const FooterDescription = React.forwardRef( function FooterDescription(props, ref) { const { description, logo, sx } = props; diff --git a/apps/civicsignalblog/src/components/LongFormRichText/LongFormRichText.js b/apps/civicsignalblog/src/components/LongFormRichText/LongFormRichText.js index 6ac524db3..6cb477ffa 100644 --- a/apps/civicsignalblog/src/components/LongFormRichText/LongFormRichText.js +++ b/apps/civicsignalblog/src/components/LongFormRichText/LongFormRichText.js @@ -1,7 +1,6 @@ +import { RichText } from "@commons-ui/payload"; import React from "react"; -import RichText from "@/civicsignalblog/components/RichText"; - const LongFormRichText = React.forwardRef((props, ref) => { const { richTextBlockFields: { content } = {} } = props; diff --git a/apps/civicsignalblog/src/components/PageHeader/PageHeader.js b/apps/civicsignalblog/src/components/PageHeader/PageHeader.js index 339b64e2b..34b105bff 100644 --- a/apps/civicsignalblog/src/components/PageHeader/PageHeader.js +++ b/apps/civicsignalblog/src/components/PageHeader/PageHeader.js @@ -1,11 +1,10 @@ import { Section } from "@commons-ui/core"; import { RichTypography } from "@commons-ui/next"; +import { RichText } from "@commons-ui/payload"; import React from "react"; import TwoToneBackground from "../TwoToneBackground"; -import RichText from "@/civicsignalblog/components/RichText"; - const PageHeader = React.forwardRef(function PageHeader(props, ref) { const { title, subtitle } = props; diff --git a/apps/civicsignalblog/src/components/RichText/RichText.js b/apps/civicsignalblog/src/components/RichText/RichText.js deleted file mode 100644 index 3d3a9c3c2..000000000 --- a/apps/civicsignalblog/src/components/RichText/RichText.js +++ /dev/null @@ -1,114 +0,0 @@ -/* eslint-disable react/no-array-index-key */ -import { Link, RichTypography } from "@commons-ui/next"; -import { Box } from "@mui/material"; -import { deepmerge } from "@mui/utils"; -import React, { Fragment } from "react"; -import { Text } from "slate"; - -const DEFAULT_PROPS = { - html: false, -}; - -const serialize = (children, props) => - children?.map((node, i) => { - if (Text.isText(node)) { - let { text } = node; - if (node.bold) { - text = {text}; - } - if (node.code) { - text = {text}; - } - if (node.italic) { - text = {text}; - } - - // Handle other leaf types here... - - return {text}; - } - - if (!node) { - return null; - } - const nodeProps = deepmerge(DEFAULT_PROPS, props, { clone: true }); - // TODO(kilemensi): handle node.type === indent - switch (node.type) { - case "h1": - return ( - - {serialize(node.children)} - - ); - case "h2": - return ( - - {serialize(node.children)} - - ); - case "h3": - return ( - - {serialize(node.children)} - - ); - case "h4": - return ( - - {serialize(node.children)} - - ); - case "h5": - return ( - - {serialize(node.children)} - - ); - case "h6": - return ( - - {serialize(node.children)} - - ); - case "quote": - return
{serialize(node.children)}
; - case "link": - return ( - - {serialize(node.children)} - - ); - default: - return ( - - {serialize(node.children, props)} - - ); - } - }); - -const RichText = React.forwardRef(function RichText(props, ref) { - const { elements, variant, typographyProps, ...other } = props; - - if (!elements?.length) { - return null; - } - return ( - - {serialize(elements, typographyProps)} - - ); -}); - -export default RichText; diff --git a/apps/civicsignalblog/src/components/RichText/RichText.snap.js b/apps/civicsignalblog/src/components/RichText/RichText.snap.js deleted file mode 100644 index 8b0ddbe8e..000000000 --- a/apps/civicsignalblog/src/components/RichText/RichText.snap.js +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` renders unchanged 1`] = ` -
-
-

- The Charter Project is a pan-African initiative by a coalition of watchdog organisations that use civic technologies to strengthen democracy. -

-

- We do this by helping digital activists and democracy changemakers leverage the African Union’s Charter on Democracy, Elections and Governance (ACDEG). -

-

- The project currently supports initiatives in 11 countries. Find out more - - here - -

-
-
-`; diff --git a/apps/civicsignalblog/src/components/RichText/RichText.test.js b/apps/civicsignalblog/src/components/RichText/RichText.test.js deleted file mode 100644 index d8ddb6821..000000000 --- a/apps/civicsignalblog/src/components/RichText/RichText.test.js +++ /dev/null @@ -1,64 +0,0 @@ -import { createRender } from "@commons-ui/testing-library"; -import React from "react"; - -import RichText from "./RichText"; - -import theme from "@/civicsignalblog/theme"; - -// eslint-disable-next-line testing-library/render-result-naming-convention -const render = createRender({ theme }); - -const defaultProps = { - elements: [ - { - children: [ - { - text: "The Charter Project is a pan-African initiative by a coalition of watchdog organisations that use civic technologies to strengthen democracy.", - children: null, - }, - ], - }, - { - children: [ - { - text: "We do this by helping digital activists and democracy changemakers leverage the African Union’s Charter on Democracy, Elections and Governance (ACDEG).", - children: null, - }, - ], - }, - { - children: [ - { - text: "The project currently supports initiatives in 11 countries. Find out more ", - children: null, - }, - { - type: "link", - linkType: "internal", - doc: { - value: "63887cf05bc566facccee049", - relationTo: "pages", - }, - children: [ - { - text: "here", - children: null, - }, - ], - href: "/", - }, - { - text: "", - children: null, - }, - ], - }, - ], -}; - -describe("", () => { - it("renders unchanged", () => { - const { container } = render(); - expect(container).toMatchSnapshot(); - }); -}); diff --git a/apps/civicsignalblog/src/components/RichText/index.js b/apps/civicsignalblog/src/components/RichText/index.js deleted file mode 100644 index 49b1d7e02..000000000 --- a/apps/civicsignalblog/src/components/RichText/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import RichText from "./RichText"; - -export default RichText; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b1c903e82..c3c082478 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -853,6 +853,9 @@ importers: '@commons-ui/next': specifier: workspace:* version: link:../../packages/commons-ui-next + '@commons-ui/payload': + specifier: workspace:* + version: link:../../packages/commons-ui-payload '@emotion/cache': specifier: 'catalog:' version: 11.13.1 From c78545371183d5aefd8a84ea8c68db556bc94e02 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Wed, 16 Oct 2024 16:53:53 +0300 Subject: [PATCH 12/67] chore: Update Jest snapshots for CMSContent and LongFormRichText --- .../src/components/CMSContent/CMSContent.snap.js | 2 +- .../src/components/LongFormRichText/LongFormRichText.snap.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/civicsignalblog/src/components/CMSContent/CMSContent.snap.js b/apps/civicsignalblog/src/components/CMSContent/CMSContent.snap.js index 4f8818320..451e90550 100644 --- a/apps/civicsignalblog/src/components/CMSContent/CMSContent.snap.js +++ b/apps/civicsignalblog/src/components/CMSContent/CMSContent.snap.js @@ -13,7 +13,7 @@ exports[` renders unchanged 1`] = ` > Women make up only 22% of the people seen, heard or read about in the news in Africa, the results of the  renders unchanged 1`] = ` > Women make up only 22% of the people seen, heard or read about in the news in Africa, the results of the  Date: Thu, 17 Oct 2024 14:52:17 +0300 Subject: [PATCH 13/67] chore: Create Subscriber role --- apps/civicsignalblog/src/payload/access/roles.js | 4 ++-- apps/civicsignalblog/src/payload/collections/Users.js | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/civicsignalblog/src/payload/access/roles.js b/apps/civicsignalblog/src/payload/access/roles.js index 825078e46..651cd2429 100644 --- a/apps/civicsignalblog/src/payload/access/roles.js +++ b/apps/civicsignalblog/src/payload/access/roles.js @@ -1,9 +1,9 @@ export const ROLE_ADMIN = "admin"; export const ROLE_EDITOR = "editor"; -export const ROLE_APP = "app"; +export const ROLE_SUBSCRIBER = "subscriber"; export const ROLE_DEFAULT = ROLE_EDITOR; export const ROLE_OPTIONS = [ { label: "Admin", value: ROLE_ADMIN }, - { label: "Application", value: ROLE_APP }, + { label: "Subscriber", value: ROLE_SUBSCRIBER }, { label: "Editor", value: ROLE_EDITOR }, ]; diff --git a/apps/civicsignalblog/src/payload/collections/Users.js b/apps/civicsignalblog/src/payload/collections/Users.js index 780f24f14..5c5082958 100644 --- a/apps/civicsignalblog/src/payload/collections/Users.js +++ b/apps/civicsignalblog/src/payload/collections/Users.js @@ -87,6 +87,16 @@ const Users = { }, options: applications, }, + { + name: "allowedApps", + defaultValue: RESEARCH, + type: "select", + hasMany: true, + admin: { + isClearable: true, + }, + options: applications, + }, ], endpoints: [ { From 7452b85cdb03a85fd817429b2411e45042058e4a Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Thu, 17 Oct 2024 15:37:13 +0300 Subject: [PATCH 14/67] feat: Add check on user allowed apps --- .../src/payload/access/applications/main.js | 4 ++-- .../src/payload/access/applications/research.js | 4 ++-- .../src/payload/access/canAccessApplication.js | 11 +++++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/apps/civicsignalblog/src/payload/access/applications/main.js b/apps/civicsignalblog/src/payload/access/applications/main.js index 87b8cb19c..3cbb046a9 100644 --- a/apps/civicsignalblog/src/payload/access/applications/main.js +++ b/apps/civicsignalblog/src/payload/access/applications/main.js @@ -1,8 +1,8 @@ import canAccessApplication from "#civicsignalblog/payload/access/canAccessApplication"; import { MAIN } from "#civicsignalblog/payload/lib/data/common/applications"; -const canRead = ({ req: { user } }) => { - return canAccessApplication(user, MAIN); +const canRead = ({ req }) => { + return canAccessApplication(req, MAIN); }; export default canRead; diff --git a/apps/civicsignalblog/src/payload/access/applications/research.js b/apps/civicsignalblog/src/payload/access/applications/research.js index dccecce0d..807b219d6 100644 --- a/apps/civicsignalblog/src/payload/access/applications/research.js +++ b/apps/civicsignalblog/src/payload/access/applications/research.js @@ -1,8 +1,8 @@ import canAccessApplication from "#civicsignalblog/payload/access/canAccessApplication"; import { RESEARCH } from "#civicsignalblog/payload/lib/data/common/applications"; -const canRead = ({ req: { user } }) => { - return canAccessApplication(user, RESEARCH); +const canRead = ({ req }) => { + return canAccessApplication(req, RESEARCH); }; export default canRead; diff --git a/apps/civicsignalblog/src/payload/access/canAccessApplication.js b/apps/civicsignalblog/src/payload/access/canAccessApplication.js index 452785db2..f07513802 100644 --- a/apps/civicsignalblog/src/payload/access/canAccessApplication.js +++ b/apps/civicsignalblog/src/payload/access/canAccessApplication.js @@ -1,11 +1,10 @@ -import { ROLE_APP } from "./roles"; +export default async function canAccessApplication(req, searchString) { + const { user, headers } = req; -export default function canAccessApplication(user, searchString) { - // We are using this condition to only control what a user can see at a given time if (user) { - const app = user.currentApp || user.defaultApp; - // The assumption is that one account with ROLE_APP will be used to access all the app content - return app === searchString.toLowerCase() || user.roles.includes(ROLE_APP); + const currentApp = headers["x-current-app"] || user.currentApp; + const app = currentApp || user.defaultApp; + return app === searchString.toLowerCase() && user.allowedApps.includes(app); } return false; } From 469460102e62b6bab619f13ff32a1fc189de96f1 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Fri, 18 Oct 2024 08:50:22 +0300 Subject: [PATCH 15/67] feat: Update app selection component to only include allowed apps --- .../src/payload/components/actions/index.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/civicsignalblog/src/payload/components/actions/index.tsx b/apps/civicsignalblog/src/payload/components/actions/index.tsx index b31ee262f..14fdfa6a2 100644 --- a/apps/civicsignalblog/src/payload/components/actions/index.tsx +++ b/apps/civicsignalblog/src/payload/components/actions/index.tsx @@ -15,6 +15,7 @@ function BeforeDashboard() { ); const [loading, setLoading] = useState(false); + const allowedApps = Array.isArray(user.allowedApps) ? user.allowedApps : []; useEffect(() => { const updateCurrentApp = async () => { @@ -85,11 +86,14 @@ function BeforeDashboard() { }} > - {applications.map((app) => ( - - ))} + {applications.map( + (app) => + allowedApps.includes(app.value) && ( + + ), + )} )} From 91670155aa49aee14c72dbc8a7c1cb88dc64afbc Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Fri, 18 Oct 2024 08:58:00 +0300 Subject: [PATCH 16/67] feat: Restrict changing of default, current and allowed apps for non admin users --- .../src/payload/collections/Users.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/civicsignalblog/src/payload/collections/Users.js b/apps/civicsignalblog/src/payload/collections/Users.js index 5c5082958..b87c5fb37 100644 --- a/apps/civicsignalblog/src/payload/collections/Users.js +++ b/apps/civicsignalblog/src/payload/collections/Users.js @@ -74,6 +74,11 @@ const Users = { isClearable: true, isSortable: true, }, + access: { + read: isAdminOrSelfFieldLevel, + create: isAdminFieldLevel, + update: isAdminFieldLevel, + }, options: applications, }, { @@ -85,6 +90,11 @@ const Users = { isClearable: true, isSortable: true, }, + access: { + read: isAdminOrSelfFieldLevel, + create: isAdminFieldLevel, + update: isAdminFieldLevel, + }, options: applications, }, { @@ -95,6 +105,11 @@ const Users = { admin: { isClearable: true, }, + access: { + read: isAdminOrSelfFieldLevel, + create: isAdminFieldLevel, + update: isAdminFieldLevel, + }, options: applications, }, ], From 5809930367029c49d6a76506542af3cda1a3a365 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Fri, 18 Oct 2024 09:32:53 +0300 Subject: [PATCH 17/67] chore: Implement access control for collections --- .../src/payload/access/isAdminOrEditor.js | 11 +++++++++++ .../src/payload/collections/Main/MediaData.js | 4 ++++ .../src/payload/collections/Main/Pages.js | 4 ++++ .../src/payload/collections/Research/Authors.js | 4 ++++ .../src/payload/collections/Research/Media.js | 5 +++++ .../src/payload/collections/Research/Pages.js | 4 ++++ .../src/payload/collections/Research/Posts.js | 4 ++++ .../src/payload/collections/Research/Tags.js | 4 ++++ 8 files changed, 40 insertions(+) create mode 100644 apps/civicsignalblog/src/payload/access/isAdminOrEditor.js diff --git a/apps/civicsignalblog/src/payload/access/isAdminOrEditor.js b/apps/civicsignalblog/src/payload/access/isAdminOrEditor.js new file mode 100644 index 000000000..527acbb98 --- /dev/null +++ b/apps/civicsignalblog/src/payload/access/isAdminOrEditor.js @@ -0,0 +1,11 @@ +import { ROLE_ADMIN, ROLE_EDITOR } from "./roles"; + +const isAdminOrEditor = ({ req: { user } }) => { + // Return true or false based on if the user has an admin or editor role + return ( + Boolean(user?.roles?.includes(ROLE_ADMIN)) || + Boolean(user?.roles?.includes(ROLE_EDITOR)) + ); +}; + +export default isAdminOrEditor; diff --git a/apps/civicsignalblog/src/payload/collections/Main/MediaData.js b/apps/civicsignalblog/src/payload/collections/Main/MediaData.js index 3ad0d0309..cc04d7b67 100644 --- a/apps/civicsignalblog/src/payload/collections/Main/MediaData.js +++ b/apps/civicsignalblog/src/payload/collections/Main/MediaData.js @@ -1,6 +1,7 @@ import { slateEditor } from "@payloadcms/richtext-slate"; import canRead from "#civicsignalblog/payload/access/applications/main"; +import isAdminOrEditor from "#civicsignalblog/payload/access/isAdminOrEditor"; import document from "#civicsignalblog/payload/fields/document"; import image from "#civicsignalblog/payload/fields/image"; import richText from "#civicsignalblog/payload/fields/richText"; @@ -9,6 +10,9 @@ const MediaData = { slug: "media-data", access: { read: canRead, + update: isAdminOrEditor, + create: isAdminOrEditor, + delete: isAdminOrEditor, }, admin: { defaultColumns: ["title", "updatedAt"], diff --git a/apps/civicsignalblog/src/payload/collections/Main/Pages.js b/apps/civicsignalblog/src/payload/collections/Main/Pages.js index f5a3efa43..bfd5e1f1d 100644 --- a/apps/civicsignalblog/src/payload/collections/Main/Pages.js +++ b/apps/civicsignalblog/src/payload/collections/Main/Pages.js @@ -1,4 +1,5 @@ import canRead from "#civicsignalblog/payload/access/applications/main"; +import isAdminOrEditor from "#civicsignalblog/payload/access/isAdminOrEditor"; import PageHeader from "#civicsignalblog/payload/blocks/PageHeader"; import { MAIN } from "#civicsignalblog/payload/lib/data/common/applications"; import pages from "#civicsignalblog/payload/utils/createPagesCollection"; @@ -11,6 +12,9 @@ const Pages = pages({ blocks: [PageHeader], access: { read: canRead, + update: isAdminOrEditor, + create: isAdminOrEditor, + delete: isAdminOrEditor, }, }); diff --git a/apps/civicsignalblog/src/payload/collections/Research/Authors.js b/apps/civicsignalblog/src/payload/collections/Research/Authors.js index 02e870655..cc1348552 100644 --- a/apps/civicsignalblog/src/payload/collections/Research/Authors.js +++ b/apps/civicsignalblog/src/payload/collections/Research/Authors.js @@ -1,9 +1,13 @@ import canRead from "#civicsignalblog/payload/access/applications/research"; +import isAdminOrEditor from "#civicsignalblog/payload/access/isAdminOrEditor"; const Authors = { slug: "author", access: { read: canRead, + update: isAdminOrEditor, + create: isAdminOrEditor, + delete: isAdminOrEditor, }, admin: { defaultColumns: ["fullName", "updatedAt"], diff --git a/apps/civicsignalblog/src/payload/collections/Research/Media.js b/apps/civicsignalblog/src/payload/collections/Research/Media.js index bbd5b3040..67dd31c0f 100644 --- a/apps/civicsignalblog/src/payload/collections/Research/Media.js +++ b/apps/civicsignalblog/src/payload/collections/Research/Media.js @@ -1,3 +1,5 @@ +import isAdminOrEditor from "#civicsignalblog/payload/access/isAdminOrEditor"; + const Media = { slug: "media", admin: { @@ -8,6 +10,9 @@ const Media = { }, access: { read: () => true, // Everyone can read Media + update: isAdminOrEditor, + create: isAdminOrEditor, + delete: isAdminOrEditor, }, upload: { staticURL: "/media", diff --git a/apps/civicsignalblog/src/payload/collections/Research/Pages.js b/apps/civicsignalblog/src/payload/collections/Research/Pages.js index b12f8f5c2..df11533c3 100644 --- a/apps/civicsignalblog/src/payload/collections/Research/Pages.js +++ b/apps/civicsignalblog/src/payload/collections/Research/Pages.js @@ -1,4 +1,5 @@ import canRead from "#civicsignalblog/payload/access/applications/research"; +import isAdminOrEditor from "#civicsignalblog/payload/access/isAdminOrEditor"; import CustomPageHeader from "#civicsignalblog/payload/blocks/CustomPageHeader"; import Error from "#civicsignalblog/payload/blocks/Error"; import FeaturedStories from "#civicsignalblog/payload/blocks/FeaturedStories"; @@ -23,6 +24,9 @@ const Pages = pages({ ], access: { read: canRead, + update: isAdminOrEditor, + create: isAdminOrEditor, + delete: isAdminOrEditor, }, adminOptions: { description: "Research", diff --git a/apps/civicsignalblog/src/payload/collections/Research/Posts.js b/apps/civicsignalblog/src/payload/collections/Research/Posts.js index 0edd10398..0a796365b 100644 --- a/apps/civicsignalblog/src/payload/collections/Research/Posts.js +++ b/apps/civicsignalblog/src/payload/collections/Research/Posts.js @@ -1,4 +1,5 @@ import canRead from "#civicsignalblog/payload/access/applications/research"; +import isAdminOrEditor from "#civicsignalblog/payload/access/isAdminOrEditor"; import authors from "#civicsignalblog/payload/fields/authors"; import content from "#civicsignalblog/payload/fields/content"; import image from "#civicsignalblog/payload/fields/image"; @@ -19,6 +20,9 @@ const Posts = { }, access: { read: canRead, + update: isAdminOrEditor, + create: isAdminOrEditor, + delete: isAdminOrEditor, }, admin: { defaultColumns: ["title", "authors", "publishedOn"], diff --git a/apps/civicsignalblog/src/payload/collections/Research/Tags.js b/apps/civicsignalblog/src/payload/collections/Research/Tags.js index e2c29b87a..b3e23b49e 100644 --- a/apps/civicsignalblog/src/payload/collections/Research/Tags.js +++ b/apps/civicsignalblog/src/payload/collections/Research/Tags.js @@ -1,4 +1,5 @@ import canRead from "#civicsignalblog/payload/access/applications/research"; +import isAdminOrEditor from "#civicsignalblog/payload/access/isAdminOrEditor"; import slug from "#civicsignalblog/payload/fields/slug/index"; const Tags = { @@ -11,6 +12,9 @@ const Tags = { }, access: { read: canRead, + update: isAdminOrEditor, + create: isAdminOrEditor, + delete: isAdminOrEditor, }, fields: [ { From 0e6586cb98919bb1c3755818cda337195198b5c4 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Fri, 18 Oct 2024 13:06:47 +0300 Subject: [PATCH 18/67] fix: Add custom x-current-app header to list of allowed headers --- apps/civicsignalblog/payload.config.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/apps/civicsignalblog/payload.config.ts b/apps/civicsignalblog/payload.config.ts index e5a5db309..64c477838 100644 --- a/apps/civicsignalblog/payload.config.ts +++ b/apps/civicsignalblog/payload.config.ts @@ -1,3 +1,4 @@ +import { Request, Response, NextFunction } from 'express'; import path from "path"; import { buildConfig } from "payload/config"; @@ -38,6 +39,8 @@ const cors = ?.map((d) => d.trim()) ?.filter(Boolean) ?? []; +const customHeaders: string[] = [ 'x-current-app',]; + const csrf = process?.env?.PAYLOAD_CSRF?.split(",") ?.map((d) => d.trim()) @@ -155,4 +158,17 @@ export default buildConfig({ }), ] as any[], telemetry: process?.env?.NODE_ENV !== "production", + express: { + postMiddleware: [ + (_req: Request, res: Response, next: NextFunction) => { + const existingHeaders = res.getHeader("Access-Control-Allow-Headers") || ''; + const additionalHeaders = customHeaders.join(', '); + res.header( + "Access-Control-Allow-Headers", + `${existingHeaders}, ${additionalHeaders}` + ); + next(); + }, + ], + }, }); From b2a186c5b3c81189b2917b5e783a0987563c2acb Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Fri, 18 Oct 2024 13:07:57 +0300 Subject: [PATCH 19/67] chore: Fix formatting issues --- apps/civicsignalblog/payload.config.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/civicsignalblog/payload.config.ts b/apps/civicsignalblog/payload.config.ts index 64c477838..7bd60f2ec 100644 --- a/apps/civicsignalblog/payload.config.ts +++ b/apps/civicsignalblog/payload.config.ts @@ -1,4 +1,4 @@ -import { Request, Response, NextFunction } from 'express'; +import { Request, Response, NextFunction } from "express"; import path from "path"; import { buildConfig } from "payload/config"; @@ -39,7 +39,7 @@ const cors = ?.map((d) => d.trim()) ?.filter(Boolean) ?? []; -const customHeaders: string[] = [ 'x-current-app',]; +const customHeaders: string[] = ["x-current-app"]; const csrf = process?.env?.PAYLOAD_CSRF?.split(",") @@ -161,11 +161,12 @@ export default buildConfig({ express: { postMiddleware: [ (_req: Request, res: Response, next: NextFunction) => { - const existingHeaders = res.getHeader("Access-Control-Allow-Headers") || ''; - const additionalHeaders = customHeaders.join(', '); + const existingHeaders = + res.getHeader("Access-Control-Allow-Headers") || ""; + const additionalHeaders = customHeaders.join(", "); res.header( "Access-Control-Allow-Headers", - `${existingHeaders}, ${additionalHeaders}` + `${existingHeaders}, ${additionalHeaders}`, ); next(); }, From 8642b72757261833ee559d1aa121ca18bd842e7f Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Fri, 18 Oct 2024 14:11:35 +0300 Subject: [PATCH 20/67] Update apps/civicsignalblog/payload.config.ts Co-authored-by: Clemence Kyara --- apps/civicsignalblog/payload.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/civicsignalblog/payload.config.ts b/apps/civicsignalblog/payload.config.ts index 7bd60f2ec..b5f707704 100644 --- a/apps/civicsignalblog/payload.config.ts +++ b/apps/civicsignalblog/payload.config.ts @@ -39,7 +39,7 @@ const cors = ?.map((d) => d.trim()) ?.filter(Boolean) ?? []; -const customHeaders: string[] = ["x-current-app"]; +const customHeaders: string[] = ["CS-App"]; const csrf = process?.env?.PAYLOAD_CSRF?.split(",") From 9be202dfc3012db3ce4572bbaeafcc7c1b1e7f80 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Fri, 18 Oct 2024 14:11:54 +0300 Subject: [PATCH 21/67] Update apps/civicsignalblog/src/payload/access/canAccessApplication.js Co-authored-by: Clemence Kyara --- .../civicsignalblog/src/payload/access/canAccessApplication.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/civicsignalblog/src/payload/access/canAccessApplication.js b/apps/civicsignalblog/src/payload/access/canAccessApplication.js index f07513802..28ddfa61c 100644 --- a/apps/civicsignalblog/src/payload/access/canAccessApplication.js +++ b/apps/civicsignalblog/src/payload/access/canAccessApplication.js @@ -2,8 +2,7 @@ export default async function canAccessApplication(req, searchString) { const { user, headers } = req; if (user) { - const currentApp = headers["x-current-app"] || user.currentApp; - const app = currentApp || user.defaultApp; + const app = headers["CS-App"] || user.currentApp || user.defaultApp; return app === searchString.toLowerCase() && user.allowedApps.includes(app); } return false; From 0042654964c3e228db6e8c8c1736fab44ec9e7e2 Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Fri, 18 Oct 2024 14:12:19 +0300 Subject: [PATCH 22/67] Update apps/civicsignalblog/src/payload/collections/Main/MediaData.js Co-authored-by: Clemence Kyara --- apps/civicsignalblog/src/payload/collections/Main/MediaData.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/civicsignalblog/src/payload/collections/Main/MediaData.js b/apps/civicsignalblog/src/payload/collections/Main/MediaData.js index cc04d7b67..4960927df 100644 --- a/apps/civicsignalblog/src/payload/collections/Main/MediaData.js +++ b/apps/civicsignalblog/src/payload/collections/Main/MediaData.js @@ -36,7 +36,7 @@ const MediaData = { }), document({ overrides: { - name: "mediaDataDocument", + name: "document", required: true, }, }), From 05a8c4787934581ae87a3c9fd0c3ea6569f1de1a Mon Sep 17 00:00:00 2001 From: Michael Hudson Nkotagu Date: Fri, 18 Oct 2024 14:40:32 +0300 Subject: [PATCH 23/67] chore: Improve field names in MediaData and removed unecessary ref in PageHeader --- apps/civicsignalblog/payload.config.ts | 1 + apps/civicsignalblog/src/components/PageHeader/PageHeader.js | 1 - apps/civicsignalblog/src/payload/collections/Main/MediaData.js | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/civicsignalblog/payload.config.ts b/apps/civicsignalblog/payload.config.ts index b5f707704..b9a0673a7 100644 --- a/apps/civicsignalblog/payload.config.ts +++ b/apps/civicsignalblog/payload.config.ts @@ -158,6 +158,7 @@ export default buildConfig({ }), ] as any[], telemetry: process?.env?.NODE_ENV !== "production", + // We need to add a postMiddleware function to add support for custom headers in Payload express: { postMiddleware: [ (_req: Request, res: Response, next: NextFunction) => { diff --git a/apps/civicsignalblog/src/components/PageHeader/PageHeader.js b/apps/civicsignalblog/src/components/PageHeader/PageHeader.js index 34b105bff..c5d3e039c 100644 --- a/apps/civicsignalblog/src/components/PageHeader/PageHeader.js +++ b/apps/civicsignalblog/src/components/PageHeader/PageHeader.js @@ -33,7 +33,6 @@ const PageHeader = React.forwardRef(function PageHeader(props, ref) { {title} Date: Fri, 18 Oct 2024 14:55:30 +0300 Subject: [PATCH 24/67] Add default location to HURUMap config --- .../src/pages/api/hurumap/profiles.js | 25 +++++++++++ .../src/payload/fields/LocationSelect.js | 43 +++++++++++++++++++ .../src/payload/globals/HURUMap/index.js | 34 +++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 apps/climatemappedafrica/src/pages/api/hurumap/profiles.js create mode 100644 apps/climatemappedafrica/src/payload/fields/LocationSelect.js diff --git a/apps/climatemappedafrica/src/pages/api/hurumap/profiles.js b/apps/climatemappedafrica/src/pages/api/hurumap/profiles.js new file mode 100644 index 000000000..ae3ff17a5 --- /dev/null +++ b/apps/climatemappedafrica/src/pages/api/hurumap/profiles.js @@ -0,0 +1,25 @@ +import { fetchProfile } from "@/climatemappedafrica/lib/hurumap"; + +let cache = null; +let cacheExpiry = 0; + +export default async function handler(req, res) { + if (req.method === "GET") { + const now = Date.now(); + + if (cache && now < cacheExpiry) { + return res.status(200).json(cache); + } + + try { + const result = await fetchProfile(); + cache = result; + cacheExpiry = now + 5 * 60 * 1000; + return res.status(200).json(result); + } catch (err) { + return res.status(500).json(err.message); + } + } + + return res.status(405).end(); +} diff --git a/apps/climatemappedafrica/src/payload/fields/LocationSelect.js b/apps/climatemappedafrica/src/payload/fields/LocationSelect.js new file mode 100644 index 000000000..5e6e3bf94 --- /dev/null +++ b/apps/climatemappedafrica/src/payload/fields/LocationSelect.js @@ -0,0 +1,43 @@ +import { Select } from "payload/components/forms"; +import { select } from "payload/dist/fields/validations"; +import { createElement, useMemo } from "react"; +import useSWR from "swr"; + +const fetcher = (url) => fetch(url).then((res) => res.json()); +const apiUrl = process.env.PAYLOAD_PUBLIC_APP_URL; + +export async function validateLocation(value, { hasMany, required, t }) { + const response = await fetch(`${apiUrl}/api/hurumap/profiles`); + const data = await response.json(); + const { locations } = data ?? {}; + const options = + locations + ?.filter(({ level }) => level !== "region") + ?.map((location) => ({ + label: location.name, + value: location.code, + })) || []; + return select(value, { hasMany, options, required, t }); +} + +function LocationSelect(props) { + const url = `${apiUrl}/api/hurumap/profiles`; + const { data } = useSWR(url, fetcher, { + dedupingInterval: 60000, + revalidateOnFocus: false, + }); + const { locations } = data ?? {}; + const memoOptions = () => + ( + locations + ?.filter(({ level }) => level !== "region") + ?.map((location) => ({ + label: location.name, + value: location.code, + })) || [] + ).sort((a, b) => a.label.localeCompare(b.label)); + const options = useMemo(memoOptions, [locations]); + return createElement(Select, { ...props, options }); +} + +export default LocationSelect; diff --git a/apps/climatemappedafrica/src/payload/globals/HURUMap/index.js b/apps/climatemappedafrica/src/payload/globals/HURUMap/index.js index 6a6592f31..3e3e9cc55 100644 --- a/apps/climatemappedafrica/src/payload/globals/HURUMap/index.js +++ b/apps/climatemappedafrica/src/payload/globals/HURUMap/index.js @@ -1,11 +1,15 @@ +import LocationSelect, { validateLocation } from "../../fields/LocationSelect"; + const HURUMap = { slug: "settings-hurumap", label: "HURUMap", + description: "HURUMap Configuration", access: { read: () => true, }, admin: { group: "Settings", + hideAPIURL: true, }, fields: [ { @@ -15,6 +19,36 @@ const HURUMap = { relationTo: ["pages"], maxDepth: 1, required: true, + admin: { + description: + "The page to use as the Explore page. It will contain the interactive map.", + }, + }, + { + name: "initialLocation", + label: "Initial Location", + type: "group", + fields: [ + { + name: "name", + type: "text", + required: true, + hasMany: false, + defaultValue: "af", + validate: validateLocation, + admin: { + components: { + Field: LocationSelect, + }, + }, + }, + { + name: "center", + label: "Center Point", + type: "point", + defaultValue: [0.3051933453207569, 37.908818734483155], + }, + ], }, ], }; From 852494c6fbca0baeff2cba6344e4570788a51066 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:01:37 +0300 Subject: [PATCH 25/67] Improve LocationSelect --- .../src/payload/fields/LocationSelect.js | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/apps/climatemappedafrica/src/payload/fields/LocationSelect.js b/apps/climatemappedafrica/src/payload/fields/LocationSelect.js index 5e6e3bf94..293f4b762 100644 --- a/apps/climatemappedafrica/src/payload/fields/LocationSelect.js +++ b/apps/climatemappedafrica/src/payload/fields/LocationSelect.js @@ -3,40 +3,37 @@ import { select } from "payload/dist/fields/validations"; import { createElement, useMemo } from "react"; import useSWR from "swr"; -const fetcher = (url) => fetch(url).then((res) => res.json()); const apiUrl = process.env.PAYLOAD_PUBLIC_APP_URL; +const fetcher = (url) => fetch(url).then((res) => res.json()); + +const getOptions = (locations) => + locations + ?.filter(({ level }) => level !== "region") + ?.map((location) => ({ + label: location.name, + value: location.code, + })) || []; export async function validateLocation(value, { hasMany, required, t }) { - const response = await fetch(`${apiUrl}/api/hurumap/profiles`); - const data = await response.json(); - const { locations } = data ?? {}; - const options = - locations - ?.filter(({ level }) => level !== "region") - ?.map((location) => ({ - label: location.name, - value: location.code, - })) || []; + const data = await fetcher(`${apiUrl}/api/hurumap/profiles`); + const options = getOptions(data.locations); return select(value, { hasMany, options, required, t }); } function LocationSelect(props) { - const url = `${apiUrl}/api/hurumap/profiles`; - const { data } = useSWR(url, fetcher, { + const { data } = useSWR(`${apiUrl}/api/hurumap/profiles`, fetcher, { dedupingInterval: 60000, revalidateOnFocus: false, }); - const { locations } = data ?? {}; - const memoOptions = () => - ( - locations - ?.filter(({ level }) => level !== "region") - ?.map((location) => ({ - label: location.name, - value: location.code, - })) || [] - ).sort((a, b) => a.label.localeCompare(b.label)); - const options = useMemo(memoOptions, [locations]); + + const options = useMemo( + () => + getOptions(data?.locations).sort((a, b) => + a.label.localeCompare(b.label), + ), + [data], + ); + return createElement(Select, { ...props, options }); } From 61e80740702961098aa755a993cde21e2dfcd1b2 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:55:32 +0300 Subject: [PATCH 26/67] Working Explore Page --- .../src/lib/data/blockify/explore-page.js | 181 ++++++++++++++++++ .../src/lib/data/blockify/index.js | 2 + .../src/lib/data/common/index.js | 22 ++- .../src/pages/[[...slug]].js | 2 + 4 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 apps/climatemappedafrica/src/lib/data/blockify/explore-page.js diff --git a/apps/climatemappedafrica/src/lib/data/blockify/explore-page.js b/apps/climatemappedafrica/src/lib/data/blockify/explore-page.js new file mode 100644 index 000000000..a3a432129 --- /dev/null +++ b/apps/climatemappedafrica/src/lib/data/blockify/explore-page.js @@ -0,0 +1,181 @@ +const apiUrl = process.env.PAYLOAD_PUBLIC_APP_URL; +const fetcher = (url) => fetch(url).then((res) => res.json()); + +const fetchProfile = async () => { + const data = await fetcher(`${apiUrl}/api/hurumap/profiles`); + return data; +}; + +const fetchProfileGeography = async (geoCode) => { + const data = await fetcher(`${apiUrl}/api/hurumap/geographies/${geoCode}`); + return data; +}; + +async function explorePage({ slug: code, center }) { + const hurumapProfile = await fetchProfile(); + + const { locations, preferredChildren, mapType, choropleth } = hurumapProfile; + + const locationCodes = locations.map(({ code: locationCode }) => locationCode); + const geoCodes = code + .split("-vs-") + .map((c) => c.trim()) + .filter((c) => c); + if (!geoCodes.every((gC) => locationCodes.includes(gC))) { + return { + notFound: true, + }; + } + + const [primaryCode, secondaryCode] = geoCodes; + const primaryProfile = await fetchProfileGeography(primaryCode); + const profile = [primaryProfile]; + if (secondaryCode) { + const secondaryProfile = await fetchProfileGeography(secondaryCode); + profile.push(secondaryProfile); + } + + // TODO: Move this to a PayloadCMS + const blocks = { + texts: [], + tutorial: { + items: [ + { + title: "SELECT LOCATION", + description: + "Select the County or Municipality you want to explore, by clicking on the search field and the dropdown menu.

Once you have made your selection, explore the visualisations, change location or pin to compare it to a second location.", + selector: "#location-search", + image: + "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-1.png", + imageProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-1.png", + width: 694, + height: 572, + type: "png", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMElEQVR4nGOoqW09f/7Shw8fzp07x8AuoC4qqdXf311YWMTAL6YVE5ve2tpcV18PAHqlETRE6fa/AAAAAElFTkSuQmCC", + placeholder: "blur", + }, + }, + { + description: + "Explore the map to confirm or change your selection. You can also pin your location if you want to compare two places.

Once a location is confirmed, click on the “Rich Data” button (on the left hand-side) to display the data visualisations.", + title: "EXPLORE THE MAP", + selector: "#none", + image: + "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-2.png", + imageProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-2.png", + width: 751, + height: 589, + type: "png", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMElEQVR4nGP49u3rxEnTDxw4sn//fobCggJeYVU+YaWCvByGzMxMPmElWwfPgvw8AH1vD9GRbZHGAAAAAElFTkSuQmCC", + placeholder: "blur", + }, + }, + { + title: "BROWSE THE CHARTS", + description: + "Continue to open the Rich Data dashboard, using the button on the left.

Browse the charts by scrolling the data dashboard. You can share and download the data using the buttons on the side of each chart.", + selector: "#rich-data", + image: + "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-3a.png", + imageProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-3a.png", + width: 670, + height: 439, + type: "png", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMklEQVR4nAEnANj/ANbW1s3NyVtbWrKyswDOztFdY38JCxe5ubcA3t7ffIKf4uPq////vgcX8ZIA2dgAAAAASUVORK5CYII=", + placeholder: "blur", + }, + }, + { + title: "PIN AND COMPARE", + description: + "There are two ways to pin and compare a second location:

1) From the data dashboard: look for the “pin” icon and select a second location from the dropdown menu.

2) From the map: pin your selected location by clicking on the ”pin” icon, then select a second location, which will appear in a different colour.", + selector: "#pin", + image: + "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-4.png", + imageProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-4.png", + width: 675, + height: 491, + type: "png", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMklEQVR4nAEnANj/APj491lWYA8QI+zs6wC/wMHXzMmLi5uztLYAu7u7w8XF39/eu7u7x7oYwYnBuWcAAAAASUVORK5CYII=", + placeholder: "blur", + }, + }, + ], + lazyblock: { + slug: "lazyblock/tutorial", + }, + align: "", + anchor: "", + blockId: "Z1npKaH", + blockUniqueClass: "lazyblock-tutorial-Z1npKaH", + ghostkitSpacings: "", + ghostkitSR: "", + }, + panel: { + panelItems: [ + { + value: "rich-data", + icon: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2021/11/Group-4505.svg", + iconProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2021/11/Group-4505.svg", + width: 44, + height: 44, + type: "svg", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGElEQVR4nGNgQAP/T///f/o/jHMWiQMHACIVCyeABSwfAAAAAElFTkSuQmCC", + placeholder: "blur", + }, + }, + { + value: "pin", + icon: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/01/Path-210-1-1.svg", + pin: true, + iconProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/01/Path-210-1-1.svg", + width: 44, + height: 44, + type: "svg", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAH0lEQVR4nGNgQAP/L/z/f/r//4P/wZzT//+fBbOQAQBvnQ3r6iVM4QAAAABJRU5ErkJggg==", + placeholder: "blur", + }, + }, + ], + scrollToTopLabel: "Back To Top", + dataNotAvailable: "— DATA NOT AVAILABLE", + lazyblock: { + slug: "lazyblock/panel", + }, + align: "", + anchor: "", + blockId: "20amuc", + blockUniqueClass: "lazyblock-panel-20amuc", + ghostkitSpacings: "", + ghostkitSR: "", + }, + }; + + const res = { + blockType: "explore-page", + blocks, + center, + choropleth, + locations, + mapType, + profile, + variant: "explore", + preferredChildren, + }; + + return res; +} + +export default explorePage; diff --git a/apps/climatemappedafrica/src/lib/data/blockify/index.js b/apps/climatemappedafrica/src/lib/data/blockify/index.js index 07d61107f..39df28c48 100644 --- a/apps/climatemappedafrica/src/lib/data/blockify/index.js +++ b/apps/climatemappedafrica/src/lib/data/blockify/index.js @@ -1,7 +1,9 @@ +import explorePage from "./explore-page"; import pageHero from "./page-hero"; import team from "./team"; const propsifyBlockBySlug = { + "explore-page": explorePage, "page-hero": pageHero, team, }; diff --git a/apps/climatemappedafrica/src/lib/data/common/index.js b/apps/climatemappedafrica/src/lib/data/common/index.js index ab0341049..7afcf048e 100644 --- a/apps/climatemappedafrica/src/lib/data/common/index.js +++ b/apps/climatemappedafrica/src/lib/data/common/index.js @@ -53,6 +53,22 @@ function getNavBar(siteSettings, variant) { }; } +async function processExplorePage(slugs, hurumap) { + const { + initialLocation: { name, center }, + } = hurumap; + const slug = slugs.length ? slugs[0] : name; + const blocks = await blockify([ + { + blockType: "explore-page", + center, + slug: slug.trim().toLowerCase(), + }, + ]); + + return blocks; +} + export async function getPageProps(api, context) { // For now, ClimatemappedAfrica only supports single paths i.e. /, /about, etc., // so params.slug[0] is good enough @@ -74,13 +90,17 @@ export async function getPageProps(api, context) { page: { value: explorePage }, } = hurumap; - const blocks = await blockify(page.blocks, api, context); + let blocks = await blockify(page.blocks, api, context); const variant = page.slug === explorePage.slug ? "explore" : "default"; const siteSettings = await api.findGlobal("settings-site"); const footer = getFooter(siteSettings, variant); const menus = getNavBar(siteSettings, variant); + if (slug === explorePage.slug) { + blocks = await processExplorePage(slugs.slice(1), hurumap); + } + return { blocks, footer, diff --git a/apps/climatemappedafrica/src/pages/[[...slug]].js b/apps/climatemappedafrica/src/pages/[[...slug]].js index d5b79793e..2be1812c3 100644 --- a/apps/climatemappedafrica/src/pages/[[...slug]].js +++ b/apps/climatemappedafrica/src/pages/[[...slug]].js @@ -3,6 +3,7 @@ import React from "react"; import { SWRConfig } from "swr"; import AboutTeam from "@/climatemappedafrica/components/AboutTeam"; +import ExplorePage from "@/climatemappedafrica/components/ExplorePage"; import Footer from "@/climatemappedafrica/components/Footer"; import Navigation from "@/climatemappedafrica/components/Navigation"; import PageHero from "@/climatemappedafrica/components/PageHero"; @@ -10,6 +11,7 @@ import Summary from "@/climatemappedafrica/components/Summary"; import { getPageServerSideProps } from "@/climatemappedafrica/lib/data"; const componentsBySlugs = { + "explore-page": ExplorePage, "page-hero": PageHero, summary: Summary, team: AboutTeam, From acb6cab656e83addbbd4e54469dc846a7d86a697 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:46:16 +0300 Subject: [PATCH 27/67] Show tutorial --- .../src/components/ExplorePage/index.js | 9 +- .../src/lib/data/blockify/explore-page.js | 160 +++++------------- .../src/lib/data/blockify/index.js | 2 + .../src/lib/data/blockify/tutorial.js | 88 ++++++++++ .../src/lib/data/common/index.js | 3 + .../src/pages/[[...slug]].js | 21 ++- 6 files changed, 156 insertions(+), 127 deletions(-) create mode 100644 apps/climatemappedafrica/src/lib/data/blockify/tutorial.js diff --git a/apps/climatemappedafrica/src/components/ExplorePage/index.js b/apps/climatemappedafrica/src/components/ExplorePage/index.js index 20c977918..792ace1b6 100644 --- a/apps/climatemappedafrica/src/components/ExplorePage/index.js +++ b/apps/climatemappedafrica/src/components/ExplorePage/index.js @@ -21,7 +21,11 @@ function initialState(profiles, onClick) { }; } -function ExplorePage({ panelProps, profile: profileProp, apiUri, ...props }) { +function ExplorePage({ + panel: panelProps = {}, + profile: profileProp, + ...props +}) { const theme = useTheme(); const classes = useStyles(props); // NOTE: This setState and the corresponding useEffect are "hacks" since at @@ -166,8 +170,7 @@ function ExplorePage({ panelProps, profile: profileProp, apiUri, ...props }) { } ExplorePage.propTypes = { - apiUri: PropTypes.string, - panelProps: PropTypes.shape({}), + panel: PropTypes.shape({}), profile: PropTypes.oneOfType([ PropTypes.shape({ geography: PropTypes.shape({}), diff --git a/apps/climatemappedafrica/src/lib/data/blockify/explore-page.js b/apps/climatemappedafrica/src/lib/data/blockify/explore-page.js index a3a432129..36a7a17cc 100644 --- a/apps/climatemappedafrica/src/lib/data/blockify/explore-page.js +++ b/apps/climatemappedafrica/src/lib/data/blockify/explore-page.js @@ -36,140 +36,56 @@ async function explorePage({ slug: code, center }) { } // TODO: Move this to a PayloadCMS - const blocks = { - texts: [], - tutorial: { - items: [ - { - title: "SELECT LOCATION", - description: - "Select the County or Municipality you want to explore, by clicking on the search field and the dropdown menu.

Once you have made your selection, explore the visualisations, change location or pin to compare it to a second location.", - selector: "#location-search", - image: - "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-1.png", - imageProps: { - src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-1.png", - width: 694, - height: 572, - type: "png", - blurDataURL: - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMElEQVR4nGOoqW09f/7Shw8fzp07x8AuoC4qqdXf311YWMTAL6YVE5ve2tpcV18PAHqlETRE6fa/AAAAAElFTkSuQmCC", - placeholder: "blur", - }, + const panel = { + panelItems: [ + { + value: "rich-data", + icon: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2021/11/Group-4505.svg", + iconProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2021/11/Group-4505.svg", + width: 44, + height: 44, + type: "svg", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGElEQVR4nGNgQAP/T///f/o/jHMWiQMHACIVCyeABSwfAAAAAElFTkSuQmCC", + placeholder: "blur", }, - { - description: - "Explore the map to confirm or change your selection. You can also pin your location if you want to compare two places.

Once a location is confirmed, click on the “Rich Data” button (on the left hand-side) to display the data visualisations.", - title: "EXPLORE THE MAP", - selector: "#none", - image: - "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-2.png", - imageProps: { - src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-2.png", - width: 751, - height: 589, - type: "png", - blurDataURL: - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMElEQVR4nGP49u3rxEnTDxw4sn//fobCggJeYVU+YaWCvByGzMxMPmElWwfPgvw8AH1vD9GRbZHGAAAAAElFTkSuQmCC", - placeholder: "blur", - }, - }, - { - title: "BROWSE THE CHARTS", - description: - "Continue to open the Rich Data dashboard, using the button on the left.

Browse the charts by scrolling the data dashboard. You can share and download the data using the buttons on the side of each chart.", - selector: "#rich-data", - image: - "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-3a.png", - imageProps: { - src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-3a.png", - width: 670, - height: 439, - type: "png", - blurDataURL: - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMklEQVR4nAEnANj/ANbW1s3NyVtbWrKyswDOztFdY38JCxe5ubcA3t7ffIKf4uPq////vgcX8ZIA2dgAAAAASUVORK5CYII=", - placeholder: "blur", - }, - }, - { - title: "PIN AND COMPARE", - description: - "There are two ways to pin and compare a second location:

1) From the data dashboard: look for the “pin” icon and select a second location from the dropdown menu.

2) From the map: pin your selected location by clicking on the ”pin” icon, then select a second location, which will appear in a different colour.", - selector: "#pin", - image: - "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-4.png", - imageProps: { - src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-4.png", - width: 675, - height: 491, - type: "png", - blurDataURL: - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMklEQVR4nAEnANj/APj491lWYA8QI+zs6wC/wMHXzMmLi5uztLYAu7u7w8XF39/eu7u7x7oYwYnBuWcAAAAASUVORK5CYII=", - placeholder: "blur", - }, - }, - ], - lazyblock: { - slug: "lazyblock/tutorial", }, - align: "", - anchor: "", - blockId: "Z1npKaH", - blockUniqueClass: "lazyblock-tutorial-Z1npKaH", - ghostkitSpacings: "", - ghostkitSR: "", - }, - panel: { - panelItems: [ - { - value: "rich-data", - icon: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2021/11/Group-4505.svg", - iconProps: { - src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2021/11/Group-4505.svg", - width: 44, - height: 44, - type: "svg", - blurDataURL: - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGElEQVR4nGNgQAP/T///f/o/jHMWiQMHACIVCyeABSwfAAAAAElFTkSuQmCC", - placeholder: "blur", - }, - }, - { - value: "pin", - icon: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/01/Path-210-1-1.svg", - pin: true, - iconProps: { - src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/01/Path-210-1-1.svg", - width: 44, - height: 44, - type: "svg", - blurDataURL: - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAH0lEQVR4nGNgQAP/L/z/f/r//4P/wZzT//+fBbOQAQBvnQ3r6iVM4QAAAABJRU5ErkJggg==", - placeholder: "blur", - }, + { + value: "pin", + icon: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/01/Path-210-1-1.svg", + pin: true, + iconProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/01/Path-210-1-1.svg", + width: 44, + height: 44, + type: "svg", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAH0lEQVR4nGNgQAP/L/z/f/r//4P/wZzT//+fBbOQAQBvnQ3r6iVM4QAAAABJRU5ErkJggg==", + placeholder: "blur", }, - ], - scrollToTopLabel: "Back To Top", - dataNotAvailable: "— DATA NOT AVAILABLE", - lazyblock: { - slug: "lazyblock/panel", }, - align: "", - anchor: "", - blockId: "20amuc", - blockUniqueClass: "lazyblock-panel-20amuc", - ghostkitSpacings: "", - ghostkitSR: "", + ], + scrollToTopLabel: "Back To Top", + dataNotAvailable: "— DATA NOT AVAILABLE", + lazyblock: { + slug: "lazyblock/panel", }, + align: "", + anchor: "", + blockId: "20amuc", + blockUniqueClass: "lazyblock-panel-20amuc", + ghostkitSpacings: "", + ghostkitSR: "", }; - const res = { + id: "explore-page", blockType: "explore-page", - blocks, center, choropleth, locations, mapType, + panel, profile, variant: "explore", preferredChildren, diff --git a/apps/climatemappedafrica/src/lib/data/blockify/index.js b/apps/climatemappedafrica/src/lib/data/blockify/index.js index 39df28c48..9e91332ea 100644 --- a/apps/climatemappedafrica/src/lib/data/blockify/index.js +++ b/apps/climatemappedafrica/src/lib/data/blockify/index.js @@ -1,11 +1,13 @@ import explorePage from "./explore-page"; import pageHero from "./page-hero"; import team from "./team"; +import tutorial from "./tutorial"; const propsifyBlockBySlug = { "explore-page": explorePage, "page-hero": pageHero, team, + tutorial, }; export const blockify = async (blocks, api, context) => { diff --git a/apps/climatemappedafrica/src/lib/data/blockify/tutorial.js b/apps/climatemappedafrica/src/lib/data/blockify/tutorial.js new file mode 100644 index 000000000..781934ccc --- /dev/null +++ b/apps/climatemappedafrica/src/lib/data/blockify/tutorial.js @@ -0,0 +1,88 @@ +async function tutorial() { + // TODO: Move this to Payload CMS + return { + blockType: "tutorial", + id: "tutorial", + items: [ + { + title: "SELECT LOCATION", + description: + "Select the County or Municipality you want to explore, by clicking on the search field and the dropdown menu.

Once you have made your selection, explore the visualisations, change location or pin to compare it to a second location.", + selector: "#location-search", + image: + "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-1.png", + imageProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-1.png", + width: 694, + height: 572, + type: "png", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMElEQVR4nGOoqW09f/7Shw8fzp07x8AuoC4qqdXf311YWMTAL6YVE5ve2tpcV18PAHqlETRE6fa/AAAAAElFTkSuQmCC", + placeholder: "blur", + }, + }, + { + description: + "Explore the map to confirm or change your selection. You can also pin your location if you want to compare two places.

Once a location is confirmed, click on the “Rich Data” button (on the left hand-side) to display the data visualisations.", + title: "EXPLORE THE MAP", + selector: "#none", + image: + "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-2.png", + imageProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-2.png", + width: 751, + height: 589, + type: "png", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMElEQVR4nGP49u3rxEnTDxw4sn//fobCggJeYVU+YaWCvByGzMxMPmElWwfPgvw8AH1vD9GRbZHGAAAAAElFTkSuQmCC", + placeholder: "blur", + }, + }, + { + title: "BROWSE THE CHARTS", + description: + "Continue to open the Rich Data dashboard, using the button on the left.

Browse the charts by scrolling the data dashboard. You can share and download the data using the buttons on the side of each chart.", + selector: "#rich-data", + image: + "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-3a.png", + imageProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-3a.png", + width: 670, + height: 439, + type: "png", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMklEQVR4nAEnANj/ANbW1s3NyVtbWrKyswDOztFdY38JCxe5ubcA3t7ffIKf4uPq////vgcX8ZIA2dgAAAAASUVORK5CYII=", + placeholder: "blur", + }, + }, + { + title: "PIN AND COMPARE", + description: + "There are two ways to pin and compare a second location:

1) From the data dashboard: look for the “pin” icon and select a second location from the dropdown menu.

2) From the map: pin your selected location by clicking on the ”pin” icon, then select a second location, which will appear in a different colour.", + selector: "#pin", + image: + "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-4.png", + imageProps: { + src: "https://cms.dev.codeforafrica.org/pesayetu/wp-content/uploads/sites/2/2022/04/PesaYetu-Tutorial-4.png", + width: 675, + height: 491, + type: "png", + blurDataURL: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAMklEQVR4nAEnANj/APj491lWYA8QI+zs6wC/wMHXzMmLi5uztLYAu7u7w8XF39/eu7u7x7oYwYnBuWcAAAAASUVORK5CYII=", + placeholder: "blur", + }, + }, + ], + lazyblock: { + slug: "lazyblock/tutorial", + }, + align: "", + anchor: "", + blockId: "Z1npKaH", + blockUniqueClass: "lazyblock-tutorial-Z1npKaH", + ghostkitSpacings: "", + ghostkitSR: "", + }; +} + +export default tutorial; diff --git a/apps/climatemappedafrica/src/lib/data/common/index.js b/apps/climatemappedafrica/src/lib/data/common/index.js index 7afcf048e..5c76cd59d 100644 --- a/apps/climatemappedafrica/src/lib/data/common/index.js +++ b/apps/climatemappedafrica/src/lib/data/common/index.js @@ -64,6 +64,9 @@ async function processExplorePage(slugs, hurumap) { center, slug: slug.trim().toLowerCase(), }, + { + blockType: "tutorial", + }, ]); return blocks; diff --git a/apps/climatemappedafrica/src/pages/[[...slug]].js b/apps/climatemappedafrica/src/pages/[[...slug]].js index 2be1812c3..471d852dc 100644 --- a/apps/climatemappedafrica/src/pages/[[...slug]].js +++ b/apps/climatemappedafrica/src/pages/[[...slug]].js @@ -1,3 +1,4 @@ +import { useRouter } from "next/router"; import { NextSeo } from "next-seo"; import React from "react"; import { SWRConfig } from "swr"; @@ -5,6 +6,7 @@ import { SWRConfig } from "swr"; import AboutTeam from "@/climatemappedafrica/components/AboutTeam"; import ExplorePage from "@/climatemappedafrica/components/ExplorePage"; import Footer from "@/climatemappedafrica/components/Footer"; +import Tutorial from "@/climatemappedafrica/components/HURUmap/Tutorial"; import Navigation from "@/climatemappedafrica/components/Navigation"; import PageHero from "@/climatemappedafrica/components/PageHero"; import Summary from "@/climatemappedafrica/components/Summary"; @@ -18,6 +20,10 @@ const componentsBySlugs = { }; function Index({ blocks, menus, footer: footerProps, seo = {}, fallback }) { + const { + query: { showTutorial }, + } = useRouter(); + const pageSeo = {}; pageSeo.title = seo?.title || null; pageSeo.description = seo?.metaDesc || null; @@ -37,6 +43,13 @@ function Index({ blocks, menus, footer: footerProps, seo = {}, fallback }) { } } + const tutorialBlock = blocks.find((block) => block.blockType === "tutorial"); + + let TutorialComponent = React.Fragment; + if (tutorialBlock) { + TutorialComponent = Tutorial; + } + let PageConfig = React.Fragment; let pageConfigProps; if (fallback) { @@ -44,7 +57,11 @@ function Index({ blocks, menus, footer: footerProps, seo = {}, fallback }) { pageConfigProps = { value: { fallback } }; } return ( - <> +