diff --git a/client/i18n/locales/english/translations.json b/client/i18n/locales/english/translations.json
index a4790789e0f..ad7e4c4ca5d 100644
--- a/client/i18n/locales/english/translations.json
+++ b/client/i18n/locales/english/translations.json
@@ -314,6 +314,7 @@
"tweet": "I just earned the {{certTitle}} certification @freeCodeCamp! Check it out here: {{certURL}}",
"avatar": "{{username}}'s avatar",
"joined": "Joined {{date}}",
+ "from": "From {{location}}",
"total-points": "Total Points:",
"points": "{{count}} point on {{date}}",
"points_plural": "{{count}} points on {{date}}",
diff --git a/client/src/components/profile/__snapshots__/profile.test.tsx.snap b/client/src/components/profile/__snapshots__/profile.test.tsx.snap
index 30b8b63fe06..ba99723108a 100644
--- a/client/src/components/profile/__snapshots__/profile.test.tsx.snap
+++ b/client/src/components/profile/__snapshots__/profile.test.tsx.snap
@@ -13,100 +13,149 @@ exports[` renders correctly 1`] = `
class="spacer"
style="padding: 15px 0px;"
/>
-
{
+ const { t } = useTranslation();
+ const {
+ joinDate,
+ location,
+ username,
+ name,
+ about,
+ githubProfile,
+ linkedin,
+ twitter,
+ website,
+ isDonating,
+ yearsTopContributor,
+ picture
+ } = useSelector(userSelector) as User;
+
+ return (
+
+
+
0}
+ picture={picture}
+ />
+
+ @{username}
+ {name && {name}
}
+
+ {about && {about}
}
+
+ {joinDate && (
+
+
+ {parseDate(joinDate, t)}
+
+ )}
+ {location && (
+
+
+ {t('profile.from', { location })}
+
+ )}
+
+
+
+
+ );
+};
+export default Bio;
diff --git a/client/src/components/profile/components/camper.css b/client/src/components/profile/components/camper.css
index 30c7de28358..a6135982554 100644
--- a/client/src/components/profile/components/camper.css
+++ b/client/src/components/profile/components/camper.css
@@ -7,7 +7,6 @@
.avatar-camper {
display: flex;
- justify-content: center;
}
.avatar-camper .avatar {
@@ -29,3 +28,28 @@
width: auto;
margin: 0 0.2em -0.3em 0.2em;
}
+
+.profile-meta-container {
+ display: flex;
+ flex-direction: row;
+ margin-bottom: 2rem;
+ color: var(--quaternary-color);
+}
+
+.profile-meta-container div {
+ margin-inline-end: 12px;
+}
+
+.profile-meta-container svg {
+ margin-inline-end: 4px;
+}
+
+.social-icons-row a {
+ display: inline-block;
+ margin-inline-end: 12px;
+ color: var(--quaternary-color);
+}
+
+.bio-container h2 {
+ color: var(--quaternary-color);
+}
diff --git a/client/src/components/profile/components/camper.tsx b/client/src/components/profile/components/camper.tsx
index 727772759b9..5890ebd6606 100644
--- a/client/src/components/profile/components/camper.tsx
+++ b/client/src/components/profile/components/camper.tsx
@@ -1,15 +1,12 @@
-import { faAward, faCalendar } from '@fortawesome/free-solid-svg-icons';
+import { faAward } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React from 'react';
import { useTranslation } from 'react-i18next';
-import { Col, Row } from '@freecodecamp/ui';
import type { User } from '../../../redux/prop-types';
-import { AvatarRenderer } from '../../helpers';
import Link from '../../helpers/link';
-import SupporterBadge from '../../../assets/icons/supporter-badge';
-import SocialIcons from './social-icons';
-import { formatYears, parseDate } from './utils';
+import { formatYears } from './utils';
import './camper.css';
+import Bio from './bio';
export type CamperProps = Pick<
User,
@@ -27,56 +24,12 @@ export type CamperProps = Pick<
| 'joinDate'
>;
-function Camper({
- name,
- username,
- location,
- picture,
- about,
- yearsTopContributor,
- githubProfile,
- isDonating,
- joinDate,
- linkedin,
- twitter,
- website
-}: CamperProps): JSX.Element {
+function Camper({ yearsTopContributor }: CamperProps): JSX.Element {
const { t } = useTranslation();
return (
-
-
-
- 0}
- picture={picture}
- />
-
-
-
-
-
@{username}
- {name &&
{name}
}
- {location &&
{location}
}
- {isDonating && (
-
-
- {t('profile.supporter')}
-
- )}
- {about &&
{about}
}
- {joinDate && (
-
- {parseDate(joinDate, t)}
-
- )}
+
+
{yearsTopContributor.filter(Boolean).length > 0 && (
diff --git a/client/src/components/profile/components/social-icons.tsx b/client/src/components/profile/components/social-icons.tsx
index e0cd47f8428..d55780c6888 100644
--- a/client/src/components/profile/components/social-icons.tsx
+++ b/client/src/components/profile/components/social-icons.tsx
@@ -86,7 +86,7 @@ function SocialIcons(props: SocialIconsProps): JSX.Element | null {
return (
-
+
{linkedin ? LinkedInIcon(linkedin, username) : null}
{githubProfile ? GitHubIcon(githubProfile, username) : null}
{website ? WebsiteIcon(website, username) : null}
diff --git a/client/src/components/profile/profile.test.tsx b/client/src/components/profile/profile.test.tsx
index ce08042aef7..8dfee898c8a 100644
--- a/client/src/components/profile/profile.test.tsx
+++ b/client/src/components/profile/profile.test.tsx
@@ -1,10 +1,13 @@
import { render, screen } from '@testing-library/react';
import React from 'react';
+import { Provider } from 'react-redux';
+import { createStore } from 'redux';
import { Themes } from '../settings/theme';
-
import Profile from './profile';
jest.mock('../../analytics');
+//workaround to avoid some strange gatsby error:
+window.___loader = { enqueue: () => {}, hovering: () => {} };
const userProps = {
user: {
@@ -77,17 +80,24 @@ const notMyProfileProps = {
isSessionUser: false,
...userProps
};
-
+function reducer() {
+ return {
+ app: { appUsername: 'vasili', user: { vasili: userProps.user } }
+ };
+}
+function renderWithRedux(ui: JSX.Element) {
+ return render({ui});
+}
describe('', () => {
it('renders the report button on another persons profile', () => {
- render();
+ renderWithRedux();
const reportButton: HTMLElement = screen.getByText('buttons.flag-user');
expect(reportButton).toHaveAttribute('href', '/user/string/report-user');
});
it('renders correctly', () => {
- const { container } = render();
+ const { container } = renderWithRedux();
expect(container).toMatchSnapshot();
});