feat(client): refactor propTypes to TS types (#42278)

This commit is contained in:
Shaun Hamilton
2021-06-03 12:23:46 +01:00
committed by GitHub
parent 232469fc58
commit 24be225fa4
23 changed files with 415 additions and 171 deletions

View File

@ -2688,6 +2688,12 @@
"safe-buffer": "*" "safe-buffer": "*"
} }
}, },
"@types/redux-actions": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/@types/redux-actions/-/redux-actions-2.6.1.tgz",
"integrity": "sha512-zKgK+ATp3sswXs6sOYo1tk8xdXTy4CTaeeYrVQlClCjeOpag5vzPo0ASWiiBJ7vsiQRAdb3VkuFLnDoBimF67g==",
"dev": true
},
"@types/rimraf": { "@types/rimraf": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.4.tgz",
@ -3982,6 +3988,15 @@
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ=="
}, },
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"bl": { "bl": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@ -7790,6 +7805,12 @@
"typedarray-to-buffer": "^3.1.5" "typedarray-to-buffer": "^3.1.5"
} }
}, },
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"optional": true
},
"filesize": { "filesize": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
@ -12784,6 +12805,12 @@
"resolved": "https://registry.npmjs.org/name-all-modules-plugin/-/name-all-modules-plugin-1.0.1.tgz", "resolved": "https://registry.npmjs.org/name-all-modules-plugin/-/name-all-modules-plugin-1.0.1.tgz",
"integrity": "sha1-Cr+2rYNXGLn7Te8GdOBmV6lUN1w=" "integrity": "sha1-Cr+2rYNXGLn7Te8GdOBmV6lUN1w="
}, },
"nan": {
"version": "2.14.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
"optional": true
},
"nanoid": { "nanoid": {
"version": "3.1.23", "version": "3.1.23",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
@ -19001,7 +19028,11 @@
"version": "1.2.13", "version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"optional": true "optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
}, },
"glob-parent": { "glob-parent": {
"version": "3.1.0", "version": "3.1.0",

View File

@ -126,6 +126,7 @@
"@testing-library/jest-dom": "5.12.0", "@testing-library/jest-dom": "5.12.0",
"@testing-library/react": "11.2.7", "@testing-library/react": "11.2.7",
"@types/react-transition-group": "4.4.1", "@types/react-transition-group": "4.4.1",
"@types/redux-actions": "^2.6.1",
"autoprefixer": "10.2.6", "autoprefixer": "10.2.6",
"babel-plugin-transform-imports": "2.0.0", "babel-plugin-transform-imports": "2.0.0",
"chokidar": "3.5.1", "chokidar": "3.5.1",

View File

@ -33,7 +33,7 @@ import envData from '../../../config/env.json';
import RedirectHome from '../components/RedirectHome'; import RedirectHome from '../components/RedirectHome';
import { Loader, Spacer } from '../components/helpers'; import { Loader, Spacer } from '../components/helpers';
import { isEmpty } from 'lodash-es'; import { isEmpty } from 'lodash-es';
import { User } from '../redux/propTypes'; import { User } from '../redux/prop-types';
const { clientLocale } = envData; const { clientLocale } = envData;

View File

@ -25,7 +25,7 @@ import Portfolio from '../components/settings/Portfolio';
import Honesty from '../components/settings/Honesty'; import Honesty from '../components/settings/Honesty';
import Certification from '../components/settings/Certification'; import Certification from '../components/settings/Certification';
import DangerZone from '../components/settings/DangerZone'; import DangerZone from '../components/settings/DangerZone';
import { User } from '../redux/propTypes'; import { User } from '../redux/prop-types';
const { apiLocation } = envData; const { apiLocation } = envData;

View File

@ -1,7 +1,7 @@
import { createAction, handleActions } from 'redux-actions'; import { createAction, handleActions } from 'redux-actions';
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import { createTypes } from '../../../utils/createTypes'; import { createTypes } from '../../../utils/create-types';
export const ns = 'flash'; export const ns = 'flash';
@ -9,17 +9,22 @@ const initialState = {
message: {} message: {}
}; };
const types = createTypes(['createFlashMessage', 'removeFlashMessage'], ns); export const types = createTypes(
['createFlashMessage', 'removeFlashMessage'],
ns
);
export const sagas = []; export const sagas = [];
export const createFlashMessage = createAction( export const createFlashMessage = createAction(
types.createFlashMessage, types.createFlashMessage,
msg => ({ id: nanoid(), ...msg }) (msg: string[]) => ({ id: nanoid(), ...msg })
); );
export const removeFlashMessage = createAction(types.removeFlashMessage); export const removeFlashMessage = createAction(types.removeFlashMessage);
export const flashMessageSelector = state => state[ns].message; // TODO: Once state is typed, add here, remove disable.
// eslint-disable-next-line
export const flashMessageSelector = (state: any): string => state[ns].message;
export const reducer = handleActions( export const reducer = handleActions(
{ {

View File

@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
import { certificatesByNameSelector } from '../../../redux'; import { certificatesByNameSelector } from '../../../redux';
import { ButtonSpacer, FullWidthRow, Link, Spacer } from '../../helpers'; import { ButtonSpacer, FullWidthRow, Link, Spacer } from '../../helpers';
import './certifications.css'; import './certifications.css';
import { CurrentCertsType } from '../../../redux/propTypes'; import { CurrentCertsType } from '../../../redux/prop-types';
const mapStateToProps = (state, props) => const mapStateToProps = (state, props) =>
createSelector( createSelector(

View File

@ -1,6 +1,6 @@
import { createAction, handleActions } from 'redux-actions'; import { createAction, handleActions } from 'redux-actions';
import { createTypes } from '../../../utils/createTypes'; import { createTypes } from '../../../utils/create-types';
export const ns = 'search'; export const ns = 'search';

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Landing from '../components/landing'; import Landing from '../components/landing';
import { AllChallengeNode } from '../redux/propTypes'; import { AllChallengeNode } from '../redux/prop-types';
const IndexPage = () => { const IndexPage = () => {
return <Landing />; return <Landing />;

View File

@ -16,7 +16,7 @@ import {
isSignedInSelector, isSignedInSelector,
userSelector userSelector
} from '../redux'; } from '../redux';
import { ChallengeNode } from '../redux/propTypes'; import { ChallengeNode } from '../redux/prop-types';
const mapStateToProps = createSelector( const mapStateToProps = createSelector(
userFetchStateSelector, userFetchStateSelector,

View File

@ -2,7 +2,7 @@ import { createAction, handleActions } from 'redux-actions';
import { uniqBy } from 'lodash-es'; import { uniqBy } from 'lodash-es';
import store from 'store'; import store from 'store';
import { createTypes, createAsyncTypes } from '../utils/createTypes'; import { createTypes, createAsyncTypes } from '../utils/create-types';
import { createFetchUserSaga } from './fetch-user-saga'; import { createFetchUserSaga } from './fetch-user-saga';
import { createAcceptTermsSaga } from './accept-terms-saga'; import { createAcceptTermsSaga } from './accept-terms-saga';
import { createAppMountSaga } from './app-mount-saga'; import { createAppMountSaga } from './app-mount-saga';

View File

@ -0,0 +1,335 @@
import PropTypes from 'prop-types';
const FileType = PropTypes.shape({
key: PropTypes.string,
ext: PropTypes.string,
name: PropTypes.string,
contents: PropTypes.string,
head: PropTypes.string,
tail: PropTypes.string
});
export const MarkdownRemark = PropTypes.shape({
html: PropTypes.string,
frontmatter: PropTypes.shape({
title: PropTypes.string,
block: PropTypes.string,
superBlock: PropTypes.string
})
});
export const ChallengeNode = PropTypes.shape({
block: PropTypes.string,
challengeOrder: PropTypes.number,
challengeType: PropTypes.number,
dashedName: PropTypes.string,
description: PropTypes.string,
files: PropTypes.shape({
indexhtml: FileType,
indexjs: FileType
}),
fields: PropTypes.shape({
slug: PropTypes.string,
blockName: PropTypes.string
}),
forumTopicId: PropTypes.number,
guideUrl: PropTypes.string,
head: PropTypes.arrayOf(PropTypes.string),
helpCategory: PropTypes.string,
instructions: PropTypes.string,
isComingSoon: PropTypes.bool,
removeComments: PropTypes.bool,
isLocked: PropTypes.bool,
isPrivate: PropTypes.bool,
order: PropTypes.number,
required: PropTypes.arrayOf(
PropTypes.shape({
link: PropTypes.string,
raw: PropTypes.string,
src: PropTypes.string
})
),
superOrder: PropTypes.number,
superBlock: PropTypes.string,
tail: PropTypes.arrayOf(PropTypes.string),
time: PropTypes.string,
title: PropTypes.string,
translationPending: PropTypes.bool,
videoUrl: PropTypes.string
});
export const AllChallengeNode = PropTypes.shape({
edges: PropTypes.arrayOf(
PropTypes.shape({
node: ChallengeNode
})
)
});
export const AllMarkdownRemark = PropTypes.shape({
edges: PropTypes.arrayOf(
PropTypes.shape({
node: MarkdownRemark
})
)
});
export const User = PropTypes.shape({
about: PropTypes.string,
completedChallenges: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string,
solution: PropTypes.string,
githubLink: PropTypes.string,
challengeType: PropTypes.number,
completedDate: PropTypes.number,
files: PropTypes.array
})
),
email: PropTypes.string,
githubProfile: PropTypes.string,
is2018DataVisCert: PropTypes.bool,
isApisMicroservicesCert: PropTypes.bool,
isBackEndCert: PropTypes.bool,
isDataVisCert: PropTypes.bool,
isEmailVerified: PropTypes.bool,
isFrontEndCert: PropTypes.bool,
isFrontEndLibsCert: PropTypes.bool,
isFullStackCert: PropTypes.bool,
isHonest: PropTypes.bool,
isInfosecQaCert: PropTypes.bool,
isQaCertV7: PropTypes.bool,
isInfosecCertV7: PropTypes.bool,
isJsAlgoDataStructCert: PropTypes.bool,
isRespWebDesignCert: PropTypes.bool,
isSciCompPyCertV7: PropTypes.bool,
isDataAnalysisPyCertV7: PropTypes.bool,
isMachineLearningPyCertV7: PropTypes.bool,
linkedin: PropTypes.string,
location: PropTypes.string,
name: PropTypes.string,
picture: PropTypes.string,
points: PropTypes.number,
portfolio: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
title: PropTypes.string,
url: PropTypes.string,
image: PropTypes.string,
description: PropTypes.string
})
),
sendQuincyEmail: PropTypes.bool,
theme: PropTypes.string,
twitter: PropTypes.string,
username: PropTypes.string,
website: PropTypes.string
});
export const CurrentCertsType = PropTypes.arrayOf(
PropTypes.shape({
show: PropTypes.bool,
title: PropTypes.string,
certSlug: PropTypes.string
})
);
// TYPESCRIPT TYPES
export type CurrentCertType = {
show: boolean;
title: string;
certSlug: string;
};
export type MarkdownRemarkType = {
html: string;
frontmatter: {
title: string;
block: string;
superBlock: string;
};
};
export type ChallengeNodeType = {
block: string;
challengeOrder: number;
challengeType: number;
dashedName: string;
description: string;
challengeFiles: ChallengeFileType[];
fields: {
slug: string;
blockName: string;
};
forumTopicId: number;
guideUrl: string;
head: string[];
helpCategory: string;
instructions: string;
isComingSoon: boolean;
removeComments: boolean;
isLocked: boolean;
isPrivate: boolean;
order: number;
required: [
{
link: string;
raw: string;
src: string;
}
];
superOrder: number;
superBlock: string;
tail: string[];
time: string;
title: string;
translationPending: boolean;
videoUrl: string;
};
export type AllChallengeNodeType = {
edges: [
{
node: ChallengeNodeType;
}
];
};
export type AllMarkdownRemarkType = {
edges: [
{
node: MarkdownRemarkType;
}
];
};
export type ResizePropsType = {
onStopResize: () => void;
onResize: () => void;
};
export type DimensionsType = {
height: number;
width: number;
};
export type TestType = {
text: string;
testString: string;
};
export type UserType = {
about: string;
completedChallenges: CompletedChallenge[];
email: string;
githubProfile: string;
isHonest: boolean;
linkedin: string;
location: string;
name: string;
picture: string;
points: number;
portfolio: PortfolioType;
profileUI: {
isLocked: boolean;
showCerts: boolean;
showName: boolean;
};
sendQuincyEmail: boolean;
theme: string;
twitter: string;
username: string;
website: string;
} & isCertifiedTypes;
export type isCertifiedTypes = {
is2018DataVisCert: boolean;
isApisMicroservicesCert: boolean;
isBackEndCert: boolean;
isDataVisCert: boolean;
isEmailVerified: boolean;
isFrontEndCert: boolean;
isFrontEndLibsCert: boolean;
isFullStackCert: boolean;
isInfosecQaCert: boolean;
isQaCertV7: boolean;
isInfosecCertV7: boolean;
isJsAlgoDataStructCert: boolean;
isRespWebDesignCert: boolean;
isSciCompPyCertV7: boolean;
isDataAnalysisPyCertV7: boolean;
isMachineLearningPyCertV7: boolean;
};
export type CompletedChallenge = {
id: string;
solution: string;
githubLink: string;
challengeType: number;
completedDate: number;
challengeFiles: ChallengeFileType[];
};
// TODO: renames: files => challengeFiles; key => fileKey;
export type ChallengeFileType = {
contents: string;
editableContents?: string;
editableRegionBoundaries?: number[] | null;
error?: string | null;
ext: ExtTypes;
head?: string[];
history?: string[];
fileKey: FileKeyTypes;
name: string;
path: string;
seed?: string;
seedEditableRegionBoundaries?: number[];
tail?: string;
};
export type ExtTypes = 'js' | 'html' | 'css' | 'jsx';
export type FileKeyTypes = 'indexjs' | 'indexhtml' | 'indexcss';
export type PortfolioType = {
id: string;
title?: string;
url?: string;
image?: string;
description?: string;
};
export type ChallengeNode = {
block: string;
challengeOrder: number;
challengeType: number;
dashedName: string;
description: string;
challengeFiles: ChallengeFileType;
fields: {
slug: string;
blockName: string;
};
forumTopicId: number;
guideUrl: string;
head: string[];
helpCategory: string;
instructions: string;
isComingSoon: boolean;
removeComments: boolean;
isLocked: boolean;
isPrivate: boolean;
order: number;
required: [
{
link: string;
raw: string;
src: string;
}
];
superOrder: number;
superBlock: string;
tail: string[];
time: string;
title: string;
translationPending: boolean;
videoUrl?: string;
};

View File

@ -1,135 +0,0 @@
import PropTypes from 'prop-types';
const FileType = PropTypes.shape({
key: PropTypes.string,
ext: PropTypes.string,
name: PropTypes.string,
contents: PropTypes.string,
head: PropTypes.string,
tail: PropTypes.string
});
export const MarkdownRemark = PropTypes.shape({
html: PropTypes.string,
frontmatter: PropTypes.shape({
title: PropTypes.string,
block: PropTypes.string,
superBlock: PropTypes.string
})
});
export const ChallengeNode = PropTypes.shape({
block: PropTypes.string,
challengeOrder: PropTypes.number,
challengeType: PropTypes.number,
dashedName: PropTypes.string,
description: PropTypes.string,
files: PropTypes.shape({
indexhtml: FileType,
indexjs: FileType
}),
fields: PropTypes.shape({
slug: PropTypes.string,
blockName: PropTypes.string
}),
forumTopicId: PropTypes.number,
guideUrl: PropTypes.string,
head: PropTypes.arrayOf(PropTypes.string),
helpCategory: PropTypes.string,
instructions: PropTypes.string,
isComingSoon: PropTypes.bool,
removeComments: PropTypes.bool,
isLocked: PropTypes.bool,
isPrivate: PropTypes.bool,
order: PropTypes.number,
required: PropTypes.arrayOf(
PropTypes.shape({
link: PropTypes.string,
raw: PropTypes.string,
src: PropTypes.string
})
),
superOrder: PropTypes.number,
superBlock: PropTypes.string,
tail: PropTypes.arrayOf(PropTypes.string),
time: PropTypes.string,
title: PropTypes.string,
translationPending: PropTypes.bool,
videoUrl: PropTypes.string
});
export const AllChallengeNode = PropTypes.shape({
edges: PropTypes.arrayOf(
PropTypes.shape({
node: ChallengeNode
})
)
});
export const AllMarkdownRemark = PropTypes.shape({
edges: PropTypes.arrayOf(
PropTypes.shape({
node: MarkdownRemark
})
)
});
export const User = PropTypes.shape({
about: PropTypes.string,
completedChallenges: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string,
solution: PropTypes.string,
githubLink: PropTypes.string,
challengeType: PropTypes.number,
completedDate: PropTypes.number,
files: PropTypes.array
})
),
email: PropTypes.string,
githubProfile: PropTypes.string,
is2018DataVisCert: PropTypes.bool,
isApisMicroservicesCert: PropTypes.bool,
isBackEndCert: PropTypes.bool,
isDataVisCert: PropTypes.bool,
isEmailVerified: PropTypes.bool,
isFrontEndCert: PropTypes.bool,
isFrontEndLibsCert: PropTypes.bool,
isFullStackCert: PropTypes.bool,
isHonest: PropTypes.bool,
isInfosecQaCert: PropTypes.bool,
isQaCertV7: PropTypes.bool,
isInfosecCertV7: PropTypes.bool,
isJsAlgoDataStructCert: PropTypes.bool,
isRespWebDesignCert: PropTypes.bool,
isSciCompPyCertV7: PropTypes.bool,
isDataAnalysisPyCertV7: PropTypes.bool,
isMachineLearningPyCertV7: PropTypes.bool,
linkedin: PropTypes.string,
location: PropTypes.string,
name: PropTypes.string,
picture: PropTypes.string,
points: PropTypes.number,
portfolio: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
title: PropTypes.string,
url: PropTypes.string,
image: PropTypes.string,
description: PropTypes.string
})
),
sendQuincyEmail: PropTypes.bool,
theme: PropTypes.string,
twitter: PropTypes.string,
username: PropTypes.string,
website: PropTypes.string
});
export const CurrentCertsType = PropTypes.arrayOf(
PropTypes.shape({
show: PropTypes.bool,
title: PropTypes.string,
certSlug: PropTypes.string
})
);

View File

@ -1,6 +1,6 @@
import { createAction, handleActions } from 'redux-actions'; import { createAction, handleActions } from 'redux-actions';
import { createTypes, createAsyncTypes } from '../../utils/createTypes'; import { createTypes, createAsyncTypes } from '../../utils/create-types';
import { createDangerZoneSaga } from './danger-zone-saga'; import { createDangerZoneSaga } from './danger-zone-saga';
import { createSettingsSagas } from './settings-sagas'; import { createSettingsSagas } from './settings-sagas';
import { createUpdateMyEmailSaga } from './update-email-saga'; import { createUpdateMyEmailSaga } from './update-email-saga';

View File

@ -23,7 +23,7 @@ import Hotkeys from '../components/Hotkeys';
import { getGuideUrl } from '../utils'; import { getGuideUrl } from '../utils';
import { challengeTypes } from '../../../../utils/challengeTypes'; import { challengeTypes } from '../../../../utils/challengeTypes';
import { ChallengeNode } from '../../../redux/propTypes'; import { ChallengeNode } from '../../../redux/prop-types';
import { import {
createFiles, createFiles,
challengeFilesSelector, challengeFilesSelector,

View File

@ -30,7 +30,7 @@ import HelpModal from '../../components/HelpModal';
import ProjectToolPanel from '../Tool-Panel'; import ProjectToolPanel from '../Tool-Panel';
import SolutionForm from '../SolutionForm'; import SolutionForm from '../SolutionForm';
import Spacer from '../../../../components/helpers/Spacer'; import Spacer from '../../../../components/helpers/Spacer';
import { ChallengeNode } from '../../../../redux/propTypes'; import { ChallengeNode } from '../../../../redux/prop-types';
import { isSignedInSelector } from '../../../../redux'; import { isSignedInSelector } from '../../../../redux';
import Hotkeys from '../../components/Hotkeys'; import Hotkeys from '../../components/Hotkeys';

View File

@ -8,7 +8,7 @@ import Helmet from 'react-helmet';
import { withTranslation } from 'react-i18next'; import { withTranslation } from 'react-i18next';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { ChallengeNode } from '../../../../redux/propTypes'; import { ChallengeNode } from '../../../../redux/prop-types';
import { import {
challengeMounted, challengeMounted,
isChallengeCompletedSelector, isChallengeCompletedSelector,

View File

@ -13,7 +13,7 @@ import { withTranslation } from 'react-i18next';
// Local Utilities // Local Utilities
import PrismFormatted from '../components/PrismFormatted'; import PrismFormatted from '../components/PrismFormatted';
import { ChallengeNode } from '../../../redux/propTypes'; import { ChallengeNode } from '../../../redux/prop-types';
import LearnLayout from '../../../components/layouts/Learn'; import LearnLayout from '../../../components/layouts/Learn';
import ChallengeTitle from '../components/Challenge-Title'; import ChallengeTitle from '../components/Challenge-Title';
import ChallengeDescription from '../components/Challenge-Description'; import ChallengeDescription from '../components/Challenge-Description';

View File

@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next';
import LearnLayout from '../../components/layouts/Learn'; import LearnLayout from '../../components/layouts/Learn';
import FullWidthRow from '../../components/helpers/FullWidthRow'; import FullWidthRow from '../../components/helpers/FullWidthRow';
import ButtonSpacer from '../../components/helpers/ButtonSpacer'; import ButtonSpacer from '../../components/helpers/ButtonSpacer';
import { MarkdownRemark, AllChallengeNode } from '../../redux/propTypes'; import { MarkdownRemark, AllChallengeNode } from '../../redux/prop-types';
import './intro.css'; import './intro.css';

View File

@ -23,7 +23,7 @@ import {
userSelector userSelector
} from '../../redux'; } from '../../redux';
import { resetExpansion, toggleBlock } from './redux'; import { resetExpansion, toggleBlock } from './redux';
import { MarkdownRemark, AllChallengeNode, User } from '../../redux/propTypes'; import { MarkdownRemark, AllChallengeNode, User } from '../../redux/prop-types';
import './intro.css'; import './intro.css';

View File

@ -9,7 +9,7 @@ import CertificationIcon from '../../../assets/icons/CertificationIcon';
import GreenPass from '../../../assets/icons/GreenPass'; import GreenPass from '../../../assets/icons/GreenPass';
import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted'; import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted';
import { certificatesByNameSelector } from '../../../redux'; import { certificatesByNameSelector } from '../../../redux';
import { CurrentCertsType, User } from '../../../redux/propTypes'; import { CurrentCertsType, User } from '../../../redux/prop-types';
import { certMap } from '../../../resources/certAndProjectMap'; import { certMap } from '../../../resources/certAndProjectMap';
import { import {
certSlugTypeMap, certSlugTypeMap,

View File

@ -9,7 +9,7 @@ import IntroInformation from '../../../assets/icons/IntroInformation';
import GreenPass from '../../../assets/icons/GreenPass'; import GreenPass from '../../../assets/icons/GreenPass';
import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted'; import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted';
import { userSelector } from '../../../redux'; import { userSelector } from '../../../redux';
import { User } from '../../../redux/propTypes'; import { User } from '../../../redux/prop-types';
const mapIconStyle = { height: '15px', marginRight: '10px', width: '15px' }; const mapIconStyle = { height: '15px', marginRight: '10px', width: '15px' };
const renderCheckMark = isCompleted => { const renderCheckMark = isCompleted => {

View File

@ -0,0 +1,22 @@
type CreateTypesType = {
[action: string]: string;
};
export function createTypes(
types: string[] = [],
ns = 'annon'
): CreateTypesType {
return types.reduce(
(types, action: string) => ({
...types,
[action]: `${ns}.${action}`
}),
{}
);
}
export const createAsyncTypes = (action: string): string[] => [
`${action}`,
`${action}Complete`,
`${action}Error`
];

View File

@ -1,15 +0,0 @@
export function createTypes(types = [], ns = 'annon') {
return types.reduce(
(types, action) => ({
...types,
[action]: `${ns}.${action}`
}),
{}
);
}
export const createAsyncTypes = action => [
`${action}`,
`${action}Complete`,
`${action}Error`
];