diff --git a/src/components/shared/link/link.jsx b/src/components/shared/link/link.jsx index 563623da..a29c1730 100644 --- a/src/components/shared/link/link.jsx +++ b/src/components/shared/link/link.jsx @@ -122,6 +122,12 @@ const Link = ({ > {children} {isUnderline && underline} + {withArrow && ( + + + + + )} ); } diff --git a/src/components/shared/reusable-sections/section-with-big-icons/section-with-big-icons.jsx b/src/components/shared/reusable-sections/section-with-big-icons/section-with-big-icons.jsx index 3842338f..3edf6961 100644 --- a/src/components/shared/reusable-sections/section-with-big-icons/section-with-big-icons.jsx +++ b/src/components/shared/reusable-sections/section-with-big-icons/section-with-big-icons.jsx @@ -1,11 +1,17 @@ +import clsx from 'clsx'; import PropTypes from 'prop-types'; import React from 'react'; import Heading from 'components/shared/heading'; import Link from 'components/shared/link'; -const SectionWithBigIcons = ({ title, items }) => ( -
+const SectionWithBigIcons = ({ className, title, items, isCentered }) => ( +
( > {title} -
    - {items.map(({ icon, title, description, linkUrl }, index) => ( -
  • +
      + {items.map(({ icon, title, description, linkUrl, linkText }, index) => ( +
    • ( rel="noopener noreferrer" withArrow > - {title} - Learn more + {linkText || ( + <> + {title} - Learn more + + )}
    • ))} @@ -50,6 +60,7 @@ const SectionWithBigIcons = ({ title, items }) => ( ); SectionWithBigIcons.propTypes = { + className: PropTypes.string, title: PropTypes.string.isRequired, items: PropTypes.arrayOf( PropTypes.shape({ @@ -57,8 +68,15 @@ SectionWithBigIcons.propTypes = { title: PropTypes.string.isRequired, description: PropTypes.string.isRequired, linkUrl: PropTypes.string.isRequired, + linkText: PropTypes.string, }) ).isRequired, + isCentered: PropTypes.bool, +}; + +SectionWithBigIcons.defaultProps = { + className: '', + isCentered: false, }; export default SectionWithBigIcons; diff --git a/src/components/shared/reusable-sections/text-with-picture/text-with-picture.jsx b/src/components/shared/reusable-sections/text-with-picture/text-with-picture.jsx index 4e4e8548..e46a715f 100644 --- a/src/components/shared/reusable-sections/text-with-picture/text-with-picture.jsx +++ b/src/components/shared/reusable-sections/text-with-picture/text-with-picture.jsx @@ -5,8 +5,21 @@ import React from 'react'; import Button from 'components/shared/button'; import Heading from 'components/shared/heading'; -const TextWithPicture = ({ title, description, image, button, theme }) => ( -
      +const TextWithPicture = ({ + className, + title, + description, + image, + imageClassName, + button, + theme, +}) => ( +
      ( )} >
      ( )}
      -
      {image}
      +
      {image}
      {button && theme === 'imageFullWidth' && ( )}
      @@ -69,21 +83,26 @@ const TextWithPicture = ({ title, description, image, button, theme }) => ( ); TextWithPicture.propTypes = { + className: PropTypes.string, title: PropTypes.string.isRequired, description: PropTypes.string.isRequired, image: PropTypes.node.isRequired, + imageClassName: PropTypes.string, button: PropTypes.shape({ label: PropTypes.string.isRequired, link: PropTypes.string.isRequired, rel: PropTypes.string, target: PropTypes.string, + hiddenLabel: PropTypes.string, }), theme: PropTypes.oneOf(['imageLeft', 'imageRight', 'imageFullWidth']), }; TextWithPicture.defaultProps = { + className: '', button: null, theme: 'imageLeft', + imageClassName: '', }; export default TextWithPicture; diff --git a/src/images/icons/calendar.svg b/src/images/icons/calendar.svg new file mode 100644 index 00000000..c4f83297 --- /dev/null +++ b/src/images/icons/calendar.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/icons/consolidation.svg b/src/images/icons/consolidation.svg new file mode 100644 index 00000000..49028b62 --- /dev/null +++ b/src/images/icons/consolidation.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/icons/context.svg b/src/images/icons/context.svg new file mode 100644 index 00000000..fa56c4f0 --- /dev/null +++ b/src/images/icons/context.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/icons/customization.svg b/src/images/icons/customization.svg new file mode 100644 index 00000000..f589793a --- /dev/null +++ b/src/images/icons/customization.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/icons/digest.svg b/src/images/icons/digest.svg new file mode 100644 index 00000000..27ec5669 --- /dev/null +++ b/src/images/icons/digest.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/icons/flexibility.svg b/src/images/icons/flexibility.svg new file mode 100644 index 00000000..27c96a8d --- /dev/null +++ b/src/images/icons/flexibility.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/icons/interval.svg b/src/images/icons/interval.svg new file mode 100644 index 00000000..ca27110e --- /dev/null +++ b/src/images/icons/interval.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/icons/selection.svg b/src/images/icons/selection.svg new file mode 100644 index 00000000..a8fdb5a5 --- /dev/null +++ b/src/images/icons/selection.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/pages/digest/fatigue.jpg b/src/images/pages/digest/fatigue.jpg new file mode 100644 index 00000000..be2c3592 Binary files /dev/null and b/src/images/pages/digest/fatigue.jpg differ diff --git a/src/images/pages/digest/notifications-workflow.jpg b/src/images/pages/digest/notifications-workflow.jpg new file mode 100644 index 00000000..5d4e9e60 Binary files /dev/null and b/src/images/pages/digest/notifications-workflow.jpg differ diff --git a/src/images/pages/digest/strategies.jpg b/src/images/pages/digest/strategies.jpg new file mode 100644 index 00000000..96884db0 Binary files /dev/null and b/src/images/pages/digest/strategies.jpg differ diff --git a/src/pages/digest.jsx b/src/pages/digest.jsx new file mode 100644 index 00000000..e9b12988 --- /dev/null +++ b/src/pages/digest.jsx @@ -0,0 +1,187 @@ +import { StaticImage } from 'gatsby-plugin-image'; +import React from 'react'; + +import Layout from 'components/shared/layout'; +import CtaWithForm from 'components/shared/reusable-sections/cta-with-form/cta-with-form'; +import SectionWithBigIcons from 'components/shared/reusable-sections/section-with-big-icons'; +import TextWithPicture from 'components/shared/reusable-sections/text-with-picture'; +import SEO from 'components/shared/seo'; +import calendarIcon from 'images/icons/calendar.svg'; +import consolidationIcon from 'images/icons/consolidation.svg'; +import contextIcon from 'images/icons/context.svg'; +import customizationIcon from 'images/icons/customization.svg'; +import digestIcon from 'images/icons/digest.svg'; +import flexibilityIcon from 'images/icons/flexibility.svg'; +import intervalIcon from 'images/icons/interval.svg'; +import selectionIcon from 'images/icons/selection.svg'; +import settingsIcon from 'images/icons/settings.svg'; + +const NOTIFICATION_BATCHING = [ + { + icon: consolidationIcon, + title: 'Event consolidation', + description: 'Combine multiple events into a single notification.', + linkUrl: '/', + }, + { + icon: customizationIcon, + title: 'Custom grouping', + description: 'Customize event grouping by type or frequency.', + linkUrl: '/', + }, + { + icon: intervalIcon, + title: 'Interval scheduling', + description: ( + <> + Set specific times for digest +
      + delivery. + + ), + linkUrl: '/', + }, + { + icon: flexibilityIcon, + title: 'Flexible strategy', + description: 'Choose between time-based and event-based aggregation.', + linkUrl: '/', + }, + { + icon: contextIcon, + title: 'Context preservation', + description: 'Ensure relevant context accompanies digested notifications.', + linkUrl: '/', + }, + { + icon: settingsIcon, + title: 'User control', + description: 'Reduce fatigue while ensuring key updates reach users.', + linkUrl: '/', + }, +]; + +const USE_CASE_EXAMPLES = [ + { + icon: digestIcon, + title: 'Workflow digest', + description: 'Summary workflow for digesting multiple notifications', + linkUrl: '/', + linkText: 'Show me how', + }, + { + icon: calendarIcon, + title: 'Define digest step', + description: 'Add a simple timed digest step to your workflow.', + linkUrl: '/', + linkText: 'Show me how', + }, + { + icon: selectionIcon, + title: 'Select a digest strategy', + description: 'Learn about the regular, look-back, and scheduled digest steps.', + linkUrl: '/', + }, +]; + +const Digests = () => ( + + + + +
      + } + imageClassName="relative w-full h-[655px] !overflow-visible lg:h-[500px] md:h-[400px] sm:w-full sm-xs:h-96" + /> + + + + +
+ } + imageClassName="relative w-full h-[657px] !overflow-visible lg:h-96 md:h-80 sm:h-72 sm-xs:h-56" + button={{ + label: 'Learn more', + hiddenLabel: 'about multiple digest strategies', + link: '/', + }} + theme="imageRight" + /> + + + + + } + imageClassName="relative w-full h-96 !overflow-visible lg:h-[400px] md:h-80 sm:h-48" + button={{ + label: 'Learn more', + hiddenLabel: 'how to eliminate notification fatigue', + link: '/', + }} + /> + + + +); + +export default Digests; + +export const Head = () => { + const pageMetadata = { + title: "Streamline Notifications with Novu's Digest", + description: + "Consolidate notifications, reduce overload, and keep users informed with Novu's flexible Digest feature.", + }; + return ; +};