diff --git a/api-server/common/models/user.js b/api-server/common/models/user.js index 543a17bceb..9a4fd059f6 100644 --- a/api-server/common/models/user.js +++ b/api-server/common/models/user.js @@ -769,6 +769,7 @@ export default function(User) { calendar, completedChallenges, isDonating, + joinDate, location, name, points, @@ -813,6 +814,7 @@ export default function(User) { } })(), isDonating: showDonation ? isDonating : null, + joinDate: showAbout ? joinDate : '', location: showLocation ? location : '', name: showName ? name : '', points: showPoints ? points : null, @@ -843,7 +845,8 @@ export default function(User) { points: progressTimestamps.length, completedChallenges, ...getProgress(progressTimestamps, timezone), - ...normaliseUserFields(user) + ...normaliseUserFields(user), + joinDate: user.id.getTimestamp() }; const publicUser = prepUserForPublish(allUser, profileUI); diff --git a/api-server/server/boot/user.js b/api-server/server/boot/user.js index 1266f95bbd..4d9d40da11 100644 --- a/api-server/server/boot/user.js +++ b/api-server/server/boot/user.js @@ -39,7 +39,6 @@ function createReadSessionUser(app) { return function getSessionUser(req, res, next) { const queryUser = req.user; - const source = queryUser && Observable.forkJoin( @@ -75,7 +74,8 @@ function createReadSessionUser(app) { isLinkedIn: !!user.linkedin, isTwitter: !!user.twitter, isWebsite: !!user.website, - ...normaliseUserFields(user) + ...normaliseUserFields(user), + joinDate: user.id.getTimestamp() } }, sessionMeta, diff --git a/client/src/components/profile/Profile.js b/client/src/components/profile/Profile.js index 6f366a5a7d..680357b69d 100644 --- a/client/src/components/profile/Profile.js +++ b/client/src/components/profile/Profile.js @@ -37,6 +37,7 @@ const propTypes = { isLinkedIn: PropTypes.bool, isTwitter: PropTypes.bool, isWebsite: PropTypes.bool, + joinDate: PropTypes.string, linkedin: PropTypes.string, location: PropTypes.string, name: PropTypes.string, @@ -114,6 +115,7 @@ function renderProfile(user) { website, name, username, + joinDate, location, points, picture, @@ -133,6 +135,7 @@ function renderProfile(user) { isLinkedIn={isLinkedIn} isTwitter={isTwitter} isWebsite={isWebsite} + joinDate={showAbout ? joinDate : null} linkedin={linkedin} location={showLocation ? location : null} name={showName ? name : null} diff --git a/client/src/components/profile/Profile.test.js b/client/src/components/profile/Profile.test.js index 7d2a11160a..a2e41fa058 100644 --- a/client/src/components/profile/Profile.test.js +++ b/client/src/components/profile/Profile.test.js @@ -32,6 +32,7 @@ const userProps = { isLinkedIn: true, isTwitter: true, isWebsite: true, + joinDate: 'string', linkedin: 'string', location: 'string', name: 'string', diff --git a/client/src/components/profile/components/Camper.js b/client/src/components/profile/components/Camper.js index a2d1cff4be..d2a9bac728 100644 --- a/client/src/components/profile/components/Camper.js +++ b/client/src/components/profile/components/Camper.js @@ -2,7 +2,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Col, Row, Image } from '@freecodecamp/react-bootstrap'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faAward, faHeart } from '@fortawesome/free-solid-svg-icons'; +import { + faAward, + faHeart, + faCalendar +} from '@fortawesome/free-solid-svg-icons'; import Identicon from 'react-identicons'; import SocialIcons from './SocialIcons'; @@ -17,6 +21,7 @@ const propTypes = { isLinkedIn: PropTypes.bool, isTwitter: PropTypes.bool, isWebsite: PropTypes.bool, + joinDate: PropTypes.string, linkedin: PropTypes.string, location: PropTypes.string, name: PropTypes.string, @@ -46,6 +51,13 @@ function joinArray(array) { }); } +function parseDate(joinDate) { + joinDate = new Date(joinDate); + const year = joinDate.getFullYear(); + const month = joinDate.toLocaleString('en-US', { month: 'long' }); + return `Joined ${month} ${year}`; +} + function Camper({ name, username, @@ -60,6 +72,7 @@ function Camper({ isGithub, isTwitter, isWebsite, + joinDate, linkedin, twitter, website @@ -110,6 +123,11 @@ function Camper({

)} {about &&

{about}

} + {joinDate && ( +

+ {parseDate(joinDate)} +

+ )} {yearsTopContributor.filter(Boolean).length > 0 && (