diff --git a/src/layouts/components/Homepage/HeroBody.tsx b/src/layouts/components/Homepage/HeroBody.tsx index f2f0f3b397..bd594daff2 100644 --- a/src/layouts/components/Homepage/HeroBody.tsx +++ b/src/layouts/components/Homepage/HeroBody.tsx @@ -5,14 +5,19 @@ import { Text, Box, Divider, + VStack, HStack, + Spacer, } from "@chakra-ui/react" import { FormErrorMessage, FormLabel, + IconButton, Input, Radio, + SingleSelect, } from "@opengovsg/design-system-react" +import _ from "lodash" import { useState } from "react" import { BiInfoCircle } from "react-icons/bi" @@ -37,6 +42,285 @@ export interface HeroBodyFormFields { background: string } +const HERO_LAYOUTS = { + CENTERED: { + value: "center", + label: "Centre-aligned text", + }, + IMAGE_ONLY: { + value: "image", + label: "Image only", + }, + SIDE_SECTION: { + value: "side", + label: "Side section", + }, +} as const + +interface HeroCenteredLayoutProps extends HeroBodyFormFields { + index: number + errors: { + title: string + subtitle: string + background: string + } & HeroBodyFormFields +} + +const HeroCenteredLayout = ({ + title, + subtitle, + background, + index, + errors, +}: HeroCenteredLayoutProps) => { + const { onChange } = useEditableContext() + return ( + <> + + Hero title + + {errors.title} + + + Hero subtitle + + {errors.subtitle} + + + {/* TODO: migrate this to design system components */} + + + Hero background image + + + {errors.background} + + + + ) +} + +const HeroImageOnlyLayout = ({ + errors, + background, + index, +}: Omit) => { + const { onChange } = useEditableContext() + return ( + + {/* TODO: migrate this to design system components */} + + + Hero background image + + + {errors.background} + + + ) +} + +type SectionSize = "half" | "one-third" + +type SectionAlignment = "left" | "right" + +type SectionBackgroundColor = "black" | "white" | "translucent gray" + +interface HeroSideSectionProps { + background: string + index: number + errors: { + title: string + subtitle: string + background: string + } & HeroBodyFormFields + size: SectionSize + alignment: SectionAlignment + backgroundColor: SectionBackgroundColor +} + +const HeroSideSectionLayout = ({ + background, + index, + errors, + size = "half", + alignment = "left", + backgroundColor = "black", +}: HeroSideSectionProps) => { + const { onChange } = useEditableContext() + const [, setSectionSize] = useState(size) + const [, setSectionAlignment] = useState(alignment) + const [, setSectionBackgroundColor] = useState(backgroundColor) + + return ( + <> + + {/* TODO: migrate this to design system components */} + + + Hero background image + + + {errors.background} + + + + Section size + { + setSectionSize(nextSectionSize as SectionSize) + }} + defaultValue="half" + > + + + Half (1/2) of banner + + + + Third (1/3) of banner + + + + + + Alignment + { + setSectionAlignment(nextSectionAlignment as SectionAlignment) + }} + defaultValue="left" + > + + + Left + + + + Right + + + + + + Section background colour + + setSectionBackgroundColor("black")} + _focus={{ + boxShadow: "0 0 0 2px var(--chakra-colors-border-action-default)", + }} + > + + + setSectionBackgroundColor("white")} + > + + + setSectionBackgroundColor("translucent gray")} + /> + + + + ) +} + +type HeroBannerLayouts = typeof HERO_LAYOUTS[keyof typeof HERO_LAYOUTS]["value"] + +interface HeroLayoutFormProps { + children: (props: { + currentSelectedOption: HeroBannerLayouts + }) => React.ReactNode +} + +const HeroLayoutForm = ({ children }: HeroLayoutFormProps): JSX.Element => { + const [currentLayout, setCurrentLayout] = useState( + HERO_LAYOUTS.CENTERED.value + ) + + return ( + <> + + Layout + setCurrentLayout(val as HeroBannerLayouts)} + /> + + + {children({ currentSelectedOption: currentLayout })} + + + ) +} + interface HeroBodyProps extends HeroBodyFormFields { index: number errors: { @@ -54,14 +338,10 @@ interface HeroBodyProps extends HeroBodyFormFields { } export const HeroBody = ({ - title, - subtitle, - background, - index, - errors, handleHighlightDropdownToggle, notification, children, + ...rest }: HeroBodyProps) => { const [heroSectionType, setHeroSectionType] = useState( "highlights" @@ -93,48 +373,36 @@ export const HeroBody = ({ - - Hero title - - {errors.title} - - - Hero subtitle - - {errors.subtitle} - - - {/* TODO: migrate this to design system components */} - - - Hero background image - - - {errors.background} - - + + + {({ currentSelectedOption }) => { + if (currentSelectedOption === HERO_LAYOUTS.CENTERED.value) { + return + } + + if (currentSelectedOption === HERO_LAYOUTS.IMAGE_ONLY.value) { + return + } + + if (currentSelectedOption === HERO_LAYOUTS.SIDE_SECTION.value) { + return ( + + ) + } + + const unmatchedOption: never = currentSelectedOption + throw new Error(`Unmatched option for layout: ${unmatchedOption}`) + }} + - + Customise Layout @@ -149,21 +417,11 @@ export const HeroBody = ({ }} defaultValue="highlights" > - - + + Button + Highlights - + Dropdown