Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions backend/models/user.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ const userSchema = mongoose.Schema({
managedProjects: [{ type: String}], // Which projects managed by user.
//currentProject: { type: String } // no longer need this as we can get it from Project Team Member table
// password: { type: String, required: true }
isActive: { type: Boolean, default: true }
isActive: { type: Boolean, default: true },
isAdmin: {type: Boolean, default: false} // Signifies if a user is an admin or not
});

userSchema.methods.serialize = function () {
Expand Down Expand Up @@ -67,7 +68,8 @@ userSchema.methods.serialize = function () {
githubPublic2FA: this.githubPublic2FA,
availability: this.availability,
managedProjects: this.managedProjects,
isActive: this.isActive
isActive: this.isActive,
isAdmin: this.isAmdin
};
};

Expand Down
16 changes: 16 additions & 0 deletions client/src/api/UserApiService.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ class UserApiService {
alert('server not responding. Please try again.');
}
}

async updateUserDbIsAdmin(userToEdit, isAdmin) {
const url = `${this.baseUserUrl}${userToEdit._id}`;
const requestOptions = {
method: 'PATCH',
headers: this.headers,
body: JSON.stringify({ isAdmin }),
};

try {
return await fetch(url, requestOptions);
} catch (err) {
console.error('update is-admin error', err);
alert('server not responding. Please try again.');
}
}
}

export default UserApiService;
24 changes: 19 additions & 5 deletions client/src/components/user-admin/EditUsers.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import '../../sass/UserAdmin.scss';
import { FormGroup, FormControlLabel, Switch } from '@mui/material'

// child of UserAdmin. Displays form to update users.
const EditUsers = ({ userToEdit, backToSearch, updateUserDb, projects, updateUserActiveStatus }) => {
const EditUsers = ({ userToEdit, backToSearch, updateUserDb, projects, updateUserActiveStatus, updateUserAdminStatus }) => {
const [userManagedProjects, setUserManagedProjects] = useState([]); // The projects that the selected user is assigned
const [projectValue, setProjectValue] = useState(''); // State and handler for form in EditUsers
const [isActive, setIsActive] = useState(userToEdit.isActive);
const [isAdmin, setIsAdmin] = useState(userToEdit.isAdmin);

// Prepare data for display
const userName = `${userToEdit.name?.firstName} ${userToEdit.name?.lastName}`;
Expand Down Expand Up @@ -64,6 +65,10 @@ const EditUsers = ({ userToEdit, backToSearch, updateUserDb, projects, updateUse
updateUserActiveStatus(userToEdit, !isActive)
}

const handleSetIsAdmin = () => {
setIsAdmin(!isAdmin)
updateUserAdminStatus(userToEdit, !isAdmin)
}
return (
<div className="edit-users">
<div className="ua-row">
Expand All @@ -74,15 +79,24 @@ const EditUsers = ({ userToEdit, backToSearch, updateUserDb, projects, updateUse
<div className="user-display-column-left">Email:</div>
<div className="user-display-column-right">{userEmail}</div>
</div>
<div className="ua-row is-active-flex">
<div className="user-is-active-column-left">Is Active:</div>
<div className="is-active-flex">
<span className="active-status">{isActive.toString()}</span>
<div className="ua-row toggle-flex">
<div className="user-toggle-column-left">Is Active:</div>
<div className="toggle-flex">
<span className="toggle-status">{isActive.toString()}</span>
<FormGroup>
<FormControlLabel control={<Switch checked={isActive} />} onClick={() => handleSetIsActive()} />
</FormGroup>
</div>
</div>
<div className="ua-row toggle-flex">
<div className="user-toggle-column-left">Is Admin:</div>
<div className="toggle-flex">
<span className="toggle-status">{isAdmin.toString()}</span>
<FormGroup>
<FormControlLabel control={<Switch checked={isAdmin} />} onClick={() => handleSetIsAdmin()} />
</FormGroup>
</div>
</div>
<div className="ua-row">
<div className="user-display-column-left">Projects:</div>
<div className="user-display-column-right">
Expand Down
8 changes: 8 additions & 0 deletions client/src/pages/UserAdmin.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ const UserAdmin = () => {
}, [userApiService, fetchUsers]
)

const updateUserAdminStatus = useCallback(
async (user, isAdmin) => {
await userApiService.updateUserDbIsAdmin(user, isAdmin);
fetchUsers()
}, [userApiService, fetchUsers]
)

const fetchProjects = useCallback(async () => {
const projectRes = await projectApiService.fetchProjects();
setProjects(projectRes);
Expand Down Expand Up @@ -65,6 +72,7 @@ const UserAdmin = () => {
updateUserDb={updateUserDb}
backToSearch={backToSearch}
updateUserActiveStatus={updateUserActiveStatus}
updateUserAdminStatus={updateUserAdminStatus}
/>
);
}
Expand Down
6 changes: 3 additions & 3 deletions client/src/sass/UserAdmin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,18 @@
margin-bottom: 8px;
}

.user-is-active-column-left {
.user-toggle-column-left {
display: flex;
flex-direction: column;
flex-basis: 15%;
}

.active-status {
.toggle-status {
margin-right: 15px;
width: 25px;
}

.is-active-flex {
.toggle-flex {
display: flex;
align-items: center;
}
Expand Down