feat: add seasonal learn alert (#44335)

* feat:  add seasonal learn alert

* Update client/src/components/Intro/index.tsx

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>

* Update client/src/pages/learn.tsx

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Ahmad Abdolsaheb
2021-11-30 20:35:35 +03:00
committed by GitHub
parent 5b61c8a56f
commit 513f27e408
6 changed files with 84 additions and 4 deletions

View File

@ -32,6 +32,7 @@
"profile": "Profile",
"news": "News",
"donate": "Donate",
"support-our-nonprofit": "Support our non-profit",
"update-settings": "Update my account settings",
"sign-me-out": "Sign me out of freeCodeCamp",
"flag-user": "Flag This User's Account for Abuse",
@ -290,6 +291,8 @@
},
"help-translate": "We are still translating the following certifications.",
"help-translate-link": "Help us translate.",
"season-greetings": "Season's Greetings to you and your family.",
"if-getting-value": "If you're getting a lot out of freeCodeCamp, now is a great time to donate to support our nonprofit's mission.",
"project-preview-title": "Here's a preview of what you will build"
},
"donate": {

View File

@ -1,5 +1,7 @@
import { Alert } from '@freecodecamp/react-bootstrap';
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { emailToABVariant } from '../../utils/A-B-tester';
import { randomQuote } from '../../utils/get-words';
import Login from '../Header/components/Login';
import { Link, Spacer, Loader, FullWidthRow } from '../helpers';
@ -16,6 +18,8 @@ interface IntroProps {
pending?: boolean;
slug?: string;
username?: string;
email?: string;
onAlertClick?: () => void;
}
const Intro = ({
@ -24,9 +28,16 @@ const Intro = ({
pending,
complete,
completedChallengeCount,
slug
slug,
email,
onAlertClick
}: IntroProps): JSX.Element => {
const { t } = useTranslation();
const buttonVariation = (email: string | undefined): string => {
if (!email || emailToABVariant(email).isAVariant)
return t('buttons.donate');
return t('buttons.support-our-nonprofit');
};
if (pending && !complete) {
return (
<>
@ -78,6 +89,24 @@ const Intro = ({
) : (
''
)}
<Alert bsStyle='info' className='annual-donation-alert'>
<p>
<b>{t('learn.season-greetings')}</b>
</p>
<p>{t('learn.if-getting-value')}</p>
<p className={'text-center'}>
<hr />
<Link
className='btn'
key='donate'
onClick={onAlertClick}
sameTab={false}
to='/donate'
>
{buttonVariation(email)}
</Link>
</p>
</Alert>
</>
);
} else {

View File

@ -8,6 +8,7 @@ interface LinkProps {
sameTab?: boolean;
state?: Record<string, unknown>;
to: string;
onClick?: () => void;
}
const Link = ({

View File

@ -589,6 +589,32 @@ blockquote .small {
overflow-wrap: break-word;
}
.alert .btn {
background-color: #d9edf7;
color: #31708f;
border-color: #31708f;
}
.alert .btn:hover,
.alert .btn:focus {
background-color: #31708f;
color: #d9edf7;
border-color: #31708f;
}
.annual-donation-alert {
background: linear-gradient(
-10deg,
rgba(217, 237, 247, 1) 35%,
rgba(237, 202, 216, 0) 75%,
rgb(255 215 224) 100%
),
radial-gradient(
circle,
rgba(255, 202, 225, 1) 0%,
rgba(218, 234, 252, 1) 100%
);
}
/* gatsby 404 */
#search {
background-color: var(--quaternary-background);

View File

@ -4,6 +4,7 @@ import React from 'react';
import Helmet from 'react-helmet';
import { useTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import { createSelector } from 'reselect';
import Intro from '../components/Intro';
@ -13,7 +14,8 @@ import LearnLayout from '../components/layouts/learn';
import {
userFetchStateSelector,
isSignedInSelector,
userSelector
userSelector,
executeGA
} from '../redux';
interface FetchState {
@ -23,6 +25,7 @@ interface FetchState {
}
interface User {
email: string;
name: string;
username: string;
completedChallengeCount: number;
@ -53,12 +56,18 @@ interface LearnPageProps {
fields: Slug;
};
};
executeGA: (payload: Record<string, unknown>) => void;
}
const mapDispatchToProps = (dispatch: Dispatch) =>
bindActionCreators({ executeGA }, dispatch);
function LearnPage({
isSignedIn,
user,
fetchState: { pending, complete },
user: { name = '', completedChallengeCount = 0 },
executeGA,
data: {
challengeNode: {
fields: { slug }
@ -67,6 +76,16 @@ function LearnPage({
}: LearnPageProps) {
const { t } = useTranslation();
const onAlertClick = () => {
executeGA({
type: 'event',
data: {
category: 'Donation Related',
action: `learn donation alert click`
}
});
};
return (
<LearnLayout>
<Helmet title={t('metaTags:title')} />
@ -76,8 +95,10 @@ function LearnPage({
<Intro
complete={complete}
completedChallengeCount={completedChallengeCount}
email={user.email}
isSignedIn={isSignedIn}
name={name}
onAlertClick={onAlertClick}
pending={pending}
slug={slug}
/>
@ -92,7 +113,7 @@ function LearnPage({
LearnPage.displayName = 'LearnPage';
export default connect(mapStateToProps)(LearnPage);
export default connect(mapStateToProps, mapDispatchToProps)(LearnPage);
export const query = graphql`
query FirstChallenge {

View File

@ -94,7 +94,7 @@ const patreonDefaultPledgeAmount = 500;
const aBTestConfig = {
isTesting: true,
type: 'DistributionTest'
type: 'LearnAlertCTA'
};
module.exports = {