From 68d1ef7f9758e8cb6c85e8510c0da05ff84419f3 Mon Sep 17 00:00:00 2001
From: Larbi Gharib <larbi.gharib@savoirfairelinux.com>
Date: Tue, 28 Jul 2020 10:25:38 -0400
Subject: [PATCH] Users search bar user display

Change-Id: I5910dcfdace9c0a429c968af0d164b656ddd0878
---
 jams-react-client/src/api.js                  |   2 +-
 .../components/cardStyle.js                   |   6 -
 .../src/components/CaSetup/CaSetup.js         |   1 -
 .../src/components/Devices/Devices.js         |  13 +-
 .../IdentityManagement/IdentityManagement.js  |   1 -
 jams-react-client/src/layouts/Admin.js        |   4 +-
 .../views/UserProfile/DisplayUserProfile.js   | 254 +++++++++++++-----
 .../UserProfile/EditCreateUserProfile.js      | 116 +++++---
 jams-react-client/src/views/Users/Users.js    | 138 +++++-----
 9 files changed, 331 insertions(+), 204 deletions(-)

diff --git a/jams-react-client/src/api.js b/jams-react-client/src/api.js
index 9cebbd30..86819e69 100644
--- a/jams-react-client/src/api.js
+++ b/jams-react-client/src/api.js
@@ -47,7 +47,7 @@ import {
     api_path_get_needs_update,
     api_path_get_start_update,
     api_path_post_create_user,
-    api_path_get_user,
+    api_path_get_auth_user,
     api_path_post_update_user,
     api_path_get_exists_user,
     api_path_get_user_directory_search,
diff --git a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardStyle.js b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardStyle.js
index 28778131..9c8ad53a 100644
--- a/jams-react-client/src/assets/jss/material-dashboard-react/components/cardStyle.js
+++ b/jams-react-client/src/assets/jss/material-dashboard-react/components/cardStyle.js
@@ -27,12 +27,6 @@ const cardStyle = {
       "& li" :{
         display: 'flex',
         alignItems: 'center',
-        "& svg": {
-          marginRight: "10px"
-        },
-        "& img": {
-          marginRight: "10px"
-        }
       }
     },
     "&:hover": {
diff --git a/jams-react-client/src/components/CaSetup/CaSetup.js b/jams-react-client/src/components/CaSetup/CaSetup.js
index cdb6bc19..89980f29 100644
--- a/jams-react-client/src/components/CaSetup/CaSetup.js
+++ b/jams-react-client/src/components/CaSetup/CaSetup.js
@@ -135,7 +135,6 @@ export default function CaSetup(props) {
 
         axios(configApiCall(api_path_post_install_ca, "POST", jsonData, null)).then((response)=>{
             handleInstallCA(response);
-            console.log(response);
         }).catch((error)=>{
             props.setError(error);
             console.log('Error installing CA Setup: ' + error );
diff --git a/jams-react-client/src/components/Devices/Devices.js b/jams-react-client/src/components/Devices/Devices.js
index 2c0aa556..2bdab736 100755
--- a/jams-react-client/src/components/Devices/Devices.js
+++ b/jams-react-client/src/components/Devices/Devices.js
@@ -32,18 +32,17 @@ export default function Devices(props) {
         auth.checkDirectoryType(() => {
             if(auth.hasAdminScope()){
                 axios(configApiCall(api_path_get_admin_devices, 'GET', userData, null)).then((response)=>{
-                    var resultSet = JSON.parse(response.data.replace(/\s+/g, ' ').trim());
-                    setDevices(resultSet)
-                    }
-                ).catch((error) =>{
+                      var resultSet = JSON.parse(response.data.replace(/\s+/g, ' ').trim());
+                      setDevices(resultSet)
+                }).catch((error) =>{
                     console.log(error);
                 });
             }
             else{
                 axios(configApiCall(api_path_get_auth_devices, 'GET', null, null)).then((response)=>{
-                        setDevices(response.data)
-                    }
-                ).catch((error) =>{
+                      var resultSet = JSON.parse(response.data.replace(/\s+/g, ' ').trim());
+                      setDevices(resultSet)
+                }).catch((error) =>{
                     console.log(error);
                 });
             }
diff --git a/jams-react-client/src/components/IdentityManagement/IdentityManagement.js b/jams-react-client/src/components/IdentityManagement/IdentityManagement.js
index 61da28f4..68ec43e0 100644
--- a/jams-react-client/src/components/IdentityManagement/IdentityManagement.js
+++ b/jams-react-client/src/components/IdentityManagement/IdentityManagement.js
@@ -203,7 +203,6 @@ export default function IdentityManagement(props) {
         }
 
         axios(configApiCall(api_path_post_install_auth,'POST',data,null)).then((response)=>{
-            console.log(response)
             callbackIdentityManagement()
         }).catch(()=>{
             props.setErrorMessage('The information provided appears to be incorrect, the connection to the directory has failed. Please check the information and credentials provided and try again.')
diff --git a/jams-react-client/src/layouts/Admin.js b/jams-react-client/src/layouts/Admin.js
index bc63075e..f1f29631 100644
--- a/jams-react-client/src/layouts/Admin.js
+++ b/jams-react-client/src/layouts/Admin.js
@@ -128,14 +128,14 @@ export default function Admin({ ...rest }) {
             <div className={classes.map}>{switchRoutes}</div>
           )}
         {getRoute() ? <Footer /> : null}
-        <FixedPlugin
+        {/* <FixedPlugin
           handleImageClick={handleImageClick}
           handleColorClick={handleColorClick}
           bgColor={color}
           bgImage={image}
           handleFixedClick={handleFixedClick}
           fixedClasses={fixedClasses}
-        />
+        /> */}
       </div>
     </div>
   );
diff --git a/jams-react-client/src/views/UserProfile/DisplayUserProfile.js b/jams-react-client/src/views/UserProfile/DisplayUserProfile.js
index 3f2d2bcf..b162854f 100644
--- a/jams-react-client/src/views/UserProfile/DisplayUserProfile.js
+++ b/jams-react-client/src/views/UserProfile/DisplayUserProfile.js
@@ -12,6 +12,14 @@ import CardBody from "components/Card/CardBody.js";
 import CardFooter from "components/Card/CardFooter.js";
 import noProfilePicture from "assets/img/faces/no-profile-picture.png";
 
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+import IconButton from '@material-ui/core/IconButton';
+import EditIcon from '@material-ui/icons/Edit';
+import DeleteIcon from '@material-ui/icons/Delete';
 
 import Grid from '@material-ui/core/Grid';
 import BusinessCenterOutlinedIcon from '@material-ui/icons/BusinessCenterOutlined';
@@ -21,13 +29,22 @@ import SmartphoneOutlinedIcon from '@material-ui/icons/SmartphoneOutlined';
 import LocalPrintshopOutlinedIcon from '@material-ui/icons/LocalPrintshopOutlined';
 import PhoneForwardedOutlinedIcon from '@material-ui/icons/PhoneForwardedOutlined';
 import PersonOutlinedIcon from '@material-ui/icons/PersonOutlined';
-import AccountBoxOutlinedIcon from '@material-ui/icons/AccountBoxOutlined';
-import AccountCircleIcon from '@material-ui/icons/AccountCircle';
+import PermIdentityOutlinedIcon from '@material-ui/icons/PermIdentityOutlined';
 
+import Avatar from '@material-ui/core/Avatar';
+import Chip from '@material-ui/core/Chip';
+import DoneIcon from '@material-ui/icons/Done';
+
+import List from '@material-ui/core/List';
+import ListItem from '@material-ui/core/ListItem';
+import ListItemAvatar from '@material-ui/core/ListItemAvatar';
+import ListItemIcon from '@material-ui/core/ListItemIcon';
+import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
+import ListItemText from '@material-ui/core/ListItemText';
 
 import auth from "auth.js"
 import configApiCall from "api.js";
-import { api_path_get_admin_user, api_path_get_user, api_path_get_user_directory_search} from "globalUrls";
+import { api_path_get_admin_user, api_path_get_auth_user, api_path_get_user_directory_search, api_path_delete_admin_user_revoke} from "globalUrls";
 
 import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js";
 
@@ -92,7 +109,8 @@ const styles = (theme)=> ( {
         maxHeight: '60vh',
         minWidth: '80vh',
         maxWidth: '80vh'
-    },
+    }
+
     // controls: {
     //     padding: 16,
     //     display: 'flex',
@@ -130,7 +148,10 @@ export default function DisplayUserProfile(props) {
     const classes = useStyles();
 
     const [users, setUsers] = React.useState([])
-    const [userStatus, setUserStatus] = React.useState('')
+    const [userStatus, setUserStatus] = React.useState(false)
+    const [open, setOpen] = React.useState(false);
+    const [revokedUser, setRevokedUser] = React.useState("");
+
     const  searchData = {
         "queryString":props.username
     };
@@ -138,20 +159,22 @@ export default function DisplayUserProfile(props) {
     const  userData = {
         "username":props.username
     };
-    const [value, setValue] = React.useState(0);
+
     useEffect(() => {
         auth.checkDirectoryType(() => {
             if(auth.hasAdminScope()){
                 axios(configApiCall(api_path_get_admin_user, 'GET', userData, null)).then((response)=>{
-                        setStatus(response.data)
+                        const result = JSON.parse(response.data.replace(/\s+/g, ' ').trim());
+                        setUserStatus(result.revoked)
                     }
                 ).catch((error) =>{
                     console.log(error);
                 });
             }
             else{
-                axios(configApiCall(api_path_get_user, 'GET', null, null)).then((response)=>{
-                        setStatus(response.data)
+                axios(configApiCall(api_path_get_auth_user, 'GET', null, null)).then((response)=>{
+                    const result = JSON.parse(response.data.replace(/\s+/g, ' ').trim());
+                    setUserStatus(result.revoked)
                     }
                 ).catch((error) =>{
                     console.log(error);
@@ -166,92 +189,179 @@ export default function DisplayUserProfile(props) {
         });
     }, []);
 
-    function setStatus(data) {
-        if (data.revoked)
-            setUserStatus("Revoked");
-        else
-            setUserStatus("Active");
+    const getUserStatus = (user) => {
+        if(userStatus == false) {
+            return <Chip label="Active" avatar={<Avatar alt={user.username} src={user.profilePicture ? ('data:image/png;base64, ' + user.profilePicture) : noProfilePicture} />} color="primary" deleteIcon={<DoneIcon />}/>
+        }else{
+            return <Chip label="Revoked" avatar={<Avatar alt={user.username} src={user.profilePicture ? ('data:image/png;base64, ' + user.profilePicture) : noProfilePicture} />} deleteIcon={<DoneIcon />}/>            
+        }
+    }
+
+    function revokeUser(){
+
+        const data = {
+            'username': revokedUser
+        }
+
+        axios(configApiCall(api_path_delete_admin_user_revoke, 'DELETE', data, null)).then(()=>{
+            setUserStatus(true)
+        }).catch((error)=> {
+            console.log("Error revoking user: " + revokedUser + ' with error: ' + error);
+        });
+        setOpen(false);
     }
-    console.log(userStatus)
+
+    const handleClickOpen = (username) => {
+        setRevokedUser(username)
+        setOpen(true);
+    };
+
+    const handleClose = () => {
+        setOpen(false);
+    };
+
     return (
         <div>
+        <Dialog
+            open={open}
+            onClose={handleClose}
+            aria-labelledby="alert-dialog-title"
+            aria-describedby="alert-dialog-description"
+        >
+            <DialogTitle id="alert-dialog-title">{"Revoke user account"}</DialogTitle>
+            <DialogContent>
+            <DialogContentText id="alert-dialog-description">
+                Are you sure you want to revoke <strong>{revokedUser}</strong> ?
+            </DialogContentText>
+            </DialogContent>
+            <DialogActions>
+            <Button onClick={handleClose} color="primary">
+                Cancel
+            </Button>
+            <Button onClick={revokeUser} color="danger" autoFocus>
+                Revoke
+            </Button>
+            </DialogActions>
+        </Dialog>
         {users.map(user =>
             <GridContainer>
                 <Grid item xs={12} sm={12} md={8}>
                     <Card profile>
                         <CardHeader color="info" stats icon>
                             <CardIcon color="info">
-                                <AccountBoxOutlinedIcon />
+                                <PermIdentityOutlinedIcon />
                             </CardIcon>
                             <p className={classes.cardCategory}>{"Profile information"}</p>
                             <h3 className={classes.cardTitle}>{user.username}</h3>
+                            {getUserStatus(user)}
                         </CardHeader>
                         <CardBody profile>
                             <div className={classes.root}>
-                                <GridContainer spacing={5}>
-                                    <Grid item xs={12} sm={12} md={6}>
-                                        <Grid container spacing={5} >
-                                            <Grid item align="center" xs={12} sm={12} md={12} >
-                                                <img src={user.profilePicture ? ('data:image/png;base64, ' + user.profilePicture) : noProfilePicture} className={classes.editProfilePicture} alt="..." />
-                                            </Grid>
-                                        </Grid>
+                                <Grid container spacing={2}>
+                                    <Grid item align="center" xs={12} sm={12} md={12}>
+                                        <img src={user.profilePicture ? ('data:image/png;base64, ' + user.profilePicture) : noProfilePicture} className={classes.editProfilePicture} alt="..." />
+                                        <h4>{user.username ? user.username : 'no username'}</h4>
                                     </Grid>
-                                    <GridItem xs={12} sm={12} md={6}>
-                                        <Grid container spacing={5}>
-                                            <Grid item xs={12} sm={12} md={12}>
-                                                <FormControl className={classes.margin} fullWidth>
-                                                    <span><AccountCircleIcon /> {user.username ? user.username : 'no username'}, {userStatus ? userStatus: "no user status"}</span>
-                                                </FormControl>
-                                            </Grid>
-                                            <Grid item xs={12} sm={12} md={12}>
-                                                <FormControl className={classes.margin} fullWidth>
-                                                    <span> <PersonIcon /> {user.firstName ? user.firstName : 'no firstname'}</span>
-                                                </FormControl>
-                                            </Grid>
-                                            <Grid item xs={12} sm={12} md={12}>
-                                                <FormControl className={classes.margin} fullWidth>
-                                                    <span><PersonOutlinedIcon/> {user.lastName ? user.lastName : 'no lastname'}</span>
-                                                </FormControl>
-                                            </Grid>
-                                        </Grid>
-                                    </GridItem>
-
                                     <Grid item xs={12} sm={12} md={6}>
-                                        <FormControl className={classes.margin} fullWidth>
-                                            <span> <AlternateEmailOutlinedIcon/> {user.email ? user.email : 'no email'}  </span>
-                                        </FormControl>
-                                    </Grid>
-                                    <Grid item xs={12} sm={12} md={6}>
-                                        <FormControl className={classes.margin} fullWidth>
-                                            <span> <BusinessCenterOutlinedIcon/> {user.organization ? user.organization : 'no organization'}  </span>
-                                        </FormControl>
-                                    </Grid>
-                                    <Grid item xs={12} sm={12} md={6}>
-                                        <FormControl className={classes.margin} fullWidth>
-                                            <span> <PhoneInTalkOutlinedIcon/> {user.phoneNumber ? user.phoneNumber : 'no phone number'}  </span>
-                                        </FormControl>
-                                    </Grid>
-                                    <Grid item xs={12} sm={12} md={6}>
-                                        <FormControl className={classes.margin} fullWidth>
-                                            <span> <PhoneForwardedOutlinedIcon/> {user.phoneNumberExtension ? user.phoneNumberExtension : 'no Extension'}  </span>
-                                        </FormControl>
-                                    </Grid>
-                                    <Grid item xs={12} sm={12} md={6}>
-                                        <FormControl className={classes.margin} fullWidth>
-                                            <span> <SmartphoneOutlinedIcon/> {user.mobileNumber ? user.mobileNumber : 'no mobile number'}  </span>
-                                        </FormControl>
+                                        <List dense={false}>
+                                                <ListItem>
+                                                    <ListItemAvatar>
+                                                        <Avatar>
+                                                        <PersonIcon />
+                                                        </Avatar>
+                                                    </ListItemAvatar>
+                                                    <ListItemText
+                                                        primary={user.firstName ? user.firstName : 'no firstname'}
+                                                    />
+                                                </ListItem>
+                                                <ListItem>
+                                                    <ListItemAvatar>
+                                                        <Avatar>
+                                                        <PersonOutlinedIcon/>
+                                                        </Avatar>
+                                                    </ListItemAvatar>
+                                                    <ListItemText
+                                                        primary={user.lastName ? user.lastName : 'no lastname'}
+                                                    />
+                                                </ListItem>
+                                                <ListItem>
+                                                    <ListItemAvatar>
+                                                        <Avatar>
+                                                        <AlternateEmailOutlinedIcon/>
+                                                        </Avatar>
+                                                    </ListItemAvatar>
+                                                    <ListItemText
+                                                        primary={user.email ? user.email : 'no email'}
+                                                    />
+                                                </ListItem>
+                                                <ListItem>
+                                                    <ListItemAvatar>
+                                                        <Avatar>
+                                                        <BusinessCenterOutlinedIcon/>
+                                                        </Avatar>
+                                                    </ListItemAvatar>
+                                                    <ListItemText
+                                                        primary={user.organization ? user.organization : 'no organization'}
+                                                    />
+                                                </ListItem>
+                                        </List>
                                     </Grid>
+
                                     <Grid item xs={12} sm={12} md={6}>
-                                        <FormControl className={classes.margin} fullWidth>
-                                            <span> <LocalPrintshopOutlinedIcon/> {user.faxNumber ? user.faxNumber : 'no fax number'}  </span>
-                                        </FormControl>
+                                        <List dense={false}>
+                                                <ListItem>
+                                                    <ListItemAvatar>
+                                                        <Avatar>
+                                                        <PhoneInTalkOutlinedIcon/>
+                                                        </Avatar>
+                                                    </ListItemAvatar>
+                                                    <ListItemText
+                                                        primary={user.phoneNumber ? user.phoneNumber : 'no phone number'}
+                                                    />
+                                                </ListItem>
+                                                <ListItem>
+                                                    <ListItemAvatar>
+                                                        <Avatar>
+                                                        <PhoneForwardedOutlinedIcon/>
+                                                        </Avatar>
+                                                    </ListItemAvatar>
+                                                    <ListItemText
+                                                        primary={user.phoneNumberExtension ? user.phoneNumberExtension : 'no Extension'}
+                                                    />
+                                                </ListItem>
+                                                <ListItem>
+                                                    <ListItemAvatar>
+                                                        <Avatar>
+                                                        <SmartphoneOutlinedIcon/>
+                                                        </Avatar>
+                                                    </ListItemAvatar>
+                                                    <ListItemText
+                                                        primary={user.mobileNumber ? user.mobileNumber : 'no mobile number'}
+                                                    />
+                                                </ListItem>
+                                                <ListItem>
+                                                    <ListItemAvatar>
+                                                        <Avatar>
+                                                        <LocalPrintshopOutlinedIcon/>
+                                                        </Avatar>
+                                                    </ListItemAvatar>
+                                                    <ListItemText
+                                                        primary={user.faxNumber ? user.faxNumber : 'no fax number'}
+                                                    />
+                                                </ListItem>
+                                        </List>
                                     </Grid>
-                                </GridContainer>
+                                </Grid>
                             </div>
                         </CardBody>
                         <CardFooter>
-                            <Button color="info" onClick={() => props.setDisplayUser(false)}>Edit Profile</Button>
-                            {auth.hasAdminScope() && (userStatus == "Active" || userStatus == '') && <Button color="danger">Revoke Profile</Button>}
+                            {auth.isLocalDirectory() && <Button color="info" onClick={() => props.setDisplayUser(false)}>
+                                <EditIcon /> Edit Profile
+                            </Button>}
+                            {auth.hasAdminScope() && (userStatus == "Active" || userStatus == '') &&                             
+                            <Button color="danger" onClick={() => handleClickOpen(user.username)} >
+                                <DeleteIcon fontSize="small"/> Revoke user
+                            </Button>}
                         </CardFooter>
                     </Card>
                 </Grid>
diff --git a/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js b/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js
index 505fb948..af62ea4c 100644
--- a/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js
+++ b/jams-react-client/src/views/UserProfile/EditCreateUserProfile.js
@@ -56,7 +56,8 @@ import {
     api_path_put_update_user_profile,
     api_path_post_create_user,
     api_path_post_create_user_profile,
-    api_path_get_user_directory_search
+    api_path_get_user_directory_search,
+    api_path_get_exists_user
 } from "../../globalUrls"
 
 import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js";
@@ -157,6 +158,7 @@ export default function EditCreateUserProfile(props) {
     const classes = useStyles();
     const history = useHistory();
     const [createUser, setCreateUser] = React.useState(props.createUser);
+    const [userExists, setUserExists] = React.useState(false)
 
     const [firstName, setFirstName] = React.useState("")
     const [lastName, setLastName] = React.useState("")
@@ -170,6 +172,8 @@ export default function EditCreateUserProfile(props) {
     const [phoneNumber, setPhoneNumber] = React.useState("")
     const [extension, setExtension] = React.useState("")
     const [mobileNumber, setMobileNumber] = React.useState("")
+    const [openPassword, setOpenPassword] = React.useState(false)
+    const [temporaryPassword, setTemporaryPassword] = React.useState("")
 
     const [open, setOpen] = React.useState(false);
     const [crop, setCrop] = React.useState({ x: 0, y: 0 })
@@ -219,13 +223,10 @@ export default function EditCreateUserProfile(props) {
     }
 
     const handleUserProfileCreation = (data) => {
-        axios(configApiCall(api_path_post_create_user + "?username="+ data.username, 'POST', null, null)).then((response) => {
-            console.log("New user successfully created. Here is the one time password: " + response.data["password"])
-            history.push('/admin');
+        axios(configApiCall(api_path_post_create_user_profile, 'POST', data, null)).then(() => {
+            setOpenPassword(true)
         }).catch((error) => {
-            console.log("Failed to create new user. This is either because the username is already in use" +
-                    " on the public nameserver, or another unknown error has occurred. " +
-                    "Please choose another one.");
+            console.log("Error creating user profile: " + error)
         })
     }
 
@@ -243,14 +244,29 @@ export default function EditCreateUserProfile(props) {
             'mobileNumber': mobileNumber
         }
 
-        axios(configApiCall(api_path_post_create_user_profile, 'POST', data, null)).then(() => {
+        axios(configApiCall(api_path_post_create_user + "?username="+ data.username, 'POST', null, null)).then((response) => {
+            setTemporaryPassword(response.data["password"])
             handleUserProfileCreation(data)
-
         }).catch((error) => {
-            console.log("Error updating user: " + error)
+            console.log("Failed to create new user. This is either because the username is already in use" +
+            " on the public nameserver, or another unknown error has occurred. " +
+            "Please choose another one.");
         }) 
     }
 
+    const handleUserExists = (input) => {
+        const data = {
+            "username": input
+        }
+        axios(configApiCall(api_path_get_exists_user, 'GET', data, null)).then((response) =>{
+            if(response.data == "[]"){
+                setUserExists(true)
+            }
+        }).catch((error) => {
+            console.log("Error checking for existing users: " + error)
+        })
+    }
+
     const handleUserUpdate = () => {
         props.setDisplayUser(true)
     }
@@ -287,7 +303,6 @@ export default function EditCreateUserProfile(props) {
             rotation
         ).then((value) => {
             setProfilePicturePreview(value)
-            console.log(value)
         })
     }
      
@@ -304,10 +319,31 @@ export default function EditCreateUserProfile(props) {
         setProfilePicture(profilePicturePreview.replace("data:image/jpeg;base64,", ""))
         setOpen(false)
     }
-     
+    
+    const handleClosePassword = () => {
+        setOpenPassword(false);
+        history.push('/admin');
+    }
 
     return(
         <div>
+        <Dialog
+            open={openPassword}
+            aria-labelledby="alert-dialog-title"
+            aria-describedby="alert-dialog-description"
+        >
+            <DialogTitle id="alert-dialog-title">{"Temporary password"}</DialogTitle>
+            <DialogContent>
+            <DialogContentText id="alert-dialog-description">
+            New user successfully created. Here is the one time password: <strong>{temporaryPassword}</strong> ?
+            </DialogContentText>
+            </DialogContent>
+            <DialogActions>
+            <Button onClick={handleClosePassword} color="primary">
+                Ok
+            </Button>
+            </DialogActions>
+        </Dialog>
         <Dialog
             open={open}
             onClose={handleClose}
@@ -385,7 +421,7 @@ export default function EditCreateUserProfile(props) {
                 <CardBody profile>
                     <div className={classes.root}>
                     <Grid container spacing={5}>
-                        <Grid item xs={12} sm={12} md={6}>
+                        <Grid item xs={12} sm={12} md={12}>
                             <Grid container spacing={5} >
                                 <Grid item align="center" xs={12} sm={12} md={12} >
                                     <img src={profilePicturePreview} alt="..." className={classes.editProfilePicture} />
@@ -398,14 +434,10 @@ export default function EditCreateUserProfile(props) {
                                         </IconButton> Update profile image
                                     </label>
                                 </Grid>
-                            </Grid>
-                        </Grid>
-                        <Grid item xs={12} sm={12} md={6}>
-                            <Grid container spacing={5}>
-                                <Grid item xs={12} sm={12} md={12}>
                                 {createUser && 
-                                    <FormControl className={classes.margin} fullWidth>
-                                        <InputLabel htmlFor="username">Username</InputLabel>
+                                <Grid item align="center" xs={12} sm={12} md={12}>                                
+                                    <FormControl className={classes.margin} size="medium" error={userExists}>
+                                        <InputLabel htmlFor="username">{userExists ? "Error username exists" : "Username"}</InputLabel>
                                         <Input
                                         id="username"
                                         placeholder={userName}
@@ -414,27 +446,32 @@ export default function EditCreateUserProfile(props) {
                                             <AccountCircleIcon />
                                             </InputAdornment>
                                         }
-                                        onChange={e => setUserName(e.target.value)}
+                                        onChange={e => {
+                                            setUserName(e.target.value);
+                                            handleUserExists(e.target.value)
+                                        }}
                                         />
                                     </FormControl>
-                                }
                                 </Grid>
-                                <Grid item xs={12} sm={12} md={12}>
-                                                        <FormControl className={classes.margin} fullWidth>
-                                    <InputLabel htmlFor="firstname">First Name</InputLabel>
-                                    <Input
-                                    id="firstname"
-                                    placeholder={firstName}
-                                    startAdornment={
-                                        <InputAdornment position="start">
-                                        <PersonIcon />
-                                        </InputAdornment>
-                                    }
-                                    onChange={e => setFirstName(e.target.value)}
-                                    />
-                                </FormControl>
-                                </Grid>
-                            <Grid item xs={12} sm={12} md={12}>
+                                }
+                            </Grid>
+                        </Grid>
+                        <Grid item xs={12} sm={12} md={6}>
+                            <FormControl className={classes.margin} fullWidth>
+                                <InputLabel htmlFor="firstname">First Name</InputLabel>
+                                <Input
+                                id="firstname"
+                                placeholder={firstName}
+                                startAdornment={
+                                    <InputAdornment position="start">
+                                    <PersonIcon />
+                                    </InputAdornment>
+                                }
+                                onChange={e => setFirstName(e.target.value)}
+                                />
+                            </FormControl>
+                        </Grid>
+                        <Grid item xs={12} sm={12} md={6}>
                             <FormControl className={classes.margin} fullWidth>
                                 <InputLabel htmlFor="lastname">Last Name</InputLabel>
                                 <Input
@@ -448,10 +485,7 @@ export default function EditCreateUserProfile(props) {
                                 onChange={e => setLastName(e.target.value)}
                                 />
                             </FormControl>
-                            </Grid>
-                        </Grid>
                         </Grid>
-
                         <Grid item xs={12} sm={12} md={6}>
                             <FormControl className={classes.margin} fullWidth>
                                 <InputLabel htmlFor="email">Email</InputLabel>
diff --git a/jams-react-client/src/views/Users/Users.js b/jams-react-client/src/views/Users/Users.js
index 910798c3..d5d34538 100644
--- a/jams-react-client/src/views/Users/Users.js
+++ b/jams-react-client/src/views/Users/Users.js
@@ -1,4 +1,5 @@
 import React, { useState, useEffect } from "react";
+import { useHistory } from 'react-router-dom';
 import { Switch, Route, Redirect } from "react-router-dom";
 // @material-ui/core components
 import { makeStyles } from "@material-ui/core/styles";
@@ -15,28 +16,18 @@ import CardBody from "components/Card/CardBody.js";
 import CardFooter from "components/Card/CardFooter.js";
 import UserProfile from "views/UserProfile/UserProfile.js"
 import Divider from '@material-ui/core/Divider';
-import Dialog from '@material-ui/core/Dialog';
-import DialogActions from '@material-ui/core/DialogActions';
-import DialogContent from '@material-ui/core/DialogContent';
-import DialogContentText from '@material-ui/core/DialogContentText';
-import DialogTitle from '@material-ui/core/DialogTitle';
 
 import PersonIcon from '@material-ui/icons/Person';
 import PermIdentityIcon from '@material-ui/icons/PermIdentity';
 import PhoneOutlinedIcon from '@material-ui/icons/PhoneOutlined';
 import BusinessOutlinedIcon from '@material-ui/icons/BusinessOutlined';
-import DeleteIcon from '@material-ui/icons/Delete';
 import Search from "@material-ui/icons/Search";
-import IconButton from '@material-ui/core/IconButton';
 
 import MailOutlineIcon from '@material-ui/icons/MailOutline';
 import axios from "axios";
 import configApiCall from "api.js";
 import auth from 'auth.js'
-import {
-        api_path_get_user_directory_search,
-        api_path_delete_admin_user_revoke 
-        } from "globalUrls";
+import { api_path_get_user_directory_search } from "globalUrls";
 
 import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline';
 import KeyboardReturnIcon from '@material-ui/icons/KeyboardReturn';
@@ -45,6 +36,7 @@ import jami from "assets/img/faces/jami.png";
 import noProfilePicture from "assets/img/faces/no-profile-picture.png";
 import EditCreateUserProfile from "views/UserProfile/EditCreateUserProfile";
 
+import LinearProgress from '@material-ui/core/LinearProgress';
 
 import headerLinksStyle from "assets/jss/material-dashboard-react/components/headerLinksStyle.js";
 
@@ -68,6 +60,12 @@ const styles = {
     },
     deleteIcon : {
         float: "right"
+    },  
+    search : {
+        width: "90%"
+    },
+    loading: {
+        width: '100%',
     }
 };
 
@@ -75,20 +73,42 @@ const useStyles = makeStyles(styles);
 
 export default function Users() {
     const classes = useStyles();
+    const history = useHistory();
     const [users, setUsers] = React.useState([])
-    const [open, setOpen] = React.useState(false);
-    const [revokedUser, setRevokedUser] = React.useState("");
     const [selectedUsername, setSelectedUsername] = React.useState("")
     const [createUser, setCreateUser] = React.useState(false)
+    const [searchValue, setSearchValue] = React.useState(null)
+    const [loading, setLoading] = React.useState(false)
+    const [progress, setProgress] = React.useState(0);
 
     useEffect(() => {
-        setRevokedUser('')
+        setLoading(true)
+        const timer = setInterval(() => {
+            setProgress((oldProgress) => {
+              if (oldProgress === 100) {
+                return 0;
+              }
+              const diff = Math.random() * 10;
+              return Math.min(oldProgress + diff, 100);
+            });
+          }, 500);
         axios(configApiCall(api_path_get_user_directory_search, 'GET', {"queryString":"*"}, null)).then((response)=>{
-            setUsers(response.data)
-        }   
-        ).catch((error) =>{
+            let orginalUsers = response.data
+            orginalUsers.map((user) => {
+                user.display = ""
+            })
+            setUsers(orginalUsers)
+            setLoading(false)
+        }).catch((error) =>{
             console.log(error);
+            if(error.response.status == 401){
+                auth.authenticated = false
+                history.push('/')
+            }
         });
+        return () => {
+            clearInterval(timer);
+          };
     }, []);
 
     const [selectedProfile, setSelectedProfile] = useState(false);
@@ -101,32 +121,10 @@ export default function Users() {
     function redirectToUsers(e) {
         e.preventDefault()
         setSelectedProfile(false);
+        history.push('/admin')
     }
 
-    function revokeUser(){
-
-        const data = {
-            'username': revokedUser
-        }
-
-        axios(configApiCall(api_path_delete_admin_user_revoke, 'DELETE', data, null)).then((result)=>{
-            console.log("Revoked user: " + revokedUser);
-        }).catch((error)=> {
-            console.log("Error revoking user: " + revokedUser + ' with error: ' + error);
-        });
-        setOpen(false);
-    }
-
-    const handleClickOpen = (username) => {
-        setRevokedUser(username)
-        setOpen(true);
-    };
-
-    const handleClose = () => {
-        setOpen(false);
-    };
-
-    if (selectedProfile && !auth.hasAdminScope()) {
+    if (!auth.hasAdminScope()) {
         return (
             <div>
                 <UserProfile username={auth.getUsername()}/>
@@ -149,27 +147,6 @@ export default function Users() {
     else {
         return (
             <div>
-                <Dialog
-                    open={open}
-                    onClose={handleClose}
-                    aria-labelledby="alert-dialog-title"
-                    aria-describedby="alert-dialog-description"
-                >
-                    <DialogTitle id="alert-dialog-title">{"Revoke user account"}</DialogTitle>
-                    <DialogContent>
-                    <DialogContentText id="alert-dialog-description">
-                        Are you sure you want to revoke <strong>{revokedUser}</strong> ?
-                    </DialogContentText>
-                    </DialogContent>
-                    <DialogActions>
-                    <Button onClick={handleClose} color="primary">
-                        Cancel
-                    </Button>
-                    <Button onClick={revokeUser} color="danger" autoFocus>
-                        Revoke
-                    </Button>
-                    </DialogActions>
-                </Dialog>
                 <GridContainer>
                     <GridItem xs={12} sm={12} md={12}>
                         {auth.isLocalDirectory() &&
@@ -178,23 +155,42 @@ export default function Users() {
                             </Button>
                         }
                         <div className={classes.searchWrapper}>
-                            <CustomInput
+                            <CustomInput 
                             formControlProps={{
                                 className: classes.margin + " " + classes.search
                             }}
                             inputProps={{
-                                placeholder: "Search users",
+                                placeholder: "Search users using (username, name, phone, email, ...)",
                                 inputProps: {
                                 "aria-label": "Search users"
-                                }
+                                },
+                                onKeyUp: (e) => setSearchValue(e.target.value),
                             }}
                             />
                             <Search />
+                            <div className={classes.loading}>
+                                {loading && <LinearProgress variant="determinate" value={progress} />}
+                            </div>
                         </div>
                     </GridItem>
                     {
-                    users.map(user => 
-                    <GridItem xs={12} sm={12} md={2} key={user.username}>
+                    users.filter((data)=>{
+                        if(searchValue == null)
+                            return data
+                        else if((data.username != null ) && data.username.toLowerCase().includes(searchValue.toLowerCase()) || 
+                                (data.firstName != null ) &&  data.firstName.toLowerCase().includes(searchValue.toLowerCase()) || 
+                                (data.lastName != null ) &&  data.lastName.toLowerCase().includes(searchValue.toLowerCase()) || 
+                                (data.organization != null ) &&  data.organization.toLowerCase().includes(searchValue.toLowerCase()) ||
+                                (data.email != null ) &&  data.email.toLowerCase().includes(searchValue.toLowerCase()) ||
+                                (data.phoneNumber != null ) &&  data.phoneNumber.toLowerCase().includes(searchValue.toLowerCase()) ||
+                                (data.phoneNumberExtension != null ) &&  data.phoneNumberExtension.toLowerCase().includes(searchValue.toLowerCase()) ||
+                                (data.mobileNumber != null ) &&  data.mobileNumber.toLowerCase().includes(searchValue.toLowerCase()) ||
+                                (data.faxNumber != null ) &&  data.faxNumber.toLowerCase().includes(searchValue.toLowerCase())
+                                ){
+                            return data
+                        }
+                    }).map(user =>
+                    <GridItem xs={12} sm={12} md={2} key={user.username} style={{display: user.display}}>
                             
                                 <Card profile>
                                     <CardBody profile>
@@ -205,14 +201,10 @@ export default function Users() {
                                         
                                         <h4 className={classes.cardTitle}>{user.firstName} {user.lastName}</h4>    
                                         <ul>
-                                            <li><img src={jami} width="20" alt="Jami" /> {user.username}</li>
-                                            <li><BusinessOutlinedIcon fontSize='small' /> {user.organization ? user.organization : 'No organization'}</li>
+                                            <li><img src={jami} width="20" alt="Jami" style={{marginRight: "10px"}} /> {user.username}</li>
+                                            <li><BusinessOutlinedIcon fontSize='small' style={{marginRight: "10px"}} /> {user.organization ? user.organization : 'No organization'}</li>
                                         </ul>
                                         </a>
-                                        <Divider variant="middle" />
-                                        <IconButton aria-label="delete" className={classes.deleteIcon} onClick={() => handleClickOpen(user.username)}>
-                                            <DeleteIcon fontSize="small" color="error" />
-                                        </IconButton>
                                     </CardBody>
                                 </Card>
 
-- 
GitLab