chore(client): remove outdated welcome message (#59218)

This commit is contained in:
Huyen Nguyen
2025-03-22 22:59:04 +07:00
committed by GitHub
parent 88fb02f994
commit e936ddcf6e
8 changed files with 82 additions and 183 deletions

View File

@@ -401,21 +401,7 @@
"welcome-1": "Welcome back, {{name}}.", "welcome-1": "Welcome back, {{name}}.",
"welcome-2": "Welcome to freeCodeCamp.org", "welcome-2": "Welcome to freeCodeCamp.org",
"start-at-beginning": "If you are new to coding, we recommend you <0>start at the beginning</0>.", "start-at-beginning": "If you are new to coding, we recommend you <0>start at the beginning</0>.",
"read-this": { "happy-coding": "Happy coding!",
"heading": "Please slow down and read this.",
"p1": "freeCodeCamp is a proven path to your first software developer job.",
"p2": "More than 40,000 people have gotten developer jobs after completing this including at big companies like Google and Microsoft.",
"p3": "If you are new to programming, we recommend you start at the beginning and earn these certifications in order.",
"p4": "To earn each certification, build its 5 required projects and get all their tests to pass.",
"p5": "You can add these certifications to your résumé or LinkedIn. But more important than the certifications is the practice you get along the way.",
"p6": "If you feel overwhelmed, that is normal. Programming is hard.",
"p7": "Practice is the key. Practice, practice, practice.",
"p8": "And this curriculum will give you thousands of hours of hands-on programming practice.",
"p9": "And if you want to learn more math and computer science theory, we also have thousands of hours of video courses on <0>freeCodeCamp's YouTube channel</0>.",
"p10": "If you want to get a developer job or freelance clients, programming skills will be just part of the puzzle. You also need to build your personal network and your reputation as a developer.",
"p11": "You can do this on LinkedIn and GitHub, and also on <0>the freeCodeCamp forum</0>.",
"p12": "Happy coding!"
},
"upcoming-lessons": "Upcoming Lessons", "upcoming-lessons": "Upcoming Lessons",
"learn": "Learn", "learn": "Learn",
"add-subtitles": "Help improve or add subtitles", "add-subtitles": "Help improve or add subtitles",
@@ -795,7 +781,7 @@
"brand-new-account": "Welcome to your brand new freeCodeCamp account. Let's get started.", "brand-new-account": "Welcome to your brand new freeCodeCamp account. Let's get started.",
"duplicate-account-warning": "If you meant to sign into an existing account instead of creating this account, <0>click here to delete this account</0> and try another email address.", "duplicate-account-warning": "If you meant to sign into an existing account instead of creating this account, <0>click here to delete this account</0> and try another email address.",
"quincy": "- Quincy Larson, the teacher who founded freeCodeCamp.org", "quincy": "- Quincy Larson, the teacher who founded freeCodeCamp.org",
"email-blast": "By the way, each Friday I send an email with 5 links about programming and computer science. I send these to about 6 million people. Would you like me to send this to you, too?", "email-blast": "Each Friday I send an email with 5 links about programming and computer science. I send these to about 6 million people. Would you like me to send this to you, too?",
"update-email-1": "Update your email address", "update-email-1": "Update your email address",
"update-email-2": "Update your email address here:", "update-email-2": "Update your email address here:",
"email": "Email", "email": "Email",

View File

@@ -1,60 +0,0 @@
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { Spacer } from '@freecodecamp/ui';
import envData from '../../../../config/env.json';
import { Link } from '../../helpers';
import '../intro.css';
const { forumLocation } = envData;
function IntroDescription(): JSX.Element {
const { t } = useTranslation();
return (
<div
className='intro-description'
data-playwright-test-label='learn-read-this-section'
>
<Spacer size='m' />
<p
className='text-center'
data-playwright-test-label='learn-read-this-heading'
>
<strong>{t('learn.read-this.heading')}</strong>
</p>
<Spacer size='m' />
{[...Array(8).keys()].map(i => (
<p key={i} data-playwright-test-label='learn-read-this-p'>
{t(`learn.read-this.p${i + 1}`)}
</p>
))}
<p>
<Trans
i18nKey='learn.read-this.p9'
data-playwright-test-label='learn-read-this-p'
>
<Link className='inline' to='https://youtube.com/freecodecamp' />
</Trans>
</p>
<p data-playwright-test-label='learn-read-this-p'>
{t('learn.read-this.p10')}
</p>
<p>
<Trans
i18nKey='learn.read-this.p11'
data-playwright-test-label='learn-read-this-p'
>
<Link className='inline' to={forumLocation} />
</Trans>
</p>
<p data-playwright-test-label='learn-read-this-p'>
{t('learn.read-this.p12')}
</p>
<strong>{t('misc.quincy')}</strong>
</div>
);
}
IntroDescription.displayName = 'IntroDescription';
export default IntroDescription;

View File

@@ -4,7 +4,6 @@ import { Spacer } from '@freecodecamp/ui';
import { randomQuote } from '../../utils/get-words'; import { randomQuote } from '../../utils/get-words';
import Login from '../Header/components/login'; import Login from '../Header/components/login';
import { Link, Loader } from '../helpers'; import { Link, Loader } from '../helpers';
import IntroDescription from './components/intro-description';
import './intro.css'; import './intro.css';
import LearnAlert from './learn-alert'; import LearnAlert from './learn-alert';
@@ -83,16 +82,10 @@ const Intro = ({
return ( return (
<> <>
<Spacer size='m' /> <Spacer size='m' />
<h1 <h1 id='content-start' className='text-center'>
id='content-start'
className='text-center'
data-playwright-test-label='learn-heading'
>
{t('learn.heading')} {t('learn.heading')}
</h1> </h1>
<Spacer size='m' /> <Spacer size='m' />
<IntroDescription />
<Spacer size='m' />
<Login block={true}>{t('buttons.logged-out-cta-btn')}</Login> <Login block={true}>{t('buttons.logged-out-cta-btn')}</Login>
<Spacer size='m' /> <Spacer size='m' />
</> </>

View File

@@ -24,7 +24,6 @@
border: none; border: none;
} }
.intro-description strong,
.intro-description p { .intro-description p {
font-size: 1.17rem; font-size: 1.17rem;
} }
@@ -35,7 +34,6 @@
border: none; border: none;
} }
.intro-description strong,
.intro-description p { .intro-description p {
font-size: 1rem; font-size: 1rem;
} }

View File

@@ -37,7 +37,7 @@ const Faq = (): JSX.Element => {
<Spacer size='xs' /> <Spacer size='xs' />
</div> </div>
))} ))}
<h2 className='landing-page-happy'>{t('learn.read-this.p12')}</h2> <h2 className='landing-page-happy'>{t('learn.happy-coding')}</h2>
<Spacer size='m' /> <Spacer size='m' />
<BigCallToAction /> <BigCallToAction />
<Spacer size='l' /> <Spacer size='l' />

View File

@@ -7,7 +7,6 @@ import type { Dispatch } from 'redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { Container, Col, Row, Button, Spacer } from '@freecodecamp/ui'; import { Container, Col, Row, Button, Spacer } from '@freecodecamp/ui';
import IntroDescription from '../components/Intro/components/intro-description';
import createRedirect from '../components/create-redirect'; import createRedirect from '../components/create-redirect';
import { Loader, Link } from '../components/helpers'; import { Loader, Link } from '../components/helpers';
import { apiLocation } from '../../config/env.json'; import { apiLocation } from '../../config/env.json';
@@ -115,6 +114,7 @@ function AcceptPrivacyTerms({
const { t } = useTranslation(); const { t } = useTranslation();
const acceptedPrivacyRef = useRef(acceptedPrivacyTerms); const acceptedPrivacyRef = useRef(acceptedPrivacyTerms);
const acceptTermsRef = useRef(acceptTerms); const acceptTermsRef = useRef(acceptTerms);
const newAccount = isSignedIn && completedChallengeCount < 1;
useEffect(() => { useEffect(() => {
acceptedPrivacyRef.current = acceptedPrivacyTerms; acceptedPrivacyRef.current = acceptedPrivacyTerms;
@@ -130,29 +130,29 @@ function AcceptPrivacyTerms({
<title>{t('misc.email-signup')} | freeCodeCamp.org</title> <title>{t('misc.email-signup')} | freeCodeCamp.org</title>
</Helmet> </Helmet>
<Container> <Container>
{isSignedIn && completedChallengeCount < 1 ? ( <Row>
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
<Spacer size='l' />
<h1 className='text-center'>
{newAccount
? t('misc.brand-new-account')
: t('misc.email-signup')}
</h1>
<Spacer size='xs' />
</Col>
</Row>
{newAccount && (
<Row> <Row>
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}> <Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
<Spacer size='l' />
<h1 className='text-center'>{t('misc.brand-new-account')}</h1>
<Spacer size='xs' />
<p> <p>
<Trans i18nKey='misc.duplicate-account-warning'> <Trans i18nKey='misc.duplicate-account-warning'>
<Link className='inline' to='/settings#danger-zone' /> <Link className='inline' to='/settings#danger-zone' />
</Trans> </Trans>
</p> </p>
<hr />
</Col> </Col>
</Row> </Row>
) : (
''
)} )}
<Row>
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
<Spacer size='xs' />
<IntroDescription />
<hr />
</Col>
</Row>
<Row className='email-sign-up'> <Row className='email-sign-up'>
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}> <Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
<Spacer size='xs' /> <Spacer size='xs' />

View File

@@ -18,23 +18,6 @@ test.describe('Learn - Unauthenticated user', () => {
}) })
).toBeVisible(); ).toBeVisible();
// Advice for new learners
const learnReadThisSection = page.getByTestId('learn-read-this-section');
await expect(learnReadThisSection).toBeVisible();
const learnReadThisSectionHeading = page.getByTestId(
'learn-read-this-heading'
);
await expect(learnReadThisSectionHeading).toBeVisible();
const learnReadThisSectionParagraphs =
page.getByTestId('learn-read-this-p');
await expect(learnReadThisSectionParagraphs).toHaveCount(10);
for (const paragraph of await learnReadThisSectionParagraphs.all()) {
await expect(paragraph).toBeVisible();
}
await expect( await expect(
page.getByRole('link', { name: 'Sign in to save your progress' }) page.getByRole('link', { name: 'Sign in to save your progress' })
).toBeVisible(); ).toBeVisible();

View File

@@ -7,24 +7,6 @@ import { allowTrailingSlash } from './utils/url';
const apiLocation = process.env.API_LOCATION || 'http://localhost:3000'; const apiLocation = process.env.API_LOCATION || 'http://localhost:3000';
const contents = [
translations.learn['read-this'].heading,
translations.learn['read-this'].p1,
translations.learn['read-this'].p2,
translations.learn['read-this'].p3,
translations.learn['read-this'].p4,
translations.learn['read-this'].p5,
translations.learn['read-this'].p6,
translations.learn['read-this'].p7,
translations.learn['read-this'].p8,
"And if you want to learn more math and computer science theory, we also have thousands of hours of video courses on freeCodeCamp's YouTube channel.",
translations.learn['read-this'].p10,
'You can do this on LinkedIn and GitHub, and also on the freeCodeCamp forum.',
translations.learn['read-this'].p12,
translations.misc.quincy,
translations.misc['email-blast']
];
test.describe('Email sign-up page when user is not signed in', () => { test.describe('Email sign-up page when user is not signed in', () => {
test.use({ storageState: { cookies: [], origins: [] } }); test.use({ storageState: { cookies: [], origins: [] } });
@@ -33,25 +15,20 @@ test.describe('Email sign-up page when user is not signed in', () => {
}); });
test('should display the content correctly', async ({ page }) => { test('should display the content correctly', async ({ page }) => {
for (const content of contents) { await expect(
await expect(page.getByText(content)).toBeVisible(); page.getByRole('heading', {
} level: 1,
name: translations.misc['email-signup']
const youtubeLink = page.getByRole('link', { })
name: "freeCodeCamp's YouTube channel" ).toBeVisible();
}); await expect(
await expect(youtubeLink).toHaveAttribute( page.getByText(translations.misc['email-blast'])
'href', ).toBeVisible();
'https://youtube.com/freecodecamp' await expect(
); page.getByRole('link', {
name: translations.buttons['sign-up-email-list']
const forumLink = page.getByRole('link', { })
name: 'the freeCodeCamp forum' ).toBeVisible();
});
await expect(forumLink).toHaveAttribute(
'href',
'https://forum.freecodecamp.org'
);
}); });
test("should not enable Quincy's weekly newsletter when the user clicks the sign up button", async ({ test("should not enable Quincy's weekly newsletter when the user clicks the sign up button", async ({
@@ -59,9 +36,7 @@ test.describe('Email sign-up page when user is not signed in', () => {
}) => { }) => {
await expect(page).toHaveTitle('Email Sign Up | freeCodeCamp.org'); await expect(page).toHaveTitle('Email Sign Up | freeCodeCamp.org');
await expect( await expect(
page.getByText( page.getByText(translations.misc['email-blast'])
'freeCodeCamp is a proven path to your first software developer job.'
)
).toBeVisible(); ).toBeVisible();
const signupLink = page.getByRole('link', { const signupLink = page.getByRole('link', {
@@ -105,25 +80,16 @@ test.describe('Email sign-up page when user is signed in', () => {
}); });
test('should display the content correctly', async ({ page }) => { test('should display the content correctly', async ({ page }) => {
for (const content of contents) { await expect(page).toHaveTitle('Email Sign Up | freeCodeCamp.org');
await expect(page.getByText(content)).toBeVisible(); await expect(
} page.getByText(translations.misc['email-blast'])
).toBeVisible();
const youtubeLink = page.getByRole('link', { await expect(
name: "freeCodeCamp's YouTube channel" page.getByRole('button', { name: translations.buttons['yes-please'] })
}); ).toBeVisible();
await expect(youtubeLink).toHaveAttribute( await expect(
'href', page.getByRole('button', { name: translations.buttons['no-thanks'] })
'https://youtube.com/freecodecamp' ).toBeVisible();
);
const forumLink = page.getByRole('link', {
name: 'the freeCodeCamp forum'
});
await expect(forumLink).toHaveAttribute(
'href',
'https://forum.freecodecamp.org'
);
}); });
test("should disable Quincy's weekly newsletter if the user clicks No", async ({ test("should disable Quincy's weekly newsletter if the user clicks No", async ({
@@ -131,9 +97,7 @@ test.describe('Email sign-up page when user is signed in', () => {
}) => { }) => {
await expect(page).toHaveTitle('Email Sign Up | freeCodeCamp.org'); await expect(page).toHaveTitle('Email Sign Up | freeCodeCamp.org');
await expect( await expect(
page.getByText( page.getByText(translations.misc['email-blast'])
'freeCodeCamp is a proven path to your first software developer job.'
)
).toBeVisible(); ).toBeVisible();
const noThanksButton = page.getByRole('button', { const noThanksButton = page.getByRole('button', {
@@ -167,9 +131,7 @@ test.describe('Email sign-up page when user is signed in', () => {
}) => { }) => {
await expect(page).toHaveTitle('Email Sign Up | freeCodeCamp.org'); await expect(page).toHaveTitle('Email Sign Up | freeCodeCamp.org');
await expect( await expect(
page.getByText( page.getByText(translations.misc['email-blast'])
'freeCodeCamp is a proven path to your first software developer job.'
)
).toBeVisible(); ).toBeVisible();
const signupButton = page.getByRole('button', { const signupButton = page.getByRole('button', {
@@ -210,3 +172,40 @@ test.describe('Email sign-up page when user is signed in', () => {
).toHaveAttribute('aria-pressed', 'false'); ).toHaveAttribute('aria-pressed', 'false');
}); });
}); });
test.describe('Email sign-up page when the user is new', () => {
test.use({ storageState: 'playwright/.auth/development-user.json' });
test.beforeEach(async ({ page }) => {
// It's necessary to seed with a user that has not accepted the privacy
// terms, otherwise the user will be redirected away from the email sign-up
// page.
execSync(
'node ./tools/scripts/seed/seed-demo-user --set-false acceptedPrivacyTerms'
);
await page.goto('/email-sign-up');
});
test.afterAll(() => {
execSync('node ./tools/scripts/seed/seed-demo-user --certified-user');
});
test('should display the content correctly', async ({ page }) => {
await expect(
page.getByRole('heading', {
level: 1,
name: translations.misc['brand-new-account']
})
).toBeVisible();
await expect(
page.getByText(translations.misc['email-blast'])
).toBeVisible();
await expect(
page.getByRole('button', { name: translations.buttons['yes-please'] })
).toBeVisible();
await expect(
page.getByRole('button', { name: translations.buttons['no-thanks'] })
).toBeVisible();
});
});