diff --git a/backend/go-app/main.go b/backend/go-app/main.go index fbd2a251..60f162b4 100755 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -1069,6 +1069,7 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { activatedAppIds = append(activatedAppIds, app.ID) } + userInfo.ActiveOrg.Branding = org.Branding returnValue := shuffle.HandleInfo{ Success: true, diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index cd092d98..fa3ac7ea 100755 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -92,8 +92,8 @@ const App = (message, props) => { const [dataset, setDataset] = useState(false) const [isLoaded, setIsLoaded] = useState(false) const [curpath, setCurpath] = useState(typeof window === "undefined" || window.location === undefined ? "" : window.location.pathname) - const { themeMode, handleThemeChange } = useContext(Context); - const currentTheme = getTheme(themeMode); + const { themeMode, handleThemeChange, setBrandColor, brandColor} = useContext(Context); + const currentTheme = getTheme(themeMode, brandColor); const mainColor = currentTheme?.palette?.backgroundColor const [isPreviousThemeLight, setIsPreviousThemeLight] = useState(false) @@ -106,18 +106,27 @@ const App = (message, props) => { }, []); useEffect(() => { - const isDarkPath = curpath === "/" || curpath === "/pricing" || curpath === "/partners" || curpath === "/faq" || curpath === "/professional-services" || curpath === "/contact" || curpath === "/training"; - if (curpath && isDarkPath) { - if (themeMode === "light") { - setIsPreviousThemeLight(true) + const isDarkPath = curpath === "/" || curpath === "/pricing" || curpath === "/partners" || curpath === "/faq" || curpath === "/professional-services" || curpath === "/contact" || curpath === "/training"; + if (curpath && isDarkPath) { + if (themeMode === "light") { + setIsPreviousThemeLight(true) + } + handleThemeChange("dark") + }else if ( !isDarkPath && isPreviousThemeLight && userdata?.active_org?.branding?.theme === "light") { + handleThemeChange("light") + setIsPreviousThemeLight(false) } - handleThemeChange("dark") - }else if ( !isDarkPath && isPreviousThemeLight && userdata?.active_org?.branding?.theme === "light") { - handleThemeChange("light") - setIsPreviousThemeLight(false) - } -}, [themeMode, curpath, userdata]) + if (isDarkPath && userdata && userdata?.active_org?.branding?.brand_color !== "#ff8544") { + setBrandColor("#ff8544") + }else if(!isDarkPath && userdata && userdata?.active_org?.branding?.brand_color !== "#ff8544" && userdata?.active_org?.branding?.brand_color?.length > 0) { + const brandColor = localStorage.getItem("brandColor") + if (brandColor !== null && brandColor !== undefined && brandColor.length > 0) { + setBrandColor(brandColor) + } + } + + }, [themeMode, curpath, userdata]) if ( isLoaded && @@ -936,7 +945,7 @@ const App = (message, props) => { pauseOnFocusLoss draggable pauseOnHover - theme="dark" + theme={themeMode} /> diff --git a/frontend/src/components/Branding.jsx b/frontend/src/components/Branding.jsx index e549d12e..649c509a 100644 --- a/frontend/src/components/Branding.jsx +++ b/frontend/src/components/Branding.jsx @@ -1,8 +1,7 @@ import React, { useState, useEffect, useContext } from "react"; import ReactGA from 'react-ga4'; -import theme from "../theme.jsx"; +import {getTheme} from "../theme.jsx"; import { ToastContainer, toast } from "react-toastify" - import { CheckCircle as CheckCircleIcon, } from "@mui/icons-material"; @@ -13,8 +12,11 @@ import { Divider, Button, Tooltip, - Grid, - Card, + ToggleButtonGroup, + ToggleButton, + useMediaQuery, + TextField, + Box, } from "@mui/material"; import { @@ -27,18 +29,98 @@ import { Context } from "../context/ContextApi.jsx"; const Branding = (props) => { const { globalUrl, userdata, serverside, billingInfo,clickedFromOrgTab, stripeKey, selectedOrganization, handleGetOrg, } = props; + const { themeMode, handleThemeChange, supportEmail, setSupportEmail, logoutUrl, setLogoutUrl, brandColor, setBrandColor, setBrandName } = useContext(Context) //const alert = useAlert(); const [publishingInfo, setPublishingInfo] = useState(""); const [publishRequirements, setPublishRequirements] = useState([]) + const [currentSelectedTheme, setCurrentSelectedTheme] = useState("dark"); + const [integrationPartner, setIntegrationPartner] = useState(false); + const [changingTheme, setChangingTheme] = useState(false); + const theme = getTheme(themeMode, brandColor) + const [selectedBrandColor, setSelectedBrandColor] = useState(theme?.palette?.main || "#FF8544") + const [selectedBrandName, setSelectedBrandName] = useState(selectedOrganization?.branding?.brand_name || "") + const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"; + const [isLoading,setIsLoading] = useState(false); - const { leftSideBarOpenByClick } = useContext(Context) - - const handleEditOrg = (joinStatus) => { + const handleEditOrg = (joinStatus) => { + setIsLoading(true) const data = { "org_id": selectedOrganization.id, - "creator_config": joinStatus, }; + if (joinStatus === "join" || joinStatus === "leave") { + data["creator_config"] = joinStatus + } + + if (joinStatus === "light" || joinStatus === "dark" || joinStatus === "system") { + data["branding"] = { + "theme": joinStatus, + "enable_chat": selectedOrganization?.branding?.enable_chat || false, + "home_url": selectedOrganization?.branding?.home_url || "", + "brand_color": selectedOrganization?.branding?.brand_color || theme.palette.primary.main, + "brand_name": selectedOrganization?.branding?.brand_name || "", + "logout_url": selectedOrganization?.branding?.logout_url || "", + "support_email": selectedOrganization?.branding?.support_email || "", + } + + data["editing_branding"] = true; + } + + if (joinStatus === "brand_color") { + data["branding"] = { + "theme": selectedOrganization?.branding?.theme || "dark", + "enable_chat": selectedOrganization?.branding?.enable_chat || false, + "home_url": selectedOrganization?.branding?.home_url || "", + "brand_color": selectedBrandColor, + "brand_name": selectedOrganization?.branding?.brand_name || "", + "logout_url": selectedOrganization?.branding?.logout_url || "", + "support_email": selectedOrganization?.branding?.support_email || "", + } + + data["editing_branding"] = true; + } + + if (joinStatus === "brand_name") { + data["branding"] = { + "theme": selectedOrganization?.branding?.theme || "dark", + "enable_chat": selectedOrganization?.branding?.enable_chat || false, + "home_url": selectedOrganization?.branding?.home_url || "", + "brand_color": selectedOrganization?.branding?.brand_color || theme.palette.primary.main, + "brand_name": selectedBrandName, + "logout_url": selectedOrganization?.branding?.logout_url || "", + "support_email": selectedOrganization?.branding?.support_email || "", + } + toast.info("Updating brand name to " + selectedBrandName + ". Please wait a moment.") + data["editing_branding"] = true; + } + + if (joinStatus === "support_email") { + data["branding"] = { + "theme": selectedOrganization?.branding?.theme || "dark", + "enable_chat": selectedOrganization?.branding?.enable_chat || false, + "home_url": selectedOrganization?.branding?.home_url || "", + "brand_color": selectedOrganization?.branding?.brand_color || theme.palette.primary.main, + "brand_name": selectedOrganization?.branding?.brand_name || "", + "support_email": supportEmail, + "logout_url": selectedOrganization?.branding?.logout_url || "", + } + data["editing_branding"] = true; + } + + if (joinStatus === "logout_url") { + data["branding"] = { + "theme": selectedOrganization?.branding?.theme || "dark", + "enable_chat": selectedOrganization?.branding?.enable_chat || false, + "home_url": selectedOrganization?.branding?.home_url || "", + "brand_color": selectedOrganization?.branding?.brand_color || theme.palette.primary.main, + "brand_name": selectedOrganization?.branding?.brand_name || "", + "support_email": selectedOrganization?.branding?.support_email || "", + "logout_url": logoutUrl, + } + data["editing_branding"] = true; + } + + const url = globalUrl + `/api/v1/orgs/${selectedOrganization.id}`; fetch(url, { mode: "cors", @@ -56,18 +138,56 @@ const Branding = (props) => { if (responseJson["success"] === false) { toast("Failed updating org: ", responseJson.reason); } else { - if (joinStatus == "join") { - setPublishingInfo("Your organization is now part of the Partner Program. You can now create, publish and manage content for your organization's public page.") - } else { - setPublishingInfo("Your organization is no longer part of the Creator Incentive Program. You can still create a creator account to manage your organization's content.") + if (joinStatus === "join" || joinStatus === "leave") { + if (joinStatus === "join") { + setPublishingInfo("Your organization is now part of the Partner Program. You can now create, publish and manage content for your organization's public page.") + } else { + setPublishingInfo("Your organization is no longer part of the Creator Incentive Program. You can still create a creator account to manage your organization's content.") + } } + + if (joinStatus === "light" || joinStatus === "dark" || joinStatus === "system") { + handleThemeChange(joinStatus) + setChangingTheme(false) + setCurrentSelectedTheme(joinStatus) + } + + if (joinStatus === "support_email") { + toast.info("Support email updated successfully.") + if (supportEmail?.length > 0) { + setSupportEmail(supportEmail) + }else { + setSupportEmail("support@shuffler.io") + } + } + + if (joinStatus === "logout_url") { + toast.info("Logout URL updated successfully.") + setLogoutUrl(logoutUrl) + } + + if (joinStatus === "brand_color") { + toast.info("Brand color updated successfully.") + setBrandColor(selectedBrandColor) + localStorage.setItem("brandColor", selectedBrandColor) + } + + if (joinStatus === "brand_name") { + toast.info("Brand name updated successfully.") + setBrandName(selectedBrandName) + localStorage.setItem("brandName", selectedBrandName) + } + handleGetOrg(selectedOrganization.id); - } + + setIsLoading(false) + } }) ) .catch((error) => { toast("Err: " + error.toString()); - }); + setIsLoading(false) + }) }; // Should enable / disable org branding @@ -117,16 +237,60 @@ const Branding = (props) => { const leadinfo = selectedOrganization.lead_info === undefined || selectedOrganization.lead_info === null || selectedOrganization.lead_info === "" ? "" : JSON.stringify(selectedOrganization.lead_info) const isPartner = leadinfo.includes("partner") + + useEffect(() => { + if (selectedOrganization?.branding?.theme && selectedOrganization?.creator_org?.length === 0) { + setCurrentSelectedTheme(selectedOrganization.branding.theme); + } + + if (selectedOrganization?.creator_org?.length > 0 && userdata?.active_org?.branding.theme) { + setCurrentSelectedTheme(userdata?.active_org?.branding.theme); + } + + if (userdata.support) { + setCurrentSelectedTheme(localStorage.getItem("theme") || "dark"); + } + + if ( + selectedOrganization && + selectedOrganization?.branding?.brand_color && + selectedOrganization?.branding?.brand_color !== selectedBrandColor + ) { + setSelectedBrandColor(selectedOrganization.branding.brand_color); + } + + if (selectedOrganization?.branding?.brand_name && selectedOrganization?.branding?.brand_name !== selectedBrandName) { + setSelectedBrandName(selectedOrganization.branding.brand_name); + } + + }, [selectedOrganization, userdata]); + + useEffect(() => { + if ((userdata && userdata?.org_status?.includes("integration_partner") && !integrationPartner && !userdata?.org_status?.includes("sub_org")) || userdata?.support) { + setIntegrationPartner(true) + } + + },[userdata, integrationPartner]); + + const handleColorChange = (e) => { + setSelectedBrandColor(e.target.value); + }; + + const saveColorChanges = () => { + toast.info("Updating brand color to " + selectedBrandColor + ". Please wait a moment.") + handleEditOrg("brand_color"); + }; + return ( -