From 81c2b687fafc88f3a5a3933c219a3e51ca62fa70 Mon Sep 17 00:00:00 2001 From: Carter Date: Thu, 21 May 2026 11:03:34 -0600 Subject: [PATCH] redesigned white labeling code --- .env | 1 + package.json | 4 +- src/navigation/BottomNavigator.tsx | 43 +- src/navigation/SideNavigator.tsx | 48 +- src/pages/SignupCallback.tsx | 6 +- src/pages/Team.tsx | 7 +- src/services/whiteLabel.ts | 709 +++++++++++++++-------------- src/user/UserSettings.tsx | 4 +- src/userFeatures/UserFeatures.tsx | 19 +- 9 files changed, 423 insertions(+), 418 deletions(-) diff --git a/.env b/.env index 90ef699..1a7d2ca 100644 --- a/.env +++ b/.env @@ -7,6 +7,7 @@ VITE_AUTH0_CLIENT_DOMAIN=brandxtech.auth0.com VITE_AUTH0_AUDIENCE=api.brandxtech.ca VITE_AUTH0_DEV_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 VITE_AUTH0_STAGING_CLIENT_ID=3ib460VvLwdeyse5iUSQfxkVdQaUmphP +VITE_AUTH0_STREAMLINE_CLIENT_ID=HwUV0hHNdVvU96zuMBTAU8i7nFdwwgIX VITE_AUTH0_BXT_CLIENT_ID=sLnqOu40uWfQT1lYSDYj2wYmlLEHRB74 VITE_AUTH0_ADAPTIVE_AGRICULTURE_CLIENT_ID=5pUCkl2SfogkWmM244UDcLEUOp8EFdHd diff --git a/package.json b/package.json index 8531516..3bb0c48 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "start": "VITE_AUTH0_CLIENT_ID=5pUCkl2SfogkWmM244UDcLEUOp8EFdHd VITE_AUTH0_AUDIENCE=api.brandxtech.ca VITE_APP_API_URL=https://api.brandxtech.ca/v1 VITE_APP_WS_URL=ws://api.brandxtech.ca/v1/live vite", "start-local": "VITE_AUTH0_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 VITE_AUTH0_AUDIENCE=bxt-dev.api.adaptiveagriculture.ca VITE_APP_API_URL=http://localhost:50052/v1 VITE_APP_WS_URL=ws://localhost:50052/v1/live VITE_APP_BILLING_URL=http://localhost:50053/v1 VITE_APP_RECLUSE_URL=http://localhost:50054/v1 VITE_APP_GITLAB_URL=http://localhost:50055/v1 vite --mode localnet", "start-dev": "VITE_AUTH0_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 VITE_APP_API_URL=https://bxt-dev.api.adaptiveagriculture.ca/v1 VITE_AUTH0_CLIENT_DOMAIN=brandxtech.auth0.com VITE_AUTH0_AUDIENCE=bxt-dev.api.adaptiveagriculture.ca VITE_AUTH0_DEV_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 vite", - "start-streamline": "VITE_AUTH0_CLIENT_ID=HwUV0hHNdVvU96zuMBTAU8i7nFdwwgIX VITE_APP_API_URL=https://streamline.api.adaptiveagriculture.ca/v1 VITE_AUTH0_CLIENT_DOMAIN=brandxtech.auth0.com VITE_AUTH0_AUDIENCE=streamline.api.adaptiveagriculture.ca vite", - "start-staging": "VITE_LOCAL_STAGING=true VITE_AUTH0_CLIENT_ID=3ib460VvLwdeyse5iUSQfxkVdQaUmphP VITE_AUTH0_AUDIENCE=stagingapi.brandxtech.ca VITE_AUTH0_CLIENT_DOMAIN=adaptivestaging.us.auth0.com VITE_APP_API_URL=https://stagingapi.brandxtech.ca/v1 VITE_APP_WS_URL=ws://stagingapi.brandxtech.ca/v1/live VITE_APP_AUTH0_CLIENT_DOMAIN=adaptivestaging.us.auth0.com VITE_APP_AUTH0_AUDIENCE=stagingapi.brandxtech.ca vite", + "start-streamline": "VITE_WHITELABEL=streamline VITE_AUTH0_CLIENT_ID=HwUV0hHNdVvU96zuMBTAU8i7nFdwwgIX VITE_APP_API_URL=https://streamline.api.adaptiveagriculture.ca/v1 VITE_AUTH0_CLIENT_DOMAIN=brandxtech.auth0.com VITE_AUTH0_AUDIENCE=streamline.api.adaptiveagriculture.ca vite", + "start-staging": "VITE_WHITELABEL=staging VITE_AUTH0_CLIENT_ID=3ib460VvLwdeyse5iUSQfxkVdQaUmphP VITE_AUTH0_AUDIENCE=stagingapi.brandxtech.ca VITE_AUTH0_CLIENT_DOMAIN=adaptivestaging.us.auth0.com VITE_APP_API_URL=https://stagingapi.brandxtech.ca/v1 VITE_APP_WS_URL=ws://stagingapi.brandxtech.ca/v1/live vite", "build": "tsc -b && vite build", "lint": "eslint .", "preview": "vite preview", diff --git a/src/navigation/BottomNavigator.tsx b/src/navigation/BottomNavigator.tsx index 0cd0366..60019a6 100644 --- a/src/navigation/BottomNavigator.tsx +++ b/src/navigation/BottomNavigator.tsx @@ -13,7 +13,7 @@ import BinsIcon from "products/Bindapt/BinsIcon"; import { useGlobalState } from "providers"; import { useCallback, useEffect, useState } from "react"; import { useNavigate, useLocation } from "react-router-dom"; -import { IsAdaptiveAgriculture, isBXT, IsMiVent, IsAdCon, IsOmniAir, IsMiPCA, IsIntellifarms } from "services/whiteLabel"; +import { getFeatures, getWhitelabel } from "services/whiteLabel"; import FieldsIcon from "products/AgIcons/FieldsIcon"; import NexusSTIcon from "products/Construction/NexusSTIcon"; import OmniAirDeviceIcon from "products/AviationIcons/OmniAirDeviceIcon"; @@ -36,20 +36,16 @@ export default function BottomNavigator(props: Props) { const { isAuthenticated } = useAuthContext(); const [{ user }] = useGlobalState(); const [route, setRoute] = useState(sideIsOpen ? "side" : ""); - const isAg = IsAdaptiveAgriculture(); - const isIntel = IsIntellifarms(); - const isMiVent = IsMiVent(); - const isAdCon = IsAdCon(); - const isOmni = IsOmniAir(); - const isMiPCA = IsMiPCA(); + const wl = getWhitelabel(); + const f = getFeatures(); const reRoute = useCallback( (path: string) => { if (path === "") { - if (isAg || isIntel) { + if (f.bins) { return "bins"; } - if (isMiVent) { + if (f.ventilation) { return "ventilation"; } return "devices"; @@ -75,7 +71,7 @@ export default function BottomNavigator(props: Props) { } return path; }, - [isAg, isMiVent, isIntel] + [f] ); const autoDetectRoute = useCallback(() => { @@ -106,27 +102,27 @@ export default function BottomNavigator(props: Props) { const authenticatedNavigation = () => { return ( handleRouteChange(newValue)}> - {isAg || isIntel && ( + {f.visualFarm && ( } value="visualFarm" /> )} - {isAg || isIntel && ( + {f.bins && ( } value="bins" /> )} - {isAdCon && ( + {f.constructionMap && ( } value="constructionMap" /> )} - {(isOmni || isMiPCA) && ( + {f.aviationMap && ( } value="aviationMap" /> )} - {(isOmni || isMiPCA) && ( + {f.terminals && ( } @@ -137,11 +133,11 @@ export default function BottomNavigator(props: Props) { - ) : isAdCon ? ( + ) : f.constructionMap ? ( - ) : (isOmni || isMiPCA) ? ( + ) : f.aviationMap ? ( ) : ( @@ -149,22 +145,15 @@ export default function BottomNavigator(props: Props) { } value="devices" /> - {isAdCon && ( + {f.jobsites && ( } value="jobsites" /> )} - {/* {isMiVent && ( - } - value="ventilation" - /> - )} */} - {isBXT() && user.hasFeature("security") && ( + {f.security && user.hasFeature("security") && ( } value="security" /> )} } value="more" /> diff --git a/src/navigation/SideNavigator.tsx b/src/navigation/SideNavigator.tsx index d7c3dde..47742dd 100644 --- a/src/navigation/SideNavigator.tsx +++ b/src/navigation/SideNavigator.tsx @@ -23,17 +23,7 @@ import BindaptIcon from "../products/Bindapt/BindaptIcon"; import { useLocation, useNavigate } from "react-router-dom"; import BinsIcon from "products/Bindapt/BinsIcon"; import { useGlobalState } from "providers"; -import { - IsAdaptiveAgriculture, - // hasTutorialPlaylist, - IsAdCon, - IsIntellifarms, - IsMiPCA, - // isBXT, - IsMiVent, - IsOmniAir, - IsStreamline, -} from "services/whiteLabel"; +import { getFeatures } from "services/whiteLabel"; import MiningIcon from "products/ventilation/MiningIcon"; import { useAuthContext } from "providers/authContext"; import FieldsIcon from "products/AgIcons/FieldsIcon"; @@ -172,16 +162,10 @@ export default function SideNavigator(props: Props) { } const authenticatedSideMenu = () => { - const isMiVent = IsMiVent(); - const isAg = IsAdaptiveAgriculture() - const isIntel = IsIntellifarms() - const isStreamline = IsStreamline() - const isOmni = IsOmniAir() - const isMiPCA = IsMiPCA() - const isAdCon = IsAdCon() + const f = getFeatures(); return ( - {(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( + {(f.visualFarm || user.hasFeature("admin")) && ( )} - {((isOmni || isMiPCA) || user.hasFeature("admin")) && ( + {(f.aviationMap || user.hasFeature("admin")) && ( )} - {(isAdCon || user.hasFeature("admin")) && ( + {(f.constructionMap || user.hasFeature("admin")) && ( )} - {(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( + {(f.contracts || user.hasFeature("admin")) && ( )} - {(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( + {(f.bins || user.hasFeature("admin")) && ( )} - {((isOmni || isMiPCA) || user.hasFeature("admin")) && ( + {(f.terminals || user.hasFeature("admin")) && ( )} - {(user.hasFeature("installer") && isAg || user.hasFeature("admin")) && + {(f.cableEstimator && user.hasFeature("installer") || user.hasFeature("admin")) && } - {(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( + {(f.transactions || user.hasFeature("admin")) && ( )} - {(isMiVent || user.hasFeature("admin")) && ( + {(f.mines || user.hasFeature("admin")) && ( } - {(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( + {(f.fields || user.hasFeature("admin")) && ( )} - {(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( + {(f.grainTypes || user.hasFeature("admin")) && ( )} - {(isAdCon || user.hasFeature("admin")) && ( + {(f.jobsites || user.hasFeature("admin")) && ( )} - {(isAdCon || user.hasFeature("admin")) && ( + {(f.heaters || user.hasFeature("admin")) && ( } - {(isAg || isIntel || isStreamline || user.hasFeature("admin")) && + {(f.marketplace || user.hasFeature("admin")) && Feet (ft) - {IsAdaptiveAgriculture() && ( + {getFeatures().grainUnit && ( @@ -267,7 +266,7 @@ export default function TeamPage() { Groups - {((isAg || isStreamline) || user.hasFeature("admin")) && + {(f.bins || user.hasFeature("admin")) && <> diff --git a/src/services/whiteLabel.ts b/src/services/whiteLabel.ts index e53ef6a..35a9c8c 100644 --- a/src/services/whiteLabel.ts +++ b/src/services/whiteLabel.ts @@ -1,4 +1,3 @@ -// import { isOffline } from "utils/environment"; import DefaultDarkLogo from "../assets/whitelabels/darkLogo.png"; import DefaultLightLogo from "../assets/whitelabels/lightLogo.png"; import AdapativeAgLogo from "../assets/whitelabels/AdaptiveAgriculture/logo.png"; @@ -9,12 +8,10 @@ import BXTDarkLogo from "../assets/whitelabels/BXT/darkLogo.png"; import AeroGrowDarkLogo from "../assets/whitelabels/AeroGrow/darkLogo.png"; import AeroGrowLightLogo from "../assets/whitelabels/AeroGrow/lightLogo.png"; import MiVentLightLogo from "../assets/whitelabels/MiVent/lightLogo.png"; -// import OmniAirLogo from "../assets/whitelabels/OmniAir/OmniAirLogo.png"; import MiPCALogo from "../assets/whitelabels/MiPCA/MiPCALogo.png"; import StreamlineLogo from "../assets/whitelabels/Streamline/stream-logo.png" import IntellifarmsLogo from "../assets/whitelabels/Intellifarms/IFND-2023-Logo.png" import IntellifarmsLogoWhite from "../assets/whitelabels/Intellifarms/IFND-2023-Logo-White.png" -// import { green, yellow } from "@mui/material/colors"; const protips: string[] = [ "You can see the latest measurements for a device by starring its components!", @@ -31,354 +28,408 @@ const protips: string[] = [ "Want to receive text messages about your devices? Update your phone number and enable SMS notifications!" ]; +export interface WhiteLabelFeatures { + bins: boolean; + visualFarm: boolean; + contracts: boolean; + transactions: boolean; + fields: boolean; + grainTypes: boolean; + grainUnit: boolean; + marketplace: boolean; + cableEstimator: boolean; + ventilation: boolean; + mines: boolean; + constructionMap: boolean; + jobsites: boolean; + heaters: boolean; + aviationMap: boolean; + terminals: boolean; + security: boolean; +} + interface WhiteLabel { - name: any; - primaryColour: any; //must be a MATERIAL UI colour, used for various UI elements - secondaryColour: any; //must be a MATERIAL UI colour, used for a few UI elements (less importance) - signatureColour: any; //hex or RGB - signatureAccentColour: any; //hex or RGB - auth0ClientId: any; + slug: string; + name: string; + primaryColour: any; + secondaryColour: any; + signatureColour: any; + signatureAccentColour: any; + auth0ClientId: string; redirectOnLogout: boolean; logoutRedirectTarget: string; darkLogo: any; lightLogo: any; - transparentLogoBG: boolean; //determines whether the background of the logo should be transparent or not + transparentLogoBG: boolean; blacklist: string[]; + features: WhiteLabelFeatures; hotjarID?: string; docs: string; protips: string[]; tutorialPlaylistID?: string; thumbnail?: string; tutorialFiles?: { name: string; url: string }[]; - homePage?: string; + homePage: string; } -// const DEFAULT_WHITELABEL: WhiteLabel = { -// name: import.meta.env.REACT_APP_WEBSITE_TITLE, -// primaryColour: import.meta.env.REACT_APP_PRIMARY_COLOUR, -// secondaryColour: import.meta.env.REACT_APP_SECONDARY_COLOUR, -// signatureColour: import.meta.env.REACT_APP_SIGNATURE_COLOUR, -// signatureAccentColour: "#fff", -// auth0ClientId: import.meta.env.REACT_APP_AUTH0_CLIENT_ID, -// redirectOnLogout: false, -// logoutRedirectTarget: "", -// darkLogo: DefaultDarkLogo, -// lightLogo: DefaultLightLogo, -// transparentLogoBG: false, -// blacklist: [], -// hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_BXT, -// docs: "Platform", -// protips: protips, -// tutorialPlaylistID: "" -// }; - -const STAGING_WHITELABEL: WhiteLabel = { - name: "Staging", - primaryColour: import.meta.env.VITE_APP_PRIMARY_COLOUR, - secondaryColour: import.meta.env.VITE_APP_SECONDARY_COLOUR, - signatureColour: import.meta.env.VITE_APP_SIGNATURE_COLOUR, - signatureAccentColour: "#fff", - auth0ClientId: import.meta.env.VITE_AUTH0_STAGING_CLIENT_ID, - redirectOnLogout: false, - logoutRedirectTarget: "", - darkLogo: DefaultDarkLogo, - lightLogo: DefaultLightLogo, - transparentLogoBG: false, - blacklist: [], - hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_BXT, - docs: "Platform", - protips: protips, - tutorialPlaylistID: "", - homePage: "/devices" +const AG_FEATURES: WhiteLabelFeatures = { + bins: true, + visualFarm: true, + contracts: true, + transactions: true, + fields: true, + grainTypes: true, + grainUnit: true, + marketplace: true, + cableEstimator: true, + ventilation: false, + mines: false, + constructionMap: false, + jobsites: false, + heaters: false, + aviationMap: false, + terminals: false, + security: false, }; -const BXT_WHITE_LABEL: WhiteLabel = { - name: "Brand X Technologies", - primaryColour: "blue", - // primaryColour: "#0000FF", - secondaryColour: "yellow", - // secondaryColour: "#FFFF00", - // signatureColour: "#272727", - signatureColour: "#005bb0", - signatureAccentColour: "#fff", - auth0ClientId: import.meta.env.VITE_AUTH0_DEV_CLIENT_ID, - redirectOnLogout: false, - logoutRedirectTarget: "", - darkLogo: BXTDarkLogo, - lightLogo: BXTLightLogo, - transparentLogoBG: false, - blacklist: [], - hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_BXT, - docs: "Platform", - protips: protips, - homePage: "/devices" +const CONSTRUCTION_FEATURES: WhiteLabelFeatures = { + bins: false, + visualFarm: false, + contracts: false, + transactions: false, + fields: false, + grainTypes: false, + grainUnit: false, + marketplace: false, + cableEstimator: false, + ventilation: false, + mines: false, + constructionMap: true, + jobsites: true, + heaters: true, + aviationMap: false, + terminals: false, + security: false, }; -const STREAMLINE_WHITE_LABEL: WhiteLabel = { - name: "Streamline", - primaryColour: "#FFFF", - // primaryColour: "#0000FF", - secondaryColour: "yellow", - // secondaryColour: "#FFFF00", - // signatureColour: "#272727", - signatureColour: "#005bb0", - signatureAccentColour: "#fff", - auth0ClientId: import.meta.env.VITE_AUTH0_STREAMLINE_CLIENT_ID, - redirectOnLogout: false, - logoutRedirectTarget: "", - darkLogo: StreamlineLogo, - lightLogo: StreamlineLogo, - transparentLogoBG: false, - blacklist: [], - hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_BXT, - docs: "Platform", - protips: protips, - homePage: "/devices" +const AVIATION_FEATURES: WhiteLabelFeatures = { + bins: false, + visualFarm: false, + contracts: false, + transactions: false, + fields: false, + grainTypes: false, + grainUnit: false, + marketplace: false, + cableEstimator: false, + ventilation: false, + mines: false, + constructionMap: false, + jobsites: false, + heaters: false, + aviationMap: true, + terminals: true, + security: false, }; -export function isBXT(): boolean { - return getName() === "Brand X Technologies"; +const MIVENT_FEATURES: WhiteLabelFeatures = { + bins: false, + visualFarm: false, + contracts: false, + transactions: false, + fields: false, + grainTypes: false, + grainUnit: false, + marketplace: false, + cableEstimator: false, + ventilation: true, + mines: true, + constructionMap: false, + jobsites: false, + heaters: false, + aviationMap: false, + terminals: false, + security: false, +}; + +const BASE_FEATURES: WhiteLabelFeatures = { + bins: false, + visualFarm: false, + contracts: false, + transactions: false, + fields: false, + grainTypes: false, + grainUnit: false, + marketplace: false, + cableEstimator: false, + ventilation: false, + mines: false, + constructionMap: false, + jobsites: false, + heaters: false, + aviationMap: false, + terminals: false, + security: false, +}; + +const registry: Record = { + "bxt": { + slug: "bxt", + name: "Brand X Technologies", + primaryColour: "blue", + secondaryColour: "yellow", + signatureColour: "#005bb0", + signatureAccentColour: "#fff", + auth0ClientId: import.meta.env.VITE_AUTH0_DEV_CLIENT_ID, + + redirectOnLogout: false, + logoutRedirectTarget: "", + darkLogo: BXTDarkLogo, + lightLogo: BXTLightLogo, + transparentLogoBG: false, + blacklist: [], + features: { ...BASE_FEATURES, security: true }, + hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_BXT, + docs: "Platform", + protips: protips, + homePage: "/devices", + }, + "staging": { + slug: "staging", + name: "Staging", + primaryColour: import.meta.env.VITE_APP_PRIMARY_COLOUR, + secondaryColour: import.meta.env.VITE_APP_SECONDARY_COLOUR, + signatureColour: import.meta.env.VITE_APP_SIGNATURE_COLOUR, + signatureAccentColour: "#fff", + auth0ClientId: import.meta.env.VITE_AUTH0_STAGING_CLIENT_ID, + + redirectOnLogout: false, + logoutRedirectTarget: "", + darkLogo: DefaultDarkLogo, + lightLogo: DefaultLightLogo, + transparentLogoBG: false, + blacklist: [], + features: AG_FEATURES, + hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_BXT, + docs: "Platform", + protips: protips, + homePage: "/devices", + }, + "adaptive-ag": { + slug: "adaptive-ag", + name: "Adaptive Agriculture", + primaryColour: "green", + secondaryColour: "yellow", + signatureColour: "#272727", + signatureAccentColour: "#fff", + auth0ClientId: import.meta.env.VITE_AUTH0_ADAPTIVE_AGRICULTURE_CLIENT_ID, + + redirectOnLogout: true, + logoutRedirectTarget: "https://adaptiveagriculture.ca", + darkLogo: AdapativeAgLogo, + lightLogo: AdapativeAgLogo, + transparentLogoBG: true, + blacklist: ["cost"], + features: AG_FEATURES, + hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_ADAPTIVE_AGRICULTURE, + docs: "AdaptiveAg", + protips: protips, + tutorialPlaylistID: "PLpLmJnI66Jfl5FXME31ckGam-sD8gB1s2", + thumbnail: AdaptiveAgThumbnail, + tutorialFiles: [ + { + name: "Bindapt+", + url: "https://adaptiveagriculture.ca/wp-content/uploads/2023/08/Bindapt-Set-Up-Guide.pdf" + }, + { + name: "Adapter Plate", + url: "https://adaptiveagriculture.ca/wp-content/uploads/2023/08/Bindapt-Adapter-Plate-Set-Up-Guide.pdf" + } + ], + homePage: "/bins", + }, + "intellifarms": { + slug: "intellifarms", + name: "Intellifarms", + primaryColour: "#9E1B32", + secondaryColour: "#4A4F55", + signatureColour: "#272727", + signatureAccentColour: "#fff", + auth0ClientId: import.meta.env.VITE_AUTH0_INTELLIFARMS_CLIENT_ID, + + redirectOnLogout: true, + logoutRedirectTarget: "https://myintellifarms.com", + darkLogo: IntellifarmsLogo, + lightLogo: IntellifarmsLogoWhite, + transparentLogoBG: true, + blacklist: [], + features: AG_FEATURES, + docs: "Platform", + protips: protips, + homePage: "/bins", + }, + "streamline": { + slug: "streamline", + name: "Streamline", + primaryColour: "#FFFF", + secondaryColour: "yellow", + signatureColour: "#005bb0", + signatureAccentColour: "#fff", + auth0ClientId: import.meta.env.VITE_AUTH0_STREAMLINE_CLIENT_ID, + + redirectOnLogout: false, + logoutRedirectTarget: "", + darkLogo: StreamlineLogo, + lightLogo: StreamlineLogo, + transparentLogoBG: false, + blacklist: [], + features: AG_FEATURES, + docs: "Platform", + protips: protips, + homePage: "/devices", + }, + "aerogrow": { + slug: "aerogrow", + name: "AeroGrow", + primaryColour: "green", + secondaryColour: "cyan", + signatureColour: "#fff", + signatureAccentColour: "#000", + auth0ClientId: import.meta.env.VITE_AUTH0_AEROGROW_CLIENT_ID, + + redirectOnLogout: true, + logoutRedirectTarget: "https://www.aerogrowmanufacturing.com", + darkLogo: AeroGrowDarkLogo, + lightLogo: AeroGrowLightLogo, + transparentLogoBG: true, + blacklist: [], + features: BASE_FEATURES, + hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_AEROGROW, + docs: "Platform", + protips: protips, + homePage: "/devices", + }, + "mivent": { + slug: "mivent", + name: "MiVent", + primaryColour: "green", + secondaryColour: "yellow", + signatureColour: "#272727", + signatureAccentColour: "#fff", + auth0ClientId: import.meta.env.VITE_AUTH0_MIVENT_CLIENT_ID, + + redirectOnLogout: true, + logoutRedirectTarget: "https://mivent.ca", + darkLogo: MiVentLightLogo, + lightLogo: MiVentLightLogo, + transparentLogoBG: true, + blacklist: ["cost"], + features: MIVENT_FEATURES, + hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_MIVENT, + docs: "Platform", + protips: protips, + homePage: "/devices", + }, + "adaptive-construction": { + slug: "adaptive-construction", + name: "Adaptive Construction", + primaryColour: "blue", + secondaryColour: "blue", + signatureColour: "#272727", + signatureAccentColour: "#fff", + auth0ClientId: import.meta.env.VITE_AUTH0_ADAPTIVE_CONSTRUCTION_CLIENT_ID, + + redirectOnLogout: true, + logoutRedirectTarget: "https://adaptiveconstruction.ca", + darkLogo: AdConLogo, + lightLogo: AdConLogo, + transparentLogoBG: true, + blacklist: ["cost"], + features: CONSTRUCTION_FEATURES, + hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_ADAPTIVE_CONSTRUCTION, + docs: "AdaptiveConstruction", + protips: protips, + homePage: "/devices", + }, + "omniair": { + slug: "omniair", + name: "OmniAir", + primaryColour: "#004f9b", + secondaryColour: "yellow", + signatureColour: "#272727", + signatureAccentColour: "#fff", + auth0ClientId: import.meta.env.VITE_AUTH0_OMNIAIR_CLIENT_ID, + + redirectOnLogout: true, + logoutRedirectTarget: "https://omniairsystems.com", + darkLogo: MiPCALogo, + lightLogo: MiPCALogo, + transparentLogoBG: true, + blacklist: ["cost"], + features: AVIATION_FEATURES, + docs: "OmniAir", + protips: protips, + homePage: "/devices", + }, + "mipca": { + slug: "mipca", + name: "MiPCA", + primaryColour: "#004f9b", + secondaryColour: "yellow", + signatureColour: "#272727", + signatureAccentColour: "#fff", + auth0ClientId: import.meta.env.VITE_AUTH0_OMNIAIR_CLIENT_ID, + + redirectOnLogout: true, + logoutRedirectTarget: "https://mionetech.com", + darkLogo: MiPCALogo, + lightLogo: MiPCALogo, + transparentLogoBG: true, + blacklist: ["cost"], + features: AVIATION_FEATURES, + docs: "MiPCA", + protips: protips, + homePage: "/devices", + }, +}; + +// Ordered most-specific to least-specific +const DOMAIN_RULES: [RegExp, string][] = [ + [/bxt-dev/, "bxt"], + [/staging\.brandxtech/, "staging"], + [/streamline\./, "streamline"], + [/brandxtech|brandxducks/, "bxt"], + [/adaptiveagriculture|adaptiveag/, "adaptive-ag"], + [/adaptiveconstruction/, "adaptive-construction"], + [/aerogrowmanufacturing/, "aerogrow"], + [/mivent/, "mivent"], + [/omniair/, "omniair"], + [/mionetech|mipca/, "mipca"], + [/myintellifarms|intellifarms/, "intellifarms"], +]; + +function resolveSlug(): string { + const override = import.meta.env.VITE_WHITELABEL; + if (override && registry[override]) return override; + + const host = window.location.hostname; + for (const [pattern, slug] of DOMAIN_RULES) { + if (pattern.test(host)) return slug; + } + return "adaptive-ag"; } -const ADAPTIVE_AGRICULTURE_WHITE_LABEL: WhiteLabel = { - name: "Adaptive Agriculture", - primaryColour: "green", - // primaryColour: "#008000", - secondaryColour: "yellow", - // secondaryColour: "#FFFF00", - signatureColour: "#272727", - signatureAccentColour: "#fff", - auth0ClientId: import.meta.env.VITE_AUTH0_ADAPTIVE_AGRICULTURE_CLIENT_ID, - redirectOnLogout: true, - logoutRedirectTarget: "https://adaptiveagriculture.ca", - darkLogo: AdapativeAgLogo, - lightLogo: AdapativeAgLogo, - transparentLogoBG: true, - blacklist: ["cost"], - hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_ADAPTIVE_AGRICULTURE, - docs: "AdaptiveAg", - protips: protips.concat([]), - tutorialPlaylistID: "PLpLmJnI66Jfl5FXME31ckGam-sD8gB1s2", - thumbnail: AdaptiveAgThumbnail, - tutorialFiles: [ - { - name: "Bindapt+", - url: "https://adaptiveagriculture.ca/wp-content/uploads/2023/08/Bindapt-Set-Up-Guide.pdf" - }, - { - name: "Adapter Plate", - url: - "https://adaptiveagriculture.ca/wp-content/uploads/2023/08/Bindapt-Adapter-Plate-Set-Up-Guide.pdf" - } - ], - homePage: "/bins" -}; - -export function IsAdaptiveAgriculture(): boolean { - return ( - getName() === "Adaptive Agriculture" || - window.location.origin.includes("staging") || - window.location.origin.includes("localhost") - ); -} - -const INTELLIFARMS_WHITE_LABEL: WhiteLabel = { - name: "Intellifarms", - primaryColour: "#9E1B32", - secondaryColour: "#4A4F55", - signatureColour: "#272727", - signatureAccentColour: "#fff", - auth0ClientId: import.meta.env.VITE_AUTH0_INTELLIFARMS_CLIENT_ID, - redirectOnLogout: true, - logoutRedirectTarget: "https://myintellifarms.com", - darkLogo: IntellifarmsLogo, - lightLogo: IntellifarmsLogoWhite, - transparentLogoBG: true, - blacklist: [], - docs: "Platform", - protips: protips, - homePage: "/bins" -}; - -export function IsIntellifarms(): boolean { - return ( - getName() === "Intellifarms" - // window.location.origin.includes("staging") || - // window.location.origin.includes("localhost") - ); -} - -export function IsStreamline(): boolean { - return ( - getName() === "Streamline" - // window.location.origin.includes("staging") || - // window.location.origin.includes("localhost") - ); -} - -const AEROGROW_WHITE_LABEL: WhiteLabel = { - name: "AeroGrow", - primaryColour: "green", - secondaryColour: "cyan", - signatureColour: "#fff", - signatureAccentColour: "#000", - auth0ClientId: import.meta.env.VITE_AUTH0_AEROGROW_CLIENT_ID, - redirectOnLogout: true, - logoutRedirectTarget: "https://www.aerogrowmanufacturing.com", - darkLogo: AeroGrowDarkLogo, - lightLogo: AeroGrowLightLogo, - transparentLogoBG: true, - blacklist: [], - hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_AEROGROW, - docs: "Platform", - protips: protips -}; - -export function IsMiVent(): boolean { - return ( - getName() === "MiVent" || - window.location.origin.includes("staging") || - window.location.origin.includes("localhost") - ); -} - -const MIVENT_WHITE_LABEL: WhiteLabel = { - name: "MiVent", - primaryColour: "green", - secondaryColour: "yellow", - signatureColour: "#272727", - signatureAccentColour: "#fff", - auth0ClientId: import.meta.env.VITE_AUTH0_MIVENT_CLIENT_ID, - redirectOnLogout: true, - logoutRedirectTarget: "https://mivent.ca", - darkLogo: MiVentLightLogo, - lightLogo: MiVentLightLogo, - transparentLogoBG: true, - blacklist: ["cost"], - hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_MIVENT, - docs: "Platform", - protips: protips.concat([]) -}; - -const ADAPTIVE_CONSTRUCTION_WHITE_LABEL: WhiteLabel = { - name: "Adaptive Construction", - primaryColour: "blue", - secondaryColour: "blue", - signatureColour: "#272727", - signatureAccentColour: "#fff", - auth0ClientId: import.meta.env.VITE_AUTH0_ADAPTIVE_CONSTRUCTION_CLIENT_ID, - redirectOnLogout: true, - logoutRedirectTarget: "https://adaptiveconstruction.ca", - darkLogo: AdConLogo, - lightLogo: AdConLogo, - transparentLogoBG: true, - blacklist: ["cost"], - hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_ADAPTIVE_CONSTRUCTION, - docs: "AdaptiveConstruction", - protips: protips.concat([]) -}; - -export function IsAdCon(): boolean { - return ( - getName() === "Adaptive Construction" || - window.location.origin.includes("staging") || - window.location.origin.includes("localhost") - ); -} - -const OMNIAIR_WHITE_LABEL: WhiteLabel = { - name: "OmniAir", - primaryColour: "#004f9b", - secondaryColour: "yellow", - signatureColour: "#272727", - signatureAccentColour: "#fff", - auth0ClientId: import.meta.env.VITE_AUTH0_OMNIAIR_CLIENT_ID, - redirectOnLogout: true, - logoutRedirectTarget: "https://omniairsystems.com", - darkLogo: MiPCALogo, - lightLogo: MiPCALogo, - transparentLogoBG: true, - blacklist: ["cost"], - //hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_OMNIAIR, testing what happens if this is excluded - docs: "OmniAir", - protips: protips.concat([]) -}; - -export function IsOmniAir(): boolean { - return ( - getName() === "OmniAir" || - window.location.origin.includes("staging") || - window.location.origin.includes("localhost") - ); -} - -const MIPCA_WHITE_LABEL: WhiteLabel = { - name: "MiPCA", - primaryColour: "#004f9b", - secondaryColour: "yellow", - signatureColour: "#272727", - signatureAccentColour: "#fff", - //omni air and MiPCA are the same client ID in Auth0, it is to replace it, once omniair gets removed we can re-name this - auth0ClientId: import.meta.env.VITE_AUTH0_OMNIAIR_CLIENT_ID, - redirectOnLogout: true, - logoutRedirectTarget: "https://mionetech.com", - darkLogo: MiPCALogo, - lightLogo: MiPCALogo, - transparentLogoBG: true, - blacklist: ["cost"], - docs: "MiPCA", - protips: protips.concat([]) -}; - -export function IsMiPCA(): boolean { - return ( - getName() === "MiPCA" || - window.location.origin.includes("staging") || - window.location.origin.includes("localhost") - ); -} - -const whitelabels = new Map([ - ["streamline", STREAMLINE_WHITE_LABEL], - ["adaptiveag", ADAPTIVE_AGRICULTURE_WHITE_LABEL], - ["adaptiveagriculture", ADAPTIVE_AGRICULTURE_WHITE_LABEL], - ["brandxducks", BXT_WHITE_LABEL], - ["brandxtech", BXT_WHITE_LABEL], - ["aerogrowmanufacturing", AEROGROW_WHITE_LABEL], - ["localhost", BXT_WHITE_LABEL], - ["staging", STAGING_WHITELABEL], - ["10.0", ADAPTIVE_CONSTRUCTION_WHITE_LABEL], - ["mivent", MIVENT_WHITE_LABEL], - ["adaptiveconstruction", ADAPTIVE_CONSTRUCTION_WHITE_LABEL], - ["omniair", OMNIAIR_WHITE_LABEL], - ["mipca", MIPCA_WHITE_LABEL], - ["mionetech", MIPCA_WHITE_LABEL], - ["intellifarms", INTELLIFARMS_WHITE_LABEL] -]); +let cached: WhiteLabel | null = null; export function getWhitelabel(): WhiteLabel { -// if (isOffline()) { -// return DEFAULT_WHITELABEL; -// } + if (!cached) { + cached = registry[resolveSlug()]; + } + return cached; +} - const hostname = window.location.hostname; - if (window.location.origin.includes("bxt-dev")) { - return BXT_WHITE_LABEL; - } - if (window.location.origin.includes("localhost")) { - return INTELLIFARMS_WHITE_LABEL; - } - if (window.location.origin.includes("staging") || import.meta.env.VITE_LOCAL_STAGING=='true') { - return STAGING_WHITELABEL; - } - const whiteLabelKeys = Array.from(whitelabels.keys()); - for (var i = 0; i < whiteLabelKeys.length; i++) { - let key = whiteLabelKeys[i]; - if (hostname.includes(key)) { - return whitelabels.get(key) as WhiteLabel; - } - } - return ADAPTIVE_AGRICULTURE_WHITE_LABEL; +export function getFeatures(): WhiteLabelFeatures { + return getWhitelabel().features; } export function getPrimaryColour(): any { @@ -397,7 +448,7 @@ export function getSignatureAccentColour(): any { return getWhitelabel().signatureAccentColour; } -export function getAuth0ClientId(): any { +export function getAuth0ClientId(): string { return getWhitelabel().auth0ClientId; } @@ -418,10 +469,6 @@ export function getLightLogo(): any { } export function hideLogo(): boolean { - // if (isOffline()) { - // return false; - // } - return getWhitelabel().name === ""; } diff --git a/src/user/UserSettings.tsx b/src/user/UserSettings.tsx index 57bdd6a..d451cd5 100644 --- a/src/user/UserSettings.tsx +++ b/src/user/UserSettings.tsx @@ -29,7 +29,7 @@ import { useThemeMode } from "theme/AppThemeProvider"; // import ContractsIcon from "products/CommonIcons/contractIcon"; import UnitsIcon from "@mui/icons-material/Category"; import { setThemeType } from "theme"; -import { IsAdaptiveAgriculture } from "services/whiteLabel"; +import { getFeatures } from "services/whiteLabel"; import { setDistanceUnit, setGrainUnit, setPressureUnit, setTemperatureUnit } from "utils"; import FieldsIcon from "products/AgIcons/FieldsIcon"; @@ -529,7 +529,7 @@ export default function UserSettings(props: Props) { Feet (ft) - {IsAdaptiveAgriculture() && ( + {getFeatures().grainUnit && ( { let list: ProductDetails[] = []; - if (IsAdaptiveAgriculture() || user.hasFeature("admin")) { + if (getFeatures().marketplace || user.hasFeature("admin")) { list = list.concat(agFeatureList); } - // if(IsAdCon()){ - // list = list.concat(constructionFeatureList) - // } - // if(IsOmniAir()){ - // list = list.concat(aviationFeatureList) - // } - // if(IsMiVent()){ - // list = list.concat(miningFeatureList) - // } - // list = list.concat(universalFeatureList) setFeaturList(list); }, []);