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

fix(homepage): placeholder inputs #1451

Merged
merged 16 commits into from
Sep 6, 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
76 changes: 30 additions & 46 deletions src/layouts/EditHomepage/EditHomepage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ import {
RESOURCES_SECTION,
} from "./constants"
import { HomepagePreview } from "./HomepagePreview"
import { getErrorValues } from "./utils"
import { getDefaultValues, getErrorsFromHomepageState } from "./utils"

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

Expand All @@ -78,51 +78,23 @@ const getHasError = (errorArray) =>
_.some(err, (errorMessage) => errorMessage.length > 0)
)

const getHasErrors = (errors) => {
const hasSectionErrors = _.some(errors.sections, (section) => {
// Section is an object, e.g. { hero: {} }
// _.keys(section) produces an array with length 1
// The 0th element of the array contains the sectionType
const sectionType = _.keys(section)[0]
return (
_.some(
section[sectionType],
(errorMessage) => errorMessage.length > 0
) === true
)
})

const hasHighlightErrors = getHasError(errors.highlights)
const hasDropdownElemErrors = getHasError(errors.dropdownElems)

return hasSectionErrors || hasHighlightErrors || hasDropdownElemErrors
}

// Constants
// Section constructors
// TODO: Export all these as const and write wrapper for error...

const enumSection = (type, isError) => {
const enumSection = (type) => {
switch (type) {
case "resources":
return isError
? { resources: getErrorValues(RESOURCES_SECTION) }
: { resources: RESOURCES_SECTION }
return { resources: getDefaultValues(RESOURCES_SECTION) }

case "infobar":
return isError
? { infobar: getErrorValues(INFOBAR_SECTION) }
: { infobar: INFOBAR_SECTION }
return { infobar: getDefaultValues(INFOBAR_SECTION) }

case "infopic":
return isError
? { infopic: getErrorValues(INFOPIC_SECTION) }
: { infopic: INFOPIC_SECTION }
return { infopic: getDefaultValues(INFOPIC_SECTION) }

default:
return isError
? { infobar: getErrorValues(INFOBAR_SECTION) }
: { infobar: INFOBAR_SECTION }
return { infobar: getDefaultValues(INFOBAR_SECTION) }
}
}

Expand Down Expand Up @@ -188,6 +160,7 @@ const EditHomepage = ({ match }) => {
setDisplayHighlights(displayHighlights)
}
const heroSection = frontMatter.sections.filter((section) => !!section.hero)
const errorMessages = getErrorsFromHomepageState(homepageState)

const errorToast = useErrorToast()

Expand Down Expand Up @@ -238,14 +211,14 @@ const EditHomepage = ({ match }) => {
)
// Fill in dropdown elem errors array
dropdownElemsErrors = _.map(dropdown.options, () =>
getErrorValues(DROPDOWN_ELEMENT_SECTION)
getDefaultValues(DROPDOWN_ELEMENT_SECTION)
)
}
if (keyHighlights) {
displayHighlights = _.fill(Array(keyHighlights.length), false)
// Fill in highlights errors array
highlightsErrors = _.map(keyHighlights, () =>
getErrorValues(KEY_HIGHLIGHT_SECTION)
getDefaultValues(KEY_HIGHLIGHT_SECTION)
)
}
// Fill in sectionErrors for hero
Expand All @@ -255,16 +228,16 @@ const EditHomepage = ({ match }) => {
// Check if there is already a resources section
if (section.resources) {
sectionsErrors.push({
resources: getErrorValues(RESOURCES_SECTION),
resources: getDefaultValues(RESOURCES_SECTION),
})
}

if (section.infobar) {
sectionsErrors.push({ infobar: getErrorValues(INFOBAR_SECTION) })
sectionsErrors.push({ infobar: getDefaultValues(INFOBAR_SECTION) })
}

if (section.infopic) {
sectionsErrors.push({ infopic: getErrorValues(INFOPIC_SECTION) })
sectionsErrors.push({ infopic: getDefaultValues(INFOPIC_SECTION) })
}

// Minimize all sections by default
Expand Down Expand Up @@ -536,8 +509,8 @@ const EditHomepage = ({ match }) => {

switch (elemType) {
case "section": {
const val = enumSection(value, false)
const err = enumSection(value, true)
const val = enumSection(value)
const err = enumSection(value)

const newScrollRefs = update(scrollRefs, { $push: [createRef()] })

Expand All @@ -553,8 +526,8 @@ const EditHomepage = ({ match }) => {
break
}
case "dropdownelem": {
const val = DROPDOWN_ELEMENT_SECTION
const err = getErrorValues(DROPDOWN_ELEMENT_SECTION)
const val = getDefaultValues(DROPDOWN_ELEMENT_SECTION)
const err = getDefaultValues(DROPDOWN_ELEMENT_SECTION)

const updatedHomepageState = onCreate(
homepageState,
Expand All @@ -569,8 +542,9 @@ const EditHomepage = ({ match }) => {
case "highlight": {
// depends on index to generate
// If key highlights section exists
const val = KEY_HIGHLIGHT_SECTION
const err = getErrorValues(KEY_HIGHLIGHT_SECTION)
const val = getDefaultValues(KEY_HIGHLIGHT_SECTION)
const err = getDefaultValues(KEY_HIGHLIGHT_SECTION)

const updatedHomepageState = onCreate(
homepageState,
elemType,
Expand Down Expand Up @@ -1119,8 +1093,18 @@ const EditHomepage = ({ match }) => {
/>
</HStack>
<Footer>
{errorMessages.some((message) => message.includes("longer")) && (
<Text
mr="0.25rem"
textStyle="body-2"
textColor="base.content.medium"
>
You have blocks without content. Please add content to your
empty blocks before saving.
</Text>
)}
<LoadingButton
isDisabled={getHasErrors(errors)}
isDisabled={errorMessages.length > 0}
onClick={savePage}
>
Save
Expand Down
34 changes: 15 additions & 19 deletions src/layouts/EditHomepage/HomepagePreview.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// NOTE: Below eslint disable is inherited from our legacy code :(
/* eslint-disable react/no-array-index-key */
import _ from "lodash"
import { Ref, useState } from "react"
import { useParams } from "react-router-dom"

Expand All @@ -18,6 +19,12 @@ import {
InfopicFrontmatterSection,
} from "types/homepage"

import {
INFOBAR_SECTION,
INFOPIC_SECTION,
RESOURCES_SECTION,
} from "./constants"

const isLeftInfoPic = (
sectionIndex: number,
frontMatter: EditorHomepageState["frontMatter"]
Expand Down Expand Up @@ -114,9 +121,8 @@ export const HomepagePreview = ({
<>
<TemplateResourcesSection
key={`section-${sectionIndex}`}
title={section.resources.title}
subtitle={section.resources.subtitle}
button={section.resources.button}
{...RESOURCES_SECTION}
{..._.pickBy(section.resources)}
sectionIndex={sectionIndex}
ref={scrollRefs[sectionIndex]}
/>
Expand All @@ -127,10 +133,8 @@ export const HomepagePreview = ({
<>
<TemplateInfobarSection
key={`section-${sectionIndex}`}
title={section.infobar.title}
subtitle={section.infobar.subtitle}
description={section.infobar.description}
button={section.infobar.button}
{...INFOBAR_SECTION}
{..._.pickBy(section.infobar)}
sectionIndex={sectionIndex}
ref={scrollRefs[sectionIndex]}
/>
Expand All @@ -142,24 +146,16 @@ export const HomepagePreview = ({
{isLeftInfoPic(sectionIndex, frontMatter) ? (
<TemplateInfopicLeftSection
key={`section-${sectionIndex}`}
title={section.infopic.title}
subtitle={section.infopic.subtitle}
description={section.infopic.description}
imageUrl={section.infopic.image}
imageAlt={section.infopic.alt}
button={section.infopic.button}
{...INFOPIC_SECTION}
{..._.pickBy(section.infopic)}
sectionIndex={sectionIndex}
ref={scrollRefs[sectionIndex]}
/>
) : (
<TemplateInfopicRightSection
key={`section-${sectionIndex}`}
title={section.infopic.title}
subtitle={section.infopic.subtitle}
description={section.infopic.description}
imageUrl={section.infopic.image}
imageAlt={section.infopic.alt}
button={section.infopic.button}
{...INFOPIC_SECTION}
{..._.pickBy(section.infopic)}
sectionIndex={sectionIndex}
ref={scrollRefs[sectionIndex]}
/>
Expand Down
1 change: 1 addition & 0 deletions src/layouts/EditHomepage/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const RESOURCES_SECTION = {
title: "Resources",
subtitle: "Add a preview and link to your Resource Room",
button: "",
id: "resources",
} as const

Expand Down
73 changes: 72 additions & 1 deletion src/layouts/EditHomepage/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,78 @@
import _ from "lodash"

export const getErrorValues = (
import {
EditorHomepageState,
HeroFrontmatterSection,
isDropdownSection,
isHighlightSection,
} from "types/homepage"
import { validateDropdownElem, validateHighlight, validateSection } from "utils"

export const getDefaultValues = (
obj: Record<string, string>
): Record<string, string> => {
return _.mapValues(obj, () => "")
}

const validate = <T>(
obj: Record<string, T>,
predicate: (key: string, val: T) => string
): string[] => {
return _(obj)
.entries()
.map(([key, value]) => predicate(key, value))
.filter()
.value()
}

// NOTE: We might wish to extend this so that we map the values to
// error msg etc then extract an overall boolean based on that
// but for now will return a bool
export const getErrorsFromHomepageState = ({
frontMatter,
}: EditorHomepageState): string[] => {
// we validate the frontmatter to check that all the fields are valid
const { sections } = frontMatter
const [initialSection, ...rest] = sections
const heroSection = (initialSection as HeroFrontmatterSection).hero

let errorMessages: string[] = []
if (isHighlightSection(heroSection)) {
const highlightErrors = heroSection.key_highlights.reduce((acc, cur) => {
const curError = validate(cur, validateHighlight)
return [...acc, ...curError]
}, errorMessages)
errorMessages = [...errorMessages, ...highlightErrors]
}

QiluXie marked this conversation as resolved.
Show resolved Hide resolved
// NOTE: This is mutually exclusive with the above check
seaerchin marked this conversation as resolved.
Show resolved Hide resolved
// as our hero section only has these 2 options.
if (isDropdownSection(heroSection)) {
const dropdownErrors = heroSection.dropdown.options.reduce((acc, cur) => {
const curError = validate(cur, validateDropdownElem)
return [...acc, ...curError]
}, errorMessages)
errorMessages = [...errorMessages, ...dropdownErrors]
}

QiluXie marked this conversation as resolved.
Show resolved Hide resolved
// NOTE: Section is an object keyed by the section type
// this is, for example, `{ infobar: someValue }`
const sectionErrors = _(rest)
.map((section) =>
// NOTE: Section obj contains the actual values to validate
// this is, for example, `title`/`subtitle`/`button` etc
_(section)
.entries()
.map(([sectionType, sectionObj]) =>
validate(sectionObj, (key, val) =>
validateSection(sectionType, key, val)
)
)
.flatten()
.value()
)
.flatten()
.value()

return [...errorMessages, ...sectionErrors]
}
3 changes: 3 additions & 0 deletions src/layouts/components/Homepage/HeroDropdownSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const HeroDropdownSection = ({
<Input
placeholder="This is a button"
value={title}
onBlur={onChange}
onChange={onChange}
/>
<FormErrorMessage>{errors.dropdown}</FormErrorMessage>
Expand Down Expand Up @@ -96,6 +97,7 @@ export const HeroDropdownSection = ({
placeholder="Dropdown option title"
id={`dropdownelem-${dropdownOptionIndex}-title`}
value={optionTitle}
onBlur={onChange}
onChange={onChange}
/>
<FormErrorMessage>
Expand All @@ -113,6 +115,7 @@ export const HeroDropdownSection = ({
placeholder="Insert /page-url or https://"
id={`dropdownelem-${dropdownOptionIndex}-url`}
value={optionUrl}
onBlur={onChange}
onChange={onChange}
/>
<FormErrorMessage>
Expand Down
5 changes: 5 additions & 0 deletions src/layouts/components/Homepage/HeroHighlightSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const HeroHighlightSection = ({
id="section-0-hero-button"
placeholder="This is a button"
value={button}
onBlur={onChange}
onChange={onChange}
/>
{/* TODO: Validate button.
Expand All @@ -65,6 +66,7 @@ export const HeroHighlightSection = ({
<Input
placeholder="Insert /page-url or https://"
value={url}
onBlur={onChange}
onChange={onChange}
id="section-0-hero-url"
/>
Expand Down Expand Up @@ -114,6 +116,7 @@ export const HeroHighlightSection = ({
placeholder="Highlight title"
id={`highlight-${highlightIndex}-title`}
value={highlightTitle}
onBlur={onChange}
onChange={onChange}
/>
<FormErrorMessage>
Expand All @@ -131,6 +134,7 @@ export const HeroHighlightSection = ({
placeholder="Highlight description"
id={`highlight-${highlightIndex}-description`}
value={highlightDescription}
onBlur={onChange}
onChange={onChange}
/>
<FormErrorMessage>
Expand All @@ -146,6 +150,7 @@ export const HeroHighlightSection = ({
placeholder="Insert /page-url or https://"
id={`highlight-${highlightIndex}-url`}
value={highlightUrl}
onBlur={onChange}
onChange={onChange}
/>
<FormErrorMessage>
Expand Down
Loading
Loading