diff --git a/.env b/.env
index 90ef699..0d5bcc8 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
@@ -16,6 +17,9 @@ VITE_AUTH0_MIVENT_CLIENT_ID=VNALE7RW6l3dY5uYcxgwElZV0lcT25Fg
VITE_AUTH0_OMNIAIR_CLIENT_ID=IblmarD8wFafiD6doxTmOHQ6Bx3L9wWl
VITE_AUTH0_INTELLIFARMS_CLIENT_ID=RYtuAyOcB4DSaaqJMLDMf3pV8SFY9PdY
+#Crisp
+VITE_CRISP_WEBSITE_ID=80170383-b426-43c0-8f66-8e20a05bcdce
+
#Branding (Default theme)
VITE_APP_WEBSITE_TITLE="Adaptive Dashboard"
VITE_APP_PRIMARY_COLOUR=blue
@@ -24,3 +28,6 @@ VITE_APP_SIGNATURE_COLOUR="#323232"
# Live device/component WebSocket streams (must match string "true" in code)
VITE_ENABLE_WEBSOCKETS=true
+
+# Default whitelabel; overwrite in .env.local
+VITE_WHITELABEL=adaptive-ag
diff --git a/deploy.sh b/deploy.sh
index e03b995..0a84fdb 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -32,9 +32,15 @@ SSH_OPTS="-i $DEPLOY_SSH_KEY"
echo "→ Deploying to $DEPLOY_USER@$DEPLOY_HOST using key $DEPLOY_SSH_KEY"
# 1. Build frontend for LAN / self-contained hosts (indexLocal.html via vite --mode localnet)
+# Pass VITE_WHITELABEL if provided as an argument; otherwise Vite reads it from .env
(
cd "$SCRIPT_DIR"
- npm run build:local
+ if [[ -n "${1:-}" ]]; then
+ echo "→ Whitelabel override: $1"
+ VITE_WHITELABEL="$1" npm run build:local
+ else
+ npm run build:local
+ fi
)
# Fail if the bundle still embeds Crisp (wrong vite mode or stale build/)
diff --git a/package.json b/package.json
index 895d7e0..265b238 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/app/UserWrapper.tsx b/src/app/UserWrapper.tsx
index f9bb60d..5ac1f91 100644
--- a/src/app/UserWrapper.tsx
+++ b/src/app/UserWrapper.tsx
@@ -32,7 +32,7 @@ const useStyles = makeStyles((theme: Theme) => ({
paddingBottom: 0,
},
[theme.breakpoints.up("md")]: {
- paddingLeft: theme.spacing(8)
+ paddingLeft: theme.spacing(9)
},
},
container: {
diff --git a/src/app/main.tsx b/src/app/main.tsx
index 2d8615c..feae822 100644
--- a/src/app/main.tsx
+++ b/src/app/main.tsx
@@ -1,5 +1,6 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
+import { StyledEngineProvider } from '@mui/material/styles'
import App from './App'
// I don't consider providing a disabled button to a Tooltip an error.
@@ -20,6 +21,8 @@ if ('serviceWorker' in navigator) {
createRoot(document.getElementById('root')!).render(
//
-
+
+
+
// ,
)
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 0f2de1b..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";
@@ -53,7 +43,7 @@ import CNHiIcon from "products/CommonIcons/cnhiIcon";
import LibraCartIcon from "products/CommonIcons/libracartIcon";
const drawerWidth = 230;
-const closedDrawerWidth = 8;
+const closedDrawerWidth = 9.25;
const useStyles = makeStyles((theme: Theme) => ({
sideMenu: {
@@ -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) {
- {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);
}, []);