From 4f09a2b0ca75b6286c14aef96dcde026012e8251 Mon Sep 17 00:00:00 2001
From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com>
Date: Tue, 8 Oct 2024 14:48:39 +0300
Subject: [PATCH 1/9] Initialise site settings
---
apps/climatemappedafrica/next.config.js | 14 --
apps/climatemappedafrica/payload.config.ts | 4 +-
.../src/lib/data/blockify/index.js | 23 +++
.../src/lib/data/common/index.js | 29 ++++
.../climatemappedafrica/src/lib/data/index.js | 3 +
.../src/lib/data/local/index.js | 15 ++
apps/climatemappedafrica/src/lib/index.js | 3 +
.../src/lib/payload/index.js | 64 ++++++++
.../src/pages/[[...slug]].js | 14 ++
.../src/payload/fields/image.js | 16 ++
.../src/payload/fields/links/link.js | 149 ++++++++++++++++++
.../src/payload/fields/links/linkArray.js | 27 ++++
.../src/payload/fields/links/linkGroup.js | 20 +++
.../src/payload/fields/richText.js | 60 +++++++
.../src/payload/fields/socialLinks.js | 81 ++++++++++
.../src/payload/fields/url.js | 25 +++
.../src/payload/globals/site/EngagementTab.js | 82 ++++++++++
.../src/payload/globals/site/GeneralTab.js | 53 +++++++
.../src/payload/globals/site/InitiativeTab.js | 57 +++++++
.../src/payload/globals/site/NavigationTab.js | 80 ++++++++++
.../src/payload/globals/site/index.js | 23 +++
.../src/payload/utils/mapLinkTypeToHref.js | 18 +++
22 files changed, 845 insertions(+), 15 deletions(-)
create mode 100644 apps/climatemappedafrica/src/lib/data/blockify/index.js
create mode 100644 apps/climatemappedafrica/src/lib/data/common/index.js
create mode 100644 apps/climatemappedafrica/src/lib/data/index.js
create mode 100644 apps/climatemappedafrica/src/lib/data/local/index.js
create mode 100644 apps/climatemappedafrica/src/lib/index.js
create mode 100644 apps/climatemappedafrica/src/lib/payload/index.js
create mode 100644 apps/climatemappedafrica/src/pages/[[...slug]].js
create mode 100644 apps/climatemappedafrica/src/payload/fields/image.js
create mode 100644 apps/climatemappedafrica/src/payload/fields/links/link.js
create mode 100644 apps/climatemappedafrica/src/payload/fields/links/linkArray.js
create mode 100644 apps/climatemappedafrica/src/payload/fields/links/linkGroup.js
create mode 100644 apps/climatemappedafrica/src/payload/fields/richText.js
create mode 100644 apps/climatemappedafrica/src/payload/fields/socialLinks.js
create mode 100644 apps/climatemappedafrica/src/payload/fields/url.js
create mode 100644 apps/climatemappedafrica/src/payload/globals/site/EngagementTab.js
create mode 100644 apps/climatemappedafrica/src/payload/globals/site/GeneralTab.js
create mode 100644 apps/climatemappedafrica/src/payload/globals/site/InitiativeTab.js
create mode 100644 apps/climatemappedafrica/src/payload/globals/site/NavigationTab.js
create mode 100644 apps/climatemappedafrica/src/payload/globals/site/index.js
create mode 100644 apps/climatemappedafrica/src/payload/utils/mapLinkTypeToHref.js
diff --git a/apps/climatemappedafrica/next.config.js b/apps/climatemappedafrica/next.config.js
index 2c50a972d..c282b8971 100644
--- a/apps/climatemappedafrica/next.config.js
+++ b/apps/climatemappedafrica/next.config.js
@@ -51,18 +51,4 @@ module.exports = {
};
return config;
},
- async redirects() {
- return [
- {
- source: "/",
- destination: "/explore/af",
- permanent: true,
- },
- {
- source: "/explore",
- destination: "/explore/af",
- permanent: true,
- },
- ];
- },
};
diff --git a/apps/climatemappedafrica/payload.config.ts b/apps/climatemappedafrica/payload.config.ts
index be284f509..91c734b5a 100644
--- a/apps/climatemappedafrica/payload.config.ts
+++ b/apps/climatemappedafrica/payload.config.ts
@@ -15,6 +15,8 @@ import Media from "./src/payload/collections/Media";
import Pages from "./src/payload/collections/Pages";
import Users from "./src/payload/collections/Users";
+import Site from "./src/payload/globals/Site";
+
const projectDir = process.cwd();
loadEnvConfig(projectDir);
@@ -52,7 +54,7 @@ export default buildConfig({
migrationDir: process.env.MIGRATIONS_DIR,
}),
collections: [Media, Pages, Users] as CollectionConfig[],
- globals: [] as GlobalConfig[],
+ globals: [Site] as GlobalConfig[],
...(locales?.length
? {
localization: {
diff --git a/apps/climatemappedafrica/src/lib/data/blockify/index.js b/apps/climatemappedafrica/src/lib/data/blockify/index.js
new file mode 100644
index 000000000..3d7836feb
--- /dev/null
+++ b/apps/climatemappedafrica/src/lib/data/blockify/index.js
@@ -0,0 +1,23 @@
+/* eslint-disable import/prefer-default-export */
+
+const propsifyBlockBySlug = {};
+
+export const blockify = async (blocks, api) => {
+ const promises = blocks?.map(async (block) => {
+ const slug = block.blockType;
+ const propsifyBlock = propsifyBlockBySlug[slug];
+
+ if (propsifyBlock) {
+ return propsifyBlock(block, api);
+ }
+ return {
+ ...block,
+ slug,
+ };
+ });
+
+ if (promises) {
+ return Promise.all(promises);
+ }
+ return blocks ?? null;
+};
diff --git a/apps/climatemappedafrica/src/lib/data/common/index.js b/apps/climatemappedafrica/src/lib/data/common/index.js
new file mode 100644
index 000000000..4025643d6
--- /dev/null
+++ b/apps/climatemappedafrica/src/lib/data/common/index.js
@@ -0,0 +1,29 @@
+/* eslint-disable import/prefer-default-export */
+
+import { blockify } from "@/climatemappedafrica/lib/data/blockify";
+
+export async function getPageProps(api, context) {
+ // For now, ClimatemappedAfrica only supports single paths i.e. /, /about, etc.,
+ // so params.slug[0] is good enough
+ const slugs = context.params?.slug || undefined;
+ const [slug] = slugs || ["index"];
+ const { draftMode = false } = context;
+ const options = { draft: draftMode };
+
+ const {
+ docs: [page],
+ } = await api.findPage(slug, options);
+
+ if (!page) {
+ return null;
+ }
+
+ const blocks = await blockify(page.blocks, api);
+
+ const siteSettings = await api.findGlobal("settings-site");
+
+ return {
+ blocks,
+ siteSettings,
+ };
+}
diff --git a/apps/climatemappedafrica/src/lib/data/index.js b/apps/climatemappedafrica/src/lib/data/index.js
new file mode 100644
index 000000000..c2ebe4abf
--- /dev/null
+++ b/apps/climatemappedafrica/src/lib/data/index.js
@@ -0,0 +1,3 @@
+/* eslint-disable import/prefer-default-export */
+
+export { getPageServerSideProps } from "./local";
diff --git a/apps/climatemappedafrica/src/lib/data/local/index.js b/apps/climatemappedafrica/src/lib/data/local/index.js
new file mode 100644
index 000000000..9b1693471
--- /dev/null
+++ b/apps/climatemappedafrica/src/lib/data/local/index.js
@@ -0,0 +1,15 @@
+import { payload } from "@/climatemappedafrica/lib";
+import { getPageProps } from "@/climatemappedafrica/lib/data/common";
+
+export const api = payload;
+
+export async function getPageServerSideProps(context) {
+ const props = await getPageProps(api, context);
+
+ if (!props) {
+ return { notFound: true };
+ }
+ return {
+ props,
+ };
+}
diff --git a/apps/climatemappedafrica/src/lib/index.js b/apps/climatemappedafrica/src/lib/index.js
new file mode 100644
index 000000000..7f94a740a
--- /dev/null
+++ b/apps/climatemappedafrica/src/lib/index.js
@@ -0,0 +1,3 @@
+/* eslint-disable import/prefer-default-export */
+
+export { default as payload } from "./payload";
diff --git a/apps/climatemappedafrica/src/lib/payload/index.js b/apps/climatemappedafrica/src/lib/payload/index.js
new file mode 100644
index 000000000..8bb041faf
--- /dev/null
+++ b/apps/climatemappedafrica/src/lib/payload/index.js
@@ -0,0 +1,64 @@
+import payload from "payload";
+
+async function findPage(slug, options) {
+ return payload.find({
+ ...options,
+ collection: "pages",
+ where: {
+ ...options?.where,
+ slug: {
+ equals: slug,
+ },
+ },
+ });
+}
+
+async function getCollection(collection, options) {
+ return payload.find({
+ limit: 0,
+ ...options,
+ collection,
+ });
+}
+
+async function findGlobal(slug, options) {
+ return payload.findGlobal({
+ ...options,
+ slug,
+ });
+}
+
+async function createCollection(collection, data, options) {
+ return payload.create({
+ collection,
+ data,
+ ...options,
+ });
+}
+
+async function deleteCollection(collection, options) {
+ return payload.delete({
+ ...options,
+ collection,
+ });
+}
+
+async function updateCollection(collection, id, data, options) {
+ const args = {
+ ...options,
+ collection,
+ id,
+ data,
+ };
+ return payload.update(args);
+}
+const api = {
+ createCollection,
+ deleteCollection,
+ findGlobal,
+ findPage,
+ getCollection,
+ updateCollection,
+};
+
+export default api;
diff --git a/apps/climatemappedafrica/src/pages/[[...slug]].js b/apps/climatemappedafrica/src/pages/[[...slug]].js
new file mode 100644
index 000000000..8b2d4afdc
--- /dev/null
+++ b/apps/climatemappedafrica/src/pages/[[...slug]].js
@@ -0,0 +1,14 @@
+import Page from "@/climatemappedafrica/components/Page";
+import { getPageServerSideProps } from "@/climatemappedafrica/lib/data";
+
+export default function Index(props) {
+ return (
+
+ Pahed
+
+ );
+}
+
+export async function getServerSideProps(context) {
+ return getPageServerSideProps(context);
+}
diff --git a/apps/climatemappedafrica/src/payload/fields/image.js b/apps/climatemappedafrica/src/payload/fields/image.js
new file mode 100644
index 000000000..8bf1e9c5b
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/fields/image.js
@@ -0,0 +1,16 @@
+import { deepmerge } from "@mui/utils";
+
+function image({ overrides = undefined }) {
+ const imageResult = {
+ name: "image",
+ type: "upload",
+ relationTo: "media",
+ filterOptions: {
+ mimeType: { contains: "image" },
+ },
+ };
+
+ return deepmerge(imageResult, overrides);
+}
+
+export default image;
diff --git a/apps/climatemappedafrica/src/payload/fields/links/link.js b/apps/climatemappedafrica/src/payload/fields/links/link.js
new file mode 100644
index 000000000..88d80d0a7
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/fields/links/link.js
@@ -0,0 +1,149 @@
+import { deepmerge } from "@mui/utils";
+
+import mapLinkTypeToHref from "../../utils/mapLinkTypeToHref";
+
+export async function mapLinkToHrefBeforeValidate({
+ siblingData,
+ req: { payload },
+}) {
+ // Don't modify original doc.
+ const doc = { ...siblingData.doc };
+ if (typeof doc.value === "string") {
+ const { relationTo: collection, value: id } = doc;
+ doc.value = await payload.findByID({
+ collection,
+ id,
+ // We only need slug from the collection don't expand the whole
+ // relationship. We may end up getting stuck on infinite recursion if
+ // collection contain other links.
+ depth: 0,
+ });
+ }
+ const href = mapLinkTypeToHref({ ...siblingData, doc });
+
+ return href;
+}
+
+const link = ({
+ defaultValue = "internal",
+ disableLabel = false,
+ disableLinkTypeSelection = false,
+ disableOpenInNewTab = false,
+ overrides = {},
+ required = true,
+} = {}) => {
+ const linkResult = {
+ type: "row",
+ fields: [
+ {
+ name: "linkType",
+ type: "radio",
+ options: [
+ {
+ label: {
+ en: "Custom URL",
+ },
+ value: "custom",
+ },
+ {
+ label: {
+ en: "Internal link",
+ },
+ value: "internal",
+ },
+ ],
+ defaultValue,
+ admin: {
+ hidden: disableLinkTypeSelection,
+ },
+ },
+ ],
+ };
+
+ const linkTypes = [
+ {
+ type: "row",
+ fields: [
+ {
+ name: "doc",
+ label: {
+ en: "Document to link to",
+ fr: "Document pour lien vers",
+ pt: "Documento para link para",
+ },
+ type: "relationship",
+ relationTo: ["pages"],
+ required,
+ maxDepth: 1,
+ admin: {
+ condition: (_, siblingData) => siblingData?.linkType === "internal",
+ },
+ },
+ {
+ name: "url",
+ label: {
+ en: "Custom URL",
+ fr: "URL personnalisée",
+ pt: "URL personalizado",
+ },
+ type: "text",
+ required,
+ admin: {
+ condition: (_, siblingData) => siblingData?.linkType === "custom",
+ },
+ },
+ {
+ name: "href",
+ type: "text",
+ required,
+ admin: {
+ hidden: true,
+ },
+ hooks: {
+ beforeValidate: [mapLinkToHrefBeforeValidate],
+ },
+ },
+ ],
+ },
+ ];
+ let labelFields = [];
+ if (!disableLabel) {
+ labelFields = [
+ {
+ type: "row",
+ fields: [
+ {
+ name: "label",
+ label: {
+ en: "Label",
+ pt: "Rótulo",
+ },
+ type: "text",
+ required,
+ },
+ ],
+ },
+ ];
+ }
+ linkResult.fields = [...labelFields, ...linkResult.fields, ...linkTypes];
+ if (!disableOpenInNewTab) {
+ linkResult.fields.push({
+ type: "row",
+ fields: [
+ {
+ name: "newTab",
+ label: {
+ en: "Open in new tab",
+ fr: "Ouvrir dans un nouvel onglet",
+ pt: "Abrir num novo separador",
+ },
+ type: "checkbox",
+ },
+ ],
+ });
+ }
+
+ return deepmerge(linkResult, overrides);
+};
+
+export default link;
diff --git a/apps/climatemappedafrica/src/payload/fields/links/linkArray.js b/apps/climatemappedafrica/src/payload/fields/links/linkArray.js
new file mode 100644
index 000000000..d36f2c2f3
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/fields/links/linkArray.js
@@ -0,0 +1,27 @@
+import { deepmerge } from "@mui/utils";
+
+import link from "./link";
+
+/**
+ * array field consisting of link fields .
+ */
+function linkArray(args) {
+ const { linkConfig, overrides = {} } = args ?? {};
+ const generatedLinkArray = {
+ name: "links",
+ type: "array",
+ fields: [link(linkConfig)],
+ admin: {
+ initCollapsed: true,
+ components: {
+ RowLabel: ({ data }) => {
+ return data?.label || data?.reference?.title || data?.url || data?.id;
+ },
+ },
+ },
+ };
+
+ return deepmerge(generatedLinkArray, overrides);
+}
+
+export default linkArray;
diff --git a/apps/climatemappedafrica/src/payload/fields/links/linkGroup.js b/apps/climatemappedafrica/src/payload/fields/links/linkGroup.js
new file mode 100644
index 000000000..f76381d28
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/fields/links/linkGroup.js
@@ -0,0 +1,20 @@
+import { deepmerge } from "@mui/utils";
+
+import link from "./link";
+
+/**
+ * group field consisting of a link field.
+ */
+function linkGroup(args) {
+ const { linkConfig, overrides = {} } = args ?? {};
+ const generatedLinkGroup = {
+ name: "link",
+ type: "group",
+ required: true,
+ fields: [link(linkConfig)],
+ };
+
+ return deepmerge(generatedLinkGroup, overrides);
+}
+
+export default linkGroup;
diff --git a/apps/climatemappedafrica/src/payload/fields/richText.js b/apps/climatemappedafrica/src/payload/fields/richText.js
new file mode 100644
index 000000000..e7a4eea85
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/fields/richText.js
@@ -0,0 +1,60 @@
+import { deepmerge } from "@mui/utils";
+
+import mapLinkTypeToHref from "../utils/mapLinkTypeToHref";
+
+async function insertHref(nodes, payload) {
+ if (!nodes?.length) {
+ // Front-end needs `null` for serialization
+ return null;
+ }
+ return Promise.all(
+ nodes.map(async (node) => {
+ let newNode = node;
+ // The most important thing is not to change the doc structure
+ // since the admin UI expects it to be in certain why. But of course,
+ // we can add href prop for front-end.
+ if (node.type === "link") {
+ let { doc } = node;
+ if (typeof doc?.value === "string") {
+ const { relationTo: collection, value: id } = doc;
+ if (payload.findByID) {
+ // @ts-ignore
+ const value = await payload.findByID({
+ collection,
+ id,
+ // We only need slug from the collection don't expand the whole
+ // relationship. We may end up getting stuck on infinite recursion if
+ // collection contain other links.
+ depth: 0,
+ });
+ doc = { ...doc, value };
+ }
+ }
+ const href = mapLinkTypeToHref({ ...node, doc });
+ newNode = { ...node, href };
+ }
+ newNode.children = await insertHref(node.children, payload);
+ return newNode;
+ }),
+ );
+}
+
+async function mapLinkToHrefAfterRead({ req: { payload }, value }) {
+ if (!value?.length) {
+ return value;
+ }
+ return insertHref(value, payload);
+}
+
+function richText(overrides) {
+ const richTextResult = {
+ type: "richText",
+ hooks: {
+ afterRead: [mapLinkToHrefAfterRead],
+ },
+ };
+
+ return deepmerge(richTextResult, overrides);
+}
+
+export default richText;
diff --git a/apps/climatemappedafrica/src/payload/fields/socialLinks.js b/apps/climatemappedafrica/src/payload/fields/socialLinks.js
new file mode 100644
index 000000000..be10a90c4
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/fields/socialLinks.js
@@ -0,0 +1,81 @@
+import { deepmerge } from "@mui/utils";
+import { select } from "payload/dist/fields/validations";
+
+import url from "./url";
+
+export const socialMediaOptions = [
+ "Facebook",
+ "Twitter",
+ "Instagram",
+ "Linkedin",
+ "Github",
+ "Slack",
+];
+
+function socialLinks(overrides) {
+ const defaults = {
+ name: "links",
+ type: "array",
+ labels: {
+ singular: {
+ en: "Link",
+ },
+ plural: {
+ en: "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, args) => {
+ const { data, t } = args || {};
+ const { name: linksName = "links" } = overrides || {};
+ if (
+ data?.[linksName]?.filter((l) => l.platform === val)?.length > 1
+ ) {
+ return t("codeforafrica.validation:uniquePlatforms");
+ }
+
+ const {
+ hasMany,
+ options = socialMediaOptions,
+ required = true,
+ } = args;
+ return select(val, { hasMany, options, required, t });
+ },
+ },
+ url({
+ overrides: {
+ required: true,
+ },
+ }),
+ ],
+ };
+ return deepmerge(defaults, overrides);
+}
+
+export default socialLinks;
diff --git a/apps/climatemappedafrica/src/payload/fields/url.js b/apps/climatemappedafrica/src/payload/fields/url.js
new file mode 100644
index 000000000..d4ecac720
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/fields/url.js
@@ -0,0 +1,25 @@
+import { deepmerge } from "@mui/utils";
+import { text } from "payload/dist/fields/validations";
+
+function url({ overrides = undefined }) {
+ const urlResult = {
+ name: "url",
+ type: "text",
+ label: "URL",
+ validate: (val, options) => {
+ try {
+ // eslint-disable-next-line no-new
+ new URL(val);
+ } catch (e) {
+ if (e instanceof TypeError) {
+ return "Please enter valid URL";
+ }
+ }
+ return text(val, options);
+ },
+ };
+
+ return deepmerge(urlResult, overrides);
+}
+
+export default url;
diff --git a/apps/climatemappedafrica/src/payload/globals/site/EngagementTab.js b/apps/climatemappedafrica/src/payload/globals/site/EngagementTab.js
new file mode 100644
index 000000000..ca7c01f84
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/globals/site/EngagementTab.js
@@ -0,0 +1,82 @@
+import socialLinks from "../../fields/socialLinks";
+
+const EngagementTab = {
+ label: "Engagement",
+ fields: [
+ {
+ name: "connect",
+ type: "group",
+ label: "Social Accounts",
+ localized: true,
+ fields: [
+ {
+ type: "collapsible",
+ label: "Title & Links",
+ fields: [
+ {
+ name: "title",
+ type: "text",
+ admin: {
+ description:
+ "Text that appears on contact links e.g Stay in Touch",
+ },
+ required: true,
+ },
+ socialLinks(),
+ ],
+ },
+ ],
+ },
+ {
+ name: "newsletter",
+ type: "group",
+ label: "Email Newsletter",
+ localized: true,
+ fields: [
+ {
+ type: "collapsible",
+ label: "Title & Embed Code",
+ fields: [
+ {
+ name: "title",
+ type: "text",
+ required: true,
+ },
+ {
+ name: "embedCode",
+ type: "code",
+ required: true,
+ admin: {
+ language: "html",
+ },
+ },
+ ],
+ },
+ ],
+ },
+ {
+ name: "analytics",
+ type: "group",
+ label: "Site Analytics",
+ localized: true,
+ fields: [
+ {
+ type: "collapsible",
+ label: "Google Analytics",
+ fields: [
+ {
+ name: "analyticsId",
+ type: "text",
+ },
+ ],
+ admin: {
+ description:
+ "Measurement ID: https://support.google.com/analytics/answer/12270356",
+ },
+ },
+ ],
+ },
+ ],
+};
+
+export default EngagementTab;
diff --git a/apps/climatemappedafrica/src/payload/globals/site/GeneralTab.js b/apps/climatemappedafrica/src/payload/globals/site/GeneralTab.js
new file mode 100644
index 000000000..a1fa6fb64
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/globals/site/GeneralTab.js
@@ -0,0 +1,53 @@
+import image from "../../fields/image";
+import richText from "../../fields/richText";
+
+const GeneralTab = {
+ label: "General",
+ fields: [
+ {
+ type: "collapsible",
+ label: "Title & Description",
+ fields: [
+ {
+ name: "title",
+ type: "text",
+ required: true,
+ localized: true,
+ },
+ richText({
+ name: "description",
+ required: true,
+ localized: true,
+ }),
+ ],
+ },
+ {
+ type: "collapsible",
+ label: "Logo",
+ fields: [
+ image({
+ overrides: {
+ name: "primaryLogo",
+ required: true,
+ localized: true,
+ admin: {
+ description: "Shown on main navigation bar.",
+ },
+ },
+ }),
+ image({
+ overrides: {
+ name: "secondaryLogo",
+ localized: true,
+ admin: {
+ description:
+ "Shown on main footer. If not provided, primary logo will be reused.",
+ },
+ },
+ }),
+ ],
+ },
+ ],
+};
+
+export default GeneralTab;
diff --git a/apps/climatemappedafrica/src/payload/globals/site/InitiativeTab.js b/apps/climatemappedafrica/src/payload/globals/site/InitiativeTab.js
new file mode 100644
index 000000000..9ad7647f8
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/globals/site/InitiativeTab.js
@@ -0,0 +1,57 @@
+import image from "../../fields/image";
+import link from "../../fields/links/link";
+import richText from "../../fields/richText";
+
+const PartnersTab = {
+ label: "Initiative",
+ fields: [
+ {
+ name: "initiative",
+ type: "group",
+ fields: [
+ {
+ name: "title",
+ type: "text",
+ required: true,
+ },
+ richText({
+ name: "description",
+ required: true,
+ }),
+ {
+ name: "partners",
+ label: "Partners",
+ type: "array",
+ fields: [
+ {
+ name: "name",
+ type: "text",
+ required: true,
+ },
+ image({
+ overrides: {
+ label: "Logo",
+ name: "logo",
+ required: true,
+ },
+ }),
+ link({
+ defaultValue: "custom",
+ disableLinkTypeSelection: true,
+ disableOpenInNewTab: true,
+ }),
+ ],
+ admin: {
+ components: {
+ RowLabel: ({ data, index = 0 }) => {
+ return data?.name || `Partner ${index + 1}`;
+ },
+ },
+ },
+ },
+ ],
+ },
+ ],
+};
+
+export default PartnersTab;
diff --git a/apps/climatemappedafrica/src/payload/globals/site/NavigationTab.js b/apps/climatemappedafrica/src/payload/globals/site/NavigationTab.js
new file mode 100644
index 000000000..6c2a3cf8b
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/globals/site/NavigationTab.js
@@ -0,0 +1,80 @@
+import link from "../../fields/links/link";
+import linkArray from "../../fields/links/linkArray";
+import { socialMediaOptions } from "../../fields/socialLinks";
+
+const linkField = link({
+ disableOpenInNewTab: true,
+});
+
+const NavigationTab = {
+ label: "Navigation",
+ fields: [
+ {
+ name: "primaryNavigation",
+ type: "group",
+ localized: true,
+ fields: [
+ {
+ type: "collapsible",
+ label: "Title & Links",
+ fields: [
+ linkArray({
+ overrides: {
+ name: "menus",
+ labels: {
+ singular: {
+ en: "Menu",
+ },
+ plural: {
+ en: "Menus",
+ },
+ },
+ fields: [linkField],
+ admin: {
+ className: "array-field-nested",
+ },
+ },
+ }),
+ {
+ name: "connect",
+ type: "select",
+ options: socialMediaOptions,
+ },
+ ],
+ },
+ ],
+ },
+ {
+ name: "secondaryNavigation",
+ type: "group",
+ localized: true,
+ fields: [
+ {
+ type: "collapsible",
+ label: "Title & Links",
+ fields: [
+ linkArray({
+ overrides: {
+ name: "menus",
+ labels: {
+ singular: {
+ en: "Menu",
+ },
+ plural: {
+ en: "Menus",
+ },
+ },
+ fields: [linkField],
+ admin: {
+ className: "array-field-nested",
+ },
+ },
+ }),
+ ],
+ },
+ ],
+ },
+ ],
+};
+
+export default NavigationTab;
diff --git a/apps/climatemappedafrica/src/payload/globals/site/index.js b/apps/climatemappedafrica/src/payload/globals/site/index.js
new file mode 100644
index 000000000..1e56939e8
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/globals/site/index.js
@@ -0,0 +1,23 @@
+import EngagementTab from "./EngagementTab";
+import GeneralTab from "./GeneralTab";
+import InitiativeTab from "./InitiativeTab";
+import NavigationTab from "./NavigationTab";
+
+const Site = {
+ slug: "settings-site",
+ label: "Site",
+ access: {
+ read: () => true,
+ },
+ admin: {
+ group: "Settings",
+ },
+ fields: [
+ {
+ type: "tabs",
+ tabs: [GeneralTab, NavigationTab, EngagementTab, InitiativeTab],
+ },
+ ],
+};
+
+export default Site;
diff --git a/apps/climatemappedafrica/src/payload/utils/mapLinkTypeToHref.js b/apps/climatemappedafrica/src/payload/utils/mapLinkTypeToHref.js
new file mode 100644
index 000000000..ab5c938c9
--- /dev/null
+++ b/apps/climatemappedafrica/src/payload/utils/mapLinkTypeToHref.js
@@ -0,0 +1,18 @@
+import formatPagePath from "./formatPagePath";
+
+const mapLinkTypeToHref = ({ doc: linkDoc, linkType, url }) => {
+ // default to `null` for serialization.
+ let href = null;
+ if (linkType === "internal") {
+ const { relationTo: collection, value: doc } = linkDoc;
+ if (doc?.slug) {
+ href = formatPagePath(collection, doc);
+ }
+ } else {
+ // custom link
+ href = url;
+ }
+ return href;
+};
+
+export default mapLinkTypeToHref;
From 689a69539f01f1407dca5cfcc238e067d9831028 Mon Sep 17 00:00:00 2001
From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com>
Date: Wed, 9 Oct 2024 15:58:42 +0300
Subject: [PATCH 2/9] Reusable richtext component
---
packages/commons-ui-next/package.json | 3 +-
.../commons-ui-next/src/RichText/RichText.js | 108 ++++++++++++++++++
.../src/RichText/RichText.snap.js | 31 +++++
.../src/RichText/RichText.test.js | 59 ++++++++++
.../commons-ui-next/src/RichText/index.js | 3 +
packages/commons-ui-next/src/index.js | 1 +
pnpm-lock.yaml | 3 +
7 files changed, 207 insertions(+), 1 deletion(-)
create mode 100644 packages/commons-ui-next/src/RichText/RichText.js
create mode 100644 packages/commons-ui-next/src/RichText/RichText.snap.js
create mode 100644 packages/commons-ui-next/src/RichText/RichText.test.js
create mode 100644 packages/commons-ui-next/src/RichText/index.js
diff --git a/packages/commons-ui-next/package.json b/packages/commons-ui-next/package.json
index f5cdf7922..51eed1925 100644
--- a/packages/commons-ui-next/package.json
+++ b/packages/commons-ui-next/package.json
@@ -56,7 +56,8 @@
"next": "catalog:",
"prop-types": "catalog:",
"react": "catalog:",
- "react-dom": "catalog:"
+ "react-dom": "catalog:",
+ "slate": "catalog:"
},
"dependencies": {
"clsx": "catalog:"
diff --git a/packages/commons-ui-next/src/RichText/RichText.js b/packages/commons-ui-next/src/RichText/RichText.js
new file mode 100644
index 000000000..6f1ea3ae0
--- /dev/null
+++ b/packages/commons-ui-next/src/RichText/RichText.js
@@ -0,0 +1,108 @@
+/* eslint-disable react/no-array-index-key */
+import { Box } from "@mui/material";
+import React, { Fragment } from "react";
+import { Text } from "slate";
+
+import Link from "@/commons-ui/next/Link";
+import RichTypography from "@/commons-ui/next/RichTypography";
+
+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;
+ }
+ // 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/packages/commons-ui-next/src/RichText/RichText.snap.js b/packages/commons-ui-next/src/RichText/RichText.snap.js
new file mode 100644
index 000000000..b0a821528
--- /dev/null
+++ b/packages/commons-ui-next/src/RichText/RichText.snap.js
@@ -0,0 +1,31 @@
+// 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/packages/commons-ui-next/src/RichText/RichText.test.js b/packages/commons-ui-next/src/RichText/RichText.test.js
new file mode 100644
index 000000000..bcbed0d5d
--- /dev/null
+++ b/packages/commons-ui-next/src/RichText/RichText.test.js
@@ -0,0 +1,59 @@
+import { render } from "@commons-ui/testing-library";
+import React from "react";
+
+import RichText from "./RichText";
+
+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/packages/commons-ui-next/src/RichText/index.js b/packages/commons-ui-next/src/RichText/index.js
new file mode 100644
index 000000000..49b1d7e02
--- /dev/null
+++ b/packages/commons-ui-next/src/RichText/index.js
@@ -0,0 +1,3 @@
+import RichText from "./RichText";
+
+export default RichText;
diff --git a/packages/commons-ui-next/src/index.js b/packages/commons-ui-next/src/index.js
index 548f9c705..db436ed3c 100644
--- a/packages/commons-ui-next/src/index.js
+++ b/packages/commons-ui-next/src/index.js
@@ -4,3 +4,4 @@ export { default as Link } from "./Link";
export * from "./Link";
export { default as RichTypography } from "./RichTypography";
+export { default as RichText } from "./RichText";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 79e25380a..6ccb664b1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2513,6 +2513,9 @@ importers:
clsx:
specifier: 'catalog:'
version: 2.1.1
+ slate:
+ specifier: 'catalog:'
+ version: 0.103.0
devDependencies:
'@babel/core':
specifier: 'catalog:'
From 60aa28c8cef938d02d56e1b167820003d1d52fde Mon Sep 17 00:00:00 2001
From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com>
Date: Wed, 9 Oct 2024 16:01:18 +0300
Subject: [PATCH 3/9] Setup payload footer
---
.../src/lib/data/common/index.js | 38 ++++++++++++-
.../src/payload/globals/site/InitiativeTab.js | 57 -------------------
.../src/payload/globals/site/NavigationTab.js | 11 +++-
.../src/payload/globals/site/index.js | 3 +-
4 files changed, 45 insertions(+), 64 deletions(-)
delete mode 100644 apps/climatemappedafrica/src/payload/globals/site/InitiativeTab.js
diff --git a/apps/climatemappedafrica/src/lib/data/common/index.js b/apps/climatemappedafrica/src/lib/data/common/index.js
index 4025643d6..15b838a2e 100644
--- a/apps/climatemappedafrica/src/lib/data/common/index.js
+++ b/apps/climatemappedafrica/src/lib/data/common/index.js
@@ -1,7 +1,38 @@
-/* eslint-disable import/prefer-default-export */
-
import { blockify } from "@/climatemappedafrica/lib/data/blockify";
+export function imageFromMedia(alt, url) {
+ return { alt, src: url };
+}
+
+function getFooter(siteSettings) {
+ const {
+ connect,
+ footerNavigation,
+ newsletter,
+ primaryLogo,
+ secondaryLogo,
+ description,
+ title,
+ } = siteSettings;
+
+ const { menus: footerMenus, ...footerProps } = footerNavigation;
+
+ const media = secondaryLogo || primaryLogo;
+ const footerLogoUrl = typeof media === "string" ? null : media.url;
+
+ return {
+ connect,
+ description,
+ logo: imageFromMedia(title, footerLogoUrl),
+ links: {
+ ...footerProps,
+ links: footerMenus,
+ },
+ newsletter,
+ title,
+ };
+}
+
export async function getPageProps(api, context) {
// For now, ClimatemappedAfrica only supports single paths i.e. /, /about, etc.,
// so params.slug[0] is good enough
@@ -21,9 +52,10 @@ export async function getPageProps(api, context) {
const blocks = await blockify(page.blocks, api);
const siteSettings = await api.findGlobal("settings-site");
+ const footer = getFooter(siteSettings);
return {
blocks,
- siteSettings,
+ footer,
};
}
diff --git a/apps/climatemappedafrica/src/payload/globals/site/InitiativeTab.js b/apps/climatemappedafrica/src/payload/globals/site/InitiativeTab.js
deleted file mode 100644
index 9ad7647f8..000000000
--- a/apps/climatemappedafrica/src/payload/globals/site/InitiativeTab.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import image from "../../fields/image";
-import link from "../../fields/links/link";
-import richText from "../../fields/richText";
-
-const PartnersTab = {
- label: "Initiative",
- fields: [
- {
- name: "initiative",
- type: "group",
- fields: [
- {
- name: "title",
- type: "text",
- required: true,
- },
- richText({
- name: "description",
- required: true,
- }),
- {
- name: "partners",
- label: "Partners",
- type: "array",
- fields: [
- {
- name: "name",
- type: "text",
- required: true,
- },
- image({
- overrides: {
- label: "Logo",
- name: "logo",
- required: true,
- },
- }),
- link({
- defaultValue: "custom",
- disableLinkTypeSelection: true,
- disableOpenInNewTab: true,
- }),
- ],
- admin: {
- components: {
- RowLabel: ({ data, index = 0 }) => {
- return data?.name || `Partner ${index + 1}`;
- },
- },
- },
- },
- ],
- },
- ],
-};
-
-export default PartnersTab;
diff --git a/apps/climatemappedafrica/src/payload/globals/site/NavigationTab.js b/apps/climatemappedafrica/src/payload/globals/site/NavigationTab.js
index 6c2a3cf8b..02da38263 100644
--- a/apps/climatemappedafrica/src/payload/globals/site/NavigationTab.js
+++ b/apps/climatemappedafrica/src/payload/globals/site/NavigationTab.js
@@ -45,13 +45,20 @@ const NavigationTab = {
],
},
{
- name: "secondaryNavigation",
+ name: "footerNavigation",
type: "group",
localized: true,
fields: [
+ {
+ type: "text",
+ name: "title",
+ required: true,
+ localized: true,
+ label: "Title",
+ },
{
type: "collapsible",
- label: "Title & Links",
+ label: "Links",
fields: [
linkArray({
overrides: {
diff --git a/apps/climatemappedafrica/src/payload/globals/site/index.js b/apps/climatemappedafrica/src/payload/globals/site/index.js
index 1e56939e8..207b83587 100644
--- a/apps/climatemappedafrica/src/payload/globals/site/index.js
+++ b/apps/climatemappedafrica/src/payload/globals/site/index.js
@@ -1,6 +1,5 @@
import EngagementTab from "./EngagementTab";
import GeneralTab from "./GeneralTab";
-import InitiativeTab from "./InitiativeTab";
import NavigationTab from "./NavigationTab";
const Site = {
@@ -15,7 +14,7 @@ const Site = {
fields: [
{
type: "tabs",
- tabs: [GeneralTab, NavigationTab, EngagementTab, InitiativeTab],
+ tabs: [GeneralTab, NavigationTab, EngagementTab],
},
],
};
From c1ca2b09e711ffb01a4b71eccdace50e3dabb4ca Mon Sep 17 00:00:00 2001
From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com>
Date: Wed, 9 Oct 2024 16:32:45 +0300
Subject: [PATCH 4/9] Improve stayintouch to take direction
---
.../commons-ui-core/src/StayInTouch/StayInTouch.js | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/packages/commons-ui-core/src/StayInTouch/StayInTouch.js b/packages/commons-ui-core/src/StayInTouch/StayInTouch.js
index ff63dcbda..896a8446b 100644
--- a/packages/commons-ui-core/src/StayInTouch/StayInTouch.js
+++ b/packages/commons-ui-core/src/StayInTouch/StayInTouch.js
@@ -8,7 +8,14 @@ import RichTypography from "@/commons-ui/core/RichTypography";
import SocialMediaIconLink from "@/commons-ui/core/SocialMediaIconLink";
const StayInTouch = React.forwardRef(function StayInTouch(
- { LinkProps, TitleProps, links, sx, title },
+ {
+ LinkProps,
+ TitleProps,
+ links,
+ sx,
+ title,
+ direction = { xs: "column", md: "row" },
+ },
ref,
) {
if (!links?.length) {
@@ -16,7 +23,7 @@ const StayInTouch = React.forwardRef(function StayInTouch(
}
return (
Date: Wed, 9 Oct 2024 16:33:11 +0300
Subject: [PATCH 5/9] temporary stayintouch component fix
---
packages/commons-ui-next/src/StayInTouch/index.js | 4 ++++
packages/commons-ui-next/src/index.js | 1 +
2 files changed, 5 insertions(+)
create mode 100644 packages/commons-ui-next/src/StayInTouch/index.js
diff --git a/packages/commons-ui-next/src/StayInTouch/index.js b/packages/commons-ui-next/src/StayInTouch/index.js
new file mode 100644
index 000000000..64c5ba3af
--- /dev/null
+++ b/packages/commons-ui-next/src/StayInTouch/index.js
@@ -0,0 +1,4 @@
+// This is a temporary solution for packages still using the old commons-ui-core package.
+import { StayInTouch } from "@commons-ui/core";
+
+export default StayInTouch;
diff --git a/packages/commons-ui-next/src/index.js b/packages/commons-ui-next/src/index.js
index db436ed3c..049ca3c32 100644
--- a/packages/commons-ui-next/src/index.js
+++ b/packages/commons-ui-next/src/index.js
@@ -5,3 +5,4 @@ export * from "./Link";
export { default as RichTypography } from "./RichTypography";
export { default as RichText } from "./RichText";
+export { default as StayInTouch } from "./StayInTouch";
From 8262ac1750fe9967689943c1a055f5ef2e9096cf Mon Sep 17 00:00:00 2001
From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com>
Date: Wed, 9 Oct 2024 16:43:26 +0300
Subject: [PATCH 6/9] Working footer
---
apps/climatemappedafrica/next.config.js | 23 +--
.../src/components/Footer/index.js | 108 ++++++++++++
.../src/components/Footer/index.stories.js | 160 ++++++++++++++++++
.../src/components/Footer/useStyles.js | 128 ++++++++++++++
.../src/components/Page/Base.js | 8 +-
.../src/pages/[[...slug]].js | 6 +-
6 files changed, 417 insertions(+), 16 deletions(-)
create mode 100644 apps/climatemappedafrica/src/components/Footer/index.js
create mode 100644 apps/climatemappedafrica/src/components/Footer/index.stories.js
create mode 100644 apps/climatemappedafrica/src/components/Footer/useStyles.js
diff --git a/apps/climatemappedafrica/next.config.js b/apps/climatemappedafrica/next.config.js
index c282b8971..fa6f8ae11 100644
--- a/apps/climatemappedafrica/next.config.js
+++ b/apps/climatemappedafrica/next.config.js
@@ -32,16 +32,19 @@ module.exports = {
"@hurumap/next",
],
webpack: (config) => {
- config.module.rules.push({
- test: /\.svg$/,
- use: [
- "@svgr/webpack",
- {
- loader: "svg-url-loader",
- options: {},
- },
- ],
- });
+ config.module.rules.push(
+ {
+ test: /\.svg$/i,
+ type: "asset",
+ resourceQuery: /url/, // *.svg?url
+ },
+ {
+ test: /\.svg$/i,
+ issuer: /\.[jt]sx?$/,
+ resourceQuery: { not: [/url/] }, // exclude react component if *.svg?url
+ use: ["@svgr/webpack"],
+ },
+ );
// eslint-disable-next-line no-param-reassign
config.resolve.fallback = {
...config.resolve.fallback,
diff --git a/apps/climatemappedafrica/src/components/Footer/index.js b/apps/climatemappedafrica/src/components/Footer/index.js
new file mode 100644
index 000000000..fb57a814e
--- /dev/null
+++ b/apps/climatemappedafrica/src/components/Footer/index.js
@@ -0,0 +1,108 @@
+import { QuickLinks, LogoButton, Copyright } from "@commons-ui/core";
+import { Link, RichText, StayInTouch } from "@commons-ui/next";
+import { Grid } from "@mui/material";
+import React from "react";
+
+import useStyles from "./useStyles";
+
+import Section from "@/climatemappedafrica/components/Section";
+
+function Footer(props) {
+ const { title, connect, description, logo: logoProps, links } = props;
+ const classes = useStyles(props);
+ return (
+
+
+
+
+ {logoProps && (
+
+ )}
+
+
+ {description && (
+
+ )}
+
+
+
+
+
+ {links && (
+
+ )}
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default Footer;
diff --git a/apps/climatemappedafrica/src/components/Footer/index.stories.js b/apps/climatemappedafrica/src/components/Footer/index.stories.js
new file mode 100644
index 000000000..9c46cbae2
--- /dev/null
+++ b/apps/climatemappedafrica/src/components/Footer/index.stories.js
@@ -0,0 +1,160 @@
+/* eslint-disable import/no-anonymous-default-export */
+import React from "react";
+
+import Footer from ".";
+
+export default {
+ title: "ClimateMappedAfrica/Sections/Footer",
+ argTypes: {
+ title: {
+ control: {
+ type: "text",
+ },
+ },
+ socialMedia: {
+ control: {
+ type: "object",
+ },
+ },
+ quickLinks: {
+ control: {
+ type: "array",
+ },
+ },
+ description: {
+ control: {
+ type: "text",
+ },
+ },
+ aboutVariant: {
+ control: {
+ type: "select",
+ },
+ options: ["subtitle1", "body1"],
+ },
+ copyrightProps: {
+ control: {
+ type: "object",
+ },
+ },
+ logoProps: {
+ control: {
+ type: "object",
+ },
+ },
+ },
+};
+
+function Template({ ...args }) {
+ return ;
+}
+
+export const Default = Template.bind({});
+
+Default.parameters = {
+ nextjs: {
+ router: {
+ pathname: "/?path=/story/sections-footer--default",
+ },
+ },
+};
+
+Default.args = {
+ connect: {
+ title: "Stay in Touch",
+ links: [
+ {
+ platform: "Facebook",
+ url: "https://www.google.com",
+ id: "67050ad20d400b5e511b2871",
+ },
+ {
+ platform: "Twitter",
+ url: "https://Twitter.com",
+ id: "6706844a6339b76017e6c782",
+ },
+ ],
+ },
+ description: [
+ {
+ children: [
+ {
+ text: "This site is an ",
+ children: null,
+ },
+ {
+ newTab: false,
+ type: "link",
+ url: "https://github.com/CodeForAfrica/ui/tree/main/apps/roboshield",
+ children: [
+ {
+ text: "open source code",
+ children: null,
+ },
+ ],
+ href: "https://github.com/CodeForAfrica/ui/tree/main/apps/roboshield",
+ },
+ {
+ text: " built by ",
+ children: null,
+ },
+ {
+ newTab: false,
+ type: "link",
+ url: "https://codeforafrica.org/",
+ children: [
+ {
+ text: "Code for Africa",
+ children: null,
+ },
+ ],
+ href: "https://codeforafrica.org/",
+ },
+ {
+ text: ", the continent's largest network of civic technology and data journalism labs. All content is released under a ",
+ children: null,
+ },
+ {
+ newTab: false,
+ type: "link",
+ url: "https://creativecommons.org/licenses/by/4.0/",
+ children: [
+ {
+ text: "Creative Commons 4 Attribution",
+ children: null,
+ },
+ ],
+ href: "https://creativecommons.org/licenses/by/4.0/",
+ },
+ {
+ text: " License. Reuse it to help empower your own community.",
+ children: null,
+ },
+ ],
+ },
+ ],
+ links: {
+ title: "Resources",
+ links: [
+ {
+ label: "About",
+ linkType: "custom",
+ url: "/",
+ href: "/",
+ id: "67063751048cfcc79c43a6f9",
+ },
+ {
+ label: "Privacy Policy",
+ linkType: "custom",
+ url: "/",
+ href: "/",
+ id: "6706375d048cfcc79c43a6fa",
+ },
+ ],
+ },
+ logo: {
+ alt: "ClimateMappedAfrica",
+ src: "http://localhost:3000/media/Group-4426.svg",
+ },
+ title: "Climate Mapped Africa",
+};
diff --git a/apps/climatemappedafrica/src/components/Footer/useStyles.js b/apps/climatemappedafrica/src/components/Footer/useStyles.js
new file mode 100644
index 000000000..603fb2cc9
--- /dev/null
+++ b/apps/climatemappedafrica/src/components/Footer/useStyles.js
@@ -0,0 +1,128 @@
+import makeStyles from "@mui/styles/makeStyles";
+
+const useStyles = makeStyles(({ breakpoints, palette, typography }) => ({
+ root: {
+ background: palette.grey.dark,
+ height: "auto",
+ padding: `${typography.pxToRem(80)} 0`,
+ [breakpoints.up("md")]: {
+ paddingTop: `${typography.pxToRem(58)}`,
+ paddingBottom: `${typography.pxToRem(82)}`,
+ },
+ },
+ section: {},
+ logoButton: {
+ margin: "0 auto",
+ padding: 0,
+ [breakpoints.up("lg")]: {
+ margin: 0,
+ },
+ },
+ allLinks: {
+ margin: "0 auto",
+ flexDirection: "row",
+ justifyContent: "center",
+ marginTop: typography.pxToRem(44.19),
+ },
+ stayInTouch: {
+ display: "flex",
+ flexDirection: "column",
+ alignItems: "center",
+ letterspacing: typography.pxToRem(0.7),
+ [breakpoints.up("lg")]: {
+ alignItems: "flex-start",
+ },
+ },
+ stayInTouchIcon: {
+ height: "auto",
+ objectFit: "none",
+ display: "flex",
+ width: "auto",
+ },
+ stayInTouchText: {
+ color: palette.text.secondary,
+ fontSize: typography.subtitle2.fontSize,
+ fontWeight: "bold",
+ padding: `${typography.pxToRem(10)} ${typography.pxToRem(8)}`,
+ [breakpoints.up("lg")]: {
+ padding: 0,
+ },
+ },
+ stayInTouchLink: {
+ padding: 0,
+ },
+ stayInTouchLinks: {
+ justifyContent: "center",
+ marginLeft: typography.pxToRem(-14), // (48 - 20) / 2
+ marginTop: typography.pxToRem(24),
+ "& > a": {
+ height: typography.pxToRem(48),
+ width: typography.pxToRem(48),
+ borderRight: "none",
+ display: "flex",
+ justifyContent: "center",
+ },
+ },
+ quickLinkRoot: {
+ textAlign: "center",
+ padding: `${typography.pxToRem(32)} 0 `,
+ [breakpoints.up("lg")]: {
+ textAlign: "inherit",
+ padding: 0,
+ },
+ },
+ quickList: {
+ listStyle: "none",
+ color: palette.text.secondary,
+ padding: 0,
+ letterspacing: typography.pxToRem(0.7),
+ "& > li": {
+ marginTop: typography.pxToRem(16),
+ },
+ },
+ quickLink: {
+ fontSize: typography.subtitle1.fontSize,
+ color: palette.text.secondary,
+ fontWeight: "normal",
+ "&:hover": {
+ color: palette.primary.light,
+ },
+ },
+ quickLinksTitle: {
+ color: palette.text.secondary,
+ fontSize: typography.subtitle2.fontSize,
+ fontWeight: "bold",
+ },
+ description: {
+ color: palette.text.secondary,
+ padding: `${typography.pxToRem(32)} 0`,
+ fontSize: typography.subtitle1.fontSize,
+ textAlign: "center",
+ [breakpoints.up("lg")]: {
+ textAlign: "left",
+ },
+ },
+ copyright: {
+ margin: 0,
+ display: "flex",
+ flexWrap: "wrap",
+ flexDirection: "row",
+ justifyContent: "center",
+ [breakpoints.up("lg")]: {
+ justifyContent: "flex-start",
+ },
+ "& > a": {
+ marginTop: typography.pxToRem(3),
+ },
+ },
+ copyrightText: {
+ color: palette.text.secondary,
+ order: 5,
+ padding: `0 ${typography.pxToRem(5)}`,
+ [breakpoints.up("lg")]: {
+ padding: `0 ${typography.pxToRem(10)}`,
+ },
+ },
+}));
+
+export default useStyles;
diff --git a/apps/climatemappedafrica/src/components/Page/Base.js b/apps/climatemappedafrica/src/components/Page/Base.js
index d7421469d..45cf7010e 100644
--- a/apps/climatemappedafrica/src/components/Page/Base.js
+++ b/apps/climatemappedafrica/src/components/Page/Base.js
@@ -1,7 +1,10 @@
+import { useMediaQuery } from "@mui/material";
+import { useTheme } from "@mui/material/styles";
import { NextSeo } from "next-seo";
import PropTypes from "prop-types";
import React from "react";
+import Footer from "@/climatemappedafrica/components/Footer";
import Navigation from "@/climatemappedafrica/components/Navigation";
import { navigationArgs } from "@/climatemappedafrica/config";
import getNavigationMenu from "@/climatemappedafrica/functions/menus/getNavigationMenu";
@@ -9,12 +12,14 @@ import getNavigationMenu from "@/climatemappedafrica/functions/menus/getNavigati
/**
* Base page that can be used to build all other pages.
*/
-function BasePage({ children, menus, variant, ...props }) {
+function BasePage({ children, menus, variant, footer: footerProps, ...props }) {
const seo = {};
const navigation = getNavigationMenu(menus?.primaryMenu || []);
const { menuProps, socialLinks } = navigation;
const { desktopLogoProps, mobileLogoProps, drawerLogoProps } = navigationArgs;
+ const theme = useTheme();
+ const isDesktop = useMediaQuery(theme.breakpoints.up("lg"));
const navigationProps = {
...props,
...menus,
@@ -53,6 +58,7 @@ function BasePage({ children, menus, variant, ...props }) {
noindex={seo?.metaRobotsNoindex !== "index"}
/>
{children}
+ {!(variant === "explore" && isDesktop) && }
>
);
}
diff --git a/apps/climatemappedafrica/src/pages/[[...slug]].js b/apps/climatemappedafrica/src/pages/[[...slug]].js
index 8b2d4afdc..0cd7f4d68 100644
--- a/apps/climatemappedafrica/src/pages/[[...slug]].js
+++ b/apps/climatemappedafrica/src/pages/[[...slug]].js
@@ -2,11 +2,7 @@ import Page from "@/climatemappedafrica/components/Page";
import { getPageServerSideProps } from "@/climatemappedafrica/lib/data";
export default function Index(props) {
- return (
-
- Pahed
-
- );
+ return ;
}
export async function getServerSideProps(context) {
From 36af4a72cc142f6b4ec10e4b27d07a8275888c09 Mon Sep 17 00:00:00 2001
From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com>
Date: Wed, 9 Oct 2024 17:02:46 +0300
Subject: [PATCH 7/9] Remove comments
Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com>
---
apps/climatemappedafrica/src/components/Footer/index.js | 7 -------
1 file changed, 7 deletions(-)
diff --git a/apps/climatemappedafrica/src/components/Footer/index.js b/apps/climatemappedafrica/src/components/Footer/index.js
index fb57a814e..47705f72c 100644
--- a/apps/climatemappedafrica/src/components/Footer/index.js
+++ b/apps/climatemappedafrica/src/components/Footer/index.js
@@ -88,13 +88,6 @@ function Footer(props) {
}}
sx={{ gap: 2 }}
direction="column"
- // classes={{
- // root: classes.stayInTouch,
- // icon: classes.stayInTouchIcon,
- // links: classes.stayInTouchLinks,
- // text: classes.stayInTouchText,
- // link: classes.stayInTouchLink,
- // }}
/>
From bac4d8c52cc37b0b095a6f915f7104bc0d6b6c58 Mon Sep 17 00:00:00 2001
From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com>
Date: Wed, 9 Oct 2024 17:13:56 +0300
Subject: [PATCH 8/9] Fix tests
Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com>
---
packages/commons-ui-next/src/RichText/RichText.snap.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/packages/commons-ui-next/src/RichText/RichText.snap.js b/packages/commons-ui-next/src/RichText/RichText.snap.js
index b0a821528..85112ef17 100644
--- a/packages/commons-ui-next/src/RichText/RichText.snap.js
+++ b/packages/commons-ui-next/src/RichText/RichText.snap.js
@@ -6,21 +6,21 @@ exports[` renders unchanged 1`] = `
class="MuiBox-root css-0"
>
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
From c30876c4bbcadfe496f6e06c6ca2603c93cef898 Mon Sep 17 00:00:00 2001
From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com>
Date: Fri, 11 Oct 2024 12:56:33 +0300
Subject: [PATCH 9/9] Setup commons-ui-payload
---
apps/climatemappedafrica/package.json | 1 +
.../src/components/Footer/index.js | 3 +-
packages/commons-ui-next/src/index.js | 1 -
packages/commons-ui-payload/.eslintignore | 29 ++++++
packages/commons-ui-payload/.eslintrc.js | 4 +
packages/commons-ui-payload/.lintstagedrc.js | 1 +
packages/commons-ui-payload/jest.config.js | 14 +++
packages/commons-ui-payload/jest.setup.js | 12 +++
packages/commons-ui-payload/jsconfig.json | 9 ++
packages/commons-ui-payload/package.json | 66 ++++++++++++++
.../src/RichText/RichText.js | 4 +-
.../src/RichText/RichText.snap.js | 0
.../src/RichText/RichText.test.js | 0
.../src/RichText/index.js | 0
packages/commons-ui-payload/src/index.js | 3 +
pnpm-lock.yaml | 88 +++++++++++++++++++
16 files changed, 230 insertions(+), 5 deletions(-)
create mode 100644 packages/commons-ui-payload/.eslintignore
create mode 100644 packages/commons-ui-payload/.eslintrc.js
create mode 100644 packages/commons-ui-payload/.lintstagedrc.js
create mode 100644 packages/commons-ui-payload/jest.config.js
create mode 100644 packages/commons-ui-payload/jest.setup.js
create mode 100644 packages/commons-ui-payload/jsconfig.json
create mode 100644 packages/commons-ui-payload/package.json
rename packages/{commons-ui-next => commons-ui-payload}/src/RichText/RichText.js (96%)
rename packages/{commons-ui-next => commons-ui-payload}/src/RichText/RichText.snap.js (100%)
rename packages/{commons-ui-next => commons-ui-payload}/src/RichText/RichText.test.js (100%)
rename packages/{commons-ui-next => commons-ui-payload}/src/RichText/index.js (100%)
create mode 100644 packages/commons-ui-payload/src/index.js
diff --git a/apps/climatemappedafrica/package.json b/apps/climatemappedafrica/package.json
index e5a2e3fd2..460c2aa51 100644
--- a/apps/climatemappedafrica/package.json
+++ b/apps/climatemappedafrica/package.json
@@ -36,6 +36,7 @@
"@apollo/client": "catalog:",
"@commons-ui/core": "catalog:",
"@commons-ui/next": "workspace:*",
+ "@commons-ui/payload": "workspace:*",
"@emotion/react": "catalog:",
"@emotion/styled": "catalog:",
"@hurumap/core": "workspace:*",
diff --git a/apps/climatemappedafrica/src/components/Footer/index.js b/apps/climatemappedafrica/src/components/Footer/index.js
index 47705f72c..eff78692f 100644
--- a/apps/climatemappedafrica/src/components/Footer/index.js
+++ b/apps/climatemappedafrica/src/components/Footer/index.js
@@ -1,5 +1,6 @@
import { QuickLinks, LogoButton, Copyright } from "@commons-ui/core";
-import { Link, RichText, StayInTouch } from "@commons-ui/next";
+import { Link, StayInTouch } from "@commons-ui/next";
+import { RichText } from "@commons-ui/payload";
import { Grid } from "@mui/material";
import React from "react";
diff --git a/packages/commons-ui-next/src/index.js b/packages/commons-ui-next/src/index.js
index 049ca3c32..c37bd3e41 100644
--- a/packages/commons-ui-next/src/index.js
+++ b/packages/commons-ui-next/src/index.js
@@ -4,5 +4,4 @@ export { default as Link } from "./Link";
export * from "./Link";
export { default as RichTypography } from "./RichTypography";
-export { default as RichText } from "./RichText";
export { default as StayInTouch } from "./StayInTouch";
diff --git a/packages/commons-ui-payload/.eslintignore b/packages/commons-ui-payload/.eslintignore
new file mode 100644
index 000000000..c0e426719
--- /dev/null
+++ b/packages/commons-ui-payload/.eslintignore
@@ -0,0 +1,29 @@
+# dependencies
+node_modules
+.pnp
+.pnp.js
+.pnpm-debug.log
+
+# testing
+coverage
+
+# next.js
+.next/
+out/
+build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Vercel
+.vercel
+.now
+
+# turbo
+.turbo
diff --git a/packages/commons-ui-payload/.eslintrc.js b/packages/commons-ui-payload/.eslintrc.js
new file mode 100644
index 000000000..a728847a6
--- /dev/null
+++ b/packages/commons-ui-payload/.eslintrc.js
@@ -0,0 +1,4 @@
+module.exports = {
+ root: true,
+ extends: ["eslint-config-commons-ui"],
+};
diff --git a/packages/commons-ui-payload/.lintstagedrc.js b/packages/commons-ui-payload/.lintstagedrc.js
new file mode 100644
index 000000000..bce8a3fb3
--- /dev/null
+++ b/packages/commons-ui-payload/.lintstagedrc.js
@@ -0,0 +1 @@
+module.exports = require("eslint-config-commons-ui/.lintstagedrc");
diff --git a/packages/commons-ui-payload/jest.config.js b/packages/commons-ui-payload/jest.config.js
new file mode 100644
index 000000000..5dcb2b586
--- /dev/null
+++ b/packages/commons-ui-payload/jest.config.js
@@ -0,0 +1,14 @@
+const defaultConfig = require("jest-config-commons-ui");
+
+const { moduleNameMapper } = defaultConfig;
+
+module.exports = {
+ ...defaultConfig,
+ moduleNameMapper: {
+ ...moduleNameMapper,
+ // Handle module aliases
+ "^@/commons-ui/core/(.*)$": "/../commons-ui-core/src/$1",
+ "^@/commons-ui/next/(.*)$": "/../commons-ui-next/src/$1",
+ "^@/commons-ui/payload/(.*)$": "/src/$1",
+ },
+};
diff --git a/packages/commons-ui-payload/jest.setup.js b/packages/commons-ui-payload/jest.setup.js
new file mode 100644
index 000000000..6f6929f58
--- /dev/null
+++ b/packages/commons-ui-payload/jest.setup.js
@@ -0,0 +1,12 @@
+/* eslint-env jest */
+
+jest.mock("next/router", () => ({
+ useRouter: jest.fn().mockImplementation(() => ({
+ asPath: "",
+ isReady: true,
+ push: jest.fn(),
+ query: {},
+ })),
+}));
+
+module.exports = require("@commons-ui/testing-library/jest.setup");
diff --git a/packages/commons-ui-payload/jsconfig.json b/packages/commons-ui-payload/jsconfig.json
new file mode 100644
index 000000000..2b74ff6a9
--- /dev/null
+++ b/packages/commons-ui-payload/jsconfig.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/commons-ui/payload/*": ["./src/*"]
+ }
+ },
+ "exclude": ["node_modules"]
+}
diff --git a/packages/commons-ui-payload/package.json b/packages/commons-ui-payload/package.json
new file mode 100644
index 000000000..c93cb6d71
--- /dev/null
+++ b/packages/commons-ui-payload/package.json
@@ -0,0 +1,66 @@
+{
+ "name": "@commons-ui/payload",
+ "version": "0.0.1",
+ "private": false,
+ "author": "Code for Africa ",
+ "description": "",
+ "main": "src/index.js",
+ "keywords": [
+ "react",
+ "react-component",
+ "mui",
+ "material-ui",
+ "material design"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/codeforafrica/ui.git",
+ "directory": "packages/commons-ui-core"
+ },
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/codeforafrica/ui/issues"
+ },
+ "scripts": {
+ "jest": "jest",
+ "lint-check": "TIMING=1 eslint './'",
+ "lint": "TIMING=1 eslint --fix './'",
+ "clean": "rm -rf .turbo node_modules dist"
+ },
+ "devDependencies": {
+ "@babel/core": "catalog:",
+ "@babel/preset-react": "catalog:",
+ "@commons-ui/testing-library": "workspace:*",
+ "@emotion/react": "catalog:",
+ "@emotion/styled": "catalog:",
+ "@mui/material": "catalog:",
+ "@mui/utils": "catalog:",
+ "@types/react": "catalog:",
+ "babel-loader": "catalog:",
+ "eslint": "catalog:",
+ "eslint-config-commons-ui": "workspace:*",
+ "identity-obj-proxy": "catalog:",
+ "jest": "catalog:",
+ "jest-config-commons-ui": "workspace:*",
+ "prettier": "catalog:",
+ "react": "catalog:",
+ "react-dom": "catalog:",
+ "react-test-renderer": "catalog:",
+ "require-from-string": "catalog:",
+ "typescript": "catalog:",
+ "webpack": "catalog:"
+ },
+ "peerDependencies": {
+ "@babel/core": "catalog:",
+ "@commons-ui/core": "workspace:*",
+ "@commons-ui/next": "workspace:*",
+ "@mui/material": "catalog:",
+ "clsx": "catalog:",
+ "next": "catalog:",
+ "prop-types": "catalog:",
+ "react": "catalog:",
+ "react-dom": "catalog:",
+ "slate": "catalog:"
+ },
+ "dependencies": {}
+}
diff --git a/packages/commons-ui-next/src/RichText/RichText.js b/packages/commons-ui-payload/src/RichText/RichText.js
similarity index 96%
rename from packages/commons-ui-next/src/RichText/RichText.js
rename to packages/commons-ui-payload/src/RichText/RichText.js
index 6f1ea3ae0..dd1c236bd 100644
--- a/packages/commons-ui-next/src/RichText/RichText.js
+++ b/packages/commons-ui-payload/src/RichText/RichText.js
@@ -1,11 +1,9 @@
/* eslint-disable react/no-array-index-key */
+import { Link, RichTypography } from "@commons-ui/next";
import { Box } from "@mui/material";
import React, { Fragment } from "react";
import { Text } from "slate";
-import Link from "@/commons-ui/next/Link";
-import RichTypography from "@/commons-ui/next/RichTypography";
-
const DEFAULT_PROPS = {
html: false,
};
diff --git a/packages/commons-ui-next/src/RichText/RichText.snap.js b/packages/commons-ui-payload/src/RichText/RichText.snap.js
similarity index 100%
rename from packages/commons-ui-next/src/RichText/RichText.snap.js
rename to packages/commons-ui-payload/src/RichText/RichText.snap.js
diff --git a/packages/commons-ui-next/src/RichText/RichText.test.js b/packages/commons-ui-payload/src/RichText/RichText.test.js
similarity index 100%
rename from packages/commons-ui-next/src/RichText/RichText.test.js
rename to packages/commons-ui-payload/src/RichText/RichText.test.js
diff --git a/packages/commons-ui-next/src/RichText/index.js b/packages/commons-ui-payload/src/RichText/index.js
similarity index 100%
rename from packages/commons-ui-next/src/RichText/index.js
rename to packages/commons-ui-payload/src/RichText/index.js
diff --git a/packages/commons-ui-payload/src/index.js b/packages/commons-ui-payload/src/index.js
new file mode 100644
index 000000000..ace4dbf6b
--- /dev/null
+++ b/packages/commons-ui-payload/src/index.js
@@ -0,0 +1,3 @@
+/* eslint-disable import/prefer-default-export */
+
+export { default as RichText } from "./RichText";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6ccb664b1..b1c903e82 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1049,6 +1049,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/react':
specifier: 'catalog:'
version: 11.13.3(@types/react@18.3.10)(react@18.3.1)
@@ -2569,6 +2572,91 @@ importers:
specifier: 'catalog:'
version: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))
+ packages/commons-ui-payload:
+ dependencies:
+ '@commons-ui/core':
+ specifier: workspace:*
+ version: link:../commons-ui-core
+ '@commons-ui/next':
+ specifier: workspace:*
+ version: link:../commons-ui-next
+ clsx:
+ specifier: 'catalog:'
+ version: 2.1.1
+ next:
+ specifier: 'catalog:'
+ version: 14.2.13(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.69.4)
+ prop-types:
+ specifier: 'catalog:'
+ version: 15.8.1
+ slate:
+ specifier: 'catalog:'
+ version: 0.103.0
+ devDependencies:
+ '@babel/core':
+ specifier: 'catalog:'
+ version: 7.25.2
+ '@babel/preset-react':
+ specifier: 'catalog:'
+ version: 7.24.7(@babel/core@7.25.2)
+ '@commons-ui/testing-library':
+ specifier: workspace:*
+ version: link:../commons-ui-testing-library
+ '@emotion/react':
+ specifier: 'catalog:'
+ version: 11.13.3(@types/react@18.3.10)(react@18.3.1)
+ '@emotion/styled':
+ specifier: 'catalog:'
+ version: 11.13.0(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react@18.3.1)
+ '@mui/material':
+ specifier: 'catalog:'
+ version: 5.16.7(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react@18.3.1))(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@mui/utils':
+ specifier: 'catalog:'
+ version: 5.16.6(@types/react@18.3.10)(react@18.3.1)
+ '@types/react':
+ specifier: 'catalog:'
+ version: 18.3.10
+ babel-loader:
+ specifier: 'catalog:'
+ version: 9.2.1(@babel/core@7.25.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))
+ eslint:
+ specifier: 'catalog:'
+ version: 8.57.1
+ eslint-config-commons-ui:
+ specifier: workspace:*
+ version: link:../eslint-config-commons-ui
+ identity-obj-proxy:
+ specifier: 'catalog:'
+ version: 3.0.0
+ jest:
+ specifier: 'catalog:'
+ version: 29.7.0(@types/node@22.7.4)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.6.2))
+ jest-config-commons-ui:
+ specifier: workspace:*
+ version: link:../jest-config-commons-ui
+ prettier:
+ specifier: 'catalog:'
+ version: 3.3.3
+ react:
+ specifier: 'catalog:'
+ version: 18.3.1
+ react-dom:
+ specifier: 'catalog:'
+ version: 18.3.1(react@18.3.1)
+ react-test-renderer:
+ specifier: 'catalog:'
+ version: 18.3.1(react@18.3.1)
+ require-from-string:
+ specifier: 'catalog:'
+ version: 2.0.2
+ typescript:
+ specifier: 'catalog:'
+ version: 5.6.2
+ webpack:
+ specifier: 'catalog:'
+ version: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack-cli@4.10.0(webpack-bundle-analyzer@4.10.2)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))
+
packages/commons-ui-testing-library:
dependencies:
'@testing-library/jest-dom':