diff --git a/jam-ui/cypress/fixtures/person.json b/jam-ui/cypress/fixtures/person.json index 22a75e5f2..ba47106e2 100644 --- a/jam-ui/cypress/fixtures/person.json +++ b/jam-ui/cypress/fixtures/person.json @@ -18,7 +18,7 @@ "following_count": 0, "recording_count": 0, "session_count": 0, - "biography": "Biography of Test User1", + "biography": "Biography of Test User1. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "favorite_count": 0, "audio_latency": null, "upcoming_session_count": 0, diff --git a/jam-ui/cypress/integration/friends/friends-page.spec.js b/jam-ui/cypress/integration/friends/friends-page.spec.js index f31d069f9..2d4fb8bd8 100644 --- a/jam-ui/cypress/integration/friends/friends-page.spec.js +++ b/jam-ui/cypress/integration/friends/friends-page.spec.js @@ -112,12 +112,18 @@ describe('Friends page with data', () => { cy.intercept('POST', /\S+\/friend_requests/, { statusCode: 201, body: { ok: true } }); cy.visit('/friends'); - cy.contains('Test User1').click(); + cy.contains('Test User2').click(); cy.get('[data-testid=profileSidePanel]') .find('[data-testid=connect]') .should('not.be.disabled') .click(); + cy.get('[data-testid=confirmFriendRequestModal]') + .within(() => { + cy.contains('Send a friend request to Test User2') + cy.contains('Yes').click() + }) + cy.get('[data-testid=profileSidePanel]') .find('[data-testid=connect]') .should('be.disabled'); diff --git a/jam-ui/src/components/page/JKPerson.js b/jam-ui/src/components/page/JKPerson.js index eb05ce111..8a6b4e74c 100644 --- a/jam-ui/src/components/page/JKPerson.js +++ b/jam-ui/src/components/page/JKPerson.js @@ -2,47 +2,38 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { Row, Col } from 'reactstrap'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -//import avatar from '../../assets/img/team/avatar.png'; +import { useAuth } from '../../context/AuthContext'; +import { truncate } from '../../helpers/utils'; +import { fetchPerson } from '../../store/features/peopleSlice' +import { useDispatch, useSelector } from 'react-redux' + import JKProfileSidePanel from '../profile/JKProfileSidePanel'; import JKProfileAvatar from '../profile/JKProfileAvatar'; import JKProfileInstrumentsList from '../profile/JKProfileInstrumentsList'; -import { getPersonById } from '../../helpers/rest'; import JKConnectButton from '../profile/JKConnectButton'; import JKMessageButton from '../profile/JKMessageButton'; import JKLatencyBadge from '../profile/JKLatencyBadge'; import JKLastActiveAgo from '../profile/JKLastActiveAgo'; -import { useAuth } from '../../context/AuthContext'; -import { truncate } from '../../helpers/utils'; const JKPerson = props => { const { id, name, biography, photo_url, instruments, latency_data, last_active_timestamp } = props.person; const viewMode = props.viewMode; const { currentUser } = useAuth(); - const [showSidePanel, setShowSidePanel] = useState(false); - const [user, setUser] = useState(null); + const dispatch = useDispatch() + const user = useSelector(state => state.people.people.find(p => p.id === id)) - const fetchPerson = async () => { - //console.log("fetchPerson called"); - await getPersonById(id) - .then(response => { - if (response.ok) { - return response.json(); - } else { - } - }) - .then(json => { - console.log('USER', json); - setUser(json); - }) - .catch(error => console.log(error)); - }; - - const toggleMoreDetails = e => { + const toggleMoreDetails = async (e) => { e.preventDefault(); - fetchPerson(); + try { + await dispatch(fetchPerson({userId: id})).unwrap() + } catch (error) { + console.log(error); + } + setShowSidePanel(prev => !prev); }; + return ( <> {viewMode === 'list' ? ( diff --git a/jam-ui/src/components/profile/JKConnectButton.js b/jam-ui/src/components/profile/JKConnectButton.js index 6d780e6b3..e73cd8e46 100644 --- a/jam-ui/src/components/profile/JKConnectButton.js +++ b/jam-ui/src/components/profile/JKConnectButton.js @@ -1,43 +1,54 @@ -import React, {useEffect, useState} from 'react'; -import {addFriend as connect, removeFriend as disconnect} from '../../helpers/rest'; +import React, { useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; +import { addFriend as connect, removeFriend as disconnect } from '../../helpers/rest'; import { toast } from 'react-toastify'; +import { Modal, ModalBody, ModalHeader, ModalFooter, Button } from 'reactstrap'; -const JKConnectButton = (props) => { - const { user, currentUser, addContent, removeContent, cssClasses } = props - const [isFriend, setIsFriend] = useState(false) - const [pendingFriendRequest, setPendingFriendRequest] = useState(false) +const JKConnectButton = props => { + const { user, currentUser, addContent, removeContent, cssClasses } = props; + const [isFriend, setIsFriend] = useState(false); + const [pendingFriendRequest, setPendingFriendRequest] = useState(false); + const [showConfirmModal, setShowConfirmModal] = useState(false); useEffect(() => { setIsFriend(user.is_friend); - setPendingFriendRequest(user.pending_friend_request) - }, [user]) + setPendingFriendRequest(user.pending_friend_request); + }, [user]); const addFriend = () => { - setPendingFriendRequest(true) - connect(currentUser.id, user.id) - .then(resp => { - if(resp.ok && resp.status === 201){ - toast.success('Friend request was sent successfully') - } - }) - .catch(err => { - toast.error('An error encountered when sending friend request') - setPendingFriendRequest(false) - }) - } + setShowConfirmModal(!showConfirmModal); + setPendingFriendRequest(true); + connect( + currentUser.id, + user.id + ) + .then(resp => { + if (resp.ok && resp.status === 201) { + toast.success('Friend request was sent successfully'); + } + }) + .catch(err => { + toast.error('An error encountered when sending friend request'); + setPendingFriendRequest(false); + }); + }; + + const confirm = () => { + setShowConfirmModal(!showConfirmModal); + }; const removeFriend = () => { disconnect(currentUser.id, user.id) - .then(resp => { - if(resp.ok){ - setIsFriend(false) - setPendingFriendRequest(false) - } - }) - .catch(err => { - toast.error('An error encountered when removing friend') - }) - } + .then(resp => { + if (resp.ok) { + setIsFriend(false); + setPendingFriendRequest(false); + } + }) + .catch(err => { + toast.error('An error encountered when removing friend'); + }); + }; const buttonTitle = () => { let title; @@ -53,18 +64,72 @@ const JKConnectButton = (props) => { return ( <> - { !isFriend ? ( - ) - : ( - - ) - } + + + ) : ( + + )} ); }; +JKConnectButton.propTypes = { + user: PropTypes.object.isRequired, + currentUser: PropTypes.object.isRequired, + addContent: PropTypes.element.isRequired, + removeContent: PropTypes.element.isRequired +}; + +const ConnectConfirmModal = props => { + const { className, show, setShow, user, handleOnConfirm } = props; + + //const [modal, setModal] = useState(show); + + const toggle = () => setShow(!show); + + const accept = () => { + handleOnConfirm(); + }; + + return ( + + + Send Friend Request + Send a friend request to {user.name}. + + {' '} + + + + + ); +}; + export default JKConnectButton; diff --git a/jam-ui/src/components/profile/JKProfileSkillLevel.js b/jam-ui/src/components/profile/JKProfileSkillLevel.js index 9937f26b3..128bf54c1 100644 --- a/jam-ui/src/components/profile/JKProfileSkillLevel.js +++ b/jam-ui/src/components/profile/JKProfileSkillLevel.js @@ -8,7 +8,7 @@ function JKProfileSkillLevel({skillLevel}) { return ( { - skillLevel ? SKILL_LEVEL_MAP[skillLevel] : 'Not specified' + skillLevel in SKILL_LEVEL_MAP ? SKILL_LEVEL_MAP[skillLevel] : 'Not specified' } ) diff --git a/jam-ui/src/store/features/peopleSlice.js b/jam-ui/src/store/features/peopleSlice.js index 073907405..ef00e1b81 100644 --- a/jam-ui/src/store/features/peopleSlice.js +++ b/jam-ui/src/store/features/peopleSlice.js @@ -23,13 +23,15 @@ export const fetchPerson = createAsyncThunk( const {userId} = options const response = await getPersonById(userId) return response.json() - },{ + } + ,{ condition: (options, {getState, extra}) => { const {people} = getState() const {userId} = options const person = people.people.find(person => person.id === userId) console.log('fetchPerson Condition', person); - if(person){ + if(person && person.website){ + //only proceed if full data set for user has not been fetched. person.website is not included in the initial data fetching (i.e: in friends listing ). return false; } }