Skip to content

Commit

Permalink
chore: Refactor repeated form logic in DesignSettings (#2684)
Browse files Browse the repository at this point in the history
  • Loading branch information
DafyddLlyr authored Jan 22, 2024
1 parent f791959 commit 32326cf
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 156 deletions.
Original file line number Diff line number Diff line change
@@ -1,48 +1,19 @@
import Button from "@mui/material/Button";
import Link from "@mui/material/Link";
import { darken, useTheme } from "@mui/material/styles";
import { Team, TeamTheme } from "@opensystemslab/planx-core/types";
import { TeamTheme } from "@opensystemslab/planx-core/types";
import { useFormik } from "formik";
import { useStore } from "pages/FlowEditor/lib/store";
import React, { useEffect, useState } from "react";
import React from "react";
import { getContrastTextColor } from "styleUtils";
import ColorPicker from "ui/editor/ColorPicker";
import InputDescription from "ui/editor/InputDescription";
import InputRow from "ui/shared/InputRow";
import InputRowItem from "ui/shared/InputRowItem";

import { DesignPreview, SettingsForm } from ".";

type FormValues = Pick<TeamTheme, "actionColour">;

export const ButtonForm: React.FC<{ team: Team; onSuccess: () => void }> = ({
team,
onSuccess,
}) => {
import { DesignPreview, FormProps, SettingsForm } from ".";
export const ButtonForm: React.FC<FormProps> = ({ formikConfig }) => {
const theme = useTheme();

useEffect(() => {
setInitialValues({ actionColour: team.theme?.actionColour });
}, [team]);

const [initialValues, setInitialValues] = useState<FormValues>({
actionColour: "",
});

const formik = useFormik<FormValues>({
initialValues,
onSubmit: async (values, { resetForm }) => {
const isSuccess = await useStore.getState().updateTeamTheme(values);
if (isSuccess) {
onSuccess();
// Reset "dirty" status to disable Save & Reset buttons
resetForm({ values });
}
},
validateOnBlur: false,
validateOnChange: false,
enableReinitialize: true,
});
const formik = useFormik<TeamTheme>(formikConfig);

return (
<SettingsForm
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,18 @@
import Link from "@mui/material/Link";
import Typography from "@mui/material/Typography";
import { Team, TeamTheme } from "@opensystemslab/planx-core/types";
import { TeamTheme } from "@opensystemslab/planx-core/types";
import { useFormik } from "formik";
import { useStore } from "pages/FlowEditor/lib/store";
import React, { useEffect, useState } from "react";
import React from "react";
import ImgInput from "ui/editor/ImgInput";
import InputDescription from "ui/editor/InputDescription";
import InputRow from "ui/shared/InputRow";
import InputRowItem from "ui/shared/InputRowItem";
import InputRowLabel from "ui/shared/InputRowLabel";

import { SettingsForm } from ".";
import { FormProps, SettingsForm } from ".";

type FormValues = Pick<TeamTheme, "favicon">;

export const FaviconForm: React.FC<{ team: Team, onSuccess: () => void }> = ({ team, onSuccess }) => {
useEffect(() => {
setInitialValues({ favicon: team.theme?.favicon || "" });
}, [team]);

const [initialValues, setInitialValues] = useState<FormValues>({
favicon: "",
});

const formik = useFormik<FormValues>({
initialValues,
validateOnBlur: false,
validateOnChange: false,
enableReinitialize: true,
onSubmit: async (values, { resetForm }) => {
const isSuccess = await useStore.getState().updateTeamTheme(values);
if (isSuccess) {
onSuccess();
// Reset "dirty" status to disable Save & Reset buttons
resetForm({ values });
}
},
});
export const FaviconForm: React.FC<FormProps> = ({ formikConfig }) => {
const formik = useFormik<TeamTheme>(formikConfig);

const updateFavicon = (newFile: string | undefined) => newFile
? formik.setFieldValue("favicon", newFile)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,45 +1,20 @@
import Link from "@mui/material/Link";
import { getContrastRatio, useTheme } from "@mui/material/styles";
import { Team, TeamTheme } from "@opensystemslab/planx-core/types";
import { TeamTheme } from "@opensystemslab/planx-core/types";
import { useFormik } from "formik";
import { useStore } from "pages/FlowEditor/lib/store";
import React, { useEffect, useState } from "react";
import React from "react";
import ColorPicker from "ui/editor/ColorPicker";
import InputDescription from "ui/editor/InputDescription";
import InputRow from "ui/shared/InputRow";
import InputRowItem from "ui/shared/InputRowItem";

import { DesignPreview, SettingsForm } from ".";
import { DesignPreview, FormProps, SettingsForm } from ".";

type FormValues = Pick<TeamTheme, "linkColour">;

export const TextLinkForm: React.FC<{ team: Team; onSuccess: () => void }> = ({
team,
onSuccess,
}) => {
export const TextLinkForm: React.FC<FormProps> = ({ formikConfig }) => {
const theme = useTheme();

useEffect(() => {
setInitialValues({ linkColour: team.theme?.linkColour });
}, [team]);

const [initialValues, setInitialValues] = useState<FormValues>({
linkColour: "",
});

const formik = useFormik<FormValues>({
initialValues,
onSubmit: async (values, { resetForm }) => {
const isSuccess = await useStore.getState().updateTeamTheme(values);
if (isSuccess) {
onSuccess();
// Reset "dirty" status to disable Save & Reset buttons
resetForm({ values });
}
},
validateOnBlur: false,
validateOnChange: false,
enableReinitialize: true,
const formik = useFormik<TeamTheme>({
...formikConfig,
validate: ({ linkColour }) => {
const isContrastThresholdMet =
getContrastRatio("#FFF", linkColour) > theme.palette.contrastThreshold;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,52 +1,25 @@
import Link from "@mui/material/Link";
import { getContrastRatio, useTheme } from "@mui/material/styles";
import Typography from "@mui/material/Typography";
import { Team, TeamTheme } from "@opensystemslab/planx-core/types";
import { TeamTheme } from "@opensystemslab/planx-core/types";
import { useFormik } from "formik";
import { useStore } from "pages/FlowEditor/lib/store";
import React, { useEffect, useState } from "react";
import React from "react";
import ColorPicker from "ui/editor/ColorPicker";
import InputDescription from "ui/editor/InputDescription";
import InputRow from "ui/shared/InputRow";
import InputRowItem from "ui/shared/InputRowItem";
import InputRowLabel from "ui/shared/InputRowLabel";
import PublicFileUploadButton from "ui/shared/PublicFileUploadButton";

import { DesignPreview, SettingsForm } from ".";
import { DesignPreview, FormProps, SettingsForm } from ".";

type FormValues = Pick<TeamTheme, "primaryColour" | "logo">;

export const ThemeAndLogoForm: React.FC<{
team: Team;
onSuccess: () => void;
}> = ({ team, onSuccess }) => {
export const ThemeAndLogoForm: React.FC<FormProps> = ({ formikConfig }) => {
const theme = useTheme();
const teamName = useStore((state) => state.teamName);

useEffect(() => {
setInitialValues({
primaryColour: team.theme?.primaryColour,
logo: team.theme?.logo,
});
}, [team]);

const [initialValues, setInitialValues] = useState<FormValues>({
primaryColour: "",
logo: "",
});

const formik = useFormik<FormValues>({
initialValues,
onSubmit: async (values, { resetForm }) => {
const isSuccess = await useStore.getState().updateTeamTheme(values);
if (isSuccess) {
onSuccess();
// Reset "dirty" status to disable Save & Reset buttons
resetForm({ values });
}
},
validateOnBlur: false,
validateOnChange: false,
enableReinitialize: true,
const formik = useFormik<TeamTheme>({
...formikConfig,
validate: ({ primaryColour }) => {
const isContrastThresholdMet =
getContrastRatio("#FFF", primaryColour) >
Expand Down Expand Up @@ -117,7 +90,7 @@ export const ThemeAndLogoForm: React.FC<{
<img width="140" src={formik.values.logo} alt="council logo" />
) : (
<Typography color={theme.palette.primary.contrastText}>
{team?.name}
{teamName}
</Typography>
)}
</DesignPreview>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import Button from "@mui/material/Button";
import Snackbar from "@mui/material/Snackbar";
import { styled } from "@mui/material/styles";
import Typography from "@mui/material/Typography";
import { Team } from "@opensystemslab/planx-core/types";
import { FormikProps } from "formik";
import { Team, TeamTheme } from "@opensystemslab/planx-core/types";
import { FormikConfig, FormikProps } from "formik";
import { hasFeatureFlag } from "lib/featureFlags";
import { useStore } from "pages/FlowEditor/lib/store";
import React, { useEffect, useState } from "react";
Expand All @@ -32,29 +32,13 @@ type SettingsFormProps = {
legend: string;
description: React.ReactElement;
input: React.ReactElement;
formik: FormikProps<any>;
formik: FormikProps<TeamTheme>;
preview?: React.ReactElement;
};

const useTeam = () => {
const [team, setTeam] = useState<Team>({} as Team);

useEffect(() => {
const fetchTeam = async () => {
try {
const fetchedTeam = await useStore.getState().fetchCurrentTeam();
if (!fetchedTeam) throw Error("Unable to find team");
setTeam(fetchedTeam);
} catch (error) {
console.error("Error fetching team:", error);
}
};

fetchTeam();
}, []);

return team;
};
export interface FormProps {
formikConfig: FormikConfig<TeamTheme>;
}

export const SettingsForm: React.FC<SettingsFormProps> = ({
formik,
Expand Down Expand Up @@ -106,7 +90,42 @@ export const SettingsForm: React.FC<SettingsFormProps> = ({

const DesignSettings: React.FC = () => {
const isUsingFeatureFlag = hasFeatureFlag("SHOW_TEAM_SETTINGS");
const team = useTeam();
const [formikConfig, setFormikConfig] = useState<FormikConfig<TeamTheme> | undefined>(undefined);

const onSubmit: FormikConfig<TeamTheme>["onSubmit"] = async (values, { resetForm }) => {
const isSuccess = await useStore.getState().updateTeamTheme(values);
if (isSuccess) {
setOpen(true);
// Reset "dirty" status to disable Save & Reset buttons
resetForm({ values });
}
};

/**
* Fetch current team and setup shared form config
*/
useEffect(() => {
const fetchTeam = async () => {
try {
const fetchedTeam = await useStore.getState().fetchCurrentTeam();
if (!fetchedTeam) throw Error("Unable to find team");

setFormikConfig({
initialValues: fetchedTeam.theme,
onSubmit,
validateOnBlur: false,
validateOnChange: false,
enableReinitialize: true,
});
} catch (error) {
console.error("Error fetching team:", error);
}
};

fetchTeam();
}, []);


const [open, setOpen] = useState(false);

const handleClose = (
Expand Down Expand Up @@ -136,10 +155,14 @@ const DesignSettings: React.FC = () => {
</EditorRow>
) : (
<>
<ThemeAndLogoForm team={team} onSuccess={() => setOpen(true)} />
<ButtonForm team={team} onSuccess={() => setOpen(true)} />
<TextLinkForm team={team} onSuccess={() => setOpen(true)} />
<FaviconForm team={team} onSuccess={() => setOpen(true)} />
{formikConfig &&
<>
<ThemeAndLogoForm formikConfig={formikConfig} />
<ButtonForm formikConfig={formikConfig} />
<TextLinkForm formikConfig={formikConfig} />
<FaviconForm formikConfig={formikConfig} />
</>
}
<Snackbar open={open} autoHideDuration={6000} onClose={handleClose}>
<Alert
onClose={handleClose}
Expand Down

0 comments on commit 32326cf

Please sign in to comment.