-
- {title && (
-
- {!!icon && }
- {title}
-
+
+
+
+ {title && (
+
+ {!!icon && }
+ {title}
+
+ )}
+
+ {children &&
{children}
}
+ {!children && data && (
+
{getModule(data)}
)}
- {children && {children}
}
- {!children && data && (
- {getModule(data)}
- )}
-
+
);
};
diff --git a/src/components/ContentfulModule/StepsModule/StepsModule.css b/src/components/ContentfulModule/StepsModule/StepsModule.css
new file mode 100644
index 00000000..7148664e
--- /dev/null
+++ b/src/components/ContentfulModule/StepsModule/StepsModule.css
@@ -0,0 +1,135 @@
+.StepsModule {
+ display: flex;
+ flex-direction: column;
+ gap: calc(var(--s__unit) * 6);
+ padding: var(--s__main-padding) 0;
+
+ details {
+ border: 1px solid #ececec;
+ border-radius: var(--s__main-border-radius);
+ padding: var(--s__main-padding);
+
+ &[open] summary::after {
+ transform: rotate(135deg);
+ }
+ }
+
+ summary {
+ align-items: center;
+ color: var(--c__primary);
+ cursor: pointer;
+ display: flex;
+ justify-content: space-between;
+
+ &::-webkit-details-marker {
+ display: none;
+ }
+
+ &,
+ h3 {
+ font-size: 1.5rem;
+ }
+
+ h3 {
+ font-weight: var(--fw__small);
+ margin: 0;
+ }
+
+ &::after {
+ border-color: var(--c__primary);
+ border-style: solid;
+ border-width: 0.15em 0.15em 0 0;
+ content: "";
+ display: inline-block;
+ height: 0.45em;
+ left: -0.5em;
+ margin-left: 2rem;
+ position: relative;
+ transform: rotate(45deg) translateY(50%);
+ transform-origin: center;
+ transition: transform 0.2s ease;
+ vertical-align: middle;
+ width: 0.45em;
+ }
+ }
+
+ &__content {
+ border-top: 1px solid #ececec;
+ margin-top: var(--s__main-padding);
+ }
+
+ &__actions {
+ align-items: center;
+ color: var(--c__primary);
+ display: flex;
+ justify-content: space-between;
+ margin: calc(var(--s__unit) * 4) 0;
+ position: relative;
+
+ .copy {
+ font-size: 0.9rem;
+
+ &::after {
+ background-color: var(--c__primary);
+ content: "";
+ display: inline-block;
+ height: 20px;
+ margin-left: 10px;
+ mask-image: url("../../../images/icons/copy.svg");
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ position: relative;
+ vertical-align: middle;
+ width: 20px;
+ }
+
+ &:hover {
+ color: var(--c__primary);
+ cursor: pointer;
+
+ &::after {
+ background-color: var(--c__primary);
+ content: "";
+ display: inline-block;
+ height: 20px;
+ margin-left: 10px;
+ mask-image: url("../../../images/icons/copy.svg");
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ position: relative;
+ vertical-align: middle;
+ width: 20px;
+ }
+
+ &:hover {
+ color: var(--c__primary);
+ cursor: pointer;
+
+ &::before {
+ background-color: var(--c__primary);
+ }
+ }
+ }
+ }
+
+ .copy-popup {
+ opacity: 0;
+ position: absolute;
+ right: 30px; /* icon width + margin */
+ text-transform: uppercase;
+ top: 0;
+ transition: transform 0.2s ease-in, opacity 0.5s;
+
+ &--active {
+ opacity: 1;
+ transform: translateY(-2em);
+ }
+ }
+ }
+
+ &__copy-action {
+ margin-left: auto;
+ }
+}
diff --git a/src/components/ContentfulModule/StepsModule/StepsModule.jsx b/src/components/ContentfulModule/StepsModule/StepsModule.jsx
new file mode 100644
index 00000000..ca52c4de
--- /dev/null
+++ b/src/components/ContentfulModule/StepsModule/StepsModule.jsx
@@ -0,0 +1,97 @@
+import React from "react";
+import { formatRichText } from "../../../helpers/formatting";
+import {
+ StepsModulePropTypes,
+ StepsModuleDefaultProps,
+} from "./StepsModulePropTypes";
+import { getTranslatedText } from "../../../utils/getTranslatedText";
+import { handleAnchorClick } from "../../Faq";
+
+import "./StepsModule.css";
+import { useEffect } from "react";
+import { openDetailsByHash } from "../../../helpers/handlers";
+import Button from "../../Button";
+import Constraint from "../../Constraint";
+import classNames from "classnames";
+import { graphql } from "gatsby";
+
+const StepsModule = ({ steps, fullWidth }) => {
+ useEffect(() => {
+ window.addEventListener(`hashchange`, openDetailsByHash);
+ openDetailsByHash();
+
+ return () => {
+ window.removeEventListener(`hashchange`, openDetailsByHash);
+ };
+ }, []);
+
+ return (
+
+
+ {steps.map((step, index) => {
+ const tabId = `tab-${index + 1}`;
+ return (
+
+
+
+
+ {getTranslatedText(`labels.step`)} {index + 1}.
+
+ {` `}
+ {step.question}
+
+
+
+ {formatRichText(step.answer.raw)}
+
+ {step?.additionalLink && (
+
+ )}
+
+
+
+
+ );
+ })}
+
+
+ );
+};
+
+StepsModule.propTypes = StepsModulePropTypes;
+
+StepsModule.defaultProps = StepsModuleDefaultProps;
+
+export default StepsModule;
+
+export const query = graphql`
+ fragment StepsModuleFragment on ContentfulStepsModule {
+ steps {
+ ... on Node {
+ id
+ internal {
+ type
+ }
+ ...FaqItemFragment
+ }
+ }
+ }
+`;
diff --git a/src/components/ContentfulModule/StepsModule/StepsModulePropTypes.js b/src/components/ContentfulModule/StepsModule/StepsModulePropTypes.js
new file mode 100644
index 00000000..2bc9df30
--- /dev/null
+++ b/src/components/ContentfulModule/StepsModule/StepsModulePropTypes.js
@@ -0,0 +1,16 @@
+import PropTypes from "prop-types";
+import { FaqItemPropTypes } from "../../Faq/FaqModule/FaqItem/FaqItemPropTypes";
+
+const StepsModulePropTypes = {
+ steps: PropTypes.arrayOf(
+ PropTypes.oneOfType([PropTypes.shape(FaqItemPropTypes)])
+ ),
+ fullWidth: PropTypes.bool,
+};
+
+const StepsModuleDefaultProps = {
+ steps: [],
+ fullWidth: false,
+};
+
+export { StepsModuleDefaultProps, StepsModulePropTypes };
diff --git a/src/components/ContentfulModule/StepsModule/index.js b/src/components/ContentfulModule/StepsModule/index.js
new file mode 100644
index 00000000..d22db113
--- /dev/null
+++ b/src/components/ContentfulModule/StepsModule/index.js
@@ -0,0 +1,7 @@
+import StepsModule from "./StepsModule";
+import {
+ StepsModulePropTypes,
+ StepsModuleDefaultProps,
+} from "./StepsModulePropTypes";
+
+export { StepsModule, StepsModuleDefaultProps, StepsModulePropTypes };
diff --git a/src/components/Faq/Faq.js b/src/components/Faq/Faq.js
index 697a6cd3..dde0cb65 100644
--- a/src/components/Faq/Faq.js
+++ b/src/components/Faq/Faq.js
@@ -14,23 +14,7 @@ import { ResourceListModulePropTypes } from "../ContentfulModule/ResourceListMod
import { formatRichText } from "../../helpers/formatting";
import "./Faq.css";
-
-// Used stackoverflow as reference
-// Not a 1:1 copy
-// https://stackoverflow.com/a/37033774
-const openTarget = () => {
- const hash = location.hash.substring(1);
- if (hash) {
- const details = Array.from(document.getElementById(hash).children).find(
- (element) => {
- return element.tagName === `DETAILS`;
- }
- );
- if (details) {
- details.open = true;
- }
- }
-};
+import { openDetailsByHash } from "../../helpers/handlers";
const Faq = ({
title,
@@ -42,11 +26,11 @@ const Faq = ({
crumbs,
}) => {
useEffect(() => {
- window.addEventListener(`hashchange`, openTarget);
- openTarget();
+ window.addEventListener(`hashchange`, openDetailsByHash);
+ openDetailsByHash();
return () => {
- window.removeEventListener(`hashchange`, openTarget);
+ window.removeEventListener(`hashchange`, openDetailsByHash);
};
}, []);
diff --git a/src/components/Faq/FaqModule/FaqItem/FaqItemPropTypes.js b/src/components/Faq/FaqModule/FaqItem/FaqItemPropTypes.js
index 75b1a1b2..2601f1c6 100644
--- a/src/components/Faq/FaqModule/FaqItem/FaqItemPropTypes.js
+++ b/src/components/Faq/FaqModule/FaqItem/FaqItemPropTypes.js
@@ -1,4 +1,5 @@
import PropTypes from "prop-types";
+import { linkPropTypes } from "../../../../helpers/genericPropTypes";
const FaqItemPropTypes = {
id: PropTypes.string.isRequired,
@@ -8,6 +9,7 @@ const FaqItemPropTypes = {
references: PropTypes.array,
}).isRequired,
index: PropTypes.number.isRequired,
+ additionalLink: linkPropTypes,
};
export { FaqItemPropTypes };
diff --git a/src/components/Faq/index.js b/src/components/Faq/index.js
index c13ec88e..7c83a459 100644
--- a/src/components/Faq/index.js
+++ b/src/components/Faq/index.js
@@ -2,5 +2,12 @@ import Faq from "./Faq";
import { FaqNavDataPropTypes } from "./Faq";
import { FaqNav } from "./FaqNav";
import { FaqModulePropTypes } from "./FaqModule/FaqModulePropTypes";
+import { handleAnchorClick } from "./FaqModule/FaqItem/faqItemUtils";
-export { Faq, FaqNavDataPropTypes, FaqNav, FaqModulePropTypes };
+export {
+ Faq,
+ FaqNavDataPropTypes,
+ FaqNav,
+ FaqModulePropTypes,
+ handleAnchorClick,
+};
diff --git a/src/components/LinkCollectionWithImage/LinkCollectionWithImage.js b/src/components/LinkCollectionWithImage/LinkCollectionWithImage.js
deleted file mode 100644
index 3bd32c7f..00000000
--- a/src/components/LinkCollectionWithImage/LinkCollectionWithImage.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import * as React from "react";
-import PropTypes from "prop-types";
-import { GatsbyImage, getImage } from "gatsby-plugin-image";
-
-// Style.
-import "./LinkCollectionWithImage.css";
-import { gatsbyImagePropType } from "../../helpers/genericPropTypes";
-
-const LinkCollectionWithImage = ({ title, children, image }) => {
- return (
-
-
- {!!title &&
{title}
}
-
-
-
- {image && (
-
-
-
- )}
-
- );
-};
-
-LinkCollectionWithImage.propTypes = {
- title: PropTypes.string,
- children: PropTypes.node,
- image: gatsbyImagePropType,
-};
-
-export default LinkCollectionWithImage;
diff --git a/src/components/LinkCollectionWithImage/index.js b/src/components/LinkCollectionWithImage/index.js
deleted file mode 100644
index 5c2b5544..00000000
--- a/src/components/LinkCollectionWithImage/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from "./LinkCollectionWithImage";
diff --git a/src/components/Section/Section.css b/src/components/Section/Section.css
index 39601c13..1ebd95b6 100644
--- a/src/components/Section/Section.css
+++ b/src/components/Section/Section.css
@@ -28,10 +28,6 @@
&.ProtestFormsSection {
margin-bottom: calc(var(--s__unit) * 10);
}
-
- &.BeVigilantSection {
- background-color: #f6f6f6;
- }
}
.HeroSection {
diff --git a/src/constants/AdditionalNavigation.js b/src/constants/AdditionalNavigation.js
index d0abb509..5e6708cd 100644
--- a/src/constants/AdditionalNavigation.js
+++ b/src/constants/AdditionalNavigation.js
@@ -1,38 +1,136 @@
export const ADDITIONAL_NAVIGATION = {
"/pagalba-ukrainai/savanoryste": [
{
- pathname: `/pagalba-ukrainai/aukojimas`,
+ pathname: `/pagalba-ukrainai/aukojimas/`,
title: `Aukojimas`,
},
],
"/pagalba-ukrainai/aukojimas": [
{
- pathname: `/pagalba-ukrainai/savanoryste`,
+ pathname: `/pagalba-ukrainai/savanoryste/`,
title: `Savanorystė`,
},
],
"/ua/dopomoha/pozhertvy": [
{
- pathname: `/ua/dopomoha/volonterstvo`,
+ pathname: `/ua/dopomoha/volonterstvo/`,
title: `Волонтерство`,
},
],
"/ua/dopomoha/volonterstvo": [
{
- pathname: `/ua/dopomoha/pozhertvy`,
+ pathname: `/ua/dopomoha/pozhertvy/`,
title: `Пожертви`,
},
],
"/en/support-ukraine/donation": [
{
- pathname: `/en/support-ukraine/volunteering`,
+ pathname: `/en/support-ukraine/volunteering/`,
title: `Volunteering`,
},
],
"/en/support-ukraine/volunteering": [
{
- pathname: `/en/support-ukraine/donation`,
+ pathname: `/en/support-ukraine/donation/`,
title: `Donation`,
},
],
+
+ // @todo: fix these links once we have all the slugs for personalized guide pages
+ /* Personalized guides */
+ /* Guide for new arrivals */
+ "/guide-for-new-arrivals": [
+ {
+ pathname: `/guide-for-persons-with-children/`,
+ title: `Guide for persons with children`,
+ },
+ {
+ pathname: `/guide-for-persons-with-disabilities/`,
+ title: `Guide for persons with disabilities`,
+ },
+ ],
+ "/en/guide-for-new-arrivals": [
+ {
+ pathname: `/en/guide-for-persons-with-children/`,
+ title: `Guide for persons with children`,
+ },
+ {
+ pathname: `/en/guide-for-persons-with-disabilities/`,
+ title: `Guide for persons with disabilities`,
+ },
+ ],
+ "/ua/guide-for-new-arrivals": [
+ {
+ pathname: `/ua/guide-for-persons-with-children/`,
+ title: `Guide for persons with children`,
+ },
+ {
+ pathname: `/ua/guide-for-persons-with-disabilities/`,
+ title: `Guide for persons with disabilities`,
+ },
+ ],
+
+ /* Guide for persons with children */
+ "/guide-for-persons-with-children": [
+ {
+ pathname: `/guide-for-persons-with-disabilities/`,
+ title: `Guide for persons with disabilities`,
+ },
+ {
+ pathname: `/guide-for-new-arrivals/`,
+ title: `Guide for new arrivals`,
+ },
+ ],
+ "/en/guide-for-persons-with-children": [
+ {
+ pathname: `/en/guide-for-persons-with-disabilities/`,
+ title: `Guide for persons with disabilities`,
+ },
+ {
+ pathname: `/en/guide-for-new-arrivals/`,
+ title: `Guide for new arrivals`,
+ },
+ ],
+ "/ua/guide-for-persons-with-children": [
+ {
+ pathname: `/ua/guide-for-persons-with-disabilities/`,
+ title: `Guide for persons with disabilities`,
+ },
+ {
+ pathname: `/ua/guide-for-new-arrivals/`,
+ title: `Guide for new arrivals`,
+ },
+ ],
+
+ /* Guide for persons with disabilities */
+ "/guide-for-persons-with-disabilities": [
+ {
+ pathname: `/guide-for-new-arrivals/`,
+ title: `Guide for new arrivals`,
+ },
+ {
+ pathname: `/guide-for-persons-with-children/`,
+ title: `Guide for persons with children`,
+ },
+ ],
+ "/en/guide-for-persons-with-disabilities": [
+ {
+ pathname: `/en/guide-for-new-arrivals/`,
+ title: `Guide for new arrivals`,
+ },
+ {
+ pathname: `/en/guide-for-persons-with-children/`,
+ title: `Guide for persons with children`,
+ },
+ ],
+ "/ua/guide-for-persons-with-disabilities": [
+ {
+ pathname: `/ua/guide-for-new-arrivals/`,
+ title: `Guide for new arrivals`,
+ },
+ {
+ pathname: `/ua/guide-for-persons-with-children/`,
+ title: `Guide for persons with children`,
+ },
+ ],
};
diff --git a/src/constants/contentfulIds.js b/src/constants/contentfulIds.js
index 56657565..c30a7324 100644
--- a/src/constants/contentfulIds.js
+++ b/src/constants/contentfulIds.js
@@ -1,7 +1,11 @@
const NAVIGATION_ID = `1yKThqiNevVEU4BCn7zZ9y`;
+// This is the PRODUCTION homepage
const HOMEPAGE_ID = `VoE6QU1LhN2Y5h6Tja3fq`;
+// This is the DUMMY homepage
+// const HOMEPAGE_ID = `2hHrtVu5fUseOPMTxz82fV`;
+
const PROMOLINE_ID = `1zlccw24eib2cd3wTXRHfk`;
module.exports = {
diff --git a/src/helpers/genericPropTypes.js b/src/helpers/genericPropTypes.js
index 4df031ac..93b64696 100644
--- a/src/helpers/genericPropTypes.js
+++ b/src/helpers/genericPropTypes.js
@@ -40,18 +40,18 @@ const navigationPropTypes = PropTypes.shape({
node_locale: localePropType.isRequired,
});
+const linkPropTypes = PropTypes.shape({
+ id: PropTypes.string,
+ label: PropTypes.string,
+ url: PropTypes.string,
+ sublabel: PropTypes.string,
+});
+
const promoLinePropTypes = PropTypes.shape({
heading: PropTypes.string.isRequired,
headingLink: PropTypes.string,
subheading: PropTypes.string,
- linkButton: PropTypes.arrayOf(
- PropTypes.shape({
- id: PropTypes.string,
- label: PropTypes.string,
- url: PropTypes.string,
- sublabel: PropTypes.string,
- })
- ),
+ linkButton: PropTypes.arrayOf(linkPropTypes),
});
const nodeSlugsPropTypes = PropTypes.shape({
@@ -70,6 +70,7 @@ export {
localePropType,
gatsbyImagePropType,
navigationPropTypes,
+ linkPropTypes,
promoLinePropTypes,
nodeSlugsPropTypes,
nodeSlugsDefaultProps,
diff --git a/src/helpers/handlers.js b/src/helpers/handlers.js
index a1348954..9ba52cbc 100644
--- a/src/helpers/handlers.js
+++ b/src/helpers/handlers.js
@@ -26,4 +26,31 @@ const getRichTextModuleData = (node, refs) => {
return moduleData || null;
};
-export { isUkrainianPage, getLocaleFromPath, getRichTextModuleData };
+// Used stackoverflow as reference
+// Not a 1:1 copy
+// https://stackoverflow.com/a/37033774
+const openDetailsByHash = () => {
+ const hash = location.hash.substring(1);
+ if (hash) {
+ const hashElement = document.getElementById(hash);
+ if (hashElement.tagName === `DETAILS`) {
+ hashElement.open = true;
+ return;
+ }
+
+ const details = Array.from(hashElement.children).find(
+ ({ tagName }) => tagName === `DETAILS`
+ );
+
+ if (details) {
+ details.open = true;
+ }
+ }
+};
+
+export {
+ isUkrainianPage,
+ getLocaleFromPath,
+ getRichTextModuleData,
+ openDetailsByHash,
+};
diff --git a/src/locales/en/index.json b/src/locales/en/index.json
index 7d7d597a..8a9f5b90 100644
--- a/src/locales/en/index.json
+++ b/src/locales/en/index.json
@@ -22,7 +22,8 @@
"email": "E-mail",
"message": "Message",
"source": "Source",
- "links": "Links"
+ "links": "Links",
+ "step": "Step"
},
"organisation": {
"about": "About",
diff --git a/src/locales/lt/index.json b/src/locales/lt/index.json
index 75f90592..e892ac64 100644
--- a/src/locales/lt/index.json
+++ b/src/locales/lt/index.json
@@ -22,7 +22,8 @@
"email": "El. paštas",
"message": "Žinutė",
"source": "Šaltinis",
- "links": "Nuorodos"
+ "links": "Nuorodos",
+ "step": "Žingsnis"
},
"organisation": {
"about": "Apie",
diff --git a/src/locales/ua/index.json b/src/locales/ua/index.json
index 36fd2632..edcfc7dc 100644
--- a/src/locales/ua/index.json
+++ b/src/locales/ua/index.json
@@ -22,7 +22,8 @@
"email": "Е. пошта",
"message": "Повідомлення",
"source": "Джерело",
- "links": "Посилання"
+ "links": "Посилання",
+ "step": "Крок"
},
"organisation": {
"about": "Про",
diff --git a/src/templates/faqIndexPage.jsx b/src/templates/faqIndexPage.jsx
index f91377ac..042fd11f 100644
--- a/src/templates/faqIndexPage.jsx
+++ b/src/templates/faqIndexPage.jsx
@@ -15,6 +15,11 @@ import {
promoLinePropTypes,
} from "../helpers/genericPropTypes";
import { FaqCategoriesPropType } from "../components/Faq/FaqPropTypes";
+import {
+ LinkCollectionModule,
+ LinkCollectionModulePropTypes,
+ LinkCollectionModuleDefaultProps,
+} from "../components/ContentfulModule/LinkCollectionModule";
import { graphql } from "gatsby";
const FaqIndexPage = ({ data, path, pageContext }) => {
@@ -26,6 +31,7 @@ const FaqIndexPage = ({ data, path, pageContext }) => {
const {
contentfulNavigation: navigation,
contentfulPromoLineModule: promoLine,
+ contentfulLinkCollectionModule: personalizedGuidesLinks,
contentfulFaqPage: {
metaTitle,
metaDescription,
@@ -58,6 +64,13 @@ const FaqIndexPage = ({ data, path, pageContext }) => {
)}
+
+ {personalizedGuidesLinks && (
+
+ )}
);
};
@@ -89,6 +102,9 @@ FaqIndexPage.propTypes = {
}),
categories: FaqCategoriesPropType,
}),
+ contentfulLinkCollectionModule: PropTypes.shape(
+ LinkCollectionModulePropTypes
+ ),
}),
};
@@ -99,6 +115,7 @@ FaqIndexPage.defaultProps = {
},
organisations: [],
navData: [],
+ contentfulLinkCollectionModule: LinkCollectionModuleDefaultProps,
};
export default FaqIndexPage;
@@ -127,6 +144,13 @@ export const faqIndexPageQuery = graphql`
...PromoLineFragment
}
+ contentfulLinkCollectionModule(
+ contentful_id: { eq: "1JYPNg9dcfazxccUEpijxk" }
+ ) {
+ id
+ ...LinkCollectionModuleFragment
+ }
+
# Faq Page (all categories for faq nav)
contentfulFaqPage(
contentful_id: { eq: $id }
diff --git a/src/templates/modularPage.jsx b/src/templates/modularPage.jsx
index a813f2f5..3adc5c54 100644
--- a/src/templates/modularPage.jsx
+++ b/src/templates/modularPage.jsx
@@ -1,6 +1,5 @@
import React from "react";
import PropTypes from "prop-types";
-import classNames from "classnames";
import Layout from "../components/Layout";
import Constraint from "../components/Constraint";
@@ -40,7 +39,6 @@ const ModularPage = ({ data, path, pageContext }) => {
pageDescription,
modules,
includeContactForm,
- fullWidthModules,
showBreadcrumbs,
stickyHeader,
},
@@ -88,23 +86,21 @@ const ModularPage = ({ data, path, pageContext }) => {
{pageDescription?.raw && formatRichText(pageDescription.raw)}
-
+
+
+ )}
+ {!!modules?.at(0) &&
+ modules.map((module) => {
+ return (
+
+ );
})}
- >
- {slidingNavData &&
}
- {!!modules?.at(0) &&
- modules.map((module) => {
- return (
-
- );
- })}
-
);
};
@@ -215,6 +211,7 @@ export const modularPageQuery = graphql`
...ResourceListModuleFragment
...LinkCollectionModuleFragment
...HelpSearchFragment
+ ...StepsModuleFragment
}
}
includeContactForm