From 1cff2e663b4d3acf6721a38b488835aad6edbc1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Fri, 12 Jan 2024 15:07:34 +0000 Subject: [PATCH] feat: Basic theme and logo updating --- .../DesignSettings/ThemeAndLogoForm.tsx | 69 ++++++++++++++----- .../Settings/DesignSettings/index.tsx | 27 +++++++- .../src/pages/FlowEditor/lib/store/team.ts | 1 - editor.planx.uk/src/theme.ts | 2 +- 4 files changed, 76 insertions(+), 23 deletions(-) diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/DesignSettings/ThemeAndLogoForm.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Settings/DesignSettings/ThemeAndLogoForm.tsx index a8a2f3f15c..eddf9188f9 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Settings/DesignSettings/ThemeAndLogoForm.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/DesignSettings/ThemeAndLogoForm.tsx @@ -1,7 +1,10 @@ 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 { useFormik } from "formik"; -import React from "react"; +import { useStore } from "pages/FlowEditor/lib/store"; +import React, { useEffect, useState } from "react"; import ColorPicker from "ui/editor/ColorPicker"; import InputDescription from "ui/editor/InputDescription"; import InputRow from "ui/shared/InputRow"; @@ -9,17 +12,42 @@ import InputRowItem from "ui/shared/InputRowItem"; import InputRowLabel from "ui/shared/InputRowLabel"; import PublicFileUploadButton from "ui/shared/PublicFileUploadButton"; -import { DesignPreview, EXAMPLE_COLOUR, SettingsForm } from "."; +import { DesignPreview, SettingsForm } from "."; -export const ThemeAndLogoForm: React.FC = () => { - const formik = useFormik<{ - themeColor: string; - }>({ - initialValues: { - themeColor: EXAMPLE_COLOUR, +type FormValues = Pick; + +export const ThemeAndLogoForm: React.FC<{ team: Team }> = ({ team }) => { + const theme = useTheme(); + + useEffect(() => { + setInitialValues({ + primaryColour: team.theme?.primaryColour, + logo: team.theme?.logo, + }) + }, [team]) + + const [initialValues, setInitialValues] = useState({ + primaryColour: "", + logo: "", + }) + + const formik = useFormik({ + initialValues, + onSubmit: async (values, { resetForm }) => { + await useStore.getState().updateTeamTheme(values); + // Reset "dirty" status to disable Save & Reset buttons + resetForm({ values }); + }, + validateOnBlur: false, + validateOnChange: false, + enableReinitialize: true, + validate: ({ primaryColour }) => { + const isContrastThresholdMet = getContrastRatio("#FFF", primaryColour) > theme.palette.contrastThreshold; + + if (!isContrastThresholdMet) { + return { primaryColour: "Theme colour does not meet accessibility contrast requirements (3:1)"} + }; }, - onSubmit: () => {}, - validate: () => {}, }); return ( @@ -46,8 +74,8 @@ export const ThemeAndLogoForm: React.FC = () => { formik.setFieldValue("themeColor", color)} + color={formik.values.primaryColour} + onChange={(color) => formik.setFieldValue("primaryColour", color)} label="Theme colour" /> @@ -55,7 +83,7 @@ export const ThemeAndLogoForm: React.FC = () => { Logo: - + formik.setFieldValue("logo", newUrl)}/> { } preview={ - - council logo + + { formik.values.logo + ? council logo + : {team?.name} + } } /> diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/DesignSettings/index.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Settings/DesignSettings/index.tsx index 43ab2b13fd..74b06ff0f1 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Settings/DesignSettings/index.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/DesignSettings/index.tsx @@ -2,9 +2,11 @@ import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; import { styled } from "@mui/material/styles"; import Typography from "@mui/material/Typography"; +import { Team } from "@opensystemslab/planx-core/types"; import { FormikProps, getIn } from "formik"; import { hasFeatureFlag } from "lib/featureFlags"; -import React from "react"; +import { useStore } from "pages/FlowEditor/lib/store"; +import React, { useEffect, useState } from "react"; import EditorRow from "ui/editor/EditorRow"; import { FeaturePlaceholder } from "ui/editor/FeaturePlaceholder"; import InputGroup from "ui/editor/InputGroup"; @@ -32,6 +34,26 @@ type SettingsFormProps = { preview?: React.ReactElement; }; +const useTeam = () => { + const [team, setTeam] = useState({} 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 const SettingsForm: React.FC = ({ formik, legend, @@ -79,6 +101,7 @@ export const SettingsForm: React.FC = ({ const DesignSettings: React.FC = () => { const isUsingFeatureFlag = hasFeatureFlag("SHOW_TEAM_SETTINGS"); + const team = useTeam(); return ( <> @@ -96,7 +119,7 @@ const DesignSettings: React.FC = () => { ) : ( <> - + diff --git a/editor.planx.uk/src/pages/FlowEditor/lib/store/team.ts b/editor.planx.uk/src/pages/FlowEditor/lib/store/team.ts index 6c61ce11f1..aab7af9a93 100644 --- a/editor.planx.uk/src/pages/FlowEditor/lib/store/team.ts +++ b/editor.planx.uk/src/pages/FlowEditor/lib/store/team.ts @@ -112,7 +112,6 @@ export const teamStore: StateCreator fetchCurrentTeam: async () => { const { teamSlug, _client } = get() const team = await _client.team.getBySlug(teamSlug); - console.log({team}) return team; }, diff --git a/editor.planx.uk/src/theme.ts b/editor.planx.uk/src/theme.ts index 5910ebcf3a..3d383921b7 100644 --- a/editor.planx.uk/src/theme.ts +++ b/editor.planx.uk/src/theme.ts @@ -16,8 +16,8 @@ import { deepmerge } from "@mui/utils"; import { TeamTheme } from "@opensystemslab/planx-core/types"; import { getContrastTextColor } from "styleUtils"; -const DEFAULT_TONAL_OFFSET = 0.2; const DEFAULT_PRIMARY_COLOR = "#0010A4"; +const DEFAULT_TONAL_OFFSET = 0.2; // Type styles export const FONT_WEIGHT_SEMI_BOLD = "600";