feat(client, api): Add Camper Join Date to Profile (#38408)
This commit is contained in:
		@@ -769,6 +769,7 @@ export default function(User) {
 | 
				
			|||||||
      calendar,
 | 
					      calendar,
 | 
				
			||||||
      completedChallenges,
 | 
					      completedChallenges,
 | 
				
			||||||
      isDonating,
 | 
					      isDonating,
 | 
				
			||||||
 | 
					      joinDate,
 | 
				
			||||||
      location,
 | 
					      location,
 | 
				
			||||||
      name,
 | 
					      name,
 | 
				
			||||||
      points,
 | 
					      points,
 | 
				
			||||||
@@ -813,6 +814,7 @@ export default function(User) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      })(),
 | 
					      })(),
 | 
				
			||||||
      isDonating: showDonation ? isDonating : null,
 | 
					      isDonating: showDonation ? isDonating : null,
 | 
				
			||||||
 | 
					      joinDate: showAbout ? joinDate : '',
 | 
				
			||||||
      location: showLocation ? location : '',
 | 
					      location: showLocation ? location : '',
 | 
				
			||||||
      name: showName ? name : '',
 | 
					      name: showName ? name : '',
 | 
				
			||||||
      points: showPoints ? points : null,
 | 
					      points: showPoints ? points : null,
 | 
				
			||||||
@@ -843,7 +845,8 @@ export default function(User) {
 | 
				
			|||||||
          points: progressTimestamps.length,
 | 
					          points: progressTimestamps.length,
 | 
				
			||||||
          completedChallenges,
 | 
					          completedChallenges,
 | 
				
			||||||
          ...getProgress(progressTimestamps, timezone),
 | 
					          ...getProgress(progressTimestamps, timezone),
 | 
				
			||||||
          ...normaliseUserFields(user)
 | 
					          ...normaliseUserFields(user),
 | 
				
			||||||
 | 
					          joinDate: user.id.getTimestamp()
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const publicUser = prepUserForPublish(allUser, profileUI);
 | 
					        const publicUser = prepUserForPublish(allUser, profileUI);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,6 @@ function createReadSessionUser(app) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return function getSessionUser(req, res, next) {
 | 
					  return function getSessionUser(req, res, next) {
 | 
				
			||||||
    const queryUser = req.user;
 | 
					    const queryUser = req.user;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    const source =
 | 
					    const source =
 | 
				
			||||||
      queryUser &&
 | 
					      queryUser &&
 | 
				
			||||||
      Observable.forkJoin(
 | 
					      Observable.forkJoin(
 | 
				
			||||||
@@ -75,7 +74,8 @@ function createReadSessionUser(app) {
 | 
				
			|||||||
              isLinkedIn: !!user.linkedin,
 | 
					              isLinkedIn: !!user.linkedin,
 | 
				
			||||||
              isTwitter: !!user.twitter,
 | 
					              isTwitter: !!user.twitter,
 | 
				
			||||||
              isWebsite: !!user.website,
 | 
					              isWebsite: !!user.website,
 | 
				
			||||||
              ...normaliseUserFields(user)
 | 
					              ...normaliseUserFields(user),
 | 
				
			||||||
 | 
					              joinDate: user.id.getTimestamp()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          sessionMeta,
 | 
					          sessionMeta,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,7 @@ const propTypes = {
 | 
				
			|||||||
    isLinkedIn: PropTypes.bool,
 | 
					    isLinkedIn: PropTypes.bool,
 | 
				
			||||||
    isTwitter: PropTypes.bool,
 | 
					    isTwitter: PropTypes.bool,
 | 
				
			||||||
    isWebsite: PropTypes.bool,
 | 
					    isWebsite: PropTypes.bool,
 | 
				
			||||||
 | 
					    joinDate: PropTypes.string,
 | 
				
			||||||
    linkedin: PropTypes.string,
 | 
					    linkedin: PropTypes.string,
 | 
				
			||||||
    location: PropTypes.string,
 | 
					    location: PropTypes.string,
 | 
				
			||||||
    name: PropTypes.string,
 | 
					    name: PropTypes.string,
 | 
				
			||||||
@@ -114,6 +115,7 @@ function renderProfile(user) {
 | 
				
			|||||||
    website,
 | 
					    website,
 | 
				
			||||||
    name,
 | 
					    name,
 | 
				
			||||||
    username,
 | 
					    username,
 | 
				
			||||||
 | 
					    joinDate,
 | 
				
			||||||
    location,
 | 
					    location,
 | 
				
			||||||
    points,
 | 
					    points,
 | 
				
			||||||
    picture,
 | 
					    picture,
 | 
				
			||||||
@@ -133,6 +135,7 @@ function renderProfile(user) {
 | 
				
			|||||||
        isLinkedIn={isLinkedIn}
 | 
					        isLinkedIn={isLinkedIn}
 | 
				
			||||||
        isTwitter={isTwitter}
 | 
					        isTwitter={isTwitter}
 | 
				
			||||||
        isWebsite={isWebsite}
 | 
					        isWebsite={isWebsite}
 | 
				
			||||||
 | 
					        joinDate={showAbout ? joinDate : null}
 | 
				
			||||||
        linkedin={linkedin}
 | 
					        linkedin={linkedin}
 | 
				
			||||||
        location={showLocation ? location : null}
 | 
					        location={showLocation ? location : null}
 | 
				
			||||||
        name={showName ? name : null}
 | 
					        name={showName ? name : null}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ const userProps = {
 | 
				
			|||||||
    isLinkedIn: true,
 | 
					    isLinkedIn: true,
 | 
				
			||||||
    isTwitter: true,
 | 
					    isTwitter: true,
 | 
				
			||||||
    isWebsite: true,
 | 
					    isWebsite: true,
 | 
				
			||||||
 | 
					    joinDate: 'string',
 | 
				
			||||||
    linkedin: 'string',
 | 
					    linkedin: 'string',
 | 
				
			||||||
    location: 'string',
 | 
					    location: 'string',
 | 
				
			||||||
    name: 'string',
 | 
					    name: 'string',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,11 @@ import React from 'react';
 | 
				
			|||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import { Col, Row, Image } from '@freecodecamp/react-bootstrap';
 | 
					import { Col, Row, Image } from '@freecodecamp/react-bootstrap';
 | 
				
			||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 | 
					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 Identicon from 'react-identicons';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import SocialIcons from './SocialIcons';
 | 
					import SocialIcons from './SocialIcons';
 | 
				
			||||||
@@ -17,6 +21,7 @@ const propTypes = {
 | 
				
			|||||||
  isLinkedIn: PropTypes.bool,
 | 
					  isLinkedIn: PropTypes.bool,
 | 
				
			||||||
  isTwitter: PropTypes.bool,
 | 
					  isTwitter: PropTypes.bool,
 | 
				
			||||||
  isWebsite: PropTypes.bool,
 | 
					  isWebsite: PropTypes.bool,
 | 
				
			||||||
 | 
					  joinDate: PropTypes.string,
 | 
				
			||||||
  linkedin: PropTypes.string,
 | 
					  linkedin: PropTypes.string,
 | 
				
			||||||
  location: PropTypes.string,
 | 
					  location: PropTypes.string,
 | 
				
			||||||
  name: 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({
 | 
					function Camper({
 | 
				
			||||||
  name,
 | 
					  name,
 | 
				
			||||||
  username,
 | 
					  username,
 | 
				
			||||||
@@ -60,6 +72,7 @@ function Camper({
 | 
				
			|||||||
  isGithub,
 | 
					  isGithub,
 | 
				
			||||||
  isTwitter,
 | 
					  isTwitter,
 | 
				
			||||||
  isWebsite,
 | 
					  isWebsite,
 | 
				
			||||||
 | 
					  joinDate,
 | 
				
			||||||
  linkedin,
 | 
					  linkedin,
 | 
				
			||||||
  twitter,
 | 
					  twitter,
 | 
				
			||||||
  website
 | 
					  website
 | 
				
			||||||
@@ -110,6 +123,11 @@ function Camper({
 | 
				
			|||||||
        </p>
 | 
					        </p>
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
      {about && <p className='bio text-center'>{about}</p>}
 | 
					      {about && <p className='bio text-center'>{about}</p>}
 | 
				
			||||||
 | 
					      {joinDate && (
 | 
				
			||||||
 | 
					        <p className='bio text-center'>
 | 
				
			||||||
 | 
					          <FontAwesomeIcon icon={faCalendar} /> {parseDate(joinDate)}
 | 
				
			||||||
 | 
					        </p>
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
      {yearsTopContributor.filter(Boolean).length > 0 && (
 | 
					      {yearsTopContributor.filter(Boolean).length > 0 && (
 | 
				
			||||||
        <div>
 | 
					        <div>
 | 
				
			||||||
          <br />
 | 
					          <br />
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user