Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Haoji fetch images from team page and multiple profile images selection for individuals #1531

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
046d0bd
add profilePic select modal to user management page
juneluo Sep 15, 2023
0c48bd8
Create SelectProfilePicPopup.jsx
Haoj1 Oct 28, 2023
33d237b
Update Dockerfile
Haoj1 Oct 28, 2023
55eb6eb
Merge branch 'development' into Haoji-create-profile-picture-selectio…
Haoj1 Oct 28, 2023
4543c3e
Merge remote-tracking branch 'origin/jun_profile_image' into Haoji-cr…
Haoj1 Oct 28, 2023
cf3d163
finished selectPicPopup
Haoj1 Oct 29, 2023
924611a
Merge branch 'development' into Haoji-create-profile-picture-selectio…
Haoj1 Oct 29, 2023
05e4d7a
fix bug of not correctly displayed the ProfilePic
Haoj1 Oct 29, 2023
36ad7ad
Merge branch 'Haoji-create-profile-picture-selection-by-admin' into H…
Haoj1 Nov 3, 2023
df55420
Update UserProfile.jsx
Haoj1 Nov 4, 2023
43620db
update file name
Haoj1 Nov 5, 2023
2a8ca66
Merge branch 'development' into Haoji-create-multiple-profile-images-…
Haoj1 Nov 11, 2023
4b19521
Update UserProfile.jsx
Haoj1 Nov 11, 2023
17214d5
Merge branch 'development' into Haoji-create-multiple-profile-images-…
Haoj1 Feb 4, 2024
13fd41d
Merge branch 'development' into Haoji-create-multiple-profile-images-…
Haoj1 Feb 17, 2024
21c788d
new notification through banner
Haoj1 Mar 3, 2024
a76b0d4
Update Header.jsx
Haoj1 Mar 3, 2024
52a4e25
Merge branch 'development' into Haoji-create-multiple-profile-images-…
Haoj1 Mar 3, 2024
dc5f1ef
improve usermanagement page loading time
Haoj1 Mar 22, 2024
aafa910
Merge branch 'development' into Haoji-create-multiple-profile-images-…
Haoj1 Apr 7, 2024
8bc433f
Merge branch 'development' into Haoji-create-multiple-profile-images-…
Haoj1 Apr 13, 2024
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
28 changes: 24 additions & 4 deletions src/actions/userManagement.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const getAllUserProfile = () => {
* @param {*} status - Active/InActive
*/
export const updateUserStatus = (user, status, reactivationDate) => {
const userProfile = { ...user};
const userProfile = { ...user };
userProfile.isActive = status === UserStatus.Active;
userProfile.reactivationDate = reactivationDate;
const patchData = { status, reactivationDate };
Expand Down Expand Up @@ -72,6 +72,26 @@ export const updateRehireableStatus = (user, isRehireable) => {
};
};

/**
* update the user profile picture
* @param {*} user - the user to be updated
* @param {*} pic - profile picture url
*/
export const updateUserProfilePic = (user, pic, status) => {
const userProfile = { ...user };
const patchData = { status, profilePic: pic };
if (pic) {
patchData.profilePic = pic;
userProfile.profilePic = pic;
}
const updateProfilePromise = axios.patch(ENDPOINTS.USER_PROFILE(user._id), patchData);
return async dispatch => {
updateProfilePromise.then(res => {
dispatch(userProfileUpdateAction(userProfile));
});
};
};

/**
* delete an existing user
* @param {*} user - the user to be deleted
Expand Down Expand Up @@ -152,7 +172,7 @@ export const userProfileDeleteAction = user => {
* @param {*} finalDate - the date to be inactive
*/
export const updateUserFinalDayStatus = (user, status, finalDayDate) => {
const userProfile = { ...user};
const userProfile = { ...user };
userProfile.endDate = finalDayDate;
userProfile.isActive = status === 'Active';
const patchData = { status, endDate: finalDayDate };
Expand All @@ -173,7 +193,7 @@ export const updateUserFinalDayStatus = (user, status, finalDayDate) => {
};

export const updateUserFinalDayStatusIsSet = (user, status, finalDayDate, isSet) => {
const userProfile = { ...user};
const userProfile = { ...user };
userProfile.endDate = finalDayDate;
userProfile.isActive = status === 'Active';
userProfile.isSet = isSet === 'FinalDay';
Expand All @@ -192,4 +212,4 @@ export const updateUserFinalDayStatusIsSet = (user, status, finalDayDate, isSet)
dispatch(userProfileUpdateAction(userProfile));
});
};
};
};
21 changes: 19 additions & 2 deletions src/components/Header/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import PopUpBar from 'components/PopUpBar';
import './Header.css';
import hasPermission, { cantUpdateDevAdminDetails } from '../../utils/permissions';
import { fetchTaskEditSuggestions } from 'components/TaskEditSuggestions/thunks';
import { tr } from 'date-fns/locale';

export function Header(props) {
const [isOpen, setIsOpen] = useState(false);
Expand Down Expand Up @@ -110,7 +111,7 @@ export function Header(props) {
const [hasProfileLoaded, setHasProfileLoaded] = useState(false);
const dismissalKey = `lastDismissed_${userId}`;
const [lastDismissed, setLastDismissed] = useState(localStorage.getItem(dismissalKey));

const [isSelectImgModalVisible, setSelectImgModalVisible] = useState(true);
const dispatch = useDispatch();

useEffect(() => {
Expand Down Expand Up @@ -432,7 +433,23 @@ export function Header(props) {
<div className="card-content">{modalContent}</div>
</Card>
)}

{isSelectImgModalVisible && (
<Card color="primary">
{props?.userProfile?.storedPics?.length > 0 && (
<>
<div className="close-button">
<Button close onClick={()=>{setSelectImgModalVisible(false)}} />
</div>
<p></p>
<Link to={`/userprofile/${props.userProfile._id}`}>
<div className='card-content'>We found multiple pictures for you on our website.
Please choose one of them in Profile page</div>
</Link>
<p></p>
</>
)}
</Card>
)}
</div>
);
}
Expand Down
160 changes: 160 additions & 0 deletions src/components/UserManagement/SelectProfilePicPopUp.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import moment from 'moment';
import React, { useEffect, useState } from 'react';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Input, Alert } from 'reactstrap';
import { boxStyle } from 'styles';
import { toast } from 'react-toastify';
import { getUserProfile, updateUserProfile } from '../../actions/userProfile';
import { connect, useDispatch, useSelector } from 'react-redux';
import { ENDPOINTS } from '../../utils/URL';
import axios from 'axios';
import { set } from 'lodash';
/**
* Modal popup to show the user profile picture
*/
const SelectProfilePicPopup = React.memo(props => {
const [selectedPic, setSelectedPic] = useState();
const [newPic, setNewPic] = useState();
const [storedPics, setStoredPics] = useState();
const [profilePic, setProfilePic] = useState();
const userProfile = useSelector(state => state.userProfile);



useEffect(() => {
loadUserProfile();
}, [props]);

const loadUserProfile = async () => {

const userId = props?.user?._id;
if (!userId) return;
console.log(userId);
try {
const response = await axios.get(ENDPOINTS.USER_PROFILE(userId));
const userProfile = response.data;
setStoredPics(userProfile.storedPics);
setProfilePic(userProfile.profilePic);
} catch (err) {
console.error(err);
toast.error('Failed to load user profile.');
}
};

const closePopup = e => {
props.onClose();
};

/****
* Remaining Problem: cannot selct the added url because it does not pass the
* validateProfilePic function in the userHelper.js, which should be further
* modified for the new feature.
* ****/
const saveChange = async e => {
try {
await props.getUserProfile(props.user._id);
console.log(selectedPic[0])
const updatedProfile = {
...userProfile,
profilePic: selectedPic[0],
};
await props.updateUserProfile(updatedProfile);
toast.success('Picture selected has been saved as profile photo.');
} catch (err) {
console.log(err);
toast.error('Failed to update the profile picture.');
}
};

const addPic = e => {
const newURL = [document.getElementById('newProfilePicURL').value];
setNewPic(newURL);
};

const selectPic = async (pic, id) => {
await props.getUserProfile(props.user._id);
console.log(userProfile)
const selected = [pic].flat();
setSelectedPic(selected);
document.querySelectorAll('.dashboardimg').forEach(element => {
element.style.border = '';
});
document.getElementById(id).style.border = '3px solid red';
};

return (
<Modal isOpen={props.open} toggle={closePopup} autoFocus={false}>
<ModalHeader toggle={closePopup}>Select Your Profile Picture</ModalHeader>
<ModalBody>
<b>Please choose the profile picture:</b>
<div>
{
profilePic ?
<img
src={`${profilePic || '/pfp-default-header.png'}`}
alt=""
style={{ maxWidth: '60px', maxHeight: '60px' }}
className="dashboardimg"
id={'currentProfilePic'}
onClick={e => selectPic(profilePic, 'currentProfilePic')}
/>
:
(Array.isArray(storedPics) && storedPics.length > 0) ?
storedPics.map((pic, index) => (
<img
src={`${pic || '/pfp-default-header.png'}`}
alt=""
style={{ maxWidth: '60px', maxHeight: '60px' }}
className="dashboardimg"
key={`pic_fetched_'+${index}`}
id={`pic_fetched_'+${index}`}
onClick={e => selectPic(pic, `pic_fetched_'+${index}`)}
/>
))
:
null
}
{newPic && (
<img
src={`${newPic || '/pfp-default-header.png'}`}
alt=""
style={{ maxWidth: '60px', maxHeight: '60px' }}
className="dashboardimg"
key={`pic_added`}
id={`pic_added`}
onClick={e => selectPic(newPic, `pic_added`)}
/>
)}
</div>
<p>Cannot find any? Add an image:</p>

<input
type="url"
name="url"
id="newProfilePicURL"
placeholder="https://example.com"
pattern="https://.*"
size="30"
required
/>
<Button color="primary" onClick={addPic} style={boxStyle} id="add_url">
Add
</Button>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={saveChange} style={boxStyle}>
Save
</Button>
<Button color="secondary" onClick={closePopup} style={boxStyle}>
Close
</Button>
</ModalFooter>
</Modal>
);
});

const mapStateToProps = state => state;

export default connect(mapStateToProps, {
getUserProfile,
updateUserProfile,
})(SelectProfilePicPopup);
Loading
Loading