Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce new help overlay for add section button #1515

Merged
merged 6 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions src/assets/images/HomepageAnnouncementsSampleImage.tsx

Large diffs are not rendered by default.

274 changes: 274 additions & 0 deletions src/assets/images/HomepageTextCardsSampleImage.tsx

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/assets/images/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ export * from "./SiteLaunchSuccessImage"
export * from "./SiteLaunchFailureImage"
export * from "./SiteLaunchPendingImage"
export * from "./NotFoundSubmarineImage"
export * from "./HomepageAnnouncementsSampleImage"
export * from "./HomepageTextCardsSampleImage"
108 changes: 108 additions & 0 deletions src/components/Editable/AddSectionButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { Box, Center } from "@chakra-ui/react"
import type { Meta, StoryFn } from "@storybook/react"

import {
HomepageAnnouncementsSampleImage,
HomepageTextCardsSampleImage,
} from "assets/images"

import { AddSectionButton } from "./AddSectionButton"

const addSectionButtonMeta = {
title: "Components/AddSectionButton",
component: AddSectionButton,
} as Meta<typeof AddSectionButton>

interface AddSectionButtonOptions {
title: string
subtitle: string
overlayTitle?: string
overlayDescription?: string
overlayImage?: JSX.Element
}

interface AddSectionButtonTemplateArgs {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, what are your thoughts on creating an object interface for each card, then passing in an array?
This way we can

  1. easily extend in the future if needed
  2. less verbose code
  3. Guarantee each object has the same shape in one glance

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adjusted in b688a48! I think I got a little carried away here oops.

buttonText: string
options: AddSectionButtonOptions[]
}

const Template: StoryFn<AddSectionButtonTemplateArgs> = ({
buttonText,
options,
}: AddSectionButtonTemplateArgs) => {
return (
<Box height="50vh" width="450px">
<Center
height="40vh"
bgColor="brand.secondary.100"
my={3}
borderRadius="0.5rem"
>
This space is for content.
</Center>
<AddSectionButton buttonText={buttonText}>
<AddSectionButton.List>
{options.map((option) => {
if (option.overlayTitle && option.overlayDescription) {
return (
<AddSectionButton.HelpOverlay
title={option.overlayTitle}
description={option.overlayDescription}
image={option.overlayImage}
>
<AddSectionButton.Option
title={option.title}
subtitle={option.subtitle}
/>
</AddSectionButton.HelpOverlay>
)
}

return (
<AddSectionButton.Option
title={option.title}
subtitle={option.subtitle}
/>
)
})}
</AddSectionButton.List>
</AddSectionButton>
</Box>
)
}

export const Default = Template.bind({})
Default.args = {
buttonText: "Add section",
options: [
{
title: "Infopic",
subtitle: "Add an image and text",
},
{
title: "Text cards",
subtitle: "Add up to 4 clickable cards with text",
overlayTitle: "Text cards",
overlayDescription:
"Add clickable cards with bite-sized information to your homepage. You can link any page or external URL, such as blog posts, articles, and more.",
overlayImage: <HomepageTextCardsSampleImage />,
},
{
title: "Info-columns",
subtitle: "Add snippets of text in 2- or 3-column layouts",
overlayTitle: "Info-Columns",
overlayDescription:
"Add bite-sized snippets of text in a multi-column layout. These texts aren’t clickable. Perfect for showing informative text that describes your organisation.",
},
{
title: "Announcements",
subtitle: "Add a list of announcements with dates",
overlayTitle: "Announcements",
overlayDescription:
"Make exciting news from your organisation stand out by adding a list of announcements with dates on your homepage.",
overlayImage: <HomepageAnnouncementsSampleImage />,
},
],
}

export default addSectionButtonMeta
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import { HStack, Icon, MenuItemProps, Text } from "@chakra-ui/react"
import {
Box,
HStack,
Icon,
MenuItemProps,
Popover,
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverProps,
PopoverTrigger,
Portal,
Text,
VStack,
} from "@chakra-ui/react"
import { Menu, MenuButtonProps } from "@opengovsg/design-system-react"
import { PropsWithChildren } from "react"
import { BiPlus } from "react-icons/bi"

type AddSectionButtonProps = MenuButtonProps & {
Expand Down Expand Up @@ -54,5 +69,48 @@ const AddSectionButtonOption = ({
)
}

export interface HelpOverlayProps
extends Omit<PopoverProps, "children">,
PropsWithChildren {
title: string
description: string
image?: JSX.Element
}
const HelpOverlay = ({
title,
description,
image,
children,
...rest
}: HelpOverlayProps) => {
return (
<Popover
placement="end"
trigger="hover"
arrowSize={16}
offset={[0, 11]}
{...rest}
>
<PopoverTrigger>
<Box>{children}</Box>
</PopoverTrigger>
{/* Portal is needed to avoid PopoverArrow from jumping around */}
<Portal>
<PopoverContent p="0.75rem">
<PopoverArrow />
<PopoverBody>
<VStack align="left">
{image && <Box pb="1.5rem">{image}</Box>}
<Text textStyle="subhead-1">{title}</Text>
<Text textStyle="body-1">{description}</Text>
</VStack>
</PopoverBody>
</PopoverContent>
</Portal>
</Popover>
)
}

AddSectionButton.Option = AddSectionButtonOption
AddSectionButton.List = Menu.List
AddSectionButton.HelpOverlay = HelpOverlay
2 changes: 1 addition & 1 deletion src/layouts/EditContactUs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import _ from "lodash"
import PropTypes from "prop-types"
import { createRef, useEffect, useState } from "react"

import { Editable } from "components/Editable"
import { Footer } from "components/Footer"
import Header from "components/Header"
import { LoadingButton } from "components/LoadingButton"
Expand Down Expand Up @@ -46,7 +47,6 @@ import { DEFAULT_RETRY_MSG, isEmpty } from "utils"

import { CardsSection } from "./components/ContactUs/CardsSection"
import { GeneralInfoSection } from "./components/ContactUs/GeneralInfoSection"
import { Editable } from "./components/Editable"

/* eslint-disable react/no-array-index-key */

Expand Down
13 changes: 7 additions & 6 deletions src/layouts/EditHomepage/EditHomepage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ import update from "immutability-helper"
import _ from "lodash"
import { useEffect, createRef, useState } from "react"

import { CustomiseSectionsHeader, Editable } from "components/Editable"
import { AddSectionButton } from "components/Editable/AddSectionButton"
import { Footer } from "components/Footer"
import Header from "components/Header"
import { LoadingButton } from "components/LoadingButton"
import { WarningModal } from "components/WarningModal"

import { EditableContextProvider } from "contexts/EditableContext"

// Import hooks
import { useGetHomepageHook } from "hooks/homepageHooks"
import { useUpdateHomepageHook } from "hooks/homepageHooks/useUpdateHomepageHook"
Expand All @@ -36,10 +40,7 @@ import {
import { HomepageStartEditingImage } from "assets"
import { DEFAULT_RETRY_MSG } from "utils"

import { EditableContextProvider } from "../../contexts/EditableContext"
import { useDrag, onCreate, onDelete } from "../../hooks/useDrag"
import { CustomiseSectionsHeader, Editable } from "../components/Editable"
import { AddSectionButton } from "../components/Editable/AddSectionButton"
import { HeroBody } from "../components/Homepage/HeroBody"
import { HeroDropdownSection } from "../components/Homepage/HeroDropdownSection"
import { HeroHighlightSection } from "../components/Homepage/HeroHighlightSection"
Expand Down Expand Up @@ -1091,9 +1092,9 @@ const EditHomepage = ({ match }) => {
</DragDropContext>
</VStack>
</Editable.Accordion>
{/* NOTE: Set the padding here -
We cannot let the button be part of the `Draggable`
as otherwise, when dragging,
{/* NOTE: Set the padding here -
We cannot let the button be part of the `Draggable`
as otherwise, when dragging,
the component will appear over the button
*/}
<Box px="1.5rem">
Expand Down
8 changes: 4 additions & 4 deletions src/layouts/EditNavBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import PropTypes from "prop-types"
import { useEffect, useState } from "react"
import { useQuery } from "react-query"

import { Editable } from "components/Editable"
import { AddSectionButton } from "components/Editable/AddSectionButton"
import { Footer } from "components/Footer"
import Header from "components/Header"
import { LoadingButton } from "components/LoadingButton"
Expand All @@ -31,8 +33,6 @@ import { validateLink } from "utils/validators"
import { getEditNavBarData } from "api"
import { DEFAULT_RETRY_MSG, deslugifyDirectory, isEmpty } from "utils"

import { Editable } from "./components/Editable"
import { AddSectionButton } from "./components/Editable/AddSectionButton"
import { FolderMenuBody } from "./components/NavBar/FolderMenuBody"
import { GroupMenuBody } from "./components/NavBar/GroupMenuBody"
import { PageMenuBody } from "./components/NavBar/PageMenuBody"
Expand Down Expand Up @@ -766,7 +766,7 @@ const EditNavBar = ({ match }) => {
<Box px="1.5rem">
<AddSectionButton buttonText="Add menu item">
<AddSectionButton.List>
{/* NOTE: Check if the site contains any collections in `options`
{/* NOTE: Check if the site contains any collections in `options`
if it does not, prevent creation of a `folder` section
*/}
{options && options.length > 0 && (
Expand Down Expand Up @@ -807,7 +807,7 @@ const EditNavBar = ({ match }) => {
})
}}
/>
{/* NOTE: Check if the site does not contain a resource room or any sections contain `resource_room`
{/* NOTE: Check if the site does not contain a resource room or any sections contain `resource_room`
If either condition is fulfilled, prevent creation of a `resource_room` section */}
{hasResourceRoom &&
!links.some(
Expand Down
6 changes: 3 additions & 3 deletions src/layouts/components/ContactUs/CardsSection.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Text, VStack } from "@chakra-ui/react"
import { DragDropContext } from "@hello-pangea/dnd"

import { useEditableContext } from "contexts/EditableContext"
import { Editable } from "components/Editable"
import { AddSectionButton } from "components/Editable/AddSectionButton"

import { Editable } from "../Editable"
import { AddSectionButton } from "../Editable/AddSectionButton"
import { useEditableContext } from "contexts/EditableContext"

import { ContactCard, ContactCardFrontMatter } from "./ContactCard"
import { LocationCard, LocationCardFrontMatter } from "./LocationCard"
Expand Down
4 changes: 2 additions & 2 deletions src/layouts/components/ContactUs/ContactCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
import _ from "lodash"
import { ChangeEvent, useState } from "react"

import { useEditableContext } from "contexts/EditableContext"
import { Editable } from "components/Editable"

import { Editable } from "../Editable"
import { useEditableContext } from "contexts/EditableContext"

type PhonePrefix = "singapore" | "toll-free"

Expand Down
4 changes: 2 additions & 2 deletions src/layouts/components/ContactUs/GeneralInfoSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import {
} from "@opengovsg/design-system-react"
import { BiInfoCircle } from "react-icons/bi"

import { useEditableContext } from "contexts/EditableContext"
import { Editable } from "components/Editable"

import { Editable } from "../Editable"
import { useEditableContext } from "contexts/EditableContext"

type GeneralInfoFrontMatter = {
agency_name: string
Expand Down
6 changes: 3 additions & 3 deletions src/layouts/components/ContactUs/LocationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import {
import _ from "lodash"
import { BiInfoCircle } from "react-icons/bi"

import { useEditableContext } from "contexts/EditableContext"
import { Editable } from "components/Editable"
import { AddSectionButton } from "components/Editable/AddSectionButton"

import { Editable } from "../Editable"
import { AddSectionButton } from "../Editable/AddSectionButton"
import { useEditableContext } from "contexts/EditableContext"

export type LocationCardFrontMatter = {
address: string[]
Expand Down
3 changes: 1 addition & 2 deletions src/layouts/components/Homepage/HeroBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import _ from "lodash"
import { useState } from "react"
import { BiInfoCircle } from "react-icons/bi"

import { Editable } from "components/Editable"
import { FormContext, FormError, FormTitle } from "components/Form"
import FormFieldMedia from "components/FormFieldMedia"

Expand All @@ -31,8 +32,6 @@ import { HERO_LAYOUTS } from "constants/homepage"

import { useEditableContext } from "contexts/EditableContext"

import { Editable } from "layouts/components/Editable"

import { BxGrayTranslucent } from "assets"
import {
SectionSize,
Expand Down
4 changes: 2 additions & 2 deletions src/layouts/components/Homepage/HeroDropdownSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
import _ from "lodash"
import { BiPlus } from "react-icons/bi"

import { useEditableContext } from "contexts/EditableContext"
import { Editable } from "components/Editable"

import { Editable } from "layouts/components/Editable"
import { useEditableContext } from "contexts/EditableContext"

import { EditorHeroDropdownSection } from "types/homepage"

Expand Down
6 changes: 3 additions & 3 deletions src/layouts/components/Homepage/HeroHighlightSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
import _ from "lodash"
import { BiPlus } from "react-icons/bi"

import { useEditableContext } from "contexts/EditableContext"
import { Editable } from "components/Editable"

import { Editable } from "layouts/components/Editable"
import { useEditableContext } from "contexts/EditableContext"

import { HighlightOption } from "types/homepage"

Expand Down Expand Up @@ -55,7 +55,7 @@ export const HeroHighlightSection = ({
value={button}
onChange={onChange}
/>
{/* TODO: Validate button.
{/* TODO: Validate button.
This isn't being done on prod also.
*/}
<FormErrorMessage>{errors.button}</FormErrorMessage>
Expand Down
4 changes: 2 additions & 2 deletions src/layouts/components/Homepage/InfobarBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {
Textarea,
} from "@opengovsg/design-system-react"

import { useEditableContext } from "contexts/EditableContext"
import { Editable } from "components/Editable"

import { Editable } from "../Editable"
import { useEditableContext } from "contexts/EditableContext"

interface InfobarFormFields {
title: string
Expand Down
Loading