From e96c37483bd2ddd45e66d6b418525258f294deb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Banno-Cloutier?=
 <leo.banno-cloutier@savoirfairelinux.com>
Date: Fri, 25 Aug 2023 14:19:02 -0400
Subject: [PATCH] jams-react-client: major refactor

Change-Id: I1458f6ce4ae8deac3e310faa1c462b0145ef7fb9
---
 jams-react-client/src/api.tsx                 | 27 ++++----
 .../src/components/CaSetup/CaSetup.tsx        |  2 +-
 .../src/components/CustomButtons/Button.tsx   | 49 +++++---------
 .../CustomUiPreview/CustomUiPreview.tsx       |  2 +-
 .../src/components/Devices/Devices.tsx        | 24 +++++--
 .../components/Devices/EditDeviceDialog.tsx   | 27 +++-----
 .../src/components/Drawer/Drawer.tsx          |  2 +-
 .../src/components/Footer/Footer.tsx          |  2 +-
 .../components/FormikField/FormikField.tsx    | 65 ++++++++-----------
 .../src/components/Grid/GridContainer.tsx     | 15 +++--
 .../src/components/Grid/GridItem.tsx          |  5 +-
 .../LanguagePicker/LanguagePicker.tsx         | 15 +++--
 .../src/components/Navbars/Navbar.tsx         |  6 +-
 .../PasswordDialog/PasswordDialog.tsx         |  2 +-
 .../src/components/Sidebar/Sidebar.tsx        | 34 ++++++----
 .../components/Snackbar/BlueprintSnackbar.tsx | 23 +++++--
 jams-react-client/src/i18n.tsx                |  3 -
 jams-react-client/src/layouts/BaseLayout.tsx  | 19 ++++--
 jams-react-client/src/layouts/ListLayout.tsx  |  9 +--
 jams-react-client/src/layouts/SignIn.tsx      |  2 +-
 jams-react-client/src/layouts/SignUp.tsx      |  2 +-
 .../src/views/Blueprint/ColorPickerPopup.tsx  | 18 ++++-
 .../Blueprint/EditBlueprintPermissions.tsx    |  2 +-
 .../src/views/Blueprint/EditBlueprintUi.tsx   |  9 ++-
 .../src/views/Blueprint/PolicyDataContext.tsx |  4 +-
 .../src/views/Blueprint/parsePolicyData.tsx   |  8 ++-
 .../src/views/Blueprint/updatePolicyData.tsx  |  2 +-
 .../src/views/Contacts/Contacts.tsx           |  7 +-
 .../src/views/Groups/EditGroup.tsx            |  9 +--
 .../src/views/Settings/General.tsx            |  5 +-
 .../views/UserProfile/DisplayUserProfile.tsx  | 34 ++++++++--
 .../UserProfile/EditCreateUserProfile.tsx     | 54 +++++++++------
 .../src/views/UserProfile/cropImage.tsx       |  4 +-
 jams-react-client/src/views/Users/Users.tsx   |  2 +-
 34 files changed, 278 insertions(+), 215 deletions(-)

diff --git a/jams-react-client/src/api.tsx b/jams-react-client/src/api.tsx
index 1dfb7b79..8ee52e8b 100644
--- a/jams-react-client/src/api.tsx
+++ b/jams-react-client/src/api.tsx
@@ -18,6 +18,7 @@
  *     along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+import { AxiosRequestConfig } from "axios";
 import {
   url_path,
   url_port,
@@ -31,18 +32,16 @@ import {
   api_path_blueprints,
 } from "./globalUrls";
 
-export default function configApiCall(
-  api_path,
-  request_type,
-  data,
-  credentials
-) {
+const configApiCall = (
+  api_path: string,
+  request_type: string,
+  data: any,
+  credentials: null
+): AxiosRequestConfig => {
   // build config call
-  const config = {
+  const config: AxiosRequestConfig = {
     url: url_path + ":" + url_port + api_path,
     method: request_type,
-    crossDomain: true,
-    dataType: "json",
     headers: {},
   };
 
@@ -51,15 +50,15 @@ export default function configApiCall(
     const base64 = btoa(
       credentials["username"] + ":" + credentials["password"]
     );
-    config["headers"]["Authorization"] = "Basic " + base64;
+    config.headers!["Authorization"] = "Basic " + base64;
   }
 
   const jwt = localStorage.getItem("access_token");
   if (jwt) {
-    config["headers"]["Authorization"] = "Bearer " + jwt;
+    config.headers!["Authorization"] = "Bearer " + jwt;
   }
 
-  config["headers"]["Content-type"] = "application/json;charset=UTF-8";
+  config.headers!["Content-type"] = "application/json;charset=UTF-8";
 
   // pass data in the header
   if (data) {
@@ -84,4 +83,6 @@ export default function configApiCall(
   }
 
   return config;
-}
+};
+
+export default configApiCall;
diff --git a/jams-react-client/src/components/CaSetup/CaSetup.tsx b/jams-react-client/src/components/CaSetup/CaSetup.tsx
index e9d35137..d0d7d2f7 100644
--- a/jams-react-client/src/components/CaSetup/CaSetup.tsx
+++ b/jams-react-client/src/components/CaSetup/CaSetup.tsx
@@ -246,7 +246,7 @@ export default function CaSetup(props) {
                 }
               />
 
-              <CountrySelect defaultValue={values.country} {...props} />
+              <CountrySelect {...props} />
               {touched.country && errors.country ? (
                 <span className="spanError">{errors.country}</span>
               ) : null}
diff --git a/jams-react-client/src/components/CustomButtons/Button.tsx b/jams-react-client/src/components/CustomButtons/Button.tsx
index 3b4aeaf5..f695c959 100644
--- a/jams-react-client/src/components/CustomButtons/Button.tsx
+++ b/jams-react-client/src/components/CustomButtons/Button.tsx
@@ -1,16 +1,26 @@
+import { FC, ReactNode } from "react";
 import classNames from "classnames";
-// nodejs library to set properties for components
-import PropTypes from "prop-types";
 
-// material-ui components
+import Button, { ButtonProps } from "@mui/material/Button";
 import { makeStyles } from "@mui/styles";
-import Button from "@mui/material/Button";
 
 import styles from "assets/jss/material-dashboard-react/components/buttonStyle";
 
 const useStyles = makeStyles(styles as any);
 
-export default function RegularButton(props) {
+interface RegularButtonProps extends ButtonProps {
+  size?: "small" | "large";
+  simple?: boolean;
+  round?: boolean;
+  disabled?: boolean;
+  block?: boolean;
+  link?: boolean;
+  justIcon?: boolean;
+  className?: string;
+  children?: ReactNode;
+}
+
+const RegularButton: FC<RegularButtonProps> = (props) => {
   const classes = useStyles();
   const {
     color,
@@ -23,7 +33,6 @@ export default function RegularButton(props) {
     link,
     justIcon,
     className,
-    muiClasses,
     ...rest
   } = props;
   const btnClasses = classNames({
@@ -39,32 +48,10 @@ export default function RegularButton(props) {
     [className]: className,
   });
   return (
-    <Button {...rest} classes={muiClasses} className={btnClasses}>
+    <Button {...rest} className={btnClasses}>
       {children}
     </Button>
   );
-}
-
-RegularButton.propTypes = {
-  color: PropTypes.oneOf([
-    "primary",
-    "info",
-    "success",
-    "warning",
-    "danger",
-    "rose",
-    "white",
-    "transparent",
-  ]),
-  size: PropTypes.oneOf(["small", "large"]),
-  simple: PropTypes.bool,
-  round: PropTypes.bool,
-  disabled: PropTypes.bool,
-  block: PropTypes.bool,
-  link: PropTypes.bool,
-  justIcon: PropTypes.bool,
-  className: PropTypes.string,
-  // use this to pass the classes props from Material-UI
-  muiClasses: PropTypes.object,
-  children: PropTypes.node,
 };
+
+export default RegularButton;
diff --git a/jams-react-client/src/components/CustomUiPreview/CustomUiPreview.tsx b/jams-react-client/src/components/CustomUiPreview/CustomUiPreview.tsx
index 65a0cacc..753c214a 100644
--- a/jams-react-client/src/components/CustomUiPreview/CustomUiPreview.tsx
+++ b/jams-react-client/src/components/CustomUiPreview/CustomUiPreview.tsx
@@ -103,7 +103,7 @@ const styles = {
 const useStyles = makeStyles(styles as any);
 
 interface CustomUiPreviewProps {
-  isOldPreview: boolean;
+  isOldPreview?: boolean;
   opacity: number;
   uiCustomization: UiCustomization;
 }
diff --git a/jams-react-client/src/components/Devices/Devices.tsx b/jams-react-client/src/components/Devices/Devices.tsx
index 06c36eaf..7d9dd9c6 100755
--- a/jams-react-client/src/components/Devices/Devices.tsx
+++ b/jams-react-client/src/components/Devices/Devices.tsx
@@ -1,4 +1,4 @@
-import { FC, useEffect, useState } from "react";
+import React, { FC, useEffect, useState } from "react";
 import { useHistory } from "react-router-dom";
 
 import classnames from "classnames";
@@ -49,7 +49,11 @@ const Devices: FC<DevicesProps> = ({ username }) => {
   const history = useHistory();
 
   const [devices, setDevices] = useState<Device[]>([]);
-  const [selectedDevice, setSelectedDevice] = useState<Device>({});
+  const [selectedDevice, setSelectedDevice] = useState<Device>({
+    deviceId: "",
+    displayName: "",
+    revoked: false,
+  });
   const [displayName, setDisplayName] = useState("");
 
   const [openEdit, setOpenEdit] = useState(false);
@@ -83,13 +87,19 @@ const Devices: FC<DevicesProps> = ({ username }) => {
     return device.revoked ? "Revoked" : "Active";
   };
 
-  const handleClickEdit = (e: MouseEvent, device: Device) => {
+  const handleClickEdit = (
+    e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
+    device: Device
+  ) => {
     e.preventDefault();
     setOpenEdit(true);
     setSelectedDevice(device);
   };
 
-  const handleClickRevoke = (e: MouseEvent, device: Device) => {
+  const handleClickRevoke = (
+    e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
+    device: Device
+  ) => {
     e.preventDefault();
     setOpenRevoke(true);
     setSelectedDevice(device);
@@ -98,7 +108,7 @@ const Devices: FC<DevicesProps> = ({ username }) => {
   const handleClose = () => {
     setOpenEdit(false);
     setOpenRevoke(false);
-    setSelectedDevice({});
+    setSelectedDevice(undefined);
   };
 
   const handleUpdate = () => {
@@ -131,7 +141,7 @@ const Devices: FC<DevicesProps> = ({ username }) => {
 
     axios(requestConfig)
       .then(() => {
-        setSelectedDevice({});
+        setSelectedDevice(undefined);
         setOpenEdit(false);
       })
       .catch((error) => {
@@ -160,7 +170,7 @@ const Devices: FC<DevicesProps> = ({ username }) => {
 
     axios(requestConfig)
       .then(() => {
-        setSelectedDevice({});
+        setSelectedDevice(undefined);
         setOpenRevoke(false);
       })
       .catch((error) => {
diff --git a/jams-react-client/src/components/Devices/EditDeviceDialog.tsx b/jams-react-client/src/components/Devices/EditDeviceDialog.tsx
index cc7fac87..b8d9c5a7 100644
--- a/jams-react-client/src/components/Devices/EditDeviceDialog.tsx
+++ b/jams-react-client/src/components/Devices/EditDeviceDialog.tsx
@@ -9,6 +9,7 @@ import {
 import { Formik, Field } from "formik";
 import i18next from "i18next";
 import { Dispatch, FC, SetStateAction } from "react";
+import * as Yup from "yup";
 import { Device } from "./Devices";
 
 interface EditDeviceDialogProps {
@@ -26,16 +27,9 @@ const EditDeviceDialog: FC<EditDeviceDialogProps> = ({
   setDisplayName,
   handleUpdate,
 }) => {
-  /**
-   * Formik Validation
-   */
-  const validateDisplayName = (displaynamevalue) => {
-    let error;
-    if (!displaynamevalue) {
-      error = "Required";
-    }
-    return error;
-  };
+  const validationSchema = Yup.object({
+    displayName: Yup.string().required("Required"),
+  });
 
   return (
     <Dialog
@@ -55,11 +49,13 @@ const EditDeviceDialog: FC<EditDeviceDialogProps> = ({
         initialValues={{
           displayName: selectedDevice.displayName,
         }}
+        onSubmit={handleUpdate}
+        validationSchema={validationSchema}
       >
-        {({ errors, touched, validateField }) => (
+        {({ errors, touched }) => (
           <form>
             <DialogContent>
-              <Field name="displayName" validate={validateDisplayName}>
+              <Field name="displayName">
                 {({ field }) => (
                   <div>
                     <TextField
@@ -87,12 +83,7 @@ const EditDeviceDialog: FC<EditDeviceDialogProps> = ({
               <Button onClick={handleClose} color="primary">
                 {i18next.t("cancel", "Cancel") as string}
               </Button>
-              <Button
-                onClick={() =>
-                  validateField("displayName").then(() => handleUpdate())
-                }
-                color="primary"
-              >
+              <Button type="submit" color="primary">
                 {i18next.t("update", "Update") as string}
               </Button>
             </DialogActions>
diff --git a/jams-react-client/src/components/Drawer/Drawer.tsx b/jams-react-client/src/components/Drawer/Drawer.tsx
index 4cfb0bea..e1db33d8 100644
--- a/jams-react-client/src/components/Drawer/Drawer.tsx
+++ b/jams-react-client/src/components/Drawer/Drawer.tsx
@@ -144,7 +144,7 @@ const TemporaryDrawer: FC<TemporaryDrawerProps> = ({
             })}
             role="presentation"
           >
-            <div className={classes.searchWrapper}>
+            <div>
               <CustomInput
                 formControlProps={{
                   className: classes.margin + " " + classes.search,
diff --git a/jams-react-client/src/components/Footer/Footer.tsx b/jams-react-client/src/components/Footer/Footer.tsx
index a8bddce5..32d790b0 100755
--- a/jams-react-client/src/components/Footer/Footer.tsx
+++ b/jams-react-client/src/components/Footer/Footer.tsx
@@ -14,7 +14,7 @@ export default function Footer() {
         <p className={classes.right}>
           <span>
             JAMS Version {pjson.version.slice(0, 3)} - &copy;
-            {1900 + new Date().getYear()}{" "}
+            {new Date().getFullYear()}{" "}
             <a
               href="https://savoirfairelinux.com"
               target="_blank"
diff --git a/jams-react-client/src/components/FormikField/FormikField.tsx b/jams-react-client/src/components/FormikField/FormikField.tsx
index 0f6df7aa..3a4c2e03 100644
--- a/jams-react-client/src/components/FormikField/FormikField.tsx
+++ b/jams-react-client/src/components/FormikField/FormikField.tsx
@@ -6,45 +6,34 @@ import FormControl from "@mui/material/FormControl";
 import InputLabel from "@mui/material/InputLabel";
 import Input from "@mui/material/Input";
 
-class FormikField extends Component {
-  render() {
-    return (
-      <div className="FormikField">
-        <FormControl
-          size="medium"
-          error={
-            this.props.onKeyUpError ||
-            <ErrorMessage name={this.props.name} /> === ""
-          }
+const FormikField = (props) => {
+  return (
+    <div className="FormikField">
+      <FormControl size="medium" error={props.onKeyUpError} fullWidth>
+        <InputLabel htmlFor={props.name}>
+          {props.onKeyUpError ? (
+            props.onKeyUpErrorMessage
+          ) : (
+            <ErrorMessage name={props.name} />
+          )}
+        </InputLabel>
+        <Field
+          placeholder={props.placeholder}
+          required={props.required}
+          name={props.name}
+          as={Input}
+          startAdornment={props.startAdornment}
+          endAdornment={props.endAdornment}
+          label={props.label}
           fullWidth
-        >
-          <InputLabel htmlFor={this.props.name}>
-            {this.props.onKeyUpError ? (
-              this.props.onKeyUpErrorMessage
-            ) : "" || <ErrorMessage name={this.props.name} /> === "" ? (
-              this.props.label
-            ) : (
-              <ErrorMessage name={this.props.name} />
-            )}
-          </InputLabel>
-          <Field
-            placeholder={this.props.placeholder}
-            required={this.props.required}
-            name={this.props.name}
-            as={Input}
-            startAdornment={this.props.startAdornment}
-            endAdornment={this.props.endAdornment}
-            label={this.props.label}
-            fullWidth
-            type={this.props.type}
-            autoComplete={this.props.autoComplete}
-            onKeyUp={(e) => this.props.handleChange(e.target.value)}
-          />
-        </FormControl>
-      </div>
-    );
-  }
-}
+          type={props.type}
+          autoComplete={props.autoComplete}
+          onKeyUp={(e) => props.handleChange(e.target.value)}
+        />
+      </FormControl>
+    </div>
+  );
+};
 
 FormikField.propTypes = {
   startAdornment: PropTypes.element,
diff --git a/jams-react-client/src/components/Grid/GridContainer.tsx b/jams-react-client/src/components/Grid/GridContainer.tsx
index 8c3e9718..012a39c6 100644
--- a/jams-react-client/src/components/Grid/GridContainer.tsx
+++ b/jams-react-client/src/components/Grid/GridContainer.tsx
@@ -1,7 +1,8 @@
 import PropTypes from "prop-types";
 // @mui/material components
 import { makeStyles } from "@mui/styles";
-import Grid from "@mui/material/Grid";
+import Grid, { GridProps } from "@mui/material/Grid";
+import { FC, ReactNode } from "react";
 
 const styles = {
   grid: {
@@ -12,7 +13,11 @@ const styles = {
 
 const useStyles = makeStyles(styles as any);
 
-export default function GridContainer(props) {
+interface GridContainerProps extends GridProps {
+  children: ReactNode;
+}
+
+const GridContainer: FC<GridContainerProps> = (props) => {
   const classes = useStyles();
   const { children, ...rest } = props;
   return (
@@ -20,8 +25,6 @@ export default function GridContainer(props) {
       {children}
     </Grid>
   );
-}
-
-GridContainer.propTypes = {
-  children: PropTypes.node,
 };
+
+export default GridContainer;
diff --git a/jams-react-client/src/components/Grid/GridItem.tsx b/jams-react-client/src/components/Grid/GridItem.tsx
index 1dc6ffb4..eb69a955 100644
--- a/jams-react-client/src/components/Grid/GridItem.tsx
+++ b/jams-react-client/src/components/Grid/GridItem.tsx
@@ -1,8 +1,7 @@
 import { FC } from "react";
 import * as React from "react";
 import { makeStyles } from "@mui/styles";
-import { Grid, GridTypeMap } from "@mui/material";
-import { OverridableComponent } from "@mui/material/OverridableComponent";
+import { Grid, GridProps } from "@mui/material";
 
 const styles = {
   grid: {
@@ -12,7 +11,7 @@ const styles = {
 
 const useStyles = makeStyles(styles as any);
 
-interface GridItemProps extends OverridableComponent<GridTypeMap> {
+interface GridItemProps extends GridProps {
   children: React.ReactNode;
 }
 
diff --git a/jams-react-client/src/components/LanguagePicker/LanguagePicker.tsx b/jams-react-client/src/components/LanguagePicker/LanguagePicker.tsx
index 38a4619d..b485ce1e 100644
--- a/jams-react-client/src/components/LanguagePicker/LanguagePicker.tsx
+++ b/jams-react-client/src/components/LanguagePicker/LanguagePicker.tsx
@@ -10,12 +10,17 @@ import i18next from "i18next";
 
 import { useTranslation } from "react-i18next";
 
+interface Language {
+  code: string;
+  name: string;
+}
+
 export default function LanguagePicker(props) {
   const history = useHistory();
-  const [language, setLanguage] = useState(
+  const [language, setLanguage] = useState<string>(
     i18next.language || window.localStorage.i18nextLng || "en"
   );
-  const [languages, setLanguages] = useState([]);
+  const [languages, setLanguages] = useState<Language[]>([]);
 
   const { i18n } = useTranslation();
 
@@ -30,8 +35,10 @@ export default function LanguagePicker(props) {
     fetch("/available_languages.json")
       .then((res) => res.json())
       .then((result) => {
-        const response = result.data.map(({ attributes }) => attributes);
-        let translates_languages = [
+        const response: Language[] = result.data.map(
+          ({ attributes }: { attributes: Language }) => attributes
+        );
+        const translates_languages: Language[] = [
           { code: "en", name: "English" },
           ...response,
         ];
diff --git a/jams-react-client/src/components/Navbars/Navbar.tsx b/jams-react-client/src/components/Navbars/Navbar.tsx
index b41457ff..273389c7 100755
--- a/jams-react-client/src/components/Navbars/Navbar.tsx
+++ b/jams-react-client/src/components/Navbars/Navbar.tsx
@@ -25,11 +25,7 @@ export default function Header(props) {
     <AppBar className={classes.appBar + appBarClasses}>
       <Toolbar className={classes.container}>
         <div className={classes.flex}>
-          <Button
-            color="transparent"
-            href="#"
-            className={classes.title}
-          ></Button>
+          <Button color="info" className={classes.title}></Button>
         </div>
         <Hidden mdUp implementation="css">
           <IconButton
diff --git a/jams-react-client/src/components/PasswordDialog/PasswordDialog.tsx b/jams-react-client/src/components/PasswordDialog/PasswordDialog.tsx
index 2b4e4fda..effc5b09 100644
--- a/jams-react-client/src/components/PasswordDialog/PasswordDialog.tsx
+++ b/jams-react-client/src/components/PasswordDialog/PasswordDialog.tsx
@@ -271,7 +271,7 @@ const PasswordDialog: FC<PasswordDialogProps> = ({
                     </Button>
                     <Button
                       type="submit"
-                      disable={!isValid && !dirty}
+                      disabled={!isValid && !dirty}
                       color="info"
                       className={classes.whiteButtonText}
                       autoFocus
diff --git a/jams-react-client/src/components/Sidebar/Sidebar.tsx b/jams-react-client/src/components/Sidebar/Sidebar.tsx
index 3a9fbc1d..2acc3c87 100755
--- a/jams-react-client/src/components/Sidebar/Sidebar.tsx
+++ b/jams-react-client/src/components/Sidebar/Sidebar.tsx
@@ -1,4 +1,4 @@
-import { createRef, useEffect, useState } from "react";
+import { FC, createRef, useEffect, useState } from "react";
 import { Link, useHistory } from "react-router-dom";
 import classNames from "classnames";
 import PropTypes from "prop-types";
@@ -21,10 +21,25 @@ import styles from "assets/jss/material-dashboard-react/components/sidebarStyle"
 import auth from "auth";
 
 import i18next from "i18next";
+import { Route } from "layouts/BaseLayout";
 
 const useStyles = makeStyles(styles as any);
 
-export default function Sidebar(props) {
+interface SidebarProps {
+  updating: boolean;
+  snackbarMessage: string;
+  rtlActive: boolean;
+  handleQuery: () => void;
+  setOpenUpdate: (open: boolean) => void;
+  open: boolean;
+  handleDrawerToggle: () => void;
+  color: string;
+  logo: string;
+  image: string;
+  routes: Route[];
+}
+
+const Sidebar: FC<SidebarProps> = (props) => {
   const classes = useStyles();
   const mainPanel = createRef();
   const [open, setOpen] = useState(false);
@@ -99,7 +114,7 @@ export default function Sidebar(props) {
                   />
                 )}
                 <ListItemText
-                  primary={props.rtlActive ? prop.rtlName : prop.name}
+                  primary={prop.name}
                   className={classNames(classes.itemText, whiteFontClasses, {
                     [classes.itemTextRTL]: props.rtlActive,
                   })}
@@ -216,15 +231,6 @@ export default function Sidebar(props) {
       </Hidden>
     </div>
   );
-}
-
-Sidebar.propTypes = {
-  rtlActive: PropTypes.bool,
-  handleDrawerToggle: PropTypes.func,
-  bgColor: PropTypes.oneOf(["purple", "blue", "green", "orange", "red"]),
-  logo: PropTypes.string,
-  image: PropTypes.string,
-  logoText: PropTypes.string,
-  routes: PropTypes.arrayOf(PropTypes.object),
-  open: PropTypes.bool,
 };
+
+export default Sidebar;
diff --git a/jams-react-client/src/components/Snackbar/BlueprintSnackbar.tsx b/jams-react-client/src/components/Snackbar/BlueprintSnackbar.tsx
index 9c50167b..9b1a0fe7 100644
--- a/jams-react-client/src/components/Snackbar/BlueprintSnackbar.tsx
+++ b/jams-react-client/src/components/Snackbar/BlueprintSnackbar.tsx
@@ -1,16 +1,29 @@
-import { forwardRef, createRef, Dispatch, FC, SetStateAction } from "react";
+import {
+  forwardRef,
+  createRef,
+  Dispatch,
+  FC,
+  SetStateAction,
+  ForwardedRef,
+} from "react";
 
 import MuiAlert from "@mui/material/Alert";
 import Snackbar from "@mui/material/Snackbar";
-import Slide from "@mui/material/Slide";
+import Slide, { SlideProps } from "@mui/material/Slide";
 import { SnackbarProps } from "views/Blueprint/PolicyDataContext";
 
 // https://stackoverflow.com/a/67961603
-const Alert = forwardRef(function Alert(props, ref) {
+const Alert = forwardRef(function Alert(
+  props: any,
+  ref: ForwardedRef<HTMLDivElement>
+) {
   return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />;
 });
 
-const SlideTransition = forwardRef(function SlideTransition(props, ref) {
+const SlideTransition = forwardRef(function SlideTransition(
+  props: SlideProps,
+  ref
+) {
   return <Slide ref={ref} {...props} direction="left" />;
 });
 
@@ -23,7 +36,7 @@ export const BlueprintSnackbar: FC<BlueprintSnackbarProps> = ({
   snackbar,
   setSnackbar,
 }) => {
-  const snackbarRef = createRef(null);
+  const snackbarRef = createRef();
 
   const handleClose = () => {
     setSnackbar((state) => ({ ...state, open: false }));
diff --git a/jams-react-client/src/i18n.tsx b/jams-react-client/src/i18n.tsx
index d251bfcb..72f43d2f 100644
--- a/jams-react-client/src/i18n.tsx
+++ b/jams-react-client/src/i18n.tsx
@@ -9,9 +9,6 @@ i18next
   .use(Backend)
   .init({
     fallbackLng: "en",
-    lookupCookie: "i18next",
-    lookupLocalStorage: "i18nextLng",
-    lookupSessionStorage: "i18nextLng",
     debug: false,
     detection: {
       order: ["cookie", "localStorage", "sessionStorage", "navigator"],
diff --git a/jams-react-client/src/layouts/BaseLayout.tsx b/jams-react-client/src/layouts/BaseLayout.tsx
index 81620015..86483d29 100644
--- a/jams-react-client/src/layouts/BaseLayout.tsx
+++ b/jams-react-client/src/layouts/BaseLayout.tsx
@@ -1,4 +1,4 @@
-import { createRef, useEffect, useState } from "react";
+import { FC, ReactNode, createRef, useEffect, useState } from "react";
 // creates a beautiful scrollbar
 import PerfectScrollbar from "perfect-scrollbar";
 import "perfect-scrollbar/css/perfect-scrollbar.css";
@@ -46,15 +46,24 @@ let ps;
 
 const useStyles = makeStyles(styles as any);
 
+export interface Route {
+  path: string;
+  name: string;
+  icon: FC<any>;
+  component: FC<any>;
+  layout: string;
+  admin?: boolean;
+}
+
 export default function Admin(props) {
   // styles
   const classes = useStyles();
   // ref to help us initialize PerfectScrollbar on windows devices
-  const mainPanel = createRef();
+  const mainPanel = createRef<HTMLDivElement>();
   // states and functions
   const [mobileOpen, setMobileOpen] = useState(false);
   const [open, setOpen] = useState(false);
-  const [message, setMessage] = useState(false);
+  const [message, setMessage] = useState("");
   const [openUpdate, setOpenUpdate] = useState(false);
   const [dialogMessage, setDialogMessage] = useState("");
   const [messageYes, setMessageYes] = useState("");
@@ -63,7 +72,7 @@ export default function Admin(props) {
   const [query, setQuery] = useState(false);
   const [snackbarMessage, setSnackbarMessage] = useState("");
 
-  const Routes = [
+  const Routes: Route[] = [
     {
       path: `/user/${auth.getUsername()}`,
       name: i18next.t("myprofile", "My profile") as string,
@@ -237,7 +246,6 @@ export default function Admin(props) {
       </Dialog>
       <Sidebar
         routes={Routes}
-        logoText={"Jams"}
         logo={logo}
         image={bgImage}
         handleDrawerToggle={handleDrawerToggle}
@@ -247,6 +255,7 @@ export default function Admin(props) {
         updating={updating}
         snackbarMessage={snackbarMessage}
         setOpenUpdate={setOpenUpdate}
+        rtlActive={false}
       />
 
       <div className={classes.mainPanel} ref={mainPanel}>
diff --git a/jams-react-client/src/layouts/ListLayout.tsx b/jams-react-client/src/layouts/ListLayout.tsx
index 3ecd4c97..89552f2c 100644
--- a/jams-react-client/src/layouts/ListLayout.tsx
+++ b/jams-react-client/src/layouts/ListLayout.tsx
@@ -41,6 +41,7 @@ import DialogContentText from "@mui/material/DialogContentText/DialogContentText
 import Button from "@mui/material/Button";
 
 import i18next from "i18next";
+import { Route } from "./BaseLayout";
 
 let ps;
 
@@ -50,11 +51,11 @@ export default function Admin(props) {
   // styles
   const classes = useStyles();
   // ref to help us initialize PerfectScrollbar on windows devices
-  const mainPanel = createRef();
+  const mainPanel = createRef<HTMLDivElement>();
   // states and functions
   const [mobileOpen, setMobileOpen] = useState(false);
   const [open, setOpen] = useState(false);
-  const [message, setMessage] = useState(false);
+  const [message, setMessage] = useState("");
   const [openUpdate, setOpenUpdate] = useState(false);
   const [dialogMessage, setDialogMessage] = useState("");
   const [messageYes, setMessageYes] = useState("");
@@ -63,7 +64,7 @@ export default function Admin(props) {
   const [query, setQuery] = useState(false);
   const [snackbarMessage, setSnackbarMessage] = useState("");
 
-  const Routes = [
+  const Routes: Route[] = [
     {
       path: `/user/${auth.getUsername()}`,
       name: i18next.t("myprofile", "My profile") as string,
@@ -239,7 +240,6 @@ export default function Admin(props) {
       </Dialog>
       <Sidebar
         routes={Routes}
-        logoText={"Jams"}
         logo={logo}
         image={bgImage}
         handleDrawerToggle={handleDrawerToggle}
@@ -249,6 +249,7 @@ export default function Admin(props) {
         updating={updating}
         snackbarMessage={snackbarMessage}
         setOpenUpdate={setOpenUpdate}
+        rtlActive={false}
       />
 
       <div className={classes.mainPanel} ref={mainPanel}>
diff --git a/jams-react-client/src/layouts/SignIn.tsx b/jams-react-client/src/layouts/SignIn.tsx
index c08118b3..1a5f8b8c 100644
--- a/jams-react-client/src/layouts/SignIn.tsx
+++ b/jams-react-client/src/layouts/SignIn.tsx
@@ -90,7 +90,7 @@ export default function SignIn() {
       password: values.password,
     };
     auth.login(jsonData, () => {
-      if (auth.authenticated && auth.access_token !== "") {
+      if (auth.authenticated) {
         auth.checkLastKnownStep(() => {
           auth.checkDirectoryType(() => {
             if (auth.isServerInstalled()) {
diff --git a/jams-react-client/src/layouts/SignUp.tsx b/jams-react-client/src/layouts/SignUp.tsx
index fdbd27e4..182ee85d 100644
--- a/jams-react-client/src/layouts/SignUp.tsx
+++ b/jams-react-client/src/layouts/SignUp.tsx
@@ -51,7 +51,7 @@ const useStyles = makeStyles((theme: Theme) => ({
     marginTop: theme.spacing(3),
     marginBottom: theme.spacing(3),
     padding: theme.spacing(2),
-    [theme.breakpoints.up(600 + theme.spacing(3) * 2)]: {
+    [theme.breakpoints.up(700)]: {
       marginTop: theme.spacing(6),
       marginBottom: theme.spacing(6),
       padding: theme.spacing(3),
diff --git a/jams-react-client/src/views/Blueprint/ColorPickerPopup.tsx b/jams-react-client/src/views/Blueprint/ColorPickerPopup.tsx
index c37b7063..3f316be5 100644
--- a/jams-react-client/src/views/Blueprint/ColorPickerPopup.tsx
+++ b/jams-react-client/src/views/Blueprint/ColorPickerPopup.tsx
@@ -1,4 +1,4 @@
-import { useState } from "react";
+import { FC, useState } from "react";
 import { makeStyles } from "@mui/styles";
 import { HexAlphaColorPicker, HexColorPicker } from "react-colorful";
 
@@ -33,7 +33,17 @@ const styles = {
 
 const useStyles = makeStyles(styles as any);
 
-export default function ColorPickerPopup({ hasAlphaChannel, color, onChange }) {
+interface ColorPickerPopupProps {
+  hasAlphaChannel?: boolean;
+  color: string;
+  onChange: (color: string) => void;
+}
+
+const ColorPickerPopup: FC<ColorPickerPopupProps> = ({
+  hasAlphaChannel,
+  color,
+  onChange,
+}) => {
   const classes = useStyles();
 
   const [displayColorPicker, setDisplayColorPicker] = useState(false);
@@ -69,4 +79,6 @@ export default function ColorPickerPopup({ hasAlphaChannel, color, onChange }) {
       )}
     </div>
   );
-}
+};
+
+export default ColorPickerPopup;
diff --git a/jams-react-client/src/views/Blueprint/EditBlueprintPermissions.tsx b/jams-react-client/src/views/Blueprint/EditBlueprintPermissions.tsx
index d1511c11..819e11c0 100644
--- a/jams-react-client/src/views/Blueprint/EditBlueprintPermissions.tsx
+++ b/jams-react-client/src/views/Blueprint/EditBlueprintPermissions.tsx
@@ -120,7 +120,7 @@ export default function EditBlueprintPermissions(props) {
     allowLookup,
   } = policyData;
 
-  const searchUsers = (value) => {
+  const searchUsers = (value?: string) => {
     axios(
       configApiCall(
         api_path_get_user_directory_search,
diff --git a/jams-react-client/src/views/Blueprint/EditBlueprintUi.tsx b/jams-react-client/src/views/Blueprint/EditBlueprintUi.tsx
index c8368b22..f009d50c 100644
--- a/jams-react-client/src/views/Blueprint/EditBlueprintUi.tsx
+++ b/jams-react-client/src/views/Blueprint/EditBlueprintUi.tsx
@@ -22,7 +22,10 @@ import i18next from "i18next";
 
 import { CustomUiPreview } from "components/CustomUiPreview/CustomUiPreview";
 import EditBlueprintUiForm from "./EditBlueprintUiForm";
-import { DEFAULT_UI_CUSTOMIZATION } from "./policyData.constants";
+import {
+  DEFAULT_UI_CUSTOMIZATION,
+  UiCustomization,
+} from "./policyData.constants";
 import { PolicyDataContext } from "./PolicyDataContext";
 
 const styles = {
@@ -104,7 +107,7 @@ export default function EditBlueprintUi({ blueprintName }) {
   const [oldUiCustomization, setOldUiCustomization] = useState(uiCustomization);
   const [opacity, setOpacity] = useState(0);
 
-  const handleUpdateUi = (field: string, value: any) => {
+  const handleUpdateUi = (field: string | UiCustomization, value?: any) => {
     let newUiCustomization;
 
     if (typeof field === "object") {
@@ -206,7 +209,7 @@ export default function EditBlueprintUi({ blueprintName }) {
                         />
                         <CustomUiPreview
                           isOldPreview
-                          opacity="1"
+                          opacity={1}
                           uiCustomization={oldUiCustomization}
                         />
                       </Grid>
diff --git a/jams-react-client/src/views/Blueprint/PolicyDataContext.tsx b/jams-react-client/src/views/Blueprint/PolicyDataContext.tsx
index 9fa77385..894bccca 100644
--- a/jams-react-client/src/views/Blueprint/PolicyDataContext.tsx
+++ b/jams-react-client/src/views/Blueprint/PolicyDataContext.tsx
@@ -16,7 +16,7 @@ export interface SnackbarProps {
 
 interface PolicyDataProp {
   policyData: PolicyData;
-  updatePolicyData: (field: string, value: string) => void;
+  updatePolicyData: (field: string, value: any) => void;
   snackbar: SnackbarProps;
   setSnackbar: (snackbar: SnackbarProps) => void;
 }
@@ -61,7 +61,7 @@ export const PolicyDataContextProvider: FC<Props> = ({
       });
   }, [blueprintName]);
 
-  const updatePolicyData = (field: string, value: string) => {
+  const updatePolicyData = (field: string, value: any) => {
     _updatePolicyData(
       blueprintName,
       policyData,
diff --git a/jams-react-client/src/views/Blueprint/parsePolicyData.tsx b/jams-react-client/src/views/Blueprint/parsePolicyData.tsx
index dde06e90..8087581a 100644
--- a/jams-react-client/src/views/Blueprint/parsePolicyData.tsx
+++ b/jams-react-client/src/views/Blueprint/parsePolicyData.tsx
@@ -5,7 +5,11 @@ import {
   api_path_get_ns_name_from_addr,
   api_path_get_user_profile,
 } from "../../globalUrls";
-import { DEFAULT_UI_CUSTOMIZATION, PolicyData } from "./policyData.constants";
+import {
+  DEFAULT_UI_CUSTOMIZATION,
+  PolicyData,
+  UiCustomization,
+} from "./policyData.constants";
 
 const getModerators = async (defaultModerators: string) => {
   const moderators = [];
@@ -78,7 +82,7 @@ const setCustomizationSettings = (policyData) => {
   }
 
   const result = JSON.parse(policyData.uiCustomization);
-  const ui = { isCustomizationEnabled: true };
+  const ui: Partial<UiCustomization> = { isCustomizationEnabled: true };
 
   ui.hasTitle = result.title !== "";
   ui.title = result.title;
diff --git a/jams-react-client/src/views/Blueprint/updatePolicyData.tsx b/jams-react-client/src/views/Blueprint/updatePolicyData.tsx
index 8066a59d..c1ecc173 100644
--- a/jams-react-client/src/views/Blueprint/updatePolicyData.tsx
+++ b/jams-react-client/src/views/Blueprint/updatePolicyData.tsx
@@ -89,7 +89,7 @@ const updateUiCustomization = (data) => {
     logoUrl,
     logoSize,
   } = data.uiCustomization;
-  const ui = {};
+  const ui: Partial<ServerUiCustomization> = {};
 
   if (hasTitle === false) {
     ui.title = "";
diff --git a/jams-react-client/src/views/Contacts/Contacts.tsx b/jams-react-client/src/views/Contacts/Contacts.tsx
index cfcaed83..af726a06 100644
--- a/jams-react-client/src/views/Contacts/Contacts.tsx
+++ b/jams-react-client/src/views/Contacts/Contacts.tsx
@@ -92,12 +92,12 @@ export default function Users(props) {
   const [loading, setLoading] = useState(false);
   const [progress, setProgress] = useState(0);
   const [openDrawer, setOpenDrawer] = useState(false);
-  const [removedContact, setRemovedContact] = useState();
+  const [removedContact, setRemovedContact] = useState("");
   const [removedContactName, setRemovedContactName] = useState();
   const [open, setOpen] = useState(false);
   const [allowedToAdd, setAllowedToAdd] = useState(true);
 
-  const searchContacts = (value) => {
+  const searchContacts = (value?: string) => {
     axios(
       configApiCall(
         api_path_get_user_directory_search,
@@ -161,6 +161,7 @@ export default function Users(props) {
           axios(
             configApiCall(
               api_path_get_ns_name_from_addr + contact.uri,
+              "GET",
               null,
               null
             )
@@ -503,7 +504,7 @@ export default function Users(props) {
               )}
             </GridItem>
           ))}
-        {contacts === [] &&
+        {contacts.length === 0 &&
           ((props.username +
             i18next.t("has_no_contacts", " has no contacts")) as string)}
       </GridContainer>
diff --git a/jams-react-client/src/views/Groups/EditGroup.tsx b/jams-react-client/src/views/Groups/EditGroup.tsx
index ef28b951..9b0503a4 100644
--- a/jams-react-client/src/views/Groups/EditGroup.tsx
+++ b/jams-react-client/src/views/Groups/EditGroup.tsx
@@ -64,9 +64,10 @@ import auth from "auth";
 import { debounce } from "lodash";
 
 import { getBlueprintsOptions } from "./getBlueprintsOptions";
+import { ClassNameMap } from "@mui/material";
 
 const useStyles = makeStyles(() => ({
-  ...devicesStyle,
+  ...(devicesStyle as any),
   ...dashboardStyle,
   root: {
     flexGrow: 1,
@@ -112,7 +113,7 @@ const useStyles = makeStyles(() => ({
 }));
 
 export default function EditGroup(props) {
-  const classes = useStyles();
+  const classes: ClassNameMap<any> = useStyles();
   const history = useHistory();
 
   const [name, setName] = useState("");
@@ -209,7 +210,7 @@ export default function EditGroup(props) {
     getBlueprintsOptions(blueprints)
   );
 
-  const updateGroup = (blueprintValue) => {
+  const updateGroup = (blueprintValue?: string) => {
     const data = {
       name: newName,
       blueprint: blueprintValue ? blueprintValue : selectedBlueprint.label,
@@ -231,7 +232,7 @@ export default function EditGroup(props) {
       });
   };
 
-  const searchUsers = (value) => {
+  const searchUsers = (value?: string) => {
     axios(
       configApiCall(
         api_path_get_user_directory_search,
diff --git a/jams-react-client/src/views/Settings/General.tsx b/jams-react-client/src/views/Settings/General.tsx
index 09561994..fba0f28a 100644
--- a/jams-react-client/src/views/Settings/General.tsx
+++ b/jams-react-client/src/views/Settings/General.tsx
@@ -207,7 +207,7 @@ export default function General(props) {
                         onKeyUpErrorMessage=""
                       />
                       {touched.password && errors.password ? (
-                        <span>{errors.password}</span>
+                        <span>{errors.password.toString()}</span>
                       ) : null}
 
                       <FormikField
@@ -245,7 +245,7 @@ export default function General(props) {
                         onKeyUpErrorMessage=""
                       />
                       {touched.confirmPassword && errors.confirmPassword ? (
-                        <span>{errors.confirmPassword}</span>
+                        <span>{errors.confirmPassword.toString()}</span>
                       ) : null}
 
                       <Button
@@ -311,7 +311,6 @@ export default function General(props) {
                         color="primary"
                         fullWidth
                         disabled={!isValid || !dirty}
-                        className={classes.submit}
                       >
                         {
                           i18next.t(
diff --git a/jams-react-client/src/views/UserProfile/DisplayUserProfile.tsx b/jams-react-client/src/views/UserProfile/DisplayUserProfile.tsx
index 972d59e5..e528350b 100644
--- a/jams-react-client/src/views/UserProfile/DisplayUserProfile.tsx
+++ b/jams-react-client/src/views/UserProfile/DisplayUserProfile.tsx
@@ -184,6 +184,7 @@ export interface UserProfile {
   phoneNumberExtension: string;
   faxNumber: string;
   mobileNumber: string;
+  jamiId?: string;
 }
 
 export interface GroupMembership {
@@ -197,7 +198,7 @@ export interface Group {
   blueprint: string;
 }
 
-interface UserGroup {
+interface UserGroupMapping {
   groupId: string;
   username: string;
 }
@@ -208,7 +209,18 @@ const DisplayUserProfile: FC<DisplayUserProfileProps> = ({
 }) => {
   const classes = useStyles();
   const history = useHistory();
-  const [user, setUser] = useState<UserProfile>({});
+  const [user, setUser] = useState<UserProfile>({
+    username: "",
+    firstName: "",
+    lastName: "",
+    email: "",
+    profilePicture: "",
+    organization: "",
+    phoneNumber: "",
+    phoneNumberExtension: "",
+    faxNumber: "",
+    mobileNumber: "",
+  });
   const [groupMemberships, setGroupMemberships] = useState<GroupMembership[]>(
     []
   );
@@ -257,6 +269,7 @@ const DisplayUserProfile: FC<DisplayUserProfileProps> = ({
   }, [history, username]);
 
   const getAdminUserGroups = () => {
+    // TODO do this in a single sql query on the server, with a JOIN
     axios(
       configApiCall(
         api_path_get_admin_user_groups + username,
@@ -265,15 +278,22 @@ const DisplayUserProfile: FC<DisplayUserProfileProps> = ({
         null
       )
     ).then((userGroups) => {
-      const userGroupsData: UserGroup[] = userGroups.data;
-      userGroupsData.forEach((group) => {
+      const userGroupsData: UserGroupMapping[] = userGroups.data;
+      const promises = userGroupsData.map((group) =>
         axios(
           configApiCall(api_path_get_group + group.groupId, "GET", null, null)
         ).then((groupInfo) => {
-          group["name"] = groupInfo.data.name;
-        });
+          const g: GroupMembership = {
+            groupId: group.groupId,
+            name: groupInfo.data.name,
+          };
+          return g;
+        })
+      );
+
+      Promise.all(promises).then((groupMemberships) => {
+        setGroupMemberships(groupMemberships);
       });
-      setGroupMemberships(userGroupsData);
     });
   };
 
diff --git a/jams-react-client/src/views/UserProfile/EditCreateUserProfile.tsx b/jams-react-client/src/views/UserProfile/EditCreateUserProfile.tsx
index 6de3cb0f..b037e73a 100644
--- a/jams-react-client/src/views/UserProfile/EditCreateUserProfile.tsx
+++ b/jams-react-client/src/views/UserProfile/EditCreateUserProfile.tsx
@@ -74,6 +74,7 @@ import LinearProgress from "@mui/material/LinearProgress";
 import i18next from "i18next";
 
 import generator from "generate-password-browser";
+import { UserProfile } from "./DisplayUserProfile";
 
 const styles = (theme) => ({
   ...dashboardStyle,
@@ -218,6 +219,11 @@ const styles = (theme) => ({
 
 const useStyles = makeStyles(styles as any);
 
+interface UserProfileForm extends UserProfile {
+  password?: string;
+  confirmPassword?: string;
+}
+
 const toBase64 = (file: File): Promise<string | undefined> =>
   new Promise((resolve, reject) => {
     const reader = new FileReader();
@@ -258,7 +264,7 @@ export default function EditCreateUserProfile(props) {
 
   const intialyGeneratedPassword = passwordGenerator();
 
-  const [initialValues, setInitialValues] = useState({
+  const [initialValues, setInitialValues] = useState<UserProfileForm>({
     username: "",
     password: intialyGeneratedPassword,
     confirmPassword: intialyGeneratedPassword,
@@ -520,7 +526,9 @@ export default function EditCreateUserProfile(props) {
       2,
       i18next.t("last_name_is_too_short", "Last Name is too short!") as string
     ),
-    email: Yup.string().email(i18next.t("invalid_email", "Invalid email!")),
+    email: Yup.string().email(
+      i18next.t("invalid_email", "Invalid email!") as string
+    ),
     profilePicture: Yup.string(),
     organization: Yup.string().min(
       2,
@@ -586,7 +594,7 @@ export default function EditCreateUserProfile(props) {
                 step={0.1}
                 aria-labelledby="Zoom"
                 className={classes.slider}
-                onChange={(e, zoom) => setZoom(zoom)}
+                onChange={(e, zoom: any) => setZoom(zoom)}
               />
             </div>
             <div className={classes.sliderContainer}>
@@ -603,7 +611,7 @@ export default function EditCreateUserProfile(props) {
                 step={1}
                 aria-labelledby="Rotation"
                 className={classes.slider}
-                onChange={(e, rotation) => setRotation(rotation)}
+                onChange={(e, rotation: any) => setRotation(rotation)}
               />
             </div>
           </div>
@@ -823,16 +831,10 @@ export default function EditCreateUserProfile(props) {
                             </Grid>
                           )}
                           {props.createUser && (
-                            <Grid
-                              item
-                              align="left"
-                              xs={12}
-                              sm={12}
-                              md={6}
-                            ></Grid>
+                            <Grid item xs={12} sm={12} md={6}></Grid>
                           )}
                           {props.createUser && (
-                            <Grid item align="left" xs={12} sm={12} md={6}>
+                            <Grid item xs={12} sm={12} md={6}>
                               <Button
                                 variant="contained"
                                 color="primary"
@@ -897,7 +899,13 @@ export default function EditCreateUserProfile(props) {
                               ) : null}
                             </Grid>
                           )}
-                          <Grid item align="center" xs={12} sm={12} md={6}>
+                          <Grid
+                            item
+                            alignContent="center"
+                            xs={12}
+                            sm={12}
+                            md={6}
+                          >
                             <FormikField
                               name="firstName"
                               label={
@@ -917,7 +925,13 @@ export default function EditCreateUserProfile(props) {
                               onKeyUpErrorMessage=""
                             />
                           </Grid>
-                          <Grid item align="center" xs={12} sm={12} md={6}>
+                          <Grid
+                            item
+                            alignContent="center"
+                            xs={12}
+                            sm={12}
+                            md={6}
+                          >
                             <FormikField
                               name="lastName"
                               label={
@@ -936,7 +950,7 @@ export default function EditCreateUserProfile(props) {
                               onKeyUpErrorMessage=""
                             />
                           </Grid>
-                          <Grid item align="center" xs={12} sm={12} md={6}>
+                          <Grid item alignSelf="center" xs={12} sm={12} md={6}>
                             <FormikField
                               name="email"
                               label={i18next.t("email", "Email") as string}
@@ -953,7 +967,7 @@ export default function EditCreateUserProfile(props) {
                               onKeyUpErrorMessage=""
                             />
                           </Grid>
-                          <Grid item align="center" xs={12} sm={12} md={6}>
+                          <Grid item alignSelf="center" xs={12} sm={12} md={6}>
                             <FormikField
                               name="organization"
                               label={
@@ -976,7 +990,7 @@ export default function EditCreateUserProfile(props) {
                               onKeyUpErrorMessage=""
                             />
                           </Grid>
-                          <Grid item align="center" xs={12} sm={12} md={6}>
+                          <Grid item alignSelf="center" xs={12} sm={12} md={6}>
                             <FormikField
                               name="faxNumber"
                               label={
@@ -996,7 +1010,7 @@ export default function EditCreateUserProfile(props) {
                               onKeyUpErrorMessage=""
                             />
                           </Grid>
-                          <Grid item align="center" xs={12} sm={12} md={6}>
+                          <Grid item alignSelf="center" xs={12} sm={12} md={6}>
                             <FormikField
                               name="phoneNumber"
                               label={
@@ -1019,7 +1033,7 @@ export default function EditCreateUserProfile(props) {
                               onKeyUpErrorMessage=""
                             />
                           </Grid>
-                          <Grid item align="center" xs={12} sm={12} md={6}>
+                          <Grid item alignSelf="center" xs={12} sm={12} md={6}>
                             <FormikField
                               name="phoneNumberExtension"
                               label={
@@ -1038,7 +1052,7 @@ export default function EditCreateUserProfile(props) {
                               onKeyUpErrorMessage=""
                             />
                           </Grid>
-                          <Grid item align="center" xs={12} sm={12} md={6}>
+                          <Grid item alignSelf="center" xs={12} sm={12} md={6}>
                             <FormikField
                               name="mobileNumber"
                               label={i18next.t("mobile", "Mobile") as string}
diff --git a/jams-react-client/src/views/UserProfile/cropImage.tsx b/jams-react-client/src/views/UserProfile/cropImage.tsx
index 1bd5b8de..f626794b 100644
--- a/jams-react-client/src/views/UserProfile/cropImage.tsx
+++ b/jams-react-client/src/views/UserProfile/cropImage.tsx
@@ -1,4 +1,4 @@
-const createImage = (url) =>
+const createImage = (url: string): Promise<HTMLImageElement> =>
   new Promise((resolve, reject) => {
     const image = new Image();
     image.addEventListener("load", () => resolve(image));
@@ -7,7 +7,7 @@ const createImage = (url) =>
     image.src = url;
   });
 
-function getRadianAngle(degreeValue) {
+function getRadianAngle(degreeValue: number) {
   return (degreeValue * Math.PI) / 180;
 }
 
diff --git a/jams-react-client/src/views/Users/Users.tsx b/jams-react-client/src/views/Users/Users.tsx
index 301e58ee..1b3997b4 100644
--- a/jams-react-client/src/views/Users/Users.tsx
+++ b/jams-react-client/src/views/Users/Users.tsx
@@ -120,7 +120,7 @@ export default function Users() {
     };
   }, [history]);
 
-  const searchUsers = (value, page = "1") => {
+  const searchUsers = (value, page = 1) => {
     setSelectedPage(page);
     setLoading(true);
     setNoMatchFound(false);
-- 
GitLab