feat(client): migrate layout/default to ts (#43866)
* chore: rename Default.js to default.tsx * chore: refactor default layout to typescript * use TFunction for type Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>
This commit is contained in:
@ -26,7 +26,7 @@ import {
|
|||||||
userByNameSelector,
|
userByNameSelector,
|
||||||
fetchProfileForUser
|
fetchProfileForUser
|
||||||
} from '../redux';
|
} from '../redux';
|
||||||
import { User } from '../redux/prop-types';
|
import { UserFetchState, User } from '../redux/prop-types';
|
||||||
import { certMap } from '../resources/cert-and-project-map';
|
import { certMap } from '../resources/cert-and-project-map';
|
||||||
import certificateMissingMessage from '../utils/certificate-missing-message';
|
import certificateMissingMessage from '../utils/certificate-missing-message';
|
||||||
import reallyWeirdErrorMessage from '../utils/really-weird-error-message';
|
import reallyWeirdErrorMessage from '../utils/really-weird-error-message';
|
||||||
@ -71,9 +71,7 @@ interface ShowCertificationProps {
|
|||||||
}) => void;
|
}) => void;
|
||||||
signedInUserName: string;
|
signedInUserName: string;
|
||||||
user: User;
|
user: User;
|
||||||
userFetchState: {
|
userFetchState: UserFetchState;
|
||||||
complete: boolean;
|
|
||||||
};
|
|
||||||
userFullName: string;
|
userFullName: string;
|
||||||
username: string;
|
username: string;
|
||||||
}
|
}
|
||||||
@ -96,7 +94,7 @@ const mapStateToProps = (state: unknown, props: ShowCertificationProps) => {
|
|||||||
cert: Cert,
|
cert: Cert,
|
||||||
fetchState: ShowCertificationProps['fetchState'],
|
fetchState: ShowCertificationProps['fetchState'],
|
||||||
signedInUserName: string,
|
signedInUserName: string,
|
||||||
userFetchState: ShowCertificationProps['userFetchState'],
|
userFetchState: UserFetchState,
|
||||||
isDonating: boolean,
|
isDonating: boolean,
|
||||||
user
|
user
|
||||||
) => ({
|
) => ({
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
userSelector,
|
userSelector,
|
||||||
reportUser
|
reportUser
|
||||||
} from '../redux';
|
} from '../redux';
|
||||||
|
import { UserFetchState } from '../redux/prop-types';
|
||||||
|
|
||||||
interface ShowUserProps {
|
interface ShowUserProps {
|
||||||
email: string;
|
email: string;
|
||||||
@ -31,11 +32,7 @@ interface ShowUserProps {
|
|||||||
reportDescription: string;
|
reportDescription: string;
|
||||||
}) => void;
|
}) => void;
|
||||||
t: TFunction;
|
t: TFunction;
|
||||||
userFetchState: {
|
userFetchState: UserFetchState;
|
||||||
pending: boolean;
|
|
||||||
complete: boolean;
|
|
||||||
errored: boolean;
|
|
||||||
};
|
|
||||||
username: string;
|
username: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +42,7 @@ const mapStateToProps = createSelector(
|
|||||||
userSelector,
|
userSelector,
|
||||||
(
|
(
|
||||||
isSignedIn,
|
isSignedIn,
|
||||||
userFetchState: ShowUserProps['userFetchState'],
|
userFetchState: UserFetchState,
|
||||||
{ email }: { email: string }
|
{ email }: { email: string }
|
||||||
) => ({
|
) => ({
|
||||||
isSignedIn,
|
isSignedIn,
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import fontawesome from '@fortawesome/fontawesome';
|
import fontawesome from '@fortawesome/fontawesome';
|
||||||
import PropTypes from 'prop-types';
|
import React, { Component, ReactNode } from 'react';
|
||||||
import React, { Component } from 'react';
|
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import { withTranslation } from 'react-i18next';
|
import { TFunction, withTranslation } from 'react-i18next';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators, Dispatch } from 'redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
import latoBoldURL from '../../../static/fonts/lato/Lato-Bold.woff';
|
import latoBoldURL from '../../../static/fonts/lato/Lato-Bold.woff';
|
||||||
@ -23,9 +22,9 @@ import {
|
|||||||
isServerOnlineSelector,
|
isServerOnlineSelector,
|
||||||
userFetchStateSelector,
|
userFetchStateSelector,
|
||||||
userSelector,
|
userSelector,
|
||||||
usernameSelector,
|
|
||||||
executeGA
|
executeGA
|
||||||
} from '../../redux';
|
} from '../../redux';
|
||||||
|
import { UserFetchState, User } from '../../redux/prop-types';
|
||||||
import Flash from '../Flash';
|
import Flash from '../Flash';
|
||||||
import { flashMessageSelector, removeFlashMessage } from '../Flash/redux';
|
import { flashMessageSelector, removeFlashMessage } from '../Flash/redux';
|
||||||
|
|
||||||
@ -38,35 +37,7 @@ import './fonts.css';
|
|||||||
import './global.css';
|
import './global.css';
|
||||||
import './variables.css';
|
import './variables.css';
|
||||||
|
|
||||||
fontawesome.config = {
|
fontawesome.config.autoAddCss = false;
|
||||||
autoAddCss: false
|
|
||||||
};
|
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
children: PropTypes.node.isRequired,
|
|
||||||
executeGA: PropTypes.func,
|
|
||||||
fetchState: PropTypes.shape({ pending: PropTypes.bool }),
|
|
||||||
fetchUser: PropTypes.func.isRequired,
|
|
||||||
flashMessage: PropTypes.shape({
|
|
||||||
id: PropTypes.string,
|
|
||||||
type: PropTypes.string,
|
|
||||||
message: PropTypes.string
|
|
||||||
}),
|
|
||||||
hasMessage: PropTypes.bool,
|
|
||||||
isOnline: PropTypes.bool.isRequired,
|
|
||||||
isServerOnline: PropTypes.bool.isRequired,
|
|
||||||
isSignedIn: PropTypes.bool,
|
|
||||||
onlineStatusChange: PropTypes.func.isRequired,
|
|
||||||
pathname: PropTypes.string.isRequired,
|
|
||||||
removeFlashMessage: PropTypes.func.isRequired,
|
|
||||||
serverStatusChange: PropTypes.func.isRequired,
|
|
||||||
showFooter: PropTypes.bool,
|
|
||||||
signedInUserName: PropTypes.string,
|
|
||||||
t: PropTypes.func.isRequired,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
useTheme: PropTypes.bool,
|
|
||||||
user: PropTypes.object
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = createSelector(
|
const mapStateToProps = createSelector(
|
||||||
isSignedInSelector,
|
isSignedInSelector,
|
||||||
@ -75,8 +46,14 @@ const mapStateToProps = createSelector(
|
|||||||
isServerOnlineSelector,
|
isServerOnlineSelector,
|
||||||
userFetchStateSelector,
|
userFetchStateSelector,
|
||||||
userSelector,
|
userSelector,
|
||||||
usernameSelector,
|
(
|
||||||
(isSignedIn, flashMessage, isOnline, isServerOnline, fetchState, user) => ({
|
isSignedIn,
|
||||||
|
flashMessage,
|
||||||
|
isOnline: boolean,
|
||||||
|
isServerOnline: boolean,
|
||||||
|
fetchState: UserFetchState,
|
||||||
|
user: User
|
||||||
|
) => ({
|
||||||
isSignedIn,
|
isSignedIn,
|
||||||
flashMessage,
|
flashMessage,
|
||||||
hasMessage: !!flashMessage.message,
|
hasMessage: !!flashMessage.message,
|
||||||
@ -88,7 +65,9 @@ const mapStateToProps = createSelector(
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch =>
|
type StateProps = ReturnType<typeof mapStateToProps>;
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch: Dispatch) =>
|
||||||
bindActionCreators(
|
bindActionCreators(
|
||||||
{
|
{
|
||||||
fetchUser,
|
fetchUser,
|
||||||
@ -100,7 +79,19 @@ const mapDispatchToProps = dispatch =>
|
|||||||
dispatch
|
dispatch
|
||||||
);
|
);
|
||||||
|
|
||||||
class DefaultLayout extends Component {
|
type DispatchProps = ReturnType<typeof mapDispatchToProps>;
|
||||||
|
|
||||||
|
interface DefaultLayoutProps extends StateProps, DispatchProps {
|
||||||
|
children: ReactNode;
|
||||||
|
pathname: string;
|
||||||
|
showFooter?: boolean;
|
||||||
|
t: TFunction;
|
||||||
|
useTheme?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DefaultLayout extends Component<DefaultLayoutProps> {
|
||||||
|
static displayName = 'DefaultLayout';
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { isSignedIn, fetchUser, pathname, executeGA } = this.props;
|
const { isSignedIn, fetchUser, pathname, executeGA } = this.props;
|
||||||
if (!isSignedIn) {
|
if (!isSignedIn) {
|
||||||
@ -112,7 +103,7 @@ class DefaultLayout extends Component {
|
|||||||
window.addEventListener('offline', this.updateOnlineStatus);
|
window.addEventListener('offline', this.updateOnlineStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps: DefaultLayoutProps) {
|
||||||
const { pathname, executeGA } = this.props;
|
const { pathname, executeGA } = this.props;
|
||||||
const { pathname: prevPathname } = prevProps;
|
const { pathname: prevPathname } = prevProps;
|
||||||
if (pathname !== prevPathname) {
|
if (pathname !== prevPathname) {
|
||||||
@ -230,9 +221,6 @@ class DefaultLayout extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultLayout.displayName = 'DefaultLayout';
|
|
||||||
DefaultLayout.propTypes = propTypes;
|
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
mapDispatchToProps
|
mapDispatchToProps
|
@ -1,3 +1,3 @@
|
|||||||
export { default as CertificationLayout } from './certification';
|
export { default as CertificationLayout } from './certification';
|
||||||
export { default as DefaultLayout } from './Default';
|
export { default as DefaultLayout } from './default';
|
||||||
export { default as LearnLayout } from './learn';
|
export { default as LearnLayout } from './learn';
|
||||||
|
4
client/src/declarations.d.ts
vendored
4
client/src/declarations.d.ts
vendored
@ -9,6 +9,10 @@ declare module '*.svg' {
|
|||||||
const content: string;
|
const content: string;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
declare module '*.woff' {
|
||||||
|
const url: string;
|
||||||
|
export default url;
|
||||||
|
}
|
||||||
|
|
||||||
declare module '*.png' {
|
declare module '*.png' {
|
||||||
const content: string;
|
const content: string;
|
||||||
|
@ -347,3 +347,10 @@ export type ChallengeFile = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type ChallengeFiles = ChallengeFile[] | null;
|
export type ChallengeFiles = ChallengeFile[] | null;
|
||||||
|
|
||||||
|
export interface UserFetchState {
|
||||||
|
pending: boolean;
|
||||||
|
complete: boolean;
|
||||||
|
errored: boolean;
|
||||||
|
error: string | null;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user