Merge branch 'master' into i2c_detect
This commit is contained in:
commit
5127a78cb0
25 changed files with 619 additions and 74 deletions
BIN
src/assets/whitelabels/Streamline/stream-logo.png
Normal file
BIN
src/assets/whitelabels/Streamline/stream-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
|
|
@ -414,7 +414,7 @@ export default function BinComponents(props: Props) {
|
|||
)}
|
||||
<ListItemText inset={cIcon === undefined}>
|
||||
<Grid container direction="row" justifyContent="space-between">
|
||||
<Grid >{comp.name() + " " + comp.addressDescription(devMap.get(device)?.settings.product)}</Grid>
|
||||
<Grid >{comp.name() + " - " + comp.addressDescription(devMap.get(device)?.settings.product)}</Grid>
|
||||
<Grid >
|
||||
{components?.get(comp.key()) !== undefined ? (
|
||||
<CheckBoxIcon />
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ const useStyles = makeStyles((theme: Theme) => {
|
|||
},
|
||||
stickyHeader: {
|
||||
position: "sticky",
|
||||
backgroundColor: getThemeType() === "light" ? "rgb(245, 245, 245)" : "rgb(40, 40, 40)",
|
||||
// backgroundColor: getThemeType() === "light" ? "rgb(245, 245, 245)" : "rgb(40, 40, 40)",
|
||||
top: 0,
|
||||
zIndex: 300 //giving a really high z-index to make sure nothing is in front of it
|
||||
}
|
||||
|
|
@ -165,6 +165,7 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
const saved = localStorage.getItem(rowKey);
|
||||
return saved ? JSON.parse(saved) : [];
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem(rowKey, JSON.stringify(rowWidths));
|
||||
}, [rowWidths])
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export const appendToUrl = (appendage: number | string) => {
|
|||
|
||||
export default function Router() {
|
||||
|
||||
const { isAuthenticated, loginWithRedirect, isLoading } = useAuth0();
|
||||
const { /*isAuthenticated, loginWithRedirect,*/ isLoading } = useAuth0();
|
||||
const whiteLabel = getWhitelabel();
|
||||
const [{ user }] = useGlobalState();
|
||||
|
||||
|
|
@ -283,12 +283,12 @@ export default function Router() {
|
|||
};
|
||||
|
||||
if (isLoading) return null;
|
||||
if (!isAuthenticated) {
|
||||
loginWithRedirect()
|
||||
return (
|
||||
null
|
||||
)
|
||||
}
|
||||
// if (!isAuthenticated) {
|
||||
// loginWithRedirect()
|
||||
// return (
|
||||
// null
|
||||
// )
|
||||
// }
|
||||
|
||||
function ErrorFallback({ error }: { error: Error }) {
|
||||
return <div>Something went wrong: {error.stack}</div>;
|
||||
|
|
@ -302,6 +302,7 @@ export default function Router() {
|
|||
|
||||
{/* Redirects */}
|
||||
<Route path="/callback" element={<Navigate to="/" />} />
|
||||
{/* <Route path="/login" element={<Login />} /> */}
|
||||
{/* <Route path="/team/:teamID" element={<Navigate to="/teams/:teamID" />} /> */}
|
||||
{/* <Route path="/device/:deviceID" element={<Navigate to="/devices/:devicesID" />} /> */}
|
||||
<Route path="" element={<Navigate to={whiteLabel.homePage ? whiteLabel.homePage : "/devices"} />} />
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import {
|
|||
// isBXT,
|
||||
IsMiVent,
|
||||
IsOmniAir,
|
||||
IsStreamline,
|
||||
} from "services/whiteLabel";
|
||||
import MiningIcon from "products/ventilation/MiningIcon";
|
||||
import { useAuth0 } from "@auth0/auth0-react";
|
||||
|
|
@ -156,11 +157,12 @@ export default function SideNavigator(props: Props) {
|
|||
const authenticatedSideMenu = () => {
|
||||
const isMiVent = IsMiVent();
|
||||
const isAg = IsAdaptiveAgriculture()
|
||||
const isStreamline = IsStreamline()
|
||||
const isMiPCA = IsOmniAir()
|
||||
const isAdCon = IsAdCon()
|
||||
return (
|
||||
<List className={classes.list} component="nav">
|
||||
{(isAg || user.hasFeature("admin")) && (
|
||||
{(isAg || isStreamline || user.hasFeature("admin")) && (
|
||||
<Tooltip title="Visual Farm" placement="right">
|
||||
<ListItemButton
|
||||
id="tour-visual-farm"
|
||||
|
|
@ -202,7 +204,7 @@ export default function SideNavigator(props: Props) {
|
|||
</ListItemButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
{(isAg || user.hasFeature("admin")) && (
|
||||
{(isAg || isStreamline || user.hasFeature("admin")) && (
|
||||
<Tooltip title="Contracts" placement="right">
|
||||
<ListItemButton
|
||||
id="tour-contracts"
|
||||
|
|
@ -216,7 +218,7 @@ export default function SideNavigator(props: Props) {
|
|||
</ListItemButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
{(isAg || user.hasFeature("admin")) && (
|
||||
{(isAg || isStreamline || user.hasFeature("admin")) && (
|
||||
<Tooltip title="Bins" placement="right">
|
||||
<ListItemButton
|
||||
id="tour-dashboard"
|
||||
|
|
@ -258,7 +260,7 @@ export default function SideNavigator(props: Props) {
|
|||
</ListItemButton>
|
||||
</Tooltip>
|
||||
}
|
||||
{(isAg || user.hasFeature("admin")) && (
|
||||
{(isAg || isStreamline || user.hasFeature("admin")) && (
|
||||
<Tooltip title="Transactions" placement="right">
|
||||
<ListItemButton
|
||||
id="tour-transactions"
|
||||
|
|
@ -350,7 +352,7 @@ export default function SideNavigator(props: Props) {
|
|||
{open && <ListItemText primary="Users" />}
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
{(isAg || user.hasFeature("admin")) && (
|
||||
{(isAg || isStreamline || user.hasFeature("admin")) && (
|
||||
<Tooltip title="My Fields" placement="right">
|
||||
<ListItemButton
|
||||
id="tour-field-list"
|
||||
|
|
@ -434,7 +436,7 @@ export default function SideNavigator(props: Props) {
|
|||
</ListItemButton>
|
||||
</Tooltip>
|
||||
}
|
||||
{isAg &&
|
||||
{(isAg || isStreamline) &&
|
||||
<Tooltip title="Marketplace" placement="right">
|
||||
<ListItemButton
|
||||
id="tour-marketplace"
|
||||
|
|
@ -475,7 +477,7 @@ export default function SideNavigator(props: Props) {
|
|||
{open && <ListItemText primary="Case New Holland" />}
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
}
|
||||
}
|
||||
</List>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@ export default function Devices() {
|
|||
const [limit, setLimit] = useState(10);
|
||||
const [page, setPage] = useState(0);
|
||||
|
||||
const [{ user }] = useGlobalState()
|
||||
|
||||
const [order, setOrder] = useState<"asc" | "desc">(() => {
|
||||
// Load from sessionStorage on initial render
|
||||
const savedOrder = sessionStorage.getItem('order');
|
||||
|
|
@ -585,6 +587,7 @@ export default function Devices() {
|
|||
}
|
||||
|
||||
const provisionButton= () => {
|
||||
if (!user.allowedTo("provision")) return null
|
||||
return (
|
||||
<Tooltip title="Provision Device">
|
||||
<IconButton onClick={openProvisionDialog} aria-label="Provision Device">
|
||||
|
|
|
|||
53
src/pages/Login.tsx
Normal file
53
src/pages/Login.tsx
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { RedirectLoginOptions, useAuth0 } from "@auth0/auth0-react";
|
||||
// import { useAuth } from "hooks";
|
||||
import queryString from "query-string";
|
||||
import { useEffect } from "react";
|
||||
import { useLocation } from "react-router";
|
||||
// import Loading from "./Loading";
|
||||
import LoadingScreen from "app/LoadingScreen";
|
||||
|
||||
// interface Props {
|
||||
// prevPath?: string;
|
||||
// }
|
||||
|
||||
export default function Login() {
|
||||
// const { prevPath } = props;
|
||||
const location = useLocation();
|
||||
const { loginWithRedirect } = useAuth0();
|
||||
|
||||
// const setRouteBeforeLogin = useCallback((): Promise<string> => {
|
||||
// return new Promise(function(resolve) {
|
||||
// localStorage.setItem("routeBeforeLogin", prevPath ? prevPath : "/");
|
||||
// return resolve("success");
|
||||
// });
|
||||
// }, [prevPath]);
|
||||
|
||||
useEffect(() => {
|
||||
const options: RedirectLoginOptions = {
|
||||
authorizationParams: {} // Initialize here
|
||||
};
|
||||
|
||||
if (location && location.search) {
|
||||
let parsed = queryString.parse(location.search);
|
||||
|
||||
if (parsed.signup === "true") {
|
||||
// if (options.authorizationParams) options.authorizationParams.screen_hint = "signup"; // 'signup' tells Auth0 to show the signup tab
|
||||
options.authorizationParams!.screen_hint = "signup"; // 'signup' tells Auth0 to show the signup tab
|
||||
options.authorizationParams!.prompt = "login";
|
||||
}
|
||||
|
||||
if (parsed.email && parsed.email !== "") {
|
||||
// if (options.authorizationParams) options.authorizationParams.login_hint = parsed.email.toString(); // prefill email
|
||||
options.authorizationParams!.login_hint = parsed.email.toString(); // prefill email
|
||||
}
|
||||
}
|
||||
|
||||
// setRouteBeforeLogin().finally(() => {
|
||||
console.log(options.authorizationParams)
|
||||
loginWithRedirect(options);
|
||||
// });
|
||||
}, [location, loginWithRedirect]);
|
||||
|
||||
// return <LoadingScreen fullViewport={true} />;
|
||||
return <LoadingScreen message="login redirect" />;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { Container, SxProps, Theme } from "@mui/material";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import classNames from "classnames";
|
||||
import { useMobile } from "hooks";
|
||||
// import { useMobile } from "hooks";
|
||||
import { PropsWithChildren } from "react";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
|
|
@ -44,11 +44,11 @@ interface Props extends PropsWithChildren{
|
|||
|
||||
export const PageContainer: React.FunctionComponent<Props> = (props: Props) => {
|
||||
const classes = useStyles();
|
||||
const isMobile = useMobile();
|
||||
// const isMobile = useMobile();
|
||||
const { children, fullViewport, isCenterCenter, sx } = props;
|
||||
// let fullViewport = false
|
||||
// let isCenterCenter = false
|
||||
const spacing = props.spacing;
|
||||
const spacing = props.spacing ? props.spacing : 2;
|
||||
return (
|
||||
<Container
|
||||
className={classNames(
|
||||
|
|
|
|||
|
|
@ -1,31 +1,55 @@
|
|||
import { useAuth0 } from "@auth0/auth0-react";
|
||||
import { RedirectLoginOptions, useAuth0 } from "@auth0/auth0-react";
|
||||
import queryString from "query-string";
|
||||
import { PropsWithChildren, useEffect } from "react";
|
||||
|
||||
interface Props extends PropsWithChildren<any>{
|
||||
setToken: React.Dispatch<React.SetStateAction<string | undefined>>
|
||||
prevPath?: string
|
||||
}
|
||||
|
||||
export default function AuthWrapper(props: Props) {
|
||||
const { children, setToken } = props;
|
||||
const { isLoading, loginWithRedirect, isAuthenticated, getAccessTokenSilently } = useAuth0();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAuthenticated && !isLoading) {
|
||||
loginWithRedirect();
|
||||
}
|
||||
}, [isAuthenticated, loginWithRedirect, isLoading]);
|
||||
const { children, setToken } = props;
|
||||
const { isLoading, loginWithRedirect, isAuthenticated, getAccessTokenSilently } = useAuth0();
|
||||
|
||||
useEffect(() => {
|
||||
if (isAuthenticated) getAccessTokenSilently().then(t => {
|
||||
if (t.length < 1) {
|
||||
loginWithRedirect()
|
||||
}
|
||||
setToken(t)
|
||||
}).catch(() => {
|
||||
// No token, go back to login
|
||||
loginWithRedirect()
|
||||
})
|
||||
}, [setToken, isAuthenticated])
|
||||
|
||||
return children;
|
||||
useEffect(() => {
|
||||
const url = new URL(window.location.href);
|
||||
|
||||
const isManualLoginPage = url.pathname.includes("/login");
|
||||
|
||||
if (isManualLoginPage) {
|
||||
const options: RedirectLoginOptions = {
|
||||
authorizationParams: {} // Initialize here
|
||||
};
|
||||
|
||||
let parsed = queryString.parse(url.search);
|
||||
if (parsed.signup === "true") {
|
||||
options.authorizationParams!.screen_hint = "signup";
|
||||
options.authorizationParams!.prompt = "login";
|
||||
}
|
||||
|
||||
if (parsed.email && parsed.email !== "") {
|
||||
options.authorizationParams!.login_hint = parsed.email.toString(); // prefill email
|
||||
}
|
||||
|
||||
loginWithRedirect(options)
|
||||
|
||||
} else if (!isAuthenticated && !isLoading) {
|
||||
loginWithRedirect();
|
||||
}
|
||||
}, [isAuthenticated, loginWithRedirect, isLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isAuthenticated) getAccessTokenSilently().then(t => {
|
||||
if (t.length < 1) {
|
||||
loginWithRedirect()
|
||||
}
|
||||
setToken(t)
|
||||
}).catch(() => {
|
||||
// No token, go back to login
|
||||
loginWithRedirect()
|
||||
})
|
||||
}, [setToken, isAuthenticated])
|
||||
|
||||
return children;
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ 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/OmniAir/MiPCALogo.png";
|
||||
import StreamlineLogo from "../assets/whitelabels/Streamline/stream-logo.png"
|
||||
// import { green, yellow } from "@mui/material/colors";
|
||||
|
||||
const protips: string[] = [
|
||||
|
|
@ -111,6 +112,28 @@ const BXT_WHITE_LABEL: WhiteLabel = {
|
|||
homePage: "/devices"
|
||||
};
|
||||
|
||||
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"
|
||||
};
|
||||
|
||||
export function isBXT(): boolean {
|
||||
return getName() === "Brand X Technologies";
|
||||
}
|
||||
|
|
@ -157,6 +180,14 @@ export function IsAdaptiveAgriculture(): boolean {
|
|||
);
|
||||
}
|
||||
|
||||
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",
|
||||
|
|
@ -254,6 +285,7 @@ export function IsOmniAir(): boolean {
|
|||
}
|
||||
|
||||
const whitelabels = new Map<string, WhiteLabel>([
|
||||
["streamline", STREAMLINE_WHITE_LABEL],
|
||||
["adaptiveag", ADAPTIVE_AGRICULTURE_WHITE_LABEL],
|
||||
["adaptiveagriculture", ADAPTIVE_AGRICULTURE_WHITE_LABEL],
|
||||
["brandxducks", BXT_WHITE_LABEL],
|
||||
|
|
@ -276,6 +308,9 @@ export function getWhitelabel(): WhiteLabel {
|
|||
if (window.location.origin.includes("bxt-dev")) {
|
||||
return BXT_WHITE_LABEL;
|
||||
}
|
||||
if (window.location.origin.includes("localhost")) {
|
||||
return STREAMLINE_WHITE_LABEL;
|
||||
}
|
||||
if (window.location.origin.includes("staging") || import.meta.env.VITE_LOCAL_STAGING=='true') {
|
||||
return STAGING_WHITELABEL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ export default function TeamActions(props: Props) {
|
|||
permissions={permissions}
|
||||
isDialogOpen={openState.share}
|
||||
closeDialogCallback={() => setOpenState({ ...openState, share: false })}
|
||||
useImitation={false}
|
||||
/>
|
||||
<ObjectUsers
|
||||
scope={teamScope(key)}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { createContext, useContext, useMemo, useState } from "react";
|
||||
import { ThemeProvider, createTheme, PaletteMode } from "@mui/material/styles";
|
||||
import { ThemeProvider, PaletteMode } from "@mui/material/styles";
|
||||
import useMediaQuery from "@mui/material/useMediaQuery";
|
||||
import { getTheme } from "./theme";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import { Avatar, Box, Button, Checkbox, Divider, IconButton, ListItemIcon, ListItemText, Menu, MenuItem, PaletteColor, Theme, Tooltip, useTheme } from "@mui/material";
|
||||
import { Avatar, Box, Button, Checkbox, Divider, ListItemIcon, ListItemText, Menu, MenuItem, PaletteColor, Theme, Tooltip, useTheme } from "@mui/material";
|
||||
import { useGlobalState } from "../providers/StateContainer";
|
||||
import { getSecondaryColour, getSignatureAccentColour } from "../services/whiteLabel";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import { LockOpen, Person, Lock, Settings, SupervisedUserCircle as TeamIcon, ExitToApp, PersonAdd } from "@mui/icons-material";
|
||||
import { useState } from "react";
|
||||
import UserTeamName from "./UserTeamName";
|
||||
import ThemeIcon from "../common/ThemeIcon";
|
||||
import { useAuth0 } from "@auth0/auth0-react";
|
||||
import UserSettings from "./UserSettings";
|
||||
import UserAvatar from "./UserAvatar";
|
||||
|
|
@ -14,7 +13,7 @@ import { useNavigate } from "react-router-dom";
|
|||
import TeamDialog from "teams/TeamDialog";
|
||||
import AccessObject from "./AccessObject";
|
||||
import { useSnackbar, useUserAPI } from "hooks";
|
||||
import { useThemeMode } from "theme/AppThemeProvider";
|
||||
// import { useThemeMode } from "theme/AppThemeProvider";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
accessIcon: {
|
||||
|
|
@ -76,7 +75,7 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
|
||||
export default function UserMenu() {
|
||||
|
||||
const { toggleMode } = useThemeMode()
|
||||
// const { toggleMode } = useThemeMode()
|
||||
const [{ user, team, as }, dispatch] = useGlobalState();
|
||||
const { loginWithRedirect } = useAuth0();
|
||||
const classes = useStyles();
|
||||
|
|
@ -163,10 +162,6 @@ export default function UserMenu() {
|
|||
<Lock className={classes.rightIcon} fontSize="small" />
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<IconButton onClick={/*toggleMode*/ () => {}} className={classes.rightIcon} aria-label="Toggle Theme">
|
||||
<ThemeIcon />
|
||||
</IconButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ import {
|
|||
Textsms as TextIcon,
|
||||
Contrast,
|
||||
} from "@mui/icons-material";
|
||||
import { AppBar, Box, Button, Checkbox, CircularProgress, Collapse, Divider, FormControl, FormControlLabel, FormGroup, FormHelperText, FormLabel, Grid2, IconButton, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Radio, RadioGroup, TextField, Theme, ToggleButton, ToggleButtonGroup, Toolbar, Tooltip, Typography } from "@mui/material";
|
||||
import { AppBar, Box, Button, Checkbox, CircularProgress, Collapse, Divider, FormControl, FormControlLabel, FormGroup, FormHelperText, FormLabel, Grid2, IconButton, List, ListItem, ListItemButton, ListItemIcon, ListItemText, MenuItem, Radio, RadioGroup, TextField, Theme, ToggleButton, ToggleButtonGroup, Toolbar, Tooltip, Typography } from "@mui/material";
|
||||
import ResponsiveDialog from "common/ResponsiveDialog";
|
||||
import UserAvatar from "./UserAvatar";
|
||||
import { useGlobalState, useUserAPI } from "providers";
|
||||
import { useGlobalState, useSnackbar, useUserAPI } from "providers";
|
||||
import { useEffect, useState } from "react";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import { blue } from "@mui/material/colors";
|
||||
|
|
@ -26,8 +26,11 @@ import moment from "moment";
|
|||
import { IconPicker } from "common/IconPicker";
|
||||
import { MuiTelInput } from "mui-tel-input";
|
||||
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 { setThemeType } from "theme";
|
||||
import { IsAdaptiveAgriculture } from "services/whiteLabel";
|
||||
import { setDistanceUnit, setGrainUnit, setPressureUnit, setTemperatureUnit } from "utils";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => {
|
||||
return ({
|
||||
|
|
@ -71,14 +74,16 @@ export default function UserSettings(props: Props) {
|
|||
const [sharing, setSharing] = useState(false)
|
||||
const userAPI = useUserAPI();
|
||||
const classes = useStyles()
|
||||
const { success } = useSnackbar();
|
||||
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [user, setUser] = useState<User>(globalState.user);
|
||||
const [profileExpanded, setProfileExpanded] = useState<boolean>(false);
|
||||
const [avatarExpanded, setAvatarExpanded] = useState<boolean>(false);
|
||||
const [notificationsExpanded, setNotificationsExpanded] = useState<boolean>(false);
|
||||
const [unitsExpanded, setUnitsExpanded] = useState<boolean>(false);
|
||||
const [avatarUrl, setAvatarUrl] = useState<string>("");
|
||||
const [themeValue, setThemeValue] = useState<"light" | "dark" | "system">(themeMode.mode)
|
||||
// const [themeValue, setThemeValue] = useState<"light" | "dark" | "system">(themeMode.mode)
|
||||
|
||||
useEffect(() => {
|
||||
function changeIcon(icon: string | undefined) {
|
||||
|
|
@ -99,11 +104,11 @@ export default function UserSettings(props: Props) {
|
|||
.updateUser(user.id(), user.protobuf())
|
||||
.then(() => {
|
||||
dispatch({ key: "user", value: user });
|
||||
// success("User settings successfully updated!");
|
||||
// setTemperatureUnit(user.settings.temperatureUnit);
|
||||
// setPressureUnit(user.settings.pressureUnit);
|
||||
// setDistanceUnit(user.settings.distanceUnit);
|
||||
// setGrainUnit(user.settings.grainUnit);
|
||||
success("User settings successfully updated!");
|
||||
setTemperatureUnit(user.settings.temperatureUnit);
|
||||
setPressureUnit(user.settings.pressureUnit);
|
||||
setDistanceUnit(user.settings.distanceUnit);
|
||||
setGrainUnit(user.settings.grainUnit);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
error("Error occurred while updating your profile");
|
||||
|
|
@ -362,6 +367,160 @@ export default function UserSettings(props: Props) {
|
|||
setThemeType(theme)
|
||||
};
|
||||
|
||||
const changePressureUnit = (value: any) => {
|
||||
let updatedUser = User.clone(user);
|
||||
let pressureUnit: pond.PressureUnit;
|
||||
switch (value) {
|
||||
case 1:
|
||||
pressureUnit = pond.PressureUnit.PRESSURE_UNIT_KILOPASCALS;
|
||||
break;
|
||||
case 2:
|
||||
pressureUnit = pond.PressureUnit.PRESSURE_UNIT_INCHES_OF_WATER;
|
||||
break;
|
||||
default:
|
||||
pressureUnit = pond.PressureUnit.PRESSURE_UNIT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
updatedUser.settings.pressureUnit = pressureUnit;
|
||||
setUser(updatedUser);
|
||||
};
|
||||
|
||||
const changeTemperatureUnit = (value: any) => {
|
||||
let updatedUser = User.clone(user);
|
||||
let temperatureUnit: pond.TemperatureUnit;
|
||||
switch (value) {
|
||||
case 1:
|
||||
temperatureUnit = pond.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS;
|
||||
break;
|
||||
case 2:
|
||||
temperatureUnit = pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT;
|
||||
break;
|
||||
default:
|
||||
temperatureUnit = pond.TemperatureUnit.TEMPERATURE_UNIT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
updatedUser.settings.temperatureUnit = temperatureUnit;
|
||||
setUser(updatedUser);
|
||||
};
|
||||
|
||||
const changeDistanceUnit = (value: any) => {
|
||||
let updatedUser = User.clone(user);
|
||||
let distanceUnit: pond.DistanceUnit;
|
||||
switch (value) {
|
||||
case 1:
|
||||
distanceUnit = pond.DistanceUnit.DISTANCE_UNIT_FEET;
|
||||
break;
|
||||
case 2:
|
||||
distanceUnit = pond.DistanceUnit.DISTANCE_UNIT_METERS;
|
||||
break;
|
||||
default:
|
||||
distanceUnit = pond.DistanceUnit.DISTANCE_UNIT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
updatedUser.settings.distanceUnit = distanceUnit;
|
||||
setUser(updatedUser);
|
||||
};
|
||||
|
||||
const changeGrainUnit = (value: any) => {
|
||||
let updatedUser = User.clone(user);
|
||||
let grainUnit: pond.GrainUnit;
|
||||
switch (value) {
|
||||
case 1:
|
||||
grainUnit = pond.GrainUnit.GRAIN_UNIT_BUSHELS;
|
||||
break;
|
||||
case 2:
|
||||
grainUnit = pond.GrainUnit.GRAIN_UNIT_WEIGHT;
|
||||
break;
|
||||
default:
|
||||
grainUnit = pond.GrainUnit.GRAIN_UNIT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
updatedUser.settings.grainUnit = grainUnit;
|
||||
setUser(updatedUser);
|
||||
};
|
||||
|
||||
const unitPreferences = () => {
|
||||
const { pressureUnit, temperatureUnit, distanceUnit, grainUnit } = user.settings;
|
||||
return (
|
||||
<Grid2 container>
|
||||
<Grid2 size={{ xs: 12 }}>
|
||||
<TextField
|
||||
select
|
||||
fullWidth
|
||||
id="pressureUnit"
|
||||
name="pressureUnit"
|
||||
label="Pressure Unit"
|
||||
value={pressureUnit ? pressureUnit : pond.PressureUnit.PRESSURE_UNIT_INCHES_OF_WATER}
|
||||
onChange={event => changePressureUnit(event.target.value)}
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
InputLabelProps={{ shrink: true }}>
|
||||
<MenuItem value={pond.PressureUnit.PRESSURE_UNIT_KILOPASCALS}>
|
||||
Kilopascals (kPa)
|
||||
</MenuItem>
|
||||
<MenuItem value={pond.PressureUnit.PRESSURE_UNIT_INCHES_OF_WATER}>
|
||||
Inches of Water (iwg)
|
||||
</MenuItem>
|
||||
</TextField>
|
||||
</Grid2>
|
||||
<Grid2 size={{ xs: 12 }}>
|
||||
<TextField
|
||||
select
|
||||
fullWidth
|
||||
id="temperatureUnit"
|
||||
name="temperatureUnit"
|
||||
label="Temperature Unit"
|
||||
value={
|
||||
temperatureUnit ? temperatureUnit : pond.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS
|
||||
}
|
||||
onChange={event => changeTemperatureUnit(event.target.value)}
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
InputLabelProps={{ shrink: true }}>
|
||||
<MenuItem value={pond.TemperatureUnit.TEMPERATURE_UNIT_CELSIUS}>Celsius (°C)</MenuItem>
|
||||
<MenuItem value={pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT}>
|
||||
Fahrenheit (°F)
|
||||
</MenuItem>
|
||||
</TextField>
|
||||
</Grid2>
|
||||
<Grid2 size={{ xs: 12 }}>
|
||||
<TextField
|
||||
select
|
||||
fullWidth
|
||||
id="distanceUnit"
|
||||
name="distanceUnit"
|
||||
label="Distance Unit"
|
||||
value={distanceUnit ? distanceUnit : pond.DistanceUnit.DISTANCE_UNIT_METERS}
|
||||
onChange={event => changeDistanceUnit(event.target.value)}
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
InputLabelProps={{ shrink: true }}>
|
||||
<MenuItem value={pond.DistanceUnit.DISTANCE_UNIT_METERS}>Meters (m)</MenuItem>
|
||||
<MenuItem value={pond.DistanceUnit.DISTANCE_UNIT_FEET}>Feet (ft)</MenuItem>
|
||||
</TextField>
|
||||
</Grid2>
|
||||
{IsAdaptiveAgriculture() && (
|
||||
<Grid2 size={{ xs: 12 }}>
|
||||
<TextField
|
||||
select
|
||||
fullWidth
|
||||
id="grainUnit"
|
||||
name="grainUnit"
|
||||
label="Grain Unit"
|
||||
value={grainUnit ? grainUnit : pond.GrainUnit.GRAIN_UNIT_BUSHELS}
|
||||
onChange={event => changeGrainUnit(event.target.value)}
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
InputLabelProps={{ shrink: true }}>
|
||||
<MenuItem value={pond.GrainUnit.GRAIN_UNIT_BUSHELS}>Bushels (bu)</MenuItem>
|
||||
<MenuItem value={pond.GrainUnit.GRAIN_UNIT_WEIGHT}>Tonnes (mT)</MenuItem>
|
||||
</TextField>
|
||||
</Grid2>
|
||||
)}
|
||||
</Grid2>
|
||||
);
|
||||
};
|
||||
|
||||
const themeToggle = () => {
|
||||
return (
|
||||
<ToggleButtonGroup
|
||||
|
|
@ -453,15 +612,15 @@ export default function UserSettings(props: Props) {
|
|||
</List>
|
||||
</Collapse>
|
||||
|
||||
{/* <Divider />
|
||||
<Divider />
|
||||
|
||||
<ListItem button onClick={() => setUnitsExpanded(!unitsExpanded)}>
|
||||
<ListItemButton onClick={() => setUnitsExpanded(!unitsExpanded)}>
|
||||
<ListItemIcon>
|
||||
<UnitsIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Preferred Units" />
|
||||
{unitsExpanded ? <ExpandLess /> : <ExpandMore />}
|
||||
</ListItem>
|
||||
</ListItemButton>
|
||||
<Collapse in={unitsExpanded} timeout="auto" unmountOnExit>
|
||||
<List component="div">
|
||||
<ListItem>
|
||||
|
|
@ -472,7 +631,7 @@ export default function UserSettings(props: Props) {
|
|||
</List>
|
||||
</Collapse>
|
||||
|
||||
<Divider />
|
||||
{/* <Divider />
|
||||
|
||||
<ListItem button onClick={() => setMapsExpanded(!mapsExpanded)}>
|
||||
<ListItemIcon>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue