import { observer } from "mobx-react"; import { useTheme } from "next-themes"; import { Controller, useForm } from "react-hook-form"; // types import { IUserTheme } from "@plane/types"; // ui import { Button, InputColorPicker, setPromiseToast } from "@plane/ui"; // hooks import { useUserProfile } from "@/hooks/store"; const inputRules = { required: "Background color is required", minLength: { value: 7, message: "Enter a valid hex code of 6 characters", }, maxLength: { value: 7, message: "Enter a valid hex code of 6 characters", }, pattern: { value: /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/, message: "Enter a valid hex code of 6 characters", }, }; export const CustomThemeSelector: React.FC = observer(() => { const { setTheme } = useTheme(); // hooks const { data: userProfile, updateUserTheme } = useUserProfile(); const { control, formState: { errors, isSubmitting }, handleSubmit, watch, } = useForm({ defaultValues: { background: userProfile?.theme?.background !== "" ? userProfile?.theme?.background : "#0d101b", text: userProfile?.theme?.text !== "" ? userProfile?.theme?.text : "#c5c5c5", primary: userProfile?.theme?.primary !== "" ? userProfile?.theme?.primary : "#3f76ff", sidebarBackground: userProfile?.theme?.sidebarBackground !== "" ? userProfile?.theme?.sidebarBackground : "#0d101b", sidebarText: userProfile?.theme?.sidebarText !== "" ? userProfile?.theme?.sidebarText : "#c5c5c5", darkPalette: userProfile?.theme?.darkPalette || false, palette: userProfile?.theme?.palette !== "" ? userProfile?.theme?.palette : "", }, }); const handleUpdateTheme = async (formData: Partial) => { const payload: IUserTheme = { background: formData.background, text: formData.text, primary: formData.primary, sidebarBackground: formData.sidebarBackground, sidebarText: formData.sidebarText, darkPalette: false, palette: `${formData.background},${formData.text},${formData.primary},${formData.sidebarBackground},${formData.sidebarText}`, theme: "custom", }; setTheme("custom"); const updateCurrentUserThemePromise = updateUserTheme(payload); setPromiseToast(updateCurrentUserThemePromise, { loading: "Updating theme...", success: { title: "Success!", message: () => "Theme updated successfully!", }, error: { title: "Error!", message: () => "Failed to Update the theme", }, }); return; }; const handleValueChange = (val: string | undefined, onChange: any) => { let hex = val; // prepend a hashtag if it doesn't exist if (val && val[0] !== "#") hex = `#${val}`; onChange(hex); }; return (

Customize your theme

Background color

( handleValueChange(val, onChange)} placeholder="#0d101b" className="w-full" style={{ backgroundColor: watch("background"), color: watch("text"), }} hasError={Boolean(errors?.background)} /> )} /> {errors.background &&

{errors.background.message}

}

Text color

( handleValueChange(val, onChange)} placeholder="#c5c5c5" className="w-full" style={{ backgroundColor: watch("text"), color: watch("background"), }} hasError={Boolean(errors?.text)} /> )} /> {errors.text &&

{errors.text.message}

}

Primary(Theme) color

( handleValueChange(val, onChange)} placeholder="#3f76ff" className="w-full" style={{ backgroundColor: watch("primary"), color: watch("text"), }} hasError={Boolean(errors?.primary)} /> )} /> {errors.primary &&

{errors.primary.message}

}

Sidebar background color

( handleValueChange(val, onChange)} placeholder="#0d101b" className="w-full" style={{ backgroundColor: watch("sidebarBackground"), color: watch("sidebarText"), }} hasError={Boolean(errors?.sidebarBackground)} /> )} /> {errors.sidebarBackground && (

{errors.sidebarBackground.message}

)}

Sidebar text color

( handleValueChange(val, onChange)} placeholder="#c5c5c5" className="w-full" style={{ backgroundColor: watch("sidebarText"), color: watch("sidebarBackground"), }} hasError={Boolean(errors?.sidebarText)} /> )} /> {errors.sidebarText &&

{errors.sidebarText.message}

}
); });