Files
freeCodeCamp/client/src/pages/learn.tsx
Oliver Eyton-Williams 3b560deab6 refactor: stop spreading challenge over the node (#44499)
* refactor: stop spreading challenge over the node

Instead of creating a Gatsby node with id of challenge.id, we create a
single node field that has all the challenge data.

While this makes the GraphQL queries more verbose, it means we're free
to create multiple nodes with the same challenge.id.

* test: update time-line test for new GQL schema

* test: update mocks with new GQL schema
2021-12-14 12:11:20 -06:00

133 lines
2.8 KiB
TypeScript

import { Grid, Row, Col } from '@freecodecamp/react-bootstrap';
import { graphql } from 'gatsby';
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';
import Map from '../components/Map';
import { Spacer } from '../components/helpers';
import LearnLayout from '../components/layouts/learn';
import {
userFetchStateSelector,
isSignedInSelector,
userSelector,
executeGA
} from '../redux';
interface FetchState {
pending: boolean;
complete: boolean;
errored: boolean;
}
interface User {
email: string;
name: string;
username: string;
completedChallengeCount: number;
}
const mapStateToProps = createSelector(
userFetchStateSelector,
isSignedInSelector,
userSelector,
(fetchState: FetchState, isSignedIn: boolean, user: User) => ({
fetchState,
isSignedIn,
user
})
);
interface Slug {
slug: string;
}
interface LearnPageProps {
isSignedIn: boolean;
fetchState: FetchState;
state: Record<string, unknown>;
user: User;
data: {
challengeNode: {
challenge: {
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: {
challenge: {
fields: { slug }
}
}
}
}: 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')} />
<Grid>
<Row>
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
<Intro
complete={complete}
completedChallengeCount={completedChallengeCount}
email={user.email}
isSignedIn={isSignedIn}
name={name}
onAlertClick={onAlertClick}
pending={pending}
slug={slug}
/>
<Map />
<Spacer size={2} />
</Col>
</Row>
</Grid>
</LearnLayout>
);
}
LearnPage.displayName = 'LearnPage';
export default connect(mapStateToProps, mapDispatchToProps)(LearnPage);
export const query = graphql`
query FirstChallenge {
challengeNode(challenge: { order: { eq: 0 }, challengeOrder: { eq: 0 } }) {
challenge {
fields {
slug
}
}
}
}
`;