fix: replace hardgoto with api links
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
5409e1e62e
commit
a7d595f349
@@ -8,8 +8,7 @@ import {
|
|||||||
userByNameSelector,
|
userByNameSelector,
|
||||||
userProfileFetchStateSelector,
|
userProfileFetchStateSelector,
|
||||||
fetchProfileForUser,
|
fetchProfileForUser,
|
||||||
usernameSelector,
|
usernameSelector
|
||||||
hardGoTo as navigate
|
|
||||||
} from '../redux';
|
} from '../redux';
|
||||||
import FourOhFourPage from '../components/FourOhFour';
|
import FourOhFourPage from '../components/FourOhFour';
|
||||||
import Profile from '../components/profile/Profile';
|
import Profile from '../components/profile/Profile';
|
||||||
@@ -19,7 +18,6 @@ const propTypes = {
|
|||||||
fetchProfileForUser: PropTypes.func.isRequired,
|
fetchProfileForUser: PropTypes.func.isRequired,
|
||||||
isSessionUser: PropTypes.bool,
|
isSessionUser: PropTypes.bool,
|
||||||
maybeUser: PropTypes.string,
|
maybeUser: PropTypes.string,
|
||||||
navigate: PropTypes.func.isRequired,
|
|
||||||
requestedUser: PropTypes.shape({
|
requestedUser: PropTypes.shape({
|
||||||
username: PropTypes.string,
|
username: PropTypes.string,
|
||||||
profileUI: PropTypes.object
|
profileUI: PropTypes.object
|
||||||
@@ -45,8 +43,7 @@ const makeMapStateToProps = () => (state, props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
fetchProfileForUser,
|
fetchProfileForUser
|
||||||
navigate
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShowProfileOrFourOhFour extends Component {
|
class ShowProfileOrFourOhFour extends Component {
|
||||||
@@ -62,7 +59,7 @@ class ShowProfileOrFourOhFour extends Component {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { isSessionUser, requestedUser, showLoading, navigate } = this.props;
|
const { isSessionUser, requestedUser, showLoading } = this.props;
|
||||||
if (isEmpty(requestedUser)) {
|
if (isEmpty(requestedUser)) {
|
||||||
if (showLoading) {
|
if (showLoading) {
|
||||||
// We don't know if /:maybeUser is a user or not, we will show
|
// We don't know if /:maybeUser is a user or not, we will show
|
||||||
@@ -77,13 +74,7 @@ class ShowProfileOrFourOhFour extends Component {
|
|||||||
|
|
||||||
// We have a response from the API, and we have some state in the
|
// We have a response from the API, and we have some state in the
|
||||||
// store for /:maybeUser, we now handover rendering to the Profile component
|
// store for /:maybeUser, we now handover rendering to the Profile component
|
||||||
return (
|
return <Profile isSessionUser={isSessionUser} user={requestedUser} />;
|
||||||
<Profile
|
|
||||||
isSessionUser={isSessionUser}
|
|
||||||
navigate={navigate}
|
|
||||||
user={requestedUser}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -113,11 +113,6 @@ const mapDispatchToProps = {
|
|||||||
verifyCert
|
verifyCert
|
||||||
};
|
};
|
||||||
|
|
||||||
const createHandleSignoutClick = navigate => e => {
|
|
||||||
e.preventDefault();
|
|
||||||
return navigate(`${apiLocation}/signout`);
|
|
||||||
};
|
|
||||||
|
|
||||||
export function ShowSettings(props) {
|
export function ShowSettings(props) {
|
||||||
const {
|
const {
|
||||||
createFlashMessage,
|
createFlashMessage,
|
||||||
@@ -194,8 +189,7 @@ export function ShowSettings(props) {
|
|||||||
bsSize='lg'
|
bsSize='lg'
|
||||||
bsStyle='primary'
|
bsStyle='primary'
|
||||||
className='btn-invert'
|
className='btn-invert'
|
||||||
href={'/signout'}
|
href={`${apiLocation}/signout`}
|
||||||
onClick={createHandleSignoutClick(navigate)}
|
|
||||||
>
|
>
|
||||||
Sign me out of freeCodeCamp
|
Sign me out of freeCodeCamp
|
||||||
</Button>
|
</Button>
|
||||||
|
@@ -16,7 +16,6 @@ import Helmet from 'react-helmet';
|
|||||||
import Login from '../components/Header/components/Login';
|
import Login from '../components/Header/components/Login';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
hardGoTo as navigate,
|
|
||||||
isSignedInSelector,
|
isSignedInSelector,
|
||||||
userFetchStateSelector,
|
userFetchStateSelector,
|
||||||
userSelector,
|
userSelector,
|
||||||
@@ -29,7 +28,6 @@ import './showuser.css';
|
|||||||
const propTypes = {
|
const propTypes = {
|
||||||
email: PropTypes.string,
|
email: PropTypes.string,
|
||||||
isSignedIn: PropTypes.bool,
|
isSignedIn: PropTypes.bool,
|
||||||
navigate: PropTypes.func.isRequired,
|
|
||||||
reportUser: PropTypes.func.isRequired,
|
reportUser: PropTypes.func.isRequired,
|
||||||
userFetchState: PropTypes.shape({
|
userFetchState: PropTypes.shape({
|
||||||
pending: PropTypes.bool,
|
pending: PropTypes.bool,
|
||||||
@@ -51,7 +49,6 @@ const mapStateToProps = createSelector(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
navigate,
|
|
||||||
reportUser
|
reportUser
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -11,7 +11,6 @@ import {
|
|||||||
ToggleButton,
|
ToggleButton,
|
||||||
ToggleButtonGroup
|
ToggleButtonGroup
|
||||||
} from '@freecodecamp/react-bootstrap';
|
} from '@freecodecamp/react-bootstrap';
|
||||||
// import { StripeProvider, Elements } from 'react-stripe-elements';
|
|
||||||
import ApplePay from './assets/ApplePay';
|
import ApplePay from './assets/ApplePay';
|
||||||
import GooglePay from './assets/GooglePay';
|
import GooglePay from './assets/GooglePay';
|
||||||
import acceptedCards from './assets/accepted-cards.png';
|
import acceptedCards from './assets/accepted-cards.png';
|
||||||
@@ -24,14 +23,9 @@ import {
|
|||||||
} from '../../../../config/donation-settings';
|
} from '../../../../config/donation-settings';
|
||||||
import { deploymentEnv } from '../../../config/env.json';
|
import { deploymentEnv } from '../../../config/env.json';
|
||||||
import Spacer from '../helpers/Spacer';
|
import Spacer from '../helpers/Spacer';
|
||||||
// import DonateFormChildViewForHOC from './DonateFormChildViewForHOC';
|
|
||||||
import PaypalButton from './PaypalButton';
|
import PaypalButton from './PaypalButton';
|
||||||
import DonateCompletion from './DonateCompletion';
|
import DonateCompletion from './DonateCompletion';
|
||||||
import {
|
import { isSignedInSelector, signInLoadingSelector } from '../../redux';
|
||||||
isSignedInSelector,
|
|
||||||
signInLoadingSelector,
|
|
||||||
hardGoTo as navigate
|
|
||||||
} from '../../redux';
|
|
||||||
|
|
||||||
import './Donation.css';
|
import './Donation.css';
|
||||||
|
|
||||||
@@ -42,7 +36,6 @@ const propTypes = {
|
|||||||
handleProcessing: PropTypes.func,
|
handleProcessing: PropTypes.func,
|
||||||
isDonating: PropTypes.bool,
|
isDonating: PropTypes.bool,
|
||||||
isSignedIn: PropTypes.bool,
|
isSignedIn: PropTypes.bool,
|
||||||
navigate: PropTypes.func.isRequired,
|
|
||||||
showLoading: PropTypes.bool.isRequired,
|
showLoading: PropTypes.bool.isRequired,
|
||||||
stripe: PropTypes.shape({
|
stripe: PropTypes.shape({
|
||||||
createToken: PropTypes.func.isRequired,
|
createToken: PropTypes.func.isRequired,
|
||||||
@@ -58,9 +51,6 @@ const mapStateToProps = createSelector(
|
|||||||
showLoading
|
showLoading
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const mapDispatchToProps = {
|
|
||||||
navigate
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
donationState: {
|
donationState: {
|
||||||
@@ -345,7 +335,4 @@ class DonateForm extends Component {
|
|||||||
DonateForm.displayName = 'DonateForm';
|
DonateForm.displayName = 'DonateForm';
|
||||||
DonateForm.propTypes = propTypes;
|
DonateForm.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps)(DonateForm);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(DonateForm);
|
|
||||||
|
@@ -2,10 +2,9 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { navigate as gatsbyNavigate } from 'gatsby';
|
|
||||||
import { Button } from '@freecodecamp/react-bootstrap';
|
import { Button } from '@freecodecamp/react-bootstrap';
|
||||||
|
|
||||||
import { hardGoTo as navigate, isSignedInSelector } from '../../../redux';
|
import { isSignedInSelector } from '../../../redux';
|
||||||
import { apiLocation } from '../../../../config/env.json';
|
import { apiLocation } from '../../../../config/env.json';
|
||||||
|
|
||||||
import { gtagReportConversion } from '../../../analytics/gtag';
|
import { gtagReportConversion } from '../../../analytics/gtag';
|
||||||
@@ -18,27 +17,16 @@ const mapStateToProps = createSelector(
|
|||||||
isSignedIn
|
isSignedIn
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const mapDispatchToProps = {
|
|
||||||
navigate
|
|
||||||
};
|
|
||||||
|
|
||||||
const createOnClick = (navigate, isSignedIn) => e => {
|
|
||||||
e.preventDefault();
|
|
||||||
gtagReportConversion();
|
|
||||||
if (isSignedIn) {
|
|
||||||
return gatsbyNavigate('/learn');
|
|
||||||
}
|
|
||||||
return navigate(`${apiLocation}/signin`);
|
|
||||||
};
|
|
||||||
|
|
||||||
function Login(props) {
|
function Login(props) {
|
||||||
const { children, navigate, isSignedIn, ...restProps } = props;
|
const { children, isSignedIn, ...restProps } = props;
|
||||||
|
const href = isSignedIn ? '/learn' : `${apiLocation}/signin`;
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
bsStyle='default'
|
bsStyle='default'
|
||||||
className={(restProps.block ? 'btn-cta-big' : '') + ' signup-btn btn-cta'}
|
className={(restProps.block ? 'btn-cta-big' : '') + ' signup-btn btn-cta'}
|
||||||
href='/signin'
|
href={href}
|
||||||
onClick={createOnClick(navigate, isSignedIn)}
|
onClick={() => gtagReportConversion()}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{children || 'Sign In'}
|
{children || 'Sign In'}
|
||||||
@@ -49,11 +37,7 @@ function Login(props) {
|
|||||||
Login.displayName = 'Login';
|
Login.displayName = 'Login';
|
||||||
Login.propTypes = {
|
Login.propTypes = {
|
||||||
children: PropTypes.any,
|
children: PropTypes.any,
|
||||||
isSignedIn: PropTypes.bool,
|
isSignedIn: PropTypes.bool
|
||||||
navigate: PropTypes.func.isRequired
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps)(Login);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(Login);
|
|
||||||
|
@@ -1,30 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { apiLocation } from '../../../config/env.json';
|
import { apiLocation } from '../../../config/env.json';
|
||||||
|
|
||||||
import { hardGoTo } from '../../redux';
|
|
||||||
|
|
||||||
const currentChallengeApi = '/challenges/current-challenge';
|
const currentChallengeApi = '/challenges/current-challenge';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
children: PropTypes.any,
|
children: PropTypes.any,
|
||||||
hardGoTo: PropTypes.func.isRequired,
|
|
||||||
isLargeBtn: PropTypes.bool
|
isLargeBtn: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = () => ({});
|
function CurrentChallengeLink({ children, isLargeBtn }) {
|
||||||
const mapDispatchToProps = dispatch =>
|
|
||||||
bindActionCreators({ hardGoTo }, dispatch);
|
|
||||||
|
|
||||||
const createClickHandler = hardGoTo => e => {
|
|
||||||
e.preventDefault();
|
|
||||||
return hardGoTo(`${apiLocation}${currentChallengeApi}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
function CurrentChallengeLink({ children, hardGoTo, isLargeBtn }) {
|
|
||||||
let classNames;
|
let classNames;
|
||||||
if (isLargeBtn) {
|
if (isLargeBtn) {
|
||||||
classNames = 'btn btn-lg btn-primary btn-block';
|
classNames = 'btn btn-lg btn-primary btn-block';
|
||||||
@@ -32,11 +18,7 @@ function CurrentChallengeLink({ children, hardGoTo, isLargeBtn }) {
|
|||||||
classNames = 'btn btn-cta-big btn-primary btn-block';
|
classNames = 'btn btn-cta-big btn-primary btn-block';
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<a
|
<a className={classNames} href={`${apiLocation}${currentChallengeApi}`}>
|
||||||
className={classNames}
|
|
||||||
href={currentChallengeApi}
|
|
||||||
onClick={createClickHandler(hardGoTo)}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
@@ -45,7 +27,4 @@ function CurrentChallengeLink({ children, hardGoTo, isLargeBtn }) {
|
|||||||
CurrentChallengeLink.displayName = 'CurrentChallengeLink';
|
CurrentChallengeLink.displayName = 'CurrentChallengeLink';
|
||||||
CurrentChallengeLink.propTypes = propTypes;
|
CurrentChallengeLink.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default CurrentChallengeLink;
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(CurrentChallengeLink);
|
|
||||||
|
@@ -14,7 +14,6 @@ import { apiLocation } from '../../../config/env.json';
|
|||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
isSessionUser: PropTypes.bool,
|
isSessionUser: PropTypes.bool,
|
||||||
navigate: PropTypes.func.isRequired,
|
|
||||||
user: PropTypes.shape({
|
user: PropTypes.shape({
|
||||||
profileUI: PropTypes.shape({
|
profileUI: PropTypes.shape({
|
||||||
isLocked: PropTypes.bool,
|
isLocked: PropTypes.bool,
|
||||||
@@ -157,17 +156,12 @@ function renderProfile(user) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Profile({ user, isSessionUser, navigate }) {
|
function Profile({ user, isSessionUser }) {
|
||||||
const {
|
const {
|
||||||
profileUI: { isLocked = true },
|
profileUI: { isLocked = true },
|
||||||
username
|
username
|
||||||
} = user;
|
} = user;
|
||||||
|
|
||||||
const createHandleSignoutClick = navigate => e => {
|
|
||||||
e.preventDefault();
|
|
||||||
return navigate(`${apiLocation}/signout`);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
@@ -185,8 +179,7 @@ function Profile({ user, isSessionUser, navigate }) {
|
|||||||
bsSize='lg'
|
bsSize='lg'
|
||||||
bsStyle='primary'
|
bsStyle='primary'
|
||||||
className='btn-invert'
|
className='btn-invert'
|
||||||
href={'/signout'}
|
href={`${apiLocation}/signout`}
|
||||||
onClick={createHandleSignoutClick(navigate)}
|
|
||||||
>
|
>
|
||||||
Sign me out of freeCodeCamp
|
Sign me out of freeCodeCamp
|
||||||
</Button>
|
</Button>
|
||||||
|
@@ -3,14 +3,20 @@
|
|||||||
import '@testing-library/jest-dom/extend-expect';
|
import '@testing-library/jest-dom/extend-expect';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import { createStore } from '../../redux/createStore';
|
||||||
|
|
||||||
import { CertificationSettings } from './Certification';
|
import { CertificationSettings } from './Certification';
|
||||||
|
|
||||||
|
function renderWithRedux(ui) {
|
||||||
|
return render(<Provider store={createStore()}>{ui}</Provider>);
|
||||||
|
}
|
||||||
|
|
||||||
describe('<certification />', () => {
|
describe('<certification />', () => {
|
||||||
// shallow rendering does not render children component
|
// shallow rendering does not render children component
|
||||||
// form buttons are not included in shallow render
|
// form buttons are not included in shallow render
|
||||||
it('Should render show cert button for claimed legacy cert', () => {
|
it('Should render show cert button for claimed legacy cert', () => {
|
||||||
const { container } = render(
|
const { container } = renderWithRedux(
|
||||||
<CertificationSettings {...defaultTestProps} />
|
<CertificationSettings {...defaultTestProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -20,7 +26,7 @@ describe('<certification />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Should link show cert button to the claimed legacy cert', () => {
|
it('Should link show cert button to the claimed legacy cert', () => {
|
||||||
const { container } = render(
|
const { container } = renderWithRedux(
|
||||||
<CertificationSettings {...defaultTestProps} />
|
<CertificationSettings {...defaultTestProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -34,7 +40,7 @@ describe('<certification />', () => {
|
|||||||
|
|
||||||
// full forms with unclaimed certs should should not shallow render button
|
// full forms with unclaimed certs should should not shallow render button
|
||||||
it('Should not render show cert button for unclaimed full form', () => {
|
it('Should not render show cert button for unclaimed full form', () => {
|
||||||
const { container } = render(
|
const { container } = renderWithRedux(
|
||||||
<CertificationSettings {...defaultTestProps} />
|
<CertificationSettings {...defaultTestProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -45,7 +51,7 @@ describe('<certification />', () => {
|
|||||||
|
|
||||||
// empty forms with unclaimed certs should should not shallow render button
|
// empty forms with unclaimed certs should should not shallow render button
|
||||||
it('Should not render show cert button for empty form', () => {
|
it('Should not render show cert button for empty form', () => {
|
||||||
const { container } = render(
|
const { container } = renderWithRedux(
|
||||||
<CertificationSettings {...defaultTestProps} />
|
<CertificationSettings {...defaultTestProps} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -13,8 +13,7 @@ import Intro from '../components/Intro';
|
|||||||
import {
|
import {
|
||||||
userFetchStateSelector,
|
userFetchStateSelector,
|
||||||
isSignedInSelector,
|
isSignedInSelector,
|
||||||
userSelector,
|
userSelector
|
||||||
hardGoTo as navigate
|
|
||||||
} from '../redux';
|
} from '../redux';
|
||||||
import {
|
import {
|
||||||
ChallengeNode,
|
ChallengeNode,
|
||||||
@@ -47,7 +46,6 @@ const propTypes = {
|
|||||||
hash: PropTypes.string,
|
hash: PropTypes.string,
|
||||||
isSignedIn: PropTypes.bool,
|
isSignedIn: PropTypes.bool,
|
||||||
location: PropTypes.object,
|
location: PropTypes.object,
|
||||||
navigate: PropTypes.func.isRequired,
|
|
||||||
state: PropTypes.object,
|
state: PropTypes.object,
|
||||||
user: PropTypes.shape({
|
user: PropTypes.shape({
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
@@ -62,14 +60,10 @@ const hashValueSelector = (state, hash) => {
|
|||||||
else if (hash) return hash.substr(1);
|
else if (hash) return hash.substr(1);
|
||||||
else return null;
|
else return null;
|
||||||
};
|
};
|
||||||
const mapDispatchToProps = {
|
|
||||||
navigate
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LearnPage = ({
|
export const LearnPage = ({
|
||||||
location: { hash = '', state = '' },
|
location: { hash = '', state = '' },
|
||||||
isSignedIn,
|
isSignedIn,
|
||||||
navigate,
|
|
||||||
fetchState: { pending, complete },
|
fetchState: { pending, complete },
|
||||||
user: { name = '', username = '', completedChallengeCount = 0 },
|
user: { name = '', username = '', completedChallengeCount = 0 },
|
||||||
data: {
|
data: {
|
||||||
@@ -90,7 +84,6 @@ export const LearnPage = ({
|
|||||||
completedChallengeCount={completedChallengeCount}
|
completedChallengeCount={completedChallengeCount}
|
||||||
isSignedIn={isSignedIn}
|
isSignedIn={isSignedIn}
|
||||||
name={name}
|
name={name}
|
||||||
navigate={navigate}
|
|
||||||
pending={pending}
|
pending={pending}
|
||||||
slug={slug}
|
slug={slug}
|
||||||
username={username}
|
username={username}
|
||||||
@@ -111,10 +104,7 @@ export const LearnPage = ({
|
|||||||
LearnPage.displayName = 'LearnPage';
|
LearnPage.displayName = 'LearnPage';
|
||||||
LearnPage.propTypes = propTypes;
|
LearnPage.propTypes = propTypes;
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToProps)(LearnPage);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(LearnPage);
|
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query FirstChallenge {
|
query FirstChallenge {
|
||||||
|
Reference in New Issue
Block a user