Skip to content

Commit

Permalink
Provide super user option on member detail page (#536)
Browse files Browse the repository at this point in the history
* Provide super user option on member detail page

* able to render isMember and isArchived value

* addressed the changes suggested by vinayak

* adding api integration in the feature

* removed comments

* added condition for default behaviour control

* made a generalized functions and added conditon to variable and use it

* updated the member promotion and archive member functions
  • Loading branch information
Pratiyushkumar authored Aug 5, 2023
1 parent 49e246c commit b2c2c3c
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 52 deletions.
7 changes: 5 additions & 2 deletions src/components/keyboard-handler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import { useKeyboardContext } from '@store/keyboard/context';
import { ALT_KEY } from '@constants/AppConstants';

function isOptionKey(e) {
e.preventDefault();
return e.key === ALT_KEY;
if (e.key === ALT_KEY) {
e.preventDefault();
return true;
}
return false;
}

function KeyboardHandler({ children }) {
Expand Down
34 changes: 29 additions & 5 deletions src/components/member-profile/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable react/no-array-index-key */
import React, { useRef, useState } from 'react';
import { useRouter } from 'next/router';
import PropTypes from 'prop-types';
import SocialMediaIcon from '@components/social-media-icon';
import getBadges from '@components/member-profile/mock/get-badges';
Expand All @@ -14,6 +15,9 @@ import { KEY_ESC, KEY_TAB } from '@constants/AppConstants';
import MemberTaskUpdate from '@components/member-task-update';
import { useTaskContext } from '@store/tasks/tasks-context';
import { userContext } from '@store/user/user-context';
import { useKeyboardContext } from '@store/keyboard/context';
import SuperUserOptions from '@components/member-card/super-user-options';
import MemberRoleUpdate from '@components/member-role-update';

const renderBadgeImages = (badges) =>
badges.map((badge) => (
Expand Down Expand Up @@ -66,25 +70,28 @@ const Profile = (props) => {
} = props;
const { membersData } = props;
const isMember = Boolean(membersData?.roles?.member);

const memberStatusMessage = isMember
? 'User is a Member'
: 'User is not a Member';

const { showMemberRoleUpdateModal, isSuperUser } = userContext();
const socialMedia = [
'twitter_id',
'github_id',
'linkedin_id',
'instagram_id',
];
const { query } = useRouter() || { query: { dev: false } };
const { dev } = query;

const { showMemberTaskUpdateModal } = useTaskContext();
const { isSuperUser } = userContext();
const fullName = `${first_name} ${last_name}`;
const memberName = fullName.trim() || '--';
const rdsUserName = `@${username}`;

const badges = getBadges(username);

const { isOptionKeyPressed } = useKeyboardContext();
const [showSettings, setShowSettings] = useState(false);
const [showModal, setShowModal] = useState(false);
const { register, handleSubmit, errors } = useForm();
const submitBtnRef = useRef(null);
Expand Down Expand Up @@ -360,13 +367,20 @@ const Profile = (props) => {
e.target.src = '/images/Avatar.png';
};

const superUserOptionKeyPress = dev && isSuperUser && isOptionKeyPressed;

return (
<>
{showModal && (
<Modal style={modalStyle} show={showModal} closeModal={closeModal}>
{children}
</Modal>
)}
{isSuperUser && (
<div id="memberRoleUpdateModal">
{showMemberRoleUpdateModal && <MemberRoleUpdate />}
</div>
)}
{showMemberTaskUpdateModal && <MemberTaskUpdate />}
<div className={classNames.container}>
<div className={(classNames.sidebar, classNames.column)}>
Expand All @@ -378,15 +392,25 @@ const Profile = (props) => {
className={classNames.profilePic}
alt={fullName}
/>
{isSuperUser && (
<div className={classNames.memberStatus}>
{superUserOptionKeyPress && (
<div
className={classNames.memberStatus}
onMouseEnter={() => setShowSettings(true)}
onMouseLeave={() => setShowSettings(false)}
>
<img
alt="info icon"
src="icons/info.png"
width={20}
height={20}
/>
<span>{memberStatusMessage}</span>
<span className={classNames.showSettingsButton}>
<SuperUserOptions
showSettings={showSettings}
username={membersData.username}
/>
</span>
</div>
)}

Expand Down
4 changes: 4 additions & 0 deletions src/components/member-profile/member-profile.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@
width: 1rem;
}

.showSettingsButton {
margin-left: 0.8rem;
}

.hidden {
display: none;
}
Expand Down
89 changes: 60 additions & 29 deletions src/components/member-role-update/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import MemberTagAssign from '@components/member-tag-assign';
import { BASE_API_URL } from '@constants/AppConstants';
import useFetch from '@custom-hooks/useFetch';
import classNames from './member-role-update.module.scss';
import {
archiveMember,
moveToMember,
} from '../../helper-functions/action-handlers';
import { memberRoleUpdate } from '../../helper-functions/action-handlers';

const MemberRoleUpdate = () => {
const {
Expand All @@ -26,48 +23,82 @@ const MemberRoleUpdate = () => {
`${BASE_API_URL}/users/${selectedMember}`
);

const member = userData?.user?.roles.member;
const archived = userData?.user?.roles.archived;
const userId = userData?.user.id;
const { data: tagData } = useFetch(`${BASE_API_URL}/tags`);
const { data: levelData } = useFetch(`${BASE_API_URL}/levels`);

const promoteToMember = async (user) => {
const promoteDemoteAMember = async (id) => {
let memberRole = null;
setIsUpdating(true);
const { status } = await moveToMember(user);
setIsUpdating(false);
if (status === 204) {
setUpdateStatus('User moved to member');
if (member) {
memberRole = false;
} else {
setUpdateStatus('Some error occured, please contact admin');
memberRole = true;
}
const role = {
member: memberRole,
};
try {
const { status } = await memberRoleUpdate(id, role);
setIsUpdating(false);
if (status === 200) {
setUpdateStatus('user promoted to a member');
}
} catch (error) {
setUpdateStatus('some error occured, please contact admin');
}
};
const archiveTheMember = async (user) => {

const archiveUnArchiveTheMember = async (id) => {
let archiveRole = null;
setIsUpdating(true);
const { status } = await archiveMember(user);
setIsUpdating(false);
if (status === 204) {
setUpdateStatus('User archived!');
if (archived) {
archiveRole = false;
} else {
archiveRole = true;
}
const role = {
archived: archiveRole,
};
try {
const { status } = await memberRoleUpdate(id, role);
setIsUpdating(false);
if (status === 200) {
setUpdateStatus('user archived!');
}
} catch (error) {
setUpdateStatus('Some error occured, please contact admin');
}
};

const memberRoleUpdateButton = (
<button
className={classNames.moveToMember}
type="button"
onClick={() => promoteDemoteAMember(userId)}
>
{member ? 'Demote Member' : 'Promote to Member'}
</button>
);

const memeberArchiveUnArchiveButton = (
<button
className={classNames.moveToMember}
type="button"
onClick={() => archiveUnArchiveTheMember(userId)}
>
{archived ? 'Unarchive Member' : 'Archive Member'}
</button>
);

const renderPromoteButton = () => {
return (
<>
<button
className={classNames.moveToMember}
type="button"
onClick={() => promoteToMember(selectedMember)}
>
Promote to Member
</button>
{memberRoleUpdateButton}
{memeberArchiveUnArchiveButton}

<button
className={classNames.moveToMember}
type="button"
onClick={() => archiveTheMember(selectedMember)}
>
Archive Member
</button>
<br />

{userData && tagData && levelData && (
Expand Down
14 changes: 4 additions & 10 deletions src/helper-functions/action-handlers.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { fetch } from './fetch';
import {
getAddMemberRoleURL,
getUserProfileSelf,
getArchiveMemberURL,
getTaskUpdateURL,
getTagAssignURL,
updateMemberRole,
} from './urls';

const moveToMember = (user) =>
fetch(getAddMemberRoleURL(user), 'patch', null, null, null, {
const memberRoleUpdate = (user, role) =>
fetch(updateMemberRole(user), 'patch', null, role, null, {
withCredentials: true,
});

Expand All @@ -17,11 +16,6 @@ const getUserSelf = () =>
withCredentials: true,
});

const archiveMember = (user) =>
fetch(getArchiveMemberURL(user), 'patch', null, null, null, {
withCredentials: true,
});

const moveTask = (taskId, data) =>
fetch(
getTaskUpdateURL(taskId),
Expand All @@ -46,4 +40,4 @@ const assignTags = (data) =>
}
);

export { archiveMember, moveToMember, getUserSelf, moveTask, assignTags };
export { getUserSelf, moveTask, assignTags, memberRoleUpdate };
8 changes: 2 additions & 6 deletions src/helper-functions/urls.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,8 @@ const getActiveTasksURL = (rdsId) => `${baseURL}/tasks/${rdsId}?status=active`;
*
* @param {string} rdsId
*/
const getAddMemberRoleURL = (rdsId) =>
`${baseURL}/members/moveToMembers/${rdsId}`;

const getArchiveMemberURL = (rdsId) =>
`${baseURL}/members/archiveMembers/${rdsId}`;
const updateMemberRole = (rdsId) => `${baseURL}/users/${rdsId}/temporary/data`;

/**
*
Expand All @@ -62,8 +59,7 @@ export {
getCloudinaryImgURL,
getActiveTasksURL,
getUserProfileSelf,
getAddMemberRoleURL,
getArchiveMemberURL,
getTaskUpdateURL,
getTagAssignURL,
updateMemberRole,
};

0 comments on commit b2c2c3c

Please sign in to comment.