feat(client): refactor propTypes to TS types (#42278)
This commit is contained in:
33
client/package-lock.json
generated
33
client/package-lock.json
generated
@ -2688,6 +2688,12 @@
|
||||
"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": {
|
||||
"version": "2.0.4",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
@ -7790,6 +7805,12 @@
|
||||
"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": {
|
||||
"version": "6.1.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "3.1.23",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
|
||||
@ -19001,7 +19028,11 @@
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
|
||||
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"bindings": "^1.5.0",
|
||||
"nan": "^2.12.1"
|
||||
}
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "3.1.0",
|
||||
|
@ -126,6 +126,7 @@
|
||||
"@testing-library/jest-dom": "5.12.0",
|
||||
"@testing-library/react": "11.2.7",
|
||||
"@types/react-transition-group": "4.4.1",
|
||||
"@types/redux-actions": "^2.6.1",
|
||||
"autoprefixer": "10.2.6",
|
||||
"babel-plugin-transform-imports": "2.0.0",
|
||||
"chokidar": "3.5.1",
|
||||
|
@ -33,7 +33,7 @@ import envData from '../../../config/env.json';
|
||||
import RedirectHome from '../components/RedirectHome';
|
||||
import { Loader, Spacer } from '../components/helpers';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { User } from '../redux/propTypes';
|
||||
import { User } from '../redux/prop-types';
|
||||
|
||||
const { clientLocale } = envData;
|
||||
|
||||
|
@ -25,7 +25,7 @@ import Portfolio from '../components/settings/Portfolio';
|
||||
import Honesty from '../components/settings/Honesty';
|
||||
import Certification from '../components/settings/Certification';
|
||||
import DangerZone from '../components/settings/DangerZone';
|
||||
import { User } from '../redux/propTypes';
|
||||
import { User } from '../redux/prop-types';
|
||||
|
||||
const { apiLocation } = envData;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { createAction, handleActions } from 'redux-actions';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import { createTypes } from '../../../utils/createTypes';
|
||||
import { createTypes } from '../../../utils/create-types';
|
||||
|
||||
export const ns = 'flash';
|
||||
|
||||
@ -9,17 +9,22 @@ const initialState = {
|
||||
message: {}
|
||||
};
|
||||
|
||||
const types = createTypes(['createFlashMessage', 'removeFlashMessage'], ns);
|
||||
export const types = createTypes(
|
||||
['createFlashMessage', 'removeFlashMessage'],
|
||||
ns
|
||||
);
|
||||
|
||||
export const sagas = [];
|
||||
|
||||
export const createFlashMessage = createAction(
|
||||
types.createFlashMessage,
|
||||
msg => ({ id: nanoid(), ...msg })
|
||||
(msg: string[]) => ({ id: nanoid(), ...msg })
|
||||
);
|
||||
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(
|
||||
{
|
@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { certificatesByNameSelector } from '../../../redux';
|
||||
import { ButtonSpacer, FullWidthRow, Link, Spacer } from '../../helpers';
|
||||
import './certifications.css';
|
||||
import { CurrentCertsType } from '../../../redux/propTypes';
|
||||
import { CurrentCertsType } from '../../../redux/prop-types';
|
||||
|
||||
const mapStateToProps = (state, props) =>
|
||||
createSelector(
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { createAction, handleActions } from 'redux-actions';
|
||||
|
||||
import { createTypes } from '../../../utils/createTypes';
|
||||
import { createTypes } from '../../../utils/create-types';
|
||||
|
||||
export const ns = 'search';
|
||||
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Landing from '../components/landing';
|
||||
import { AllChallengeNode } from '../redux/propTypes';
|
||||
import { AllChallengeNode } from '../redux/prop-types';
|
||||
|
||||
const IndexPage = () => {
|
||||
return <Landing />;
|
||||
|
@ -16,7 +16,7 @@ import {
|
||||
isSignedInSelector,
|
||||
userSelector
|
||||
} from '../redux';
|
||||
import { ChallengeNode } from '../redux/propTypes';
|
||||
import { ChallengeNode } from '../redux/prop-types';
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
userFetchStateSelector,
|
||||
|
@ -2,7 +2,7 @@ import { createAction, handleActions } from 'redux-actions';
|
||||
import { uniqBy } from 'lodash-es';
|
||||
import store from 'store';
|
||||
|
||||
import { createTypes, createAsyncTypes } from '../utils/createTypes';
|
||||
import { createTypes, createAsyncTypes } from '../utils/create-types';
|
||||
import { createFetchUserSaga } from './fetch-user-saga';
|
||||
import { createAcceptTermsSaga } from './accept-terms-saga';
|
||||
import { createAppMountSaga } from './app-mount-saga';
|
||||
|
335
client/src/redux/prop-types.ts
Normal file
335
client/src/redux/prop-types.ts
Normal 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;
|
||||
};
|
@ -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
|
||||
})
|
||||
);
|
@ -1,6 +1,6 @@
|
||||
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 { createSettingsSagas } from './settings-sagas';
|
||||
import { createUpdateMyEmailSaga } from './update-email-saga';
|
||||
|
@ -23,7 +23,7 @@ import Hotkeys from '../components/Hotkeys';
|
||||
|
||||
import { getGuideUrl } from '../utils';
|
||||
import { challengeTypes } from '../../../../utils/challengeTypes';
|
||||
import { ChallengeNode } from '../../../redux/propTypes';
|
||||
import { ChallengeNode } from '../../../redux/prop-types';
|
||||
import {
|
||||
createFiles,
|
||||
challengeFilesSelector,
|
||||
|
@ -30,7 +30,7 @@ import HelpModal from '../../components/HelpModal';
|
||||
import ProjectToolPanel from '../Tool-Panel';
|
||||
import SolutionForm from '../SolutionForm';
|
||||
import Spacer from '../../../../components/helpers/Spacer';
|
||||
import { ChallengeNode } from '../../../../redux/propTypes';
|
||||
import { ChallengeNode } from '../../../../redux/prop-types';
|
||||
import { isSignedInSelector } from '../../../../redux';
|
||||
import Hotkeys from '../../components/Hotkeys';
|
||||
|
||||
|
@ -8,7 +8,7 @@ import Helmet from 'react-helmet';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import { ChallengeNode } from '../../../../redux/propTypes';
|
||||
import { ChallengeNode } from '../../../../redux/prop-types';
|
||||
import {
|
||||
challengeMounted,
|
||||
isChallengeCompletedSelector,
|
||||
|
@ -13,7 +13,7 @@ import { withTranslation } from 'react-i18next';
|
||||
|
||||
// Local Utilities
|
||||
import PrismFormatted from '../components/PrismFormatted';
|
||||
import { ChallengeNode } from '../../../redux/propTypes';
|
||||
import { ChallengeNode } from '../../../redux/prop-types';
|
||||
import LearnLayout from '../../../components/layouts/Learn';
|
||||
import ChallengeTitle from '../components/Challenge-Title';
|
||||
import ChallengeDescription from '../components/Challenge-Description';
|
||||
|
@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import LearnLayout from '../../components/layouts/Learn';
|
||||
import FullWidthRow from '../../components/helpers/FullWidthRow';
|
||||
import ButtonSpacer from '../../components/helpers/ButtonSpacer';
|
||||
import { MarkdownRemark, AllChallengeNode } from '../../redux/propTypes';
|
||||
import { MarkdownRemark, AllChallengeNode } from '../../redux/prop-types';
|
||||
|
||||
import './intro.css';
|
||||
|
||||
|
@ -23,7 +23,7 @@ import {
|
||||
userSelector
|
||||
} 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';
|
||||
|
||||
|
@ -9,7 +9,7 @@ import CertificationIcon from '../../../assets/icons/CertificationIcon';
|
||||
import GreenPass from '../../../assets/icons/GreenPass';
|
||||
import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted';
|
||||
import { certificatesByNameSelector } from '../../../redux';
|
||||
import { CurrentCertsType, User } from '../../../redux/propTypes';
|
||||
import { CurrentCertsType, User } from '../../../redux/prop-types';
|
||||
import { certMap } from '../../../resources/certAndProjectMap';
|
||||
import {
|
||||
certSlugTypeMap,
|
||||
|
@ -9,7 +9,7 @@ import IntroInformation from '../../../assets/icons/IntroInformation';
|
||||
import GreenPass from '../../../assets/icons/GreenPass';
|
||||
import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted';
|
||||
import { userSelector } from '../../../redux';
|
||||
import { User } from '../../../redux/propTypes';
|
||||
import { User } from '../../../redux/prop-types';
|
||||
|
||||
const mapIconStyle = { height: '15px', marginRight: '10px', width: '15px' };
|
||||
const renderCheckMark = isCompleted => {
|
||||
|
22
client/src/utils/create-types.ts
Normal file
22
client/src/utils/create-types.ts
Normal 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`
|
||||
];
|
@ -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`
|
||||
];
|
Reference in New Issue
Block a user