Merge branch 'local_server' into dev_environment

This commit is contained in:
Carter 2026-05-21 12:34:52 -06:00
commit e812c878f2
12 changed files with 442 additions and 422 deletions

7
.env
View file

@ -7,6 +7,7 @@ VITE_AUTH0_CLIENT_DOMAIN=brandxtech.auth0.com
VITE_AUTH0_AUDIENCE=api.brandxtech.ca VITE_AUTH0_AUDIENCE=api.brandxtech.ca
VITE_AUTH0_DEV_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 VITE_AUTH0_DEV_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1
VITE_AUTH0_STAGING_CLIENT_ID=3ib460VvLwdeyse5iUSQfxkVdQaUmphP VITE_AUTH0_STAGING_CLIENT_ID=3ib460VvLwdeyse5iUSQfxkVdQaUmphP
VITE_AUTH0_STREAMLINE_CLIENT_ID=HwUV0hHNdVvU96zuMBTAU8i7nFdwwgIX
VITE_AUTH0_BXT_CLIENT_ID=sLnqOu40uWfQT1lYSDYj2wYmlLEHRB74 VITE_AUTH0_BXT_CLIENT_ID=sLnqOu40uWfQT1lYSDYj2wYmlLEHRB74
VITE_AUTH0_ADAPTIVE_AGRICULTURE_CLIENT_ID=5pUCkl2SfogkWmM244UDcLEUOp8EFdHd 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_OMNIAIR_CLIENT_ID=IblmarD8wFafiD6doxTmOHQ6Bx3L9wWl
VITE_AUTH0_INTELLIFARMS_CLIENT_ID=RYtuAyOcB4DSaaqJMLDMf3pV8SFY9PdY VITE_AUTH0_INTELLIFARMS_CLIENT_ID=RYtuAyOcB4DSaaqJMLDMf3pV8SFY9PdY
#Crisp
VITE_CRISP_WEBSITE_ID=80170383-b426-43c0-8f66-8e20a05bcdce
#Branding (Default theme) #Branding (Default theme)
VITE_APP_WEBSITE_TITLE="Adaptive Dashboard" VITE_APP_WEBSITE_TITLE="Adaptive Dashboard"
VITE_APP_PRIMARY_COLOUR=blue 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) # Live device/component WebSocket streams (must match string "true" in code)
VITE_ENABLE_WEBSOCKETS=true VITE_ENABLE_WEBSOCKETS=true
# Default whitelabel; overwrite in .env.local
VITE_WHITELABEL=adaptive-ag

View file

@ -32,9 +32,15 @@ SSH_OPTS="-i $DEPLOY_SSH_KEY"
echo "→ Deploying to $DEPLOY_USER@$DEPLOY_HOST using key $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) # 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" 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/) # Fail if the bundle still embeds Crisp (wrong vite mode or stale build/)

View file

@ -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": "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-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-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-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_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-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", "build": "tsc -b && vite build",
"lint": "eslint .", "lint": "eslint .",
"preview": "vite preview", "preview": "vite preview",

View file

@ -32,7 +32,7 @@ const useStyles = makeStyles((theme: Theme) => ({
paddingBottom: 0, paddingBottom: 0,
}, },
[theme.breakpoints.up("md")]: { [theme.breakpoints.up("md")]: {
paddingLeft: theme.spacing(8) paddingLeft: theme.spacing(9)
}, },
}, },
container: { container: {

View file

@ -1,5 +1,6 @@
import { StrictMode } from 'react' import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client' import { createRoot } from 'react-dom/client'
import { StyledEngineProvider } from '@mui/material/styles'
import App from './App' import App from './App'
// I don't consider providing a disabled button to a Tooltip an error. // 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( createRoot(document.getElementById('root')!).render(
// <StrictMode> // <StrictMode>
<App /> <StyledEngineProvider injectFirst>
<App />
</StyledEngineProvider>
// </StrictMode>, // </StrictMode>,
) )

View file

@ -13,7 +13,7 @@ import BinsIcon from "products/Bindapt/BinsIcon";
import { useGlobalState } from "providers"; import { useGlobalState } from "providers";
import { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { useNavigate, useLocation } from "react-router-dom"; 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 FieldsIcon from "products/AgIcons/FieldsIcon";
import NexusSTIcon from "products/Construction/NexusSTIcon"; import NexusSTIcon from "products/Construction/NexusSTIcon";
import OmniAirDeviceIcon from "products/AviationIcons/OmniAirDeviceIcon"; import OmniAirDeviceIcon from "products/AviationIcons/OmniAirDeviceIcon";
@ -36,20 +36,16 @@ export default function BottomNavigator(props: Props) {
const { isAuthenticated } = useAuthContext(); const { isAuthenticated } = useAuthContext();
const [{ user }] = useGlobalState(); const [{ user }] = useGlobalState();
const [route, setRoute] = useState(sideIsOpen ? "side" : ""); const [route, setRoute] = useState(sideIsOpen ? "side" : "");
const isAg = IsAdaptiveAgriculture(); const wl = getWhitelabel();
const isIntel = IsIntellifarms(); const f = getFeatures();
const isMiVent = IsMiVent();
const isAdCon = IsAdCon();
const isOmni = IsOmniAir();
const isMiPCA = IsMiPCA();
const reRoute = useCallback( const reRoute = useCallback(
(path: string) => { (path: string) => {
if (path === "") { if (path === "") {
if (isAg || isIntel) { if (f.bins) {
return "bins"; return "bins";
} }
if (isMiVent) { if (f.ventilation) {
return "ventilation"; return "ventilation";
} }
return "devices"; return "devices";
@ -75,7 +71,7 @@ export default function BottomNavigator(props: Props) {
} }
return path; return path;
}, },
[isAg, isMiVent, isIntel] [f]
); );
const autoDetectRoute = useCallback(() => { const autoDetectRoute = useCallback(() => {
@ -106,27 +102,27 @@ export default function BottomNavigator(props: Props) {
const authenticatedNavigation = () => { const authenticatedNavigation = () => {
return ( return (
<BottomNavigation value={route} onChange={(_, newValue) => handleRouteChange(newValue)}> <BottomNavigation value={route} onChange={(_, newValue) => handleRouteChange(newValue)}>
{isAg || isIntel && ( {f.visualFarm && (
<BottomNavigationAction label="Farm" icon={<FieldsIcon type={getType()} />} value="visualFarm" /> <BottomNavigationAction label="Farm" icon={<FieldsIcon type={getType()} />} value="visualFarm" />
)} )}
{isAg || isIntel && ( {f.bins && (
<BottomNavigationAction label="Bins" icon={<BinsIcon type={getType()} />} value="bins" /> <BottomNavigationAction label="Bins" icon={<BinsIcon type={getType()} />} value="bins" />
)} )}
{isAdCon && ( {f.constructionMap && (
<BottomNavigationAction <BottomNavigationAction
label="Site Map" label="Site Map"
icon={<FieldsIcon type={getType()} />} icon={<FieldsIcon type={getType()} />}
value="constructionMap" value="constructionMap"
/> />
)} )}
{(isOmni || isMiPCA) && ( {f.aviationMap && (
<BottomNavigationAction <BottomNavigationAction
label="Map" label="Map"
icon={<AirportMapIcon type={getType()} />} icon={<AirportMapIcon type={getType()} />}
value="aviationMap" value="aviationMap"
/> />
)} )}
{(isOmni || isMiPCA) && ( {f.terminals && (
<BottomNavigationAction <BottomNavigationAction
label="Terminals" label="Terminals"
icon={<PlaneIcon type={getType()} />} icon={<PlaneIcon type={getType()} />}
@ -137,11 +133,11 @@ export default function BottomNavigator(props: Props) {
<BottomNavigationAction <BottomNavigationAction
label="Devices" label="Devices"
icon={ icon={
(isAg || isIntel) ? ( f.bins ? (
<BindaptIcon type={getType()} /> <BindaptIcon type={getType()} />
) : isAdCon ? ( ) : f.constructionMap ? (
<NexusSTIcon type={getType()} /> <NexusSTIcon type={getType()} />
) : (isOmni || isMiPCA) ? ( ) : f.aviationMap ? (
<OmniAirDeviceIcon type={getType()} /> <OmniAirDeviceIcon type={getType()} />
) : ( ) : (
<DevicesIcon /> <DevicesIcon />
@ -149,22 +145,15 @@ export default function BottomNavigator(props: Props) {
} }
value="devices" value="devices"
/> />
{isAdCon && ( {f.jobsites && (
<BottomNavigationAction <BottomNavigationAction
label="Sites" label="Sites"
icon={<JobsiteIcon type={getType()} />} icon={<JobsiteIcon type={getType()} />}
value="jobsites" value="jobsites"
/> />
)} )}
{/* {isMiVent && (
<BottomNavigationAction
label="Ventilation"
icon={<VentilationIcon type="light" />}
value="ventilation"
/>
)} */}
{isBXT() && user.hasFeature("security") && ( {f.security && user.hasFeature("security") && (
<BottomNavigationAction label="Security" icon={<Security />} value="security" /> <BottomNavigationAction label="Security" icon={<Security />} value="security" />
)} )}
<BottomNavigationAction label="More" icon={<MoreHoriz />} value="more" /> <BottomNavigationAction label="More" icon={<MoreHoriz />} value="more" />

View file

@ -23,17 +23,7 @@ import BindaptIcon from "../products/Bindapt/BindaptIcon";
import { useLocation, useNavigate } from "react-router-dom"; import { useLocation, useNavigate } from "react-router-dom";
import BinsIcon from "products/Bindapt/BinsIcon"; import BinsIcon from "products/Bindapt/BinsIcon";
import { useGlobalState } from "providers"; import { useGlobalState } from "providers";
import { import { getFeatures } from "services/whiteLabel";
IsAdaptiveAgriculture,
// hasTutorialPlaylist,
IsAdCon,
IsIntellifarms,
IsMiPCA,
// isBXT,
IsMiVent,
IsOmniAir,
IsStreamline,
} from "services/whiteLabel";
import MiningIcon from "products/ventilation/MiningIcon"; import MiningIcon from "products/ventilation/MiningIcon";
import { useAuthContext } from "providers/authContext"; import { useAuthContext } from "providers/authContext";
import FieldsIcon from "products/AgIcons/FieldsIcon"; import FieldsIcon from "products/AgIcons/FieldsIcon";
@ -53,7 +43,7 @@ import CNHiIcon from "products/CommonIcons/cnhiIcon";
import LibraCartIcon from "products/CommonIcons/libracartIcon"; import LibraCartIcon from "products/CommonIcons/libracartIcon";
const drawerWidth = 230; const drawerWidth = 230;
const closedDrawerWidth = 8; const closedDrawerWidth = 9.25;
const useStyles = makeStyles((theme: Theme) => ({ const useStyles = makeStyles((theme: Theme) => ({
sideMenu: { sideMenu: {
@ -172,16 +162,10 @@ export default function SideNavigator(props: Props) {
} }
const authenticatedSideMenu = () => { const authenticatedSideMenu = () => {
const isMiVent = IsMiVent(); const f = getFeatures();
const isAg = IsAdaptiveAgriculture()
const isIntel = IsIntellifarms()
const isStreamline = IsStreamline()
const isOmni = IsOmniAir()
const isMiPCA = IsMiPCA()
const isAdCon = IsAdCon()
return ( return (
<List className={classes.list} component="nav"> <List className={classes.list} component="nav">
{(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( {(f.visualFarm || user.hasFeature("admin")) && (
<Tooltip title="Visual Farm" placement="right"> <Tooltip title="Visual Farm" placement="right">
<ListItemButton <ListItemButton
id="tour-visual-farm" id="tour-visual-farm"
@ -195,7 +179,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}
{((isOmni || isMiPCA) || user.hasFeature("admin")) && ( {(f.aviationMap || user.hasFeature("admin")) && (
<Tooltip title="Aviation Map" placement="right"> <Tooltip title="Aviation Map" placement="right">
<ListItemButton <ListItemButton
id="tour-aviation-map" id="tour-aviation-map"
@ -209,7 +193,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}
{(isAdCon || user.hasFeature("admin")) && ( {(f.constructionMap || user.hasFeature("admin")) && (
<Tooltip title="Construction Map" placement="right"> <Tooltip title="Construction Map" placement="right">
<ListItemButton <ListItemButton
id="tour-construction-map" id="tour-construction-map"
@ -223,7 +207,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}
{(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( {(f.contracts || user.hasFeature("admin")) && (
<Tooltip title="Contracts" placement="right"> <Tooltip title="Contracts" placement="right">
<ListItemButton <ListItemButton
id="tour-contracts" id="tour-contracts"
@ -237,7 +221,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}
{(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( {(f.bins || user.hasFeature("admin")) && (
<Tooltip title="Bins" placement="right"> <Tooltip title="Bins" placement="right">
<ListItemButton <ListItemButton
id="tour-bins" id="tour-bins"
@ -251,7 +235,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}
{((isOmni || isMiPCA) || user.hasFeature("admin")) && ( {(f.terminals || user.hasFeature("admin")) && (
<Tooltip title="Terminals" placement="right"> <Tooltip title="Terminals" placement="right">
<ListItemButton <ListItemButton
id="tour-terminals" id="tour-terminals"
@ -265,7 +249,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}
{(user.hasFeature("installer") && isAg || user.hasFeature("admin")) && {(f.cableEstimator && user.hasFeature("installer") || user.hasFeature("admin")) &&
<Tooltip title="Cable Estimator" placement="right"> <Tooltip title="Cable Estimator" placement="right">
<ListItemButton <ListItemButton
id="tour-cable-estimator" id="tour-cable-estimator"
@ -279,7 +263,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
} }
{(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( {(f.transactions || user.hasFeature("admin")) && (
<Tooltip title="Transactions" placement="right"> <Tooltip title="Transactions" placement="right">
<ListItemButton <ListItemButton
id="tour-transactions" id="tour-transactions"
@ -293,7 +277,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}
{(isMiVent || user.hasFeature("admin")) && ( {(f.mines || user.hasFeature("admin")) && (
<Tooltip title="Mines" placement="right"> <Tooltip title="Mines" placement="right">
<ListItemButton <ListItemButton
id="tour-mines" id="tour-mines"
@ -371,7 +355,7 @@ export default function SideNavigator(props: Props) {
{open && <ListItemText primary="Users" />} {open && <ListItemText primary="Users" />}
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
{(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( {(f.fields || user.hasFeature("admin")) && (
<Tooltip title="My Fields" placement="right"> <Tooltip title="My Fields" placement="right">
<ListItemButton <ListItemButton
id="tour-field-list" id="tour-field-list"
@ -385,7 +369,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}
{(isAg || isIntel || isStreamline || user.hasFeature("admin")) && ( {(f.grainTypes || user.hasFeature("admin")) && (
<Tooltip title="Grain Types" placement="right"> <Tooltip title="Grain Types" placement="right">
<ListItemButton <ListItemButton
id="tour-grain-types" id="tour-grain-types"
@ -400,7 +384,7 @@ export default function SideNavigator(props: Props) {
</Tooltip> </Tooltip>
)} )}
{(isAdCon || user.hasFeature("admin")) && ( {(f.jobsites || user.hasFeature("admin")) && (
<Tooltip title="Jobsites" placement="right"> <Tooltip title="Jobsites" placement="right">
<ListItemButton <ListItemButton
id="tour-jobsites" id="tour-jobsites"
@ -414,7 +398,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}
{(isAdCon || user.hasFeature("admin")) && ( {(f.heaters || user.hasFeature("admin")) && (
<Tooltip title="Heaters" placement="right"> <Tooltip title="Heaters" placement="right">
<ListItemButton <ListItemButton
id="tour-heaters" id="tour-heaters"
@ -469,7 +453,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
} }
{(isAg || isIntel || isStreamline || user.hasFeature("admin")) && {(f.marketplace || user.hasFeature("admin")) &&
<Tooltip title="Marketplace" placement="right"> <Tooltip title="Marketplace" placement="right">
<ListItemButton <ListItemButton
id="tour-marketplace" id="tour-marketplace"

View file

@ -7,7 +7,7 @@ import { CheckCircleOutline } from "@mui/icons-material";
import { green } from "@mui/material/colors"; import { green } from "@mui/material/colors";
import Tour, { TourStep } from "common/Tour"; import Tour, { TourStep } from "common/Tour";
import Emoji from "react-emoji-render"; import Emoji from "react-emoji-render";
import { getWhitelabel, IsAdaptiveAgriculture } from "services/whiteLabel"; import { getWhitelabel, getFeatures } from "services/whiteLabel";
import { pond } from "protobuf-ts/pond"; import { pond } from "protobuf-ts/pond";
import { User } from "models"; import { User } from "models";
// import { color } from "framer-motion"; // import { color } from "framer-motion";
@ -154,7 +154,7 @@ export default function SignupCallback () {
<MenuItem value={pond.DistanceUnit.DISTANCE_UNIT_FEET}>Feet (ft)</MenuItem> <MenuItem value={pond.DistanceUnit.DISTANCE_UNIT_FEET}>Feet (ft)</MenuItem>
</TextField> </TextField>
</Grid2> </Grid2>
{IsAdaptiveAgriculture() && ( {getFeatures().grainUnit && (
<Grid2 size={{ xs: 12 }}> <Grid2 size={{ xs: 12 }}>
<TextField <TextField
select select
@ -294,7 +294,7 @@ export default function SignupCallback () {
placement: "right" placement: "right"
}) })
//tasks step //tasks step
if (IsAdaptiveAgriculture()) { if (getFeatures().visualFarm) {
steps.push({ steps.push({
title: "Visual Farm", title: "Visual Farm",
content: ( content: (

View file

@ -16,7 +16,7 @@ import { useGlobalState, useSnackbar, useUserAPI } from "providers";
import { useTeamAPI } from "providers/pond/teamAPI"; import { useTeamAPI } from "providers/pond/teamAPI";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useLocation, useNavigate, useParams } from 'react-router-dom'; import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { getSignatureAccentColour, IsAdaptiveAgriculture, IsStreamline } from "services/whiteLabel"; import { getSignatureAccentColour, getFeatures } from "services/whiteLabel";
import TeamActions from "teams/TeamActions"; import TeamActions from "teams/TeamActions";
import TeamKeyManager from "teams/TeamKeyManager"; import TeamKeyManager from "teams/TeamKeyManager";
import ObjectUsers from "user/ObjectUsers"; import ObjectUsers from "user/ObjectUsers";
@ -220,8 +220,7 @@ export default function TeamPage() {
navigate("bins") navigate("bins")
} }
const isAg = IsAdaptiveAgriculture() const f = getFeatures()
const isStreamline = IsStreamline()
return ( return (
<PageContainer spacing={isMobile ? 1 : 2}> <PageContainer spacing={isMobile ? 1 : 2}>
@ -267,7 +266,7 @@ export default function TeamPage() {
<ListItemButton onClick={toGroups}> <ListItemButton onClick={toGroups}>
Groups Groups
</ListItemButton> </ListItemButton>
{((isAg || isStreamline) || user.hasFeature("admin")) && {(f.bins || user.hasFeature("admin")) &&
<> <>
<Divider /> <Divider />
<ListItemButton onClick={toBins}> <ListItemButton onClick={toBins}>

View file

@ -1,4 +1,3 @@
// import { isOffline } from "utils/environment";
import DefaultDarkLogo from "../assets/whitelabels/darkLogo.png"; import DefaultDarkLogo from "../assets/whitelabels/darkLogo.png";
import DefaultLightLogo from "../assets/whitelabels/lightLogo.png"; import DefaultLightLogo from "../assets/whitelabels/lightLogo.png";
import AdapativeAgLogo from "../assets/whitelabels/AdaptiveAgriculture/logo.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 AeroGrowDarkLogo from "../assets/whitelabels/AeroGrow/darkLogo.png";
import AeroGrowLightLogo from "../assets/whitelabels/AeroGrow/lightLogo.png"; import AeroGrowLightLogo from "../assets/whitelabels/AeroGrow/lightLogo.png";
import MiVentLightLogo from "../assets/whitelabels/MiVent/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 MiPCALogo from "../assets/whitelabels/MiPCA/MiPCALogo.png";
import StreamlineLogo from "../assets/whitelabels/Streamline/stream-logo.png" import StreamlineLogo from "../assets/whitelabels/Streamline/stream-logo.png"
import IntellifarmsLogo from "../assets/whitelabels/Intellifarms/IFND-2023-Logo.png" import IntellifarmsLogo from "../assets/whitelabels/Intellifarms/IFND-2023-Logo.png"
import IntellifarmsLogoWhite from "../assets/whitelabels/Intellifarms/IFND-2023-Logo-White.png" import IntellifarmsLogoWhite from "../assets/whitelabels/Intellifarms/IFND-2023-Logo-White.png"
// import { green, yellow } from "@mui/material/colors";
const protips: string[] = [ const protips: string[] = [
"You can see the latest measurements for a device by starring its components!", "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!" "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 { interface WhiteLabel {
name: any; slug: string;
primaryColour: any; //must be a MATERIAL UI colour, used for various UI elements name: string;
secondaryColour: any; //must be a MATERIAL UI colour, used for a few UI elements (less importance) primaryColour: any;
signatureColour: any; //hex or RGB secondaryColour: any;
signatureAccentColour: any; //hex or RGB signatureColour: any;
auth0ClientId: any; signatureAccentColour: any;
auth0ClientId: string;
redirectOnLogout: boolean; redirectOnLogout: boolean;
logoutRedirectTarget: string; logoutRedirectTarget: string;
darkLogo: any; darkLogo: any;
lightLogo: any; lightLogo: any;
transparentLogoBG: boolean; //determines whether the background of the logo should be transparent or not transparentLogoBG: boolean;
blacklist: string[]; blacklist: string[];
features: WhiteLabelFeatures;
hotjarID?: string; hotjarID?: string;
docs: string; docs: string;
protips: string[]; protips: string[];
tutorialPlaylistID?: string; tutorialPlaylistID?: string;
thumbnail?: string; thumbnail?: string;
tutorialFiles?: { name: string; url: string }[]; tutorialFiles?: { name: string; url: string }[];
homePage?: string; homePage: string;
} }
// const DEFAULT_WHITELABEL: WhiteLabel = { const AG_FEATURES: WhiteLabelFeatures = {
// name: import.meta.env.REACT_APP_WEBSITE_TITLE, bins: true,
// primaryColour: import.meta.env.REACT_APP_PRIMARY_COLOUR, visualFarm: true,
// secondaryColour: import.meta.env.REACT_APP_SECONDARY_COLOUR, contracts: true,
// signatureColour: import.meta.env.REACT_APP_SIGNATURE_COLOUR, transactions: true,
// signatureAccentColour: "#fff", fields: true,
// auth0ClientId: import.meta.env.REACT_APP_AUTH0_CLIENT_ID, grainTypes: true,
// redirectOnLogout: false, grainUnit: true,
// logoutRedirectTarget: "", marketplace: true,
// darkLogo: DefaultDarkLogo, cableEstimator: true,
// lightLogo: DefaultLightLogo, ventilation: false,
// transparentLogoBG: false, mines: false,
// blacklist: [], constructionMap: false,
// hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_BXT, jobsites: false,
// docs: "Platform", heaters: false,
// protips: protips, aviationMap: false,
// tutorialPlaylistID: "" terminals: false,
// }; security: false,
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 BXT_WHITE_LABEL: WhiteLabel = { const CONSTRUCTION_FEATURES: WhiteLabelFeatures = {
name: "Brand X Technologies", bins: false,
primaryColour: "blue", visualFarm: false,
// primaryColour: "#0000FF", contracts: false,
secondaryColour: "yellow", transactions: false,
// secondaryColour: "#FFFF00", fields: false,
// signatureColour: "#272727", grainTypes: false,
signatureColour: "#005bb0", grainUnit: false,
signatureAccentColour: "#fff", marketplace: false,
auth0ClientId: import.meta.env.VITE_AUTH0_DEV_CLIENT_ID, cableEstimator: false,
redirectOnLogout: false, ventilation: false,
logoutRedirectTarget: "", mines: false,
darkLogo: BXTDarkLogo, constructionMap: true,
lightLogo: BXTLightLogo, jobsites: true,
transparentLogoBG: false, heaters: true,
blacklist: [], aviationMap: false,
hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_BXT, terminals: false,
docs: "Platform", security: false,
protips: protips,
homePage: "/devices"
}; };
const STREAMLINE_WHITE_LABEL: WhiteLabel = { const AVIATION_FEATURES: WhiteLabelFeatures = {
name: "Streamline", bins: false,
primaryColour: "#FFFF", visualFarm: false,
// primaryColour: "#0000FF", contracts: false,
secondaryColour: "yellow", transactions: false,
// secondaryColour: "#FFFF00", fields: false,
// signatureColour: "#272727", grainTypes: false,
signatureColour: "#005bb0", grainUnit: false,
signatureAccentColour: "#fff", marketplace: false,
auth0ClientId: import.meta.env.VITE_AUTH0_STREAMLINE_CLIENT_ID, cableEstimator: false,
redirectOnLogout: false, ventilation: false,
logoutRedirectTarget: "", mines: false,
darkLogo: StreamlineLogo, constructionMap: false,
lightLogo: StreamlineLogo, jobsites: false,
transparentLogoBG: false, heaters: false,
blacklist: [], aviationMap: true,
hotjarID: import.meta.env.REACT_APP_HOTJAR_ID_BXT, terminals: true,
docs: "Platform", security: false,
protips: protips,
homePage: "/devices"
}; };
export function isBXT(): boolean { const MIVENT_FEATURES: WhiteLabelFeatures = {
return getName() === "Brand X Technologies"; 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<string, WhiteLabel> = {
"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 = { let cached: WhiteLabel | null = null;
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<string, WhiteLabel>([
["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]
]);
export function getWhitelabel(): WhiteLabel { export function getWhitelabel(): WhiteLabel {
// if (isOffline()) { if (!cached) {
// return DEFAULT_WHITELABEL; cached = registry[resolveSlug()];
// } }
return cached;
}
const hostname = window.location.hostname; export function getFeatures(): WhiteLabelFeatures {
if (window.location.origin.includes("bxt-dev")) { return getWhitelabel().features;
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 getPrimaryColour(): any { export function getPrimaryColour(): any {
@ -397,7 +448,7 @@ export function getSignatureAccentColour(): any {
return getWhitelabel().signatureAccentColour; return getWhitelabel().signatureAccentColour;
} }
export function getAuth0ClientId(): any { export function getAuth0ClientId(): string {
return getWhitelabel().auth0ClientId; return getWhitelabel().auth0ClientId;
} }
@ -418,10 +469,6 @@ export function getLightLogo(): any {
} }
export function hideLogo(): boolean { export function hideLogo(): boolean {
// if (isOffline()) {
// return false;
// }
return getWhitelabel().name === ""; return getWhitelabel().name === "";
} }

View file

@ -29,7 +29,7 @@ import { useThemeMode } from "theme/AppThemeProvider";
// import ContractsIcon from "products/CommonIcons/contractIcon"; // import ContractsIcon from "products/CommonIcons/contractIcon";
import UnitsIcon from "@mui/icons-material/Category"; import UnitsIcon from "@mui/icons-material/Category";
import { setThemeType } from "theme"; import { setThemeType } from "theme";
import { IsAdaptiveAgriculture } from "services/whiteLabel"; import { getFeatures } from "services/whiteLabel";
import { setDistanceUnit, setGrainUnit, setPressureUnit, setTemperatureUnit } from "utils"; import { setDistanceUnit, setGrainUnit, setPressureUnit, setTemperatureUnit } from "utils";
import FieldsIcon from "products/AgIcons/FieldsIcon"; import FieldsIcon from "products/AgIcons/FieldsIcon";
@ -529,7 +529,7 @@ export default function UserSettings(props: Props) {
<MenuItem value={pond.DistanceUnit.DISTANCE_UNIT_FEET}>Feet (ft)</MenuItem> <MenuItem value={pond.DistanceUnit.DISTANCE_UNIT_FEET}>Feet (ft)</MenuItem>
</TextField> </TextField>
</Grid2> </Grid2>
{IsAdaptiveAgriculture() && ( {getFeatures().grainUnit && (
<Grid2 size={{ xs: 12 }}> <Grid2 size={{ xs: 12 }}>
<TextField <TextField
select select

View file

@ -7,12 +7,7 @@ import JohnDeereIcon from "products/CommonIcons/johnDeereIcon";
import CNHiIcon from "products/CommonIcons/cnhiIcon"; import CNHiIcon from "products/CommonIcons/cnhiIcon";
import LibraCartIcon from "products/CommonIcons/libracartIcon"; import LibraCartIcon from "products/CommonIcons/libracartIcon";
//import AgLogo from "assets/whitelabels/AdaptiveAgriculture/AGLogoSquare.png"; //import AgLogo from "assets/whitelabels/AdaptiveAgriculture/AGLogoSquare.png";
import { import { getFeatures } from "services/whiteLabel";
IsAdaptiveAgriculture
// IsAdCon,
// IsMiVent,
// IsOmniAir
} from "services/whiteLabel";
import FeatureCard from "./FeatureCard"; import FeatureCard from "./FeatureCard";
//import { ImgIcon } from "common/ImgIcon"; //import { ImgIcon } from "common/ImgIcon";
//images to import for the image in the card for the feature make sure to have a 2:1 aspect ratio to keep the cards symmetrical //images to import for the image in the card for the feature make sure to have a 2:1 aspect ratio to keep the cards symmetrical
@ -90,19 +85,9 @@ export default function Marketplace() {
useEffect(() => { useEffect(() => {
let list: ProductDetails[] = []; let list: ProductDetails[] = [];
if (IsAdaptiveAgriculture() || user.hasFeature("admin")) { if (getFeatures().marketplace || user.hasFeature("admin")) {
list = list.concat(agFeatureList); 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); setFeaturList(list);
}, []); }, []);