├── .gitignore ├── Chapter05 ├── scripts │ └── start.js ├── app │ ├── containers │ │ ├── User │ │ │ ├── style.css │ │ │ ├── Loadable.js │ │ │ └── index.js │ │ ├── AboutPage │ │ │ ├── Loadable.js │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ ├── index-test.js.snap │ │ │ │ │ └── redirect-test.js.snap │ │ │ │ ├── index-test.js │ │ │ │ └── redirect-test.js │ │ │ ├── index.js │ │ │ └── redirect.js │ │ ├── HomePage │ │ │ ├── Loadable.js │ │ │ ├── __tests__ │ │ │ │ ├── index-test.js │ │ │ │ └── __snapshots__ │ │ │ │ │ └── index-test.js.snap │ │ │ └── index.js │ │ ├── Login │ │ │ ├── Loadable.js │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── index-test.js.snap │ │ │ │ └── index-test.js │ │ │ ├── style.css │ │ │ ├── constants.js │ │ │ ├── actions.js │ │ │ └── index.js │ │ ├── Register │ │ │ ├── Loadable.js │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── index-test.js.snap │ │ │ │ └── index-test.js │ │ │ ├── constants.js │ │ │ ├── style.css │ │ │ ├── actions.js │ │ │ └── index.js │ │ ├── ContactPage │ │ │ ├── Loadable.js │ │ │ └── index.js │ │ ├── NotFoundPage │ │ │ ├── Loadable.js │ │ │ └── index.js │ │ └── App │ │ │ └── reducer.js │ ├── images │ │ ├── favicon.ico │ │ └── icon-512x512.png │ ├── components │ │ ├── Header │ │ │ ├── logo.png │ │ │ ├── bgheader.png │ │ │ ├── A.js │ │ │ ├── HeaderBg.js │ │ │ ├── tests │ │ │ │ ├── __snapshots__ │ │ │ │ │ ├── A.test.js.snap │ │ │ │ │ └── Img.test.js.snap │ │ │ │ └── index.test.js │ │ │ ├── Logo.js │ │ │ ├── NavBar.js │ │ │ ├── HeaderLink.js │ │ │ └── index.js │ │ ├── H1 │ │ │ ├── index.js │ │ │ └── tests │ │ │ │ └── index.test.js │ │ ├── LoadingIndicator │ │ │ ├── Wrapper.js │ │ │ └── index.js │ │ ├── Footer │ │ │ ├── Wrapper.js │ │ │ └── index.js │ │ ├── A │ │ │ └── index.js │ │ └── Img │ │ │ └── index.js │ ├── utils │ │ ├── history.js │ │ └── checkStore.js │ ├── reducers.js │ ├── configureStore.js │ ├── global-styles.js │ └── app.js ├── testing │ ├── test-bundler.js │ ├── mocks │ │ ├── image.js │ │ └── cssModule.js │ └── enzyme-setup.js ├── server │ ├── argv.js │ ├── port.js │ ├── middlewares │ │ └── frontendMiddleware.js │ └── index.js ├── .prettierrc ├── .gitignore ├── .editorconfig ├── readme.MD ├── jest.config.js └── babel.config.js ├── starter ├── scripts │ └── start.js ├── app │ ├── containers │ │ ├── HomePage │ │ │ ├── Loadable.js │ │ │ └── index.js │ │ ├── NotFoundPage │ │ │ ├── Loadable.js │ │ │ └── index.js │ │ └── App │ │ │ ├── selectors.js │ │ │ ├── index.js │ │ │ └── constants.js │ ├── utils │ │ ├── history.js │ │ ├── constants.js │ │ └── checkStore.js │ ├── reducers.js │ └── configureStore.js ├── .editorconfig ├── .gitignore └── babel.config.js ├── Chapter06 ├── .nvmrc ├── testing │ ├── mocks │ │ ├── image.js │ │ └── cssModule.js │ ├── test-bundler.js │ └── enzyme-setup.js ├── nodemon.json ├── server │ ├── argv.js │ ├── port.js │ ├── helpers │ │ ├── prototype.js │ │ └── jwt.js │ ├── middlewares │ │ ├── frontendMiddleware.js │ │ └── addProdMiddlewares.js │ └── models │ │ ├── questions.js │ │ ├── organizations.js │ │ └── index.js ├── .prettierignore ├── app │ ├── containers │ │ ├── App │ │ │ ├── constants.js │ │ │ ├── actions.js │ │ │ ├── tests │ │ │ │ ├── actions.test.js │ │ │ │ └── reducer.test.js │ │ │ ├── style.css │ │ │ ├── saga.js │ │ │ ├── selectors.js │ │ │ └── reducer.js │ │ ├── LanguageProvider │ │ │ ├── constants.js │ │ │ ├── actions.js │ │ │ ├── selectors.js │ │ │ ├── tests │ │ │ │ ├── selectors.test.js │ │ │ │ ├── actions.test.js │ │ │ │ └── reducer.test.js │ │ │ └── reducer.js │ │ ├── LocaleToggle │ │ │ ├── Wrapper.js │ │ │ └── messages.js │ │ ├── Doctor │ │ │ ├── style.css │ │ │ ├── Loadable.js │ │ │ ├── constants.js │ │ │ ├── messages.js │ │ │ ├── actions.js │ │ │ ├── selectors.js │ │ │ └── reducer.js │ │ ├── Home │ │ │ ├── Loadable.js │ │ │ └── index.js │ │ ├── Register │ │ │ ├── constants.js │ │ │ ├── Loadable.js │ │ │ ├── style.css │ │ │ └── actions.js │ │ ├── User │ │ │ ├── Loadable.js │ │ │ ├── style.css │ │ │ └── index.js │ │ ├── Login │ │ │ ├── Loadable.js │ │ │ ├── style.css │ │ │ ├── constants.js │ │ │ ├── actions.js │ │ │ └── messages.js │ │ └── NotFoundPage │ │ │ ├── Loadable.js │ │ │ ├── messages.js │ │ │ ├── index.js │ │ │ └── tests │ │ │ └── index.test.js │ ├── images │ │ ├── favicon.ico │ │ └── icon-512x512.png │ ├── assets │ │ └── images │ │ │ └── bgheader.png │ ├── components │ │ ├── Header │ │ │ ├── logo.png │ │ │ ├── bgheader.png │ │ │ ├── Logo.js │ │ │ ├── A.js │ │ │ ├── tests │ │ │ │ ├── __snapshots__ │ │ │ │ │ ├── Logo.test.js.snap │ │ │ │ │ ├── A.test.js.snap │ │ │ │ │ └── HeaderBg.test.js.snap │ │ │ │ └── Logo.test.js │ │ │ ├── HeaderBg.js │ │ │ ├── NavBar.js │ │ │ ├── messages.js │ │ │ └── HeaderLink.js │ │ ├── Toggle │ │ │ ├── Select.js │ │ │ └── index.js │ │ ├── LoadingIndicator │ │ │ ├── Wrapper.js │ │ │ ├── tests │ │ │ │ ├── index.test.js │ │ │ │ └── Circle.test.js │ │ │ └── index.js │ │ ├── Footer │ │ │ ├── Wrapper.js │ │ │ ├── tests │ │ │ │ └── __snapshots__ │ │ │ │ │ └── Wrapper.test.js.snap │ │ │ ├── messages.js │ │ │ └── index.js │ │ ├── ToggleOption │ │ │ └── index.js │ │ └── Form │ │ │ └── Fields │ │ │ └── tests │ │ │ ├── index.test.js │ │ │ └── search.test.js │ ├── utils │ │ ├── history.js │ │ ├── constants.js │ │ ├── withIntl.js │ │ ├── checkStore.js │ │ └── request.js │ ├── global-styles.js │ ├── reducers.js │ ├── tests │ │ └── i18n.test.js │ └── configureStore.js ├── .prettierrc ├── .stylelintrc ├── .gitignore ├── scripts │ └── helpers │ │ ├── checkmark.js │ │ └── progress.js ├── .editorconfig ├── README.md └── babel.config.js ├── Chapter07 ├── .nvmrc ├── testing │ ├── mocks │ │ ├── image.js │ │ └── cssModule.js │ ├── test-bundler.js │ └── enzyme-setup.js ├── nodemon.json ├── server │ ├── argv.js │ ├── port.js │ ├── helpers │ │ ├── prototype.js │ │ └── jwt.js │ ├── middlewares │ │ ├── frontendMiddleware.js │ │ └── addProdMiddlewares.js │ └── models │ │ ├── questions.js │ │ ├── organizations.js │ │ └── index.js ├── .prettierignore ├── app │ ├── containers │ │ ├── App │ │ │ ├── constants.js │ │ │ ├── actions.js │ │ │ ├── tests │ │ │ │ ├── actions.test.js │ │ │ │ └── reducer.test.js │ │ │ ├── style.css │ │ │ ├── saga.js │ │ │ ├── selectors.js │ │ │ └── reducer.js │ │ ├── LanguageProvider │ │ │ ├── constants.js │ │ │ ├── actions.js │ │ │ ├── selectors.js │ │ │ ├── tests │ │ │ │ ├── selectors.test.js │ │ │ │ ├── actions.test.js │ │ │ │ └── reducer.test.js │ │ │ └── reducer.js │ │ ├── LocaleToggle │ │ │ ├── Wrapper.js │ │ │ └── messages.js │ │ ├── Doctor │ │ │ ├── style.css │ │ │ ├── Loadable.js │ │ │ ├── constants.js │ │ │ ├── messages.js │ │ │ ├── actions.js │ │ │ ├── selectors.js │ │ │ └── reducer.js │ │ ├── Home │ │ │ ├── Loadable.js │ │ │ └── index.js │ │ ├── Register │ │ │ ├── constants.js │ │ │ ├── Loadable.js │ │ │ ├── style.css │ │ │ └── actions.js │ │ ├── User │ │ │ ├── Loadable.js │ │ │ ├── style.css │ │ │ └── index.js │ │ ├── Login │ │ │ ├── Loadable.js │ │ │ ├── style.css │ │ │ ├── constants.js │ │ │ ├── actions.js │ │ │ └── messages.js │ │ ├── NotFoundPage │ │ │ ├── Loadable.js │ │ │ ├── messages.js │ │ │ ├── index.js │ │ │ └── tests │ │ │ │ └── index.test.js │ │ └── DevTools.js │ ├── images │ │ ├── favicon.ico │ │ └── icon-512x512.png │ ├── assets │ │ └── images │ │ │ └── bgheader.png │ ├── components │ │ ├── Header │ │ │ ├── logo.png │ │ │ ├── bgheader.png │ │ │ ├── Logo.js │ │ │ ├── A.js │ │ │ ├── tests │ │ │ │ ├── __snapshots__ │ │ │ │ │ ├── Logo.test.js.snap │ │ │ │ │ ├── A.test.js.snap │ │ │ │ │ └── HeaderBg.test.js.snap │ │ │ │ └── Logo.test.js │ │ │ ├── HeaderBg.js │ │ │ ├── NavBar.js │ │ │ ├── messages.js │ │ │ └── HeaderLink.js │ │ ├── Toggle │ │ │ ├── Select.js │ │ │ └── index.js │ │ ├── LoadingIndicator │ │ │ ├── Wrapper.js │ │ │ ├── tests │ │ │ │ ├── index.test.js │ │ │ │ └── Circle.test.js │ │ │ └── index.js │ │ ├── Footer │ │ │ ├── Wrapper.js │ │ │ ├── tests │ │ │ │ └── __snapshots__ │ │ │ │ │ └── Wrapper.test.js.snap │ │ │ ├── messages.js │ │ │ └── index.js │ │ ├── ToggleOption │ │ │ └── index.js │ │ └── Form │ │ │ └── Fields │ │ │ └── tests │ │ │ ├── index.test.js │ │ │ └── search.test.js │ ├── utils │ │ ├── history.js │ │ ├── constants.js │ │ ├── withIntl.js │ │ ├── checkStore.js │ │ └── request.js │ ├── global-styles.js │ ├── reducers.js │ └── tests │ │ └── i18n.test.js ├── .prettierrc ├── .stylelintrc ├── .gitignore ├── scripts │ └── helpers │ │ ├── checkmark.js │ │ └── progress.js ├── .editorconfig ├── readme.MD └── babel.config.js ├── Chapter08 ├── .nvmrc ├── nodemon.json ├── server │ ├── argv.js │ ├── port.js │ ├── helpers │ │ ├── prototype.js │ │ └── jwt.js │ ├── logger.js │ └── models │ │ └── index.js ├── .prettierignore ├── .prettierrc ├── .stylelintrc ├── .gitignore ├── .editorconfig ├── readme.MD └── babel.config.js ├── Chapter01 ├── starter │ ├── scripts │ │ └── start.js │ ├── app │ │ ├── containers │ │ │ ├── HomePage │ │ │ │ ├── Loadable.js │ │ │ │ └── index.js │ │ │ ├── NotFoundPage │ │ │ │ ├── Loadable.js │ │ │ │ └── index.js │ │ │ └── App │ │ │ │ └── index.js │ │ ├── utils │ │ │ ├── history.js │ │ │ └── checkStore.js │ │ ├── reducers.js │ │ ├── configureStore.js │ │ └── app.js │ ├── .prettierrc │ ├── .gitignore │ ├── .editorconfig │ └── babel.config.js └── getting-started │ ├── .gitignore │ ├── readme.MD │ ├── babel.config.js │ ├── webpack.config.js │ └── package.json ├── Chapter02 ├── .babelrc ├── .gitignore ├── app │ ├── Redux │ │ ├── actionTypes.js │ │ ├── actionCreators.js │ │ ├── Alerts.js │ │ ├── __tests__ │ │ │ ├── __snapshots__ │ │ │ │ └── AlertContainer-test.js.snap │ │ │ ├── actionCreators-test.js │ │ │ ├── AlertContainer-test.js │ │ │ └── reducers-test.js │ │ ├── AlertContainer.js │ │ └── reducers.js │ ├── JS │ │ ├── calculateBill.js │ │ ├── __tests__ │ │ │ ├── calculateBill-test.js │ │ │ └── time-test.js │ │ └── time.js │ └── React │ │ ├── Logo.js │ │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ ├── HeaderNav-test.js.snap │ │ │ ├── EmailInput-test.js.snap │ │ │ └── Header-test.js.snap │ │ ├── Header-test.js │ │ ├── HeaderNav-test.js │ │ └── EmailInput-test.js │ │ ├── HeaderNav.js │ │ ├── Header.js │ │ ├── SocialMediaLinks.js │ │ └── EmailInput.js ├── readme.MD └── package.json ├── Chapter03 ├── testing │ ├── test-bundler.js │ ├── mocks │ │ ├── image.js │ │ └── cssModule.js │ └── enzyme-setup.js ├── server │ ├── argv.js │ ├── port.js │ ├── middlewares │ │ └── frontendMiddleware.js │ └── index.js ├── app │ ├── images │ │ ├── favicon.ico │ │ └── icon-512x512.png │ ├── containers │ │ ├── AboutPage │ │ │ ├── Loadable.js │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ ├── index-test.js.snap │ │ │ │ │ └── redirect-test.js.snap │ │ │ │ ├── index-test.js │ │ │ │ └── redirect-test.js │ │ │ ├── index.js │ │ │ └── redirect.js │ │ ├── HomePage │ │ │ ├── Loadable.js │ │ │ ├── __tests__ │ │ │ │ ├── index-test.js │ │ │ │ └── __snapshots__ │ │ │ │ │ └── index-test.js.snap │ │ │ └── index.js │ │ ├── Login │ │ │ ├── Loadable.js │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── index-test.js.snap │ │ │ │ └── index-test.js │ │ │ └── index.js │ │ ├── Register │ │ │ ├── Loadable.js │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── index-test.js.snap │ │ │ │ └── index-test.js │ │ │ └── index.js │ │ ├── ContactPage │ │ │ ├── Loadable.js │ │ │ └── index.js │ │ ├── NotFoundPage │ │ │ ├── Loadable.js │ │ │ └── index.js │ │ └── App │ │ │ └── reducer.js │ ├── utils │ │ └── history.js │ ├── reducers.js │ ├── configureStore.js │ ├── global-styles.js │ └── app.js ├── .prettierrc ├── .gitignore ├── .editorconfig ├── readme.MD ├── jest.config.js └── babel.config.js └── Chapter04 ├── public ├── favicon.ico └── manifest.json ├── src ├── reducers │ └── index.js ├── constants │ └── ActionTypes.js ├── index.html ├── index.js └── actions │ └── todos.js ├── config └── jest │ ├── cssTransform.js │ └── fileTransform.js └── .gitignore /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /Chapter05/scripts/start.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /starter/scripts/start.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter06/.nvmrc: -------------------------------------------------------------------------------- 1 | lts/carbon 2 | -------------------------------------------------------------------------------- /Chapter07/.nvmrc: -------------------------------------------------------------------------------- 1 | lts/carbon 2 | -------------------------------------------------------------------------------- /Chapter08/.nvmrc: -------------------------------------------------------------------------------- 1 | lts/carbon 2 | -------------------------------------------------------------------------------- /Chapter01/starter/scripts/start.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter05/app/containers/User/style.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter02/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | presets: ["env", "react"] 3 | } 4 | -------------------------------------------------------------------------------- /Chapter03/testing/test-bundler.js: -------------------------------------------------------------------------------- 1 | import "@babel/polyfill"; 2 | -------------------------------------------------------------------------------- /Chapter05/testing/test-bundler.js: -------------------------------------------------------------------------------- 1 | import "@babel/polyfill"; 2 | -------------------------------------------------------------------------------- /Chapter02/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | coverage 4 | -------------------------------------------------------------------------------- /Chapter03/testing/mocks/image.js: -------------------------------------------------------------------------------- 1 | module.exports = "IMAGE_MOCK"; 2 | -------------------------------------------------------------------------------- /Chapter05/testing/mocks/image.js: -------------------------------------------------------------------------------- 1 | module.exports = "IMAGE_MOCK"; 2 | -------------------------------------------------------------------------------- /Chapter06/testing/mocks/image.js: -------------------------------------------------------------------------------- 1 | module.exports = "IMAGE_MOCK"; 2 | -------------------------------------------------------------------------------- /Chapter07/testing/mocks/image.js: -------------------------------------------------------------------------------- 1 | module.exports = "IMAGE_MOCK"; 2 | -------------------------------------------------------------------------------- /Chapter03/testing/mocks/cssModule.js: -------------------------------------------------------------------------------- 1 | module.exports = "CSS_MODULE"; 2 | -------------------------------------------------------------------------------- /Chapter05/testing/mocks/cssModule.js: -------------------------------------------------------------------------------- 1 | module.exports = "CSS_MODULE"; 2 | -------------------------------------------------------------------------------- /Chapter06/testing/mocks/cssModule.js: -------------------------------------------------------------------------------- 1 | module.exports = "CSS_MODULE"; 2 | -------------------------------------------------------------------------------- /Chapter07/testing/mocks/cssModule.js: -------------------------------------------------------------------------------- 1 | module.exports = "CSS_MODULE"; 2 | -------------------------------------------------------------------------------- /Chapter01/getting-started/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | *.log 4 | dist 5 | -------------------------------------------------------------------------------- /Chapter02/app/Redux/actionTypes.js: -------------------------------------------------------------------------------- 1 | export const ADD_NEW_DOCTOR = "ADD_NEW_DOCTOR"; 2 | -------------------------------------------------------------------------------- /Chapter06/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "verbose": true, 3 | "ignore": ["app/**"] 4 | } 5 | -------------------------------------------------------------------------------- /Chapter07/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "verbose": true, 3 | "ignore": ["app/**"] 4 | } 5 | -------------------------------------------------------------------------------- /Chapter08/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "verbose": true, 3 | "ignore": ["app/**"] 4 | } 5 | -------------------------------------------------------------------------------- /Chapter03/server/argv.js: -------------------------------------------------------------------------------- 1 | module.exports = require('minimist')(process.argv.slice(2)); 2 | -------------------------------------------------------------------------------- /Chapter05/server/argv.js: -------------------------------------------------------------------------------- 1 | module.exports = require('minimist')(process.argv.slice(2)); 2 | -------------------------------------------------------------------------------- /Chapter06/server/argv.js: -------------------------------------------------------------------------------- 1 | module.exports = require('minimist')(process.argv.slice(2)); 2 | -------------------------------------------------------------------------------- /Chapter07/server/argv.js: -------------------------------------------------------------------------------- 1 | module.exports = require('minimist')(process.argv.slice(2)); 2 | -------------------------------------------------------------------------------- /Chapter08/server/argv.js: -------------------------------------------------------------------------------- 1 | module.exports = require('minimist')(process.argv.slice(2)); 2 | -------------------------------------------------------------------------------- /Chapter06/.prettierignore: -------------------------------------------------------------------------------- 1 | build/ 2 | node_modules/ 3 | package-lock.json 4 | yarn.lock 5 | package.json 6 | -------------------------------------------------------------------------------- /Chapter07/.prettierignore: -------------------------------------------------------------------------------- 1 | build/ 2 | node_modules/ 3 | package-lock.json 4 | yarn.lock 5 | package.json 6 | -------------------------------------------------------------------------------- /Chapter08/.prettierignore: -------------------------------------------------------------------------------- 1 | build/ 2 | node_modules/ 3 | package-lock.json 4 | yarn.lock 5 | package.json 6 | -------------------------------------------------------------------------------- /Chapter06/app/containers/App/constants.js: -------------------------------------------------------------------------------- 1 | export const IS_USER_AUTHENTICATED = 'App/IS_USER_AUTHENTICATED'; 2 | -------------------------------------------------------------------------------- /Chapter07/app/containers/App/constants.js: -------------------------------------------------------------------------------- 1 | export const IS_USER_AUTHENTICATED = 'App/IS_USER_AUTHENTICATED'; 2 | -------------------------------------------------------------------------------- /Chapter06/app/containers/LanguageProvider/constants.js: -------------------------------------------------------------------------------- 1 | export const CHANGE_LOCALE = 'app/LanguageToggle/CHANGE_LOCALE'; 2 | -------------------------------------------------------------------------------- /Chapter07/app/containers/LanguageProvider/constants.js: -------------------------------------------------------------------------------- 1 | export const CHANGE_LOCALE = 'app/LanguageToggle/CHANGE_LOCALE'; 2 | -------------------------------------------------------------------------------- /Chapter04/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter04/public/favicon.ico -------------------------------------------------------------------------------- /Chapter03/app/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter03/app/images/favicon.ico -------------------------------------------------------------------------------- /Chapter03/server/port.js: -------------------------------------------------------------------------------- 1 | const argv = require('./argv'); 2 | 3 | module.exports = parseInt(argv.port || process.env.PORT || '3000', 10); 4 | -------------------------------------------------------------------------------- /Chapter05/app/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter05/app/images/favicon.ico -------------------------------------------------------------------------------- /Chapter05/server/port.js: -------------------------------------------------------------------------------- 1 | const argv = require('./argv'); 2 | 3 | module.exports = parseInt(argv.port || process.env.PORT || '3000', 10); 4 | -------------------------------------------------------------------------------- /Chapter06/app/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter06/app/images/favicon.ico -------------------------------------------------------------------------------- /Chapter06/server/port.js: -------------------------------------------------------------------------------- 1 | const argv = require('./argv'); 2 | 3 | module.exports = parseInt(argv.port || process.env.PORT || '3000', 10); 4 | -------------------------------------------------------------------------------- /Chapter07/app/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter07/app/images/favicon.ico -------------------------------------------------------------------------------- /Chapter07/server/port.js: -------------------------------------------------------------------------------- 1 | const argv = require('./argv'); 2 | 3 | module.exports = parseInt(argv.port || process.env.PORT || '3000', 10); 4 | -------------------------------------------------------------------------------- /Chapter08/server/port.js: -------------------------------------------------------------------------------- 1 | const argv = require('./argv'); 2 | 3 | module.exports = parseInt(argv.port || process.env.PORT || '3000', 10); 4 | -------------------------------------------------------------------------------- /Chapter01/getting-started/readme.MD: -------------------------------------------------------------------------------- 1 | # Chapter 1 2 | 3 | ## Lists of Topics 4 | 5 | - Need of Redux 6 | - Setting up the Redux 7 | - Redux -Store 8 | -------------------------------------------------------------------------------- /Chapter03/app/containers/AboutPage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /Chapter03/app/containers/HomePage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /Chapter03/app/containers/Login/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /Chapter03/app/containers/Register/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /Chapter03/app/images/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter03/app/images/icon-512x512.png -------------------------------------------------------------------------------- /Chapter05/app/containers/AboutPage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | export default loadable(() => import('./index')); 4 | -------------------------------------------------------------------------------- /Chapter05/app/containers/HomePage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Login/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | export default loadable(() => import('./index')); 4 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Register/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /Chapter05/app/images/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter05/app/images/icon-512x512.png -------------------------------------------------------------------------------- /Chapter06/app/images/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter06/app/images/icon-512x512.png -------------------------------------------------------------------------------- /Chapter07/app/images/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter07/app/images/icon-512x512.png -------------------------------------------------------------------------------- /starter/app/containers/HomePage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /Chapter02/app/JS/calculateBill.js: -------------------------------------------------------------------------------- 1 | const calculateBill = (totalHours, ratePerHours) => totalHours * ratePerHours; 2 | 3 | module.exports = calculateBill; 4 | -------------------------------------------------------------------------------- /Chapter03/app/containers/ContactPage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | export default loadable(() => import('./index')); 4 | -------------------------------------------------------------------------------- /Chapter03/app/containers/NotFoundPage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /Chapter03/app/utils/history.js: -------------------------------------------------------------------------------- 1 | import createHistory from 'history/createBrowserHistory'; 2 | const history = createHistory(); 3 | export default history; 4 | -------------------------------------------------------------------------------- /Chapter05/app/components/Header/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter05/app/components/Header/logo.png -------------------------------------------------------------------------------- /Chapter05/app/containers/ContactPage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /Chapter05/app/containers/NotFoundPage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /Chapter05/app/utils/history.js: -------------------------------------------------------------------------------- 1 | import createHistory from 'history/createBrowserHistory'; 2 | const history = createHistory(); 3 | export default history; 4 | -------------------------------------------------------------------------------- /Chapter06/app/assets/images/bgheader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter06/app/assets/images/bgheader.png -------------------------------------------------------------------------------- /Chapter06/app/components/Header/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter06/app/components/Header/logo.png -------------------------------------------------------------------------------- /Chapter06/app/utils/history.js: -------------------------------------------------------------------------------- 1 | import createHistory from 'history/createBrowserHistory'; 2 | const history = createHistory(); 3 | export default history; 4 | -------------------------------------------------------------------------------- /Chapter06/testing/test-bundler.js: -------------------------------------------------------------------------------- 1 | // needed for regenerator-runtime 2 | // (ES7 generator support is required by redux-saga) 3 | import '@babel/polyfill'; 4 | -------------------------------------------------------------------------------- /Chapter07/app/assets/images/bgheader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter07/app/assets/images/bgheader.png -------------------------------------------------------------------------------- /Chapter07/app/components/Header/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter07/app/components/Header/logo.png -------------------------------------------------------------------------------- /Chapter07/app/utils/history.js: -------------------------------------------------------------------------------- 1 | import createHistory from 'history/createBrowserHistory'; 2 | const history = createHistory(); 3 | export default history; 4 | -------------------------------------------------------------------------------- /Chapter07/testing/test-bundler.js: -------------------------------------------------------------------------------- 1 | // needed for regenerator-runtime 2 | // (ES7 generator support is required by redux-saga) 3 | import '@babel/polyfill'; 4 | -------------------------------------------------------------------------------- /starter/app/containers/NotFoundPage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from "loadable-components"; 2 | 3 | export default loadable(() => import("./index")); 4 | -------------------------------------------------------------------------------- /starter/app/utils/history.js: -------------------------------------------------------------------------------- 1 | import createHistory from "history/createBrowserHistory"; 2 | const history = createHistory(); 3 | export default history; 4 | -------------------------------------------------------------------------------- /Chapter01/starter/app/containers/HomePage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | export default loadable(() => import('./index')); 4 | -------------------------------------------------------------------------------- /Chapter05/app/components/Header/bgheader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter05/app/components/Header/bgheader.png -------------------------------------------------------------------------------- /Chapter06/app/components/Header/bgheader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter06/app/components/Header/bgheader.png -------------------------------------------------------------------------------- /Chapter07/app/components/Header/bgheader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Redux-Quick-Start-Guide/HEAD/Chapter07/app/components/Header/bgheader.png -------------------------------------------------------------------------------- /Chapter01/starter/app/containers/NotFoundPage/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | export default loadable(() => import('./index')); 4 | -------------------------------------------------------------------------------- /Chapter01/starter/app/utils/history.js: -------------------------------------------------------------------------------- 1 | import createHistory from 'history/createBrowserHistory'; 2 | const history = createHistory(); 3 | export default history; 4 | -------------------------------------------------------------------------------- /Chapter02/app/Redux/actionCreators.js: -------------------------------------------------------------------------------- 1 | export function addNewDoctor(newDoctorData) { 2 | return { 3 | type: "ADD_NEW_DOCTOR", 4 | newDoctorData 5 | }; 6 | } 7 | -------------------------------------------------------------------------------- /Chapter03/testing/enzyme-setup.js: -------------------------------------------------------------------------------- 1 | import { configure } from "enzyme"; 2 | import Adapter from "enzyme-adapter-react-16"; 3 | 4 | configure({ adapter: new Adapter() }); 5 | -------------------------------------------------------------------------------- /Chapter05/testing/enzyme-setup.js: -------------------------------------------------------------------------------- 1 | import { configure } from "enzyme"; 2 | import Adapter from "enzyme-adapter-react-16"; 3 | 4 | configure({ adapter: new Adapter() }); 5 | -------------------------------------------------------------------------------- /Chapter06/testing/enzyme-setup.js: -------------------------------------------------------------------------------- 1 | import { configure } from 'enzyme'; 2 | import Adapter from 'enzyme-adapter-react-16'; 3 | 4 | configure({ adapter: new Adapter() }); 5 | -------------------------------------------------------------------------------- /Chapter07/testing/enzyme-setup.js: -------------------------------------------------------------------------------- 1 | import { configure } from 'enzyme'; 2 | import Adapter from 'enzyme-adapter-react-16'; 3 | 4 | configure({ adapter: new Adapter() }); 5 | -------------------------------------------------------------------------------- /Chapter03/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /Chapter04/src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from "redux"; 2 | 3 | import todos from "./todos"; 4 | 5 | export default combineReducers({ 6 | todos 7 | }); 8 | -------------------------------------------------------------------------------- /Chapter05/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /Chapter06/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /Chapter07/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /Chapter08/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /Chapter06/app/containers/App/actions.js: -------------------------------------------------------------------------------- 1 | import { IS_USER_AUTHENTICATED } from './constants'; 2 | 3 | export const onApplicationLoad = () => ({ type: IS_USER_AUTHENTICATED }); 4 | -------------------------------------------------------------------------------- /Chapter07/app/containers/App/actions.js: -------------------------------------------------------------------------------- 1 | import { IS_USER_AUTHENTICATED } from './constants'; 2 | 3 | export const onApplicationLoad = () => ({ type: IS_USER_AUTHENTICATED }); 4 | -------------------------------------------------------------------------------- /Chapter01/starter/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | node_modules 5 | stats.json 6 | 7 | # Cruft 8 | .DS_Store 9 | npm-debug.log 10 | .idea 11 | -------------------------------------------------------------------------------- /Chapter06/app/containers/LocaleToggle/Wrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | padding: 2px; 5 | `; 6 | 7 | export default Wrapper; 8 | -------------------------------------------------------------------------------- /Chapter07/app/containers/LocaleToggle/Wrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | padding: 2px; 5 | `; 6 | 7 | export default Wrapper; 8 | -------------------------------------------------------------------------------- /Chapter05/app/components/H1/index.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const H1 = styled.h1` 4 | font-size: 2em; 5 | margin-bottom: 0.25em; 6 | `; 7 | 8 | export default H1; 9 | -------------------------------------------------------------------------------- /Chapter06/app/components/Toggle/Select.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Select = styled.select` 4 | line-height: 1em; 5 | height: 20px; 6 | `; 7 | 8 | export default Select; 9 | -------------------------------------------------------------------------------- /Chapter07/app/components/Toggle/Select.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Select = styled.select` 4 | line-height: 1em; 5 | height: 20px; 6 | `; 7 | 8 | export default Select; 9 | -------------------------------------------------------------------------------- /Chapter06/.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "processors": ["stylelint-processor-styled-components"], 3 | "extends": [ 4 | "stylelint-config-recommended", 5 | "stylelint-config-styled-components" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /Chapter07/.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "processors": ["stylelint-processor-styled-components"], 3 | "extends": [ 4 | "stylelint-config-recommended", 5 | "stylelint-config-styled-components" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /Chapter08/.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "processors": ["stylelint-processor-styled-components"], 3 | "extends": [ 4 | "stylelint-config-recommended", 5 | "stylelint-config-styled-components" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /Chapter06/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | node_modules 5 | stats.json 6 | 7 | # Cruft 8 | .DS_Store 9 | npm-debug.log 10 | .idea 11 | .github 12 | .git 13 | -------------------------------------------------------------------------------- /Chapter07/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | node_modules 5 | stats.json 6 | 7 | # Cruft 8 | .DS_Store 9 | npm-debug.log 10 | .idea 11 | .github 12 | .git 13 | -------------------------------------------------------------------------------- /Chapter08/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | node_modules 5 | stats.json 6 | 7 | # Cruft 8 | .DS_Store 9 | npm-debug.log 10 | .idea 11 | .github 12 | .git 13 | -------------------------------------------------------------------------------- /Chapter03/app/containers/Login/__tests__/__snapshots__/index-test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render correctly 1`] = ` 4 |

5 | This is the Login 6 |

7 | `; 8 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Login/__tests__/__snapshots__/index-test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render correctly 1`] = ` 4 |

5 | This is the Login 6 |

7 | `; 8 | -------------------------------------------------------------------------------- /Chapter06/app/components/Header/Logo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import LogoImg from './logo.png'; 3 | 4 | export default props => ( 5 | 6 | ); 7 | -------------------------------------------------------------------------------- /Chapter07/app/components/Header/Logo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import LogoImg from './logo.png'; 3 | 4 | export default props => ( 5 | 6 | ); 7 | -------------------------------------------------------------------------------- /Chapter03/app/containers/Register/__tests__/__snapshots__/index-test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render correctly 1`] = ` 4 |

5 | This is the Register 6 |

7 | `; 8 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Register/__tests__/__snapshots__/index-test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render correctly 1`] = ` 4 |

5 | This is the Register 6 |

7 | `; 8 | -------------------------------------------------------------------------------- /Chapter06/server/helpers/prototype.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | String.prototype.humanize = function () { 4 | return this.replace(/(?:_| |\b)(\w)/g, function(key, p1) { 5 | return p1.toUpperCase() 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /Chapter07/server/helpers/prototype.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | String.prototype.humanize = function () { 4 | return this.replace(/(?:_| |\b)(\w)/g, function(key, p1) { 5 | return p1.toUpperCase() 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /Chapter08/server/helpers/prototype.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | String.prototype.humanize = function () { 4 | return this.replace(/(?:_| |\b)(\w)/g, function(key, p1) { 5 | return p1.toUpperCase() 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /Chapter03/app/containers/AboutPage/__tests__/__snapshots__/index-test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render correctly 1`] = ` 4 |

5 | This is the About page 6 |

7 | `; 8 | -------------------------------------------------------------------------------- /Chapter05/app/containers/AboutPage/__tests__/__snapshots__/index-test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render correctly 1`] = ` 4 |

5 | This is the About page 6 |

7 | `; 8 | -------------------------------------------------------------------------------- /starter/app/utils/constants.js: -------------------------------------------------------------------------------- 1 | export const RESTART_ON_REMOUNT = "@@saga-injector/restart-on-remount"; 2 | export const DAEMON = "@@saga-injector/daemon"; 3 | export const ONCE_TILL_UNMOUNT = "@@saga-injector/once-till-unmount"; 4 | -------------------------------------------------------------------------------- /Chapter05/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | node_modules 5 | stats.json 6 | 7 | # Cruft 8 | .DS_Store 9 | npm-debug.log 10 | yarn-debug.log* 11 | yarn-error.log* 12 | .idea 13 | -------------------------------------------------------------------------------- /Chapter06/app/utils/constants.js: -------------------------------------------------------------------------------- 1 | export const RESTART_ON_REMOUNT = '@@saga-injector/restart-on-remount'; 2 | export const DAEMON = '@@saga-injector/daemon'; 3 | export const ONCE_TILL_UNMOUNT = '@@saga-injector/once-till-unmount'; 4 | -------------------------------------------------------------------------------- /Chapter07/app/utils/constants.js: -------------------------------------------------------------------------------- 1 | export const RESTART_ON_REMOUNT = '@@saga-injector/restart-on-remount'; 2 | export const DAEMON = '@@saga-injector/daemon'; 3 | export const ONCE_TILL_UNMOUNT = '@@saga-injector/once-till-unmount'; 4 | -------------------------------------------------------------------------------- /Chapter01/starter/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | node_modules 5 | stats.json 6 | 7 | # Cruft 8 | .DS_Store 9 | npm-debug.log 10 | yarn-debug.log* 11 | yarn-error.log* 12 | .idea 13 | -------------------------------------------------------------------------------- /Chapter06/scripts/helpers/checkmark.js: -------------------------------------------------------------------------------- 1 | const chalk = require('chalk'); 2 | 3 | function addCheckMark(callback) { 4 | process.stdout.write(chalk.green(' ✓')); 5 | if (callback) callback(); 6 | } 7 | 8 | module.exports = addCheckMark; 9 | -------------------------------------------------------------------------------- /Chapter07/scripts/helpers/checkmark.js: -------------------------------------------------------------------------------- 1 | const chalk = require('chalk'); 2 | 3 | function addCheckMark(callback) { 4 | process.stdout.write(chalk.green(' ✓')); 5 | if (callback) callback(); 6 | } 7 | 8 | module.exports = addCheckMark; 9 | -------------------------------------------------------------------------------- /Chapter02/app/React/Logo.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "react-router-dom/Link"; 3 | 4 | const Logo = () => ( 5 |
6 | FastDoctor 7 |
8 | ); 9 | 10 | export default Logo; 11 | -------------------------------------------------------------------------------- /Chapter06/app/containers/LanguageProvider/actions.js: -------------------------------------------------------------------------------- 1 | import { CHANGE_LOCALE } from './constants'; 2 | 3 | export function changeLocale(languageLocale) { 4 | return { 5 | type: CHANGE_LOCALE, 6 | locale: languageLocale, 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /Chapter07/app/containers/LanguageProvider/actions.js: -------------------------------------------------------------------------------- 1 | import { CHANGE_LOCALE } from './constants'; 2 | 3 | export function changeLocale(languageLocale) { 4 | return { 5 | type: CHANGE_LOCALE, 6 | locale: languageLocale, 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /Chapter02/app/JS/__tests__/calculateBill-test.js: -------------------------------------------------------------------------------- 1 | const calculateBill = require("../calculateBill"); 2 | 3 | test("calculate bills when number of hours and hourly rate are provided.", () => { 4 | expect(calculateBill(10, 40)).toBe(400); 5 | }); 6 | -------------------------------------------------------------------------------- /Chapter02/app/Redux/Alerts.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Alerts = () => ( 4 | 8 | ); 9 | 10 | export default Alerts; 11 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Doctor/style.css: -------------------------------------------------------------------------------- 1 | .form-doctor-containers { 2 | width: 100%; 3 | margin: auto; 4 | max-width: 400px; 5 | padding: 50px 10px; 6 | } 7 | 8 | .form-doctor-containers .center { 9 | text-align: center; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Doctor/style.css: -------------------------------------------------------------------------------- 1 | .form-doctor-containers { 2 | width: 100%; 3 | margin: auto; 4 | max-width: 400px; 5 | padding: 50px 10px; 6 | } 7 | 8 | .form-doctor-containers .center { 9 | text-align: center; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter05/app/components/Header/A.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | const A = styled(Link)` 5 | padding: 5px 15px; 6 | display: inline-block; 7 | `; 8 | 9 | export default A; 10 | -------------------------------------------------------------------------------- /Chapter06/app/components/Header/A.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | const A = styled(Link)` 5 | padding: 5px 15px; 6 | display: inline-block; 7 | `; 8 | 9 | export default A; 10 | -------------------------------------------------------------------------------- /Chapter07/app/components/Header/A.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | const A = styled(Link)` 5 | padding: 5px 15px; 6 | display: inline-block; 7 | `; 8 | 9 | export default A; 10 | -------------------------------------------------------------------------------- /Chapter02/app/React/__tests__/__snapshots__/HeaderNav-test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render correctly 1`] = ` 4 |
5 | 6 |
7 | 8 |
9 | `; 10 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Register/constants.js: -------------------------------------------------------------------------------- 1 | export const REGISTER_REQUEST = 'raskLege/Register/REGISTER_REQUEST'; 2 | export const REGISTER_SUCCESS = 'raskLege/Register/REGISTER_SUCCESS'; 3 | export const REGISTER_FAILURE = 'raskLege/Register/REGISTER_FAILURE'; 4 | -------------------------------------------------------------------------------- /Chapter05/app/containers/User/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | import LoadingIndicator from 'components/LoadingIndicator'; 4 | 5 | export default loadable(() => import('./index'), { 6 | LoadingComponent: LoadingIndicator, 7 | }); 8 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Home/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | import LoadingIndicator from 'components/LoadingIndicator'; 4 | 5 | export default loadable(() => import('./index'), { 6 | LoadingComponent: LoadingIndicator, 7 | }); 8 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Register/constants.js: -------------------------------------------------------------------------------- 1 | export const REGISTER_REQUEST = 'raskLege/Register/REGISTER_REQUEST'; 2 | export const REGISTER_SUCCESS = 'raskLege/Register/REGISTER_SUCCESS'; 3 | export const REGISTER_FAILURE = 'raskLege/Register/REGISTER_FAILURE'; 4 | -------------------------------------------------------------------------------- /Chapter06/app/containers/User/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | import LoadingIndicator from 'components/LoadingIndicator'; 4 | 5 | export default loadable(() => import('./index'), { 6 | LoadingComponent: LoadingIndicator, 7 | }); 8 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Home/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | import LoadingIndicator from 'components/LoadingIndicator'; 4 | 5 | export default loadable(() => import('./index'), { 6 | LoadingComponent: LoadingIndicator, 7 | }); 8 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Register/constants.js: -------------------------------------------------------------------------------- 1 | export const REGISTER_REQUEST = 'raskLege/Register/REGISTER_REQUEST'; 2 | export const REGISTER_SUCCESS = 'raskLege/Register/REGISTER_SUCCESS'; 3 | export const REGISTER_FAILURE = 'raskLege/Register/REGISTER_FAILURE'; 4 | -------------------------------------------------------------------------------- /Chapter07/app/containers/User/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | import LoadingIndicator from 'components/LoadingIndicator'; 4 | 5 | export default loadable(() => import('./index'), { 6 | LoadingComponent: LoadingIndicator, 7 | }); 8 | -------------------------------------------------------------------------------- /Chapter01/starter/app/containers/App/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import HomePage from 'containers/HomePage/Loadable'; 4 | 5 | export default function App() { 6 | return ( 7 |
8 | 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter02/app/JS/time.js: -------------------------------------------------------------------------------- 1 | function takeXray(callback) { 2 | console.log("Ready, close your eye."); 3 | setTimeout(() => { 4 | console.log("Great you are done."); 5 | callback && callback(); 6 | }, 2000); 7 | } 8 | 9 | module.exports = takeXray; 10 | -------------------------------------------------------------------------------- /Chapter03/app/containers/AboutPage/__tests__/__snapshots__/redirect-test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render correctly 1`] = ` 4 | 9 | `; 10 | -------------------------------------------------------------------------------- /Chapter05/app/components/LoadingIndicator/Wrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | margin: 2em auto; 5 | width: 40px; 6 | height: 40px; 7 | position: relative; 8 | `; 9 | 10 | export default Wrapper; 11 | -------------------------------------------------------------------------------- /Chapter05/app/containers/AboutPage/__tests__/__snapshots__/redirect-test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render correctly 1`] = ` 4 | 9 | `; 10 | -------------------------------------------------------------------------------- /Chapter06/app/components/Header/tests/__snapshots__/Logo.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should match snapshot 1`] = ` 4 | 9 | `; 10 | -------------------------------------------------------------------------------- /Chapter06/app/components/LoadingIndicator/Wrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | margin: 2em auto; 5 | width: 40px; 6 | height: 40px; 7 | position: relative; 8 | `; 9 | 10 | export default Wrapper; 11 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Doctor/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | import LoadingIndicator from 'components/LoadingIndicator'; 4 | 5 | export default loadable(() => import('./index'), { 6 | LoadingComponent: LoadingIndicator, 7 | }); 8 | -------------------------------------------------------------------------------- /Chapter07/app/components/Header/tests/__snapshots__/Logo.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should match snapshot 1`] = ` 4 | 9 | `; 10 | -------------------------------------------------------------------------------- /Chapter07/app/components/LoadingIndicator/Wrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | margin: 2em auto; 5 | width: 40px; 6 | height: 40px; 7 | position: relative; 8 | `; 9 | 10 | export default Wrapper; 11 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Doctor/Loadable.js: -------------------------------------------------------------------------------- 1 | import loadable from 'loadable-components'; 2 | 3 | import LoadingIndicator from 'components/LoadingIndicator'; 4 | 5 | export default loadable(() => import('./index'), { 6 | LoadingComponent: LoadingIndicator, 7 | }); 8 | -------------------------------------------------------------------------------- /Chapter03/app/containers/Login/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class Login extends PureComponent { 5 | render() { 6 | return

This is the Login

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter04/src/constants/ActionTypes.js: -------------------------------------------------------------------------------- 1 | export const ADD_TODO = "ADD_TODO"; 2 | export const COMPLETE_TODO = "COMPLETE_TODO"; 3 | export const DELETE_TODO = "DELETE_TODO"; 4 | export const DELETE_ALL_TODOS = "DELETE_ALL_TODOS"; 5 | export const CHANGE_FILTER = "CHANGE_FILTER"; 6 | -------------------------------------------------------------------------------- /Chapter01/getting-started/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | modules: false 7 | } 8 | ], 9 | "@babel/preset-react" 10 | ], 11 | plugins: ["transform-object-rest-spread"] 12 | }; 13 | -------------------------------------------------------------------------------- /Chapter03/app/containers/AboutPage/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class HomePage extends PureComponent { 5 | render() { 6 | return

This is the About page

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/app/containers/Register/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class Register extends PureComponent { 5 | render() { 6 | return

This is the Register

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter04/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ToDo 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter05/app/components/Footer/Wrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.footer` 4 | display: flex; 5 | justify-content: space-between; 6 | padding: 3em 0; 7 | border-top: 1px solid #666; 8 | `; 9 | 10 | export default Wrapper; 11 | -------------------------------------------------------------------------------- /Chapter05/app/containers/AboutPage/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class HomePage extends PureComponent { 5 | render() { 6 | return

This is the About page

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter06/app/components/Footer/Wrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.footer` 4 | display: flex; 5 | justify-content: space-between; 6 | padding: 3em 0; 7 | border-top: 1px solid #666; 8 | `; 9 | 10 | export default Wrapper; 11 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Doctor/constants.js: -------------------------------------------------------------------------------- 1 | export const DOCTOR_SEARCH_REQUEST = 'raskLege/DOCTOR/DOCTOR_SEARCH_REQUEST'; 2 | export const DOCTOR_SEARCH_SUCCESS = 'raskLege/DOCTOR/DOCTOR_SEARCH_SUCCESS'; 3 | export const DOCTOR_SEARCH_FAILURE = 'raskLege/DOCTOR/DOCTOR_SEARCH_FAILURE'; 4 | -------------------------------------------------------------------------------- /Chapter07/app/components/Footer/Wrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.footer` 4 | display: flex; 5 | justify-content: space-between; 6 | padding: 3em 0; 7 | border-top: 1px solid #666; 8 | `; 9 | 10 | export default Wrapper; 11 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Doctor/constants.js: -------------------------------------------------------------------------------- 1 | export const DOCTOR_SEARCH_REQUEST = 'raskLege/DOCTOR/DOCTOR_SEARCH_REQUEST'; 2 | export const DOCTOR_SEARCH_SUCCESS = 'raskLege/DOCTOR/DOCTOR_SEARCH_SUCCESS'; 3 | export const DOCTOR_SEARCH_FAILURE = 'raskLege/DOCTOR/DOCTOR_SEARCH_FAILURE'; 4 | -------------------------------------------------------------------------------- /starter/app/containers/NotFoundPage/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class NotFound extends React.PureComponent { 5 | render() { 6 | return

This is the NotFoundPage container!

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/app/containers/ContactPage/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class HomePage extends PureComponent { 5 | render() { 6 | return

This is the contact page!

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/app/containers/NotFoundPage/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class NotFound extends React.PureComponent { 5 | render() { 6 | return

This is the NotFoundPage container!

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter05/app/containers/ContactPage/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class HomePage extends PureComponent { 5 | render() { 6 | return

This is the contact page!

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter05/app/containers/NotFoundPage/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class NotFound extends React.PureComponent { 5 | render() { 6 | return

This is the NotFoundPage container!

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter01/starter/app/containers/NotFoundPage/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class NotFound extends React.PureComponent { 5 | render() { 6 | return

This is the NotFoundPage container!

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /Chapter05/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /Chapter05/app/components/A/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A link to a certain page, an anchor tag 3 | */ 4 | 5 | import styled from 'styled-components'; 6 | 7 | const A = styled.a` 8 | color: #41addd; 9 | 10 | &:hover { 11 | color: #6cc0e5; 12 | } 13 | `; 14 | 15 | export default A; 16 | -------------------------------------------------------------------------------- /Chapter06/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /Chapter07/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /Chapter08/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /starter/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /Chapter05/app/components/Header/HeaderBg.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import BG from './bgheader.png'; 3 | 4 | export default styled.div` 5 | min-height: 100px; 6 | background-image: url(${BG}); 7 | background-color: #def0fb; 8 | background-position: 100% 0; 9 | `; 10 | -------------------------------------------------------------------------------- /Chapter06/app/components/Header/HeaderBg.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import BG from './bgheader.png'; 3 | 4 | export default styled.div` 5 | min-height: 100px; 6 | background-image: url(${BG}); 7 | background-color: #def0fb; 8 | background-position: 100% 0; 9 | `; 10 | -------------------------------------------------------------------------------- /Chapter07/app/components/Header/HeaderBg.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import BG from './bgheader.png'; 3 | 4 | export default styled.div` 5 | min-height: 100px; 6 | background-image: url(${BG}); 7 | background-color: #def0fb; 8 | background-position: 100% 0; 9 | `; 10 | -------------------------------------------------------------------------------- /Chapter01/starter/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /starter/app/containers/HomePage/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from "react"; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class HomePage extends PureComponent { 5 | render() { 6 | return

This is the HomePage Redux-book container!

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /starter/app/reducers.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from "redux"; 2 | 3 | import history from "utils/history"; 4 | 5 | export default function createReducer(injectedReducers = {}) { 6 | const rootReducer = combineReducers({ 7 | ...injectedReducers 8 | }); 9 | return rootReducer; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter01/starter/app/containers/HomePage/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | 3 | /* eslint-disable react/prefer-stateless-function */ 4 | export default class HomePage extends PureComponent { 5 | render() { 6 | return

This is the HomePage Redux-book container!

; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter01/starter/app/reducers.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | 3 | import history from 'utils/history'; 4 | 5 | export default function createReducer(injectedReducers = {}) { 6 | const rootReducer = combineReducers({ 7 | ...injectedReducers, 8 | }); 9 | return rootReducer; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter03/app/containers/AboutPage/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | import AboutPage from '../index'; 4 | 5 | it('should render correctly', () => { 6 | const component = renderer.create(); 7 | expect(component.toJSON()).toMatchSnapshot(); 8 | }); 9 | -------------------------------------------------------------------------------- /Chapter03/app/containers/Login/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | import AboutPage from '../index'; 4 | 5 | it('should render correctly', () => { 6 | const component = renderer.create(); 7 | expect(component.toJSON()).toMatchSnapshot(); 8 | }); 9 | -------------------------------------------------------------------------------- /Chapter03/app/containers/Register/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | import Register from '../index'; 4 | 5 | it('should render correctly', () => { 6 | const component = renderer.create(); 7 | expect(component.toJSON()).toMatchSnapshot(); 8 | }); 9 | -------------------------------------------------------------------------------- /Chapter05/app/containers/AboutPage/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | import AboutPage from '../index'; 4 | 5 | it('should render correctly', () => { 6 | const component = renderer.create(); 7 | expect(component.toJSON()).toMatchSnapshot(); 8 | }); 9 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Login/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | import AboutPage from '../index'; 4 | 5 | it('should render correctly', () => { 6 | const component = renderer.create(); 7 | expect(component.toJSON()).toMatchSnapshot(); 8 | }); 9 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Register/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | import Register from '../index'; 4 | 5 | it('should render correctly', () => { 6 | const component = renderer.create(); 7 | expect(component.toJSON()).toMatchSnapshot(); 8 | }); 9 | -------------------------------------------------------------------------------- /Chapter06/app/containers/User/style.css: -------------------------------------------------------------------------------- 1 | .form-user-containers { 2 | width: 100%; 3 | margin: auto; 4 | padding: 50px 10px; 5 | } 6 | 7 | .edit-form-user-containers .ant-form-item-label { 8 | line-height: 1; 9 | } 10 | 11 | .form-user-containers .add-user { 12 | font-size: 80%; 13 | margin-left: 10px; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter07/app/containers/User/style.css: -------------------------------------------------------------------------------- 1 | .form-user-containers { 2 | width: 100%; 3 | margin: auto; 4 | padding: 50px 10px; 5 | } 6 | 7 | .edit-form-user-containers .ant-form-item-label { 8 | line-height: 1; 9 | } 10 | 11 | .form-user-containers .add-user { 12 | font-size: 80%; 13 | margin-left: 10px; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter02/app/JS/__tests__/time-test.js: -------------------------------------------------------------------------------- 1 | jest.useFakeTimers(); 2 | 3 | test("waits 2 second before taking the x-ray", () => { 4 | const takeXray = require("../time"); 5 | takeXray(); 6 | 7 | expect(setTimeout).toHaveBeenCalledTimes(1); 8 | expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 2000); 9 | }); 10 | -------------------------------------------------------------------------------- /Chapter05/readme.MD: -------------------------------------------------------------------------------- 1 | # Chapter 5: Routing 2 | 3 | The main topics covered in this chapter are given below: 4 | 5 | - What is routing and why do we need it? 6 | - Using `react-router-dom` in our application. 7 | - Using `react-router-redux` in our application 8 | - Using `connected-react-router/immutable` 9 | - Further study 10 | -------------------------------------------------------------------------------- /starter/app/containers/App/selectors.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect'; 2 | 3 | const selectRouter = state => state.get('router'); 4 | 5 | const makeSelectLocation = () => 6 | createSelector(selectRouter, routerState => 7 | routerState.get('location').toJS(), 8 | ); 9 | 10 | export { makeSelectLocation }; 11 | -------------------------------------------------------------------------------- /Chapter05/app/components/Header/tests/__snapshots__/A.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should match the snapshot 1`] = ` 4 | .c0 { 5 | color: #41addd; 6 | padding: 2em 0; 7 | } 8 | 9 | .c0:hover { 10 | color: #6cc0e5; 11 | } 12 | 13 | 16 | `; 17 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Login/Loadable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Asynchronously loads the component for Login 3 | */ 4 | import loadable from 'loadable-components'; 5 | 6 | import LoadingIndicator from 'components/LoadingIndicator'; 7 | 8 | export default loadable(() => import('./index'), { 9 | LoadingComponent: LoadingIndicator, 10 | }); 11 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Login/Loadable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Asynchronously loads the component for Login 3 | */ 4 | import loadable from 'loadable-components'; 5 | 6 | import LoadingIndicator from 'components/LoadingIndicator'; 7 | 8 | export default loadable(() => import('./index'), { 9 | LoadingComponent: LoadingIndicator, 10 | }); 11 | -------------------------------------------------------------------------------- /Chapter03/app/containers/App/reducer.js: -------------------------------------------------------------------------------- 1 | import { fromJS } from 'immutable'; 2 | 3 | const initialState = fromJS({ 4 | loading: false, 5 | currentUser: {}, 6 | }); 7 | 8 | function appReducer(state = initialState, action) { 9 | switch (action.type) { 10 | } 11 | 12 | return state; 13 | } 14 | 15 | export default appReducer; 16 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Register/Loadable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Asynchronously loads the component for Register 3 | */ 4 | import loadable from 'loadable-components'; 5 | 6 | import LoadingIndicator from 'components/LoadingIndicator'; 7 | 8 | export default loadable(() => import('./index'), { 9 | LoadingComponent: LoadingIndicator, 10 | }); 11 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Register/Loadable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Asynchronously loads the component for Register 3 | */ 4 | import loadable from 'loadable-components'; 5 | 6 | import LoadingIndicator from 'components/LoadingIndicator'; 7 | 8 | export default loadable(() => import('./index'), { 9 | LoadingComponent: LoadingIndicator, 10 | }); 11 | -------------------------------------------------------------------------------- /Chapter06/app/containers/NotFoundPage/Loadable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Asynchronously loads the component for NotFoundPage 3 | */ 4 | import loadable from 'loadable-components'; 5 | 6 | import LoadingIndicator from 'components/LoadingIndicator'; 7 | 8 | export default loadable(() => import('./index'), { 9 | LoadingComponent: LoadingIndicator, 10 | }); 11 | -------------------------------------------------------------------------------- /Chapter07/app/containers/NotFoundPage/Loadable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Asynchronously loads the component for NotFoundPage 3 | */ 4 | import loadable from 'loadable-components'; 5 | 6 | import LoadingIndicator from 'components/LoadingIndicator'; 7 | 8 | export default loadable(() => import('./index'), { 9 | LoadingComponent: LoadingIndicator, 10 | }); 11 | -------------------------------------------------------------------------------- /starter/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | node_modules 5 | stats.json 6 | 7 | # Cruft 8 | .DS_Store 9 | npm-debug.log 10 | yarn-debug.log* 11 | yarn-error.log* 12 | .idea 13 | 14 | 15 | 16 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 17 | 18 | # dependencies 19 | -------------------------------------------------------------------------------- /Chapter05/app/components/Header/tests/__snapshots__/Img.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should match the snapshot 1`] = ` 4 | .c0 { 5 | width: 100%; 6 | margin: 0 auto; 7 | display: block; 8 | } 9 | 10 | test 15 | `; 16 | -------------------------------------------------------------------------------- /Chapter01/starter/app/configureStore.js: -------------------------------------------------------------------------------- 1 | import { createStore } from 'redux'; 2 | 3 | import createReducer from './reducers'; 4 | 5 | export default function configureStore(initialState = {}, history) { 6 | const store = createStore(createReducer()); 7 | 8 | // Extensions 9 | store.injectedReducers = {}; // Reducer registry 10 | 11 | return store; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter03/app/containers/AboutPage/redirect.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Route, Redirect } from "react-router-dom"; 3 | 4 | const redirect = () => ( 5 | 9 | loggedIn ? : 10 | } 11 | /> 12 | ); 13 | 14 | export default redirect; 15 | -------------------------------------------------------------------------------- /Chapter03/server/middlewares/frontendMiddleware.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require */ 2 | /* eslint arrow-parens: ["off"] */ 3 | module.exports = app => { 4 | const webpackConfig = require('../../webpack/webpack.dev.babel'); 5 | const addDevMiddlewares = require('./addDevMiddlewares'); 6 | addDevMiddlewares(app, webpackConfig); 7 | 8 | return app; 9 | }; 10 | -------------------------------------------------------------------------------- /Chapter05/app/containers/AboutPage/redirect.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Route, Redirect } from "react-router-dom"; 3 | 4 | const redirect = () => ( 5 | 9 | loggedIn ? : 10 | } 11 | /> 12 | ); 13 | 14 | export default redirect; 15 | -------------------------------------------------------------------------------- /Chapter05/server/middlewares/frontendMiddleware.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require */ 2 | /* eslint arrow-parens: ["off"] */ 3 | module.exports = app => { 4 | const webpackConfig = require('../../webpack/webpack.dev.babel'); 5 | const addDevMiddlewares = require('./addDevMiddlewares'); 6 | addDevMiddlewares(app, webpackConfig); 7 | 8 | return app; 9 | }; 10 | -------------------------------------------------------------------------------- /Chapter06/app/components/Header/tests/__snapshots__/A.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should match snapshot 1`] = ` 4 | .c0 { 5 | padding: 5px 15px; 6 | display: inline-block; 7 | } 8 | 9 | 15 | test 16 | 17 | `; 18 | -------------------------------------------------------------------------------- /Chapter07/app/components/Header/tests/__snapshots__/A.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should match snapshot 1`] = ` 4 | .c0 { 5 | padding: 5px 15px; 6 | display: inline-block; 7 | } 8 | 9 | 15 | test 16 | 17 | `; 18 | -------------------------------------------------------------------------------- /Chapter05/app/components/Header/tests/index.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { shallow } from 'enzyme'; 3 | 4 | import Header from '../index'; 5 | 6 | describe('
', () => { 7 | it('should render a div', () => { 8 | const renderedComponent = shallow(
); 9 | expect(renderedComponent.find('div')).toHaveLength(1); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /Chapter06/app/containers/LocaleToggle/messages.js: -------------------------------------------------------------------------------- 1 | import { defineMessages } from 'react-intl'; 2 | 3 | export const scope = 'boilerplate.containers.LocaleToggle'; 4 | 5 | export default defineMessages({ 6 | en: { 7 | id: `${scope}.en`, 8 | defaultMessage: 'en', 9 | }, 10 | de: { 11 | id: `${scope}.no`, 12 | defaultMessage: 'no', 13 | }, 14 | }); 15 | -------------------------------------------------------------------------------- /Chapter07/app/containers/LocaleToggle/messages.js: -------------------------------------------------------------------------------- 1 | import { defineMessages } from 'react-intl'; 2 | 3 | export const scope = 'boilerplate.containers.LocaleToggle'; 4 | 5 | export default defineMessages({ 6 | en: { 7 | id: `${scope}.en`, 8 | defaultMessage: 'en', 9 | }, 10 | de: { 11 | id: `${scope}.no`, 12 | defaultMessage: 'no', 13 | }, 14 | }); 15 | -------------------------------------------------------------------------------- /starter/app/containers/App/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Switch, Route } from "react-router-dom"; 3 | 4 | import HomePage from "containers/HomePage/Loadable"; 5 | import NotFoundPage from "containers/NotFoundPage/Loadable"; 6 | 7 | export default function App() { 8 | return ( 9 |
10 | 11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter02/app/React/__tests__/Header-test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import renderer from "react-test-renderer"; 3 | import Header from "../Header"; 4 | 5 | jest.mock("react-router-dom/Link", () => "Link"); 6 | 7 | it("should render correctly", () => { 8 | const component = renderer.create(
); 9 | expect(component.toJSON()).toMatchSnapshot(); 10 | }); 11 | -------------------------------------------------------------------------------- /Chapter05/app/components/Header/Logo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styled from 'styled-components'; 3 | 4 | import NormalImg from 'components/Img'; 5 | import LogoImg from './logo.png'; 6 | 7 | const Img = styled(NormalImg)` 8 | width: 50px; 9 | height: 50px; 10 | display: block; 11 | `; 12 | 13 | export default props => ; 14 | -------------------------------------------------------------------------------- /Chapter06/app/components/Header/tests/__snapshots__/HeaderBg.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should match snapshot 1`] = ` 4 | .c0 { 5 | min-height: 100px; 6 | background-image: url(IMAGE_MOCK); 7 | background-color: #def0fb; 8 | background-position: 100% 0; 9 | } 10 | 11 |
14 | `; 15 | -------------------------------------------------------------------------------- /Chapter07/app/components/Header/tests/__snapshots__/HeaderBg.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should match snapshot 1`] = ` 4 | .c0 { 5 | min-height: 100px; 6 | background-image: url(IMAGE_MOCK); 7 | background-color: #def0fb; 8 | background-position: 100% 0; 9 | } 10 | 11 |
14 | `; 15 | -------------------------------------------------------------------------------- /Chapter08/readme.MD: -------------------------------------------------------------------------------- 1 | # Chapter 8: Understanding the REST API 2 | 3 | The main topics covered in this chapter are given below: 4 | 5 | - Setting up the backend server in our application. 6 | - Learn how to setup REST API routing endpoints 7 | - Create models for endpoints 8 | - Create helper functions required for the endpoints 9 | - Create controllers required for the endpoints 10 | -------------------------------------------------------------------------------- /Chapter02/app/Redux/__tests__/__snapshots__/AlertContainer-test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render correctly 1`] = ``; 4 | 5 | exports[`should render correctly: dispatch function was called correctly 1`] = ` 6 | Array [ 7 | Array [ 8 | Object { 9 | "type": "REQUEST_ALERTS_LISTS", 10 | }, 11 | ], 12 | ] 13 | `; 14 | -------------------------------------------------------------------------------- /Chapter04/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Rask Lege", 3 | "name": "Create Rask Lege Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Chapter06/app/containers/LanguageProvider/selectors.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect'; 2 | import { initialState } from './reducer'; 3 | 4 | const selectLanguage = state => state.get('language', initialState); 5 | 6 | const makeSelectLocale = () => 7 | createSelector(selectLanguage, languageState => languageState.get('locale')); 8 | 9 | export { selectLanguage, makeSelectLocale }; 10 | -------------------------------------------------------------------------------- /Chapter07/app/containers/LanguageProvider/selectors.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect'; 2 | import { initialState } from './reducer'; 3 | 4 | const selectLanguage = state => state.get('language', initialState); 5 | 6 | const makeSelectLocale = () => 7 | createSelector(selectLanguage, languageState => languageState.get('locale')); 8 | 9 | export { selectLanguage, makeSelectLocale }; 10 | -------------------------------------------------------------------------------- /Chapter02/app/React/HeaderNav.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "react-router-dom/Link"; 3 | 4 | import Header from "./Header"; 5 | import SocialMediaLinks from "./SocialMediaLinks"; 6 | import Logo from "./Logo"; 7 | 8 | const HeaderNav = () => ( 9 |
10 | 11 |
12 | 13 |
14 | ); 15 | 16 | export default HeaderNav; 17 | -------------------------------------------------------------------------------- /Chapter04/config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This is a custom Jest transformer turning style imports into empty objects. 4 | // http://facebook.github.io/jest/docs/en/webpack.html 5 | 6 | module.exports = { 7 | process() { 8 | return 'module.exports = {};'; 9 | }, 10 | getCacheKey() { 11 | // The output is always the same. 12 | return 'cssTransform'; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Doctor/messages.js: -------------------------------------------------------------------------------- 1 | import { defineMessages } from 'react-intl'; 2 | 3 | export const scope = 'moment.containers.doctor'; 4 | 5 | export default defineMessages({ 6 | header: { 7 | id: `${scope}.header`, 8 | defaultMessage: 'Search doctor', 9 | }, 10 | placeholder: { 11 | id: `${scope}.placeholder`, 12 | defaultMessage: 'Enter doctor name', 13 | }, 14 | }); 15 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Doctor/messages.js: -------------------------------------------------------------------------------- 1 | import { defineMessages } from 'react-intl'; 2 | 3 | export const scope = 'moment.containers.doctor'; 4 | 5 | export default defineMessages({ 6 | header: { 7 | id: `${scope}.header`, 8 | defaultMessage: 'Search doctor', 9 | }, 10 | placeholder: { 11 | id: `${scope}.placeholder`, 12 | defaultMessage: 'Enter doctor name', 13 | }, 14 | }); 15 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Login/style.css: -------------------------------------------------------------------------------- 1 | .form-login-containers { 2 | width: 100%; 3 | margin: auto; 4 | max-width: 400px; 5 | padding: 50px 10px; 6 | } 7 | 8 | .form-login-containers .center { 9 | text-align: center; 10 | } 11 | 12 | .form-login-containers .ant-form-item-label { 13 | line-height: 1; 14 | } 15 | 16 | .form-login-containers .ant-form-item-with-help { 17 | margin-bottom: 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Login/style.css: -------------------------------------------------------------------------------- 1 | .form-login-containers { 2 | width: 100%; 3 | margin: auto; 4 | max-width: 400px; 5 | padding: 50px 10px; 6 | } 7 | 8 | .form-login-containers .center { 9 | text-align: center; 10 | } 11 | 12 | .form-login-containers .ant-form-item-label { 13 | line-height: 1; 14 | } 15 | 16 | .form-login-containers .ant-form-item-with-help { 17 | margin-bottom: 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Login/style.css: -------------------------------------------------------------------------------- 1 | .form-login-containers { 2 | width: 100%; 3 | margin: auto; 4 | max-width: 400px; 5 | padding: 50px 10px; 6 | } 7 | 8 | .form-login-containers .center { 9 | text-align: center; 10 | } 11 | 12 | .form-login-containers .ant-form-item-label { 13 | line-height: 1; 14 | } 15 | 16 | .form-login-containers .ant-form-item-with-help { 17 | margin-bottom: 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Login/constants.js: -------------------------------------------------------------------------------- 1 | export const LOGIN_REQUEST = 'raskLege/Login/LOGIN_REQUEST'; 2 | export const LOGIN_SUCCESS = 'raskLege/Login/LOGIN_SUCCESS'; 3 | export const LOGIN_FAILURE = 'raskLege/Login/LOGIN_FAILURE'; 4 | export const LOGOUT_REQUEST = 'raskLege/Login/LOGOUT_REQUEST'; 5 | export const LOGOUT_SUCCESS = 'raskLege/Login/LOGOUT_SUCCESS'; 6 | export const LOGOUT_FAILURE = 'raskLege/Login/LOGOUT_FAILURE'; 7 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Login/constants.js: -------------------------------------------------------------------------------- 1 | export const LOGIN_REQUEST = 'raskLege/Login/LOGIN_REQUEST'; 2 | export const LOGIN_SUCCESS = 'raskLege/Login/LOGIN_SUCCESS'; 3 | export const LOGIN_FAILURE = 'raskLege/Login/LOGIN_FAILURE'; 4 | export const LOGOUT_REQUEST = 'raskLege/Login/LOGOUT_REQUEST'; 5 | export const LOGOUT_SUCCESS = 'raskLege/Login/LOGOUT_SUCCESS'; 6 | export const LOGOUT_FAILURE = 'raskLege/Login/LOGOUT_FAILURE'; 7 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Login/constants.js: -------------------------------------------------------------------------------- 1 | export const LOGIN_REQUEST = 'raskLege/Login/LOGIN_REQUEST'; 2 | export const LOGIN_SUCCESS = 'raskLege/Login/LOGIN_SUCCESS'; 3 | export const LOGIN_FAILURE = 'raskLege/Login/LOGIN_FAILURE'; 4 | export const LOGOUT_REQUEST = 'raskLege/Login/LOGOUT_REQUEST'; 5 | export const LOGOUT_SUCCESS = 'raskLege/Login/LOGOUT_SUCCESS'; 6 | export const LOGOUT_FAILURE = 'raskLege/Login/LOGOUT_FAILURE'; 7 | -------------------------------------------------------------------------------- /Chapter02/app/Redux/AlertContainer.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { connect } from "react-redux"; 3 | 4 | import Alerts from "./Alerts"; 5 | 6 | class AlertContainer extends Component { 7 | componentDidMount() { 8 | this.props.dispatch({ type: "REQUEST_ALERTS_LISTS" }); 9 | } 10 | 11 | render() { 12 | return ; 13 | } 14 | } 15 | 16 | export default connect()(AlertContainer); 17 | -------------------------------------------------------------------------------- /Chapter04/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Register/style.css: -------------------------------------------------------------------------------- 1 | .form-register-containers { 2 | width: 100%; 3 | margin: auto; 4 | max-width: 400px; 5 | padding: 50px 10px; 6 | } 7 | 8 | .form-register-containers .center { 9 | text-align: center; 10 | } 11 | 12 | .form-register-containers .ant-form-item-label { 13 | line-height: 1; 14 | } 15 | 16 | .form-register-containers .ant-form-item-with-help { 17 | margin-bottom: 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter06/app/containers/NotFoundPage/messages.js: -------------------------------------------------------------------------------- 1 | /* 2 | * NotFoundPage Messages 3 | * 4 | * This contains all the text for the NotFoundPage component. 5 | */ 6 | import { defineMessages } from 'react-intl'; 7 | 8 | export const scope = 'boilerplate.containers.NotFoundPage'; 9 | 10 | export default defineMessages({ 11 | header: { 12 | id: `${scope}.header`, 13 | defaultMessage: 'Page not found.', 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Register/style.css: -------------------------------------------------------------------------------- 1 | .form-register-containers { 2 | width: 100%; 3 | margin: auto; 4 | max-width: 400px; 5 | padding: 50px 10px; 6 | } 7 | 8 | .form-register-containers .center { 9 | text-align: center; 10 | } 11 | 12 | .form-register-containers .ant-form-item-label { 13 | line-height: 1; 14 | } 15 | 16 | .form-register-containers .ant-form-item-with-help { 17 | margin-bottom: 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter07/app/containers/NotFoundPage/messages.js: -------------------------------------------------------------------------------- 1 | /* 2 | * NotFoundPage Messages 3 | * 4 | * This contains all the text for the NotFoundPage component. 5 | */ 6 | import { defineMessages } from 'react-intl'; 7 | 8 | export const scope = 'boilerplate.containers.NotFoundPage'; 9 | 10 | export default defineMessages({ 11 | header: { 12 | id: `${scope}.header`, 13 | defaultMessage: 'Page not found.', 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Register/style.css: -------------------------------------------------------------------------------- 1 | .form-register-containers { 2 | width: 100%; 3 | margin: auto; 4 | max-width: 400px; 5 | padding: 50px 10px; 6 | } 7 | 8 | .form-register-containers .center { 9 | text-align: center; 10 | } 11 | 12 | .form-register-containers .ant-form-item-label { 13 | line-height: 1; 14 | } 15 | 16 | .form-register-containers .ant-form-item-with-help { 17 | margin-bottom: 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter03/app/containers/AboutPage/__tests__/redirect-test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import renderer from "react-test-renderer"; 3 | import RedirectDemo from "../redirect"; 4 | 5 | jest.mock("react-router-dom", () => ({ Redirect: "Redirect", Route: "Route" })); 6 | 7 | it("should render correctly", () => { 8 | const component = renderer.create(); 9 | expect(component.toJSON()).toMatchSnapshot(); 10 | }); 11 | -------------------------------------------------------------------------------- /Chapter05/app/containers/AboutPage/__tests__/redirect-test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import renderer from "react-test-renderer"; 3 | import RedirectDemo from "../redirect"; 4 | 5 | jest.mock("react-router-dom", () => ({ Redirect: "Redirect", Route: "Route" })); 6 | 7 | it("should render correctly", () => { 8 | const component = renderer.create(); 9 | expect(component.toJSON()).toMatchSnapshot(); 10 | }); 11 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Register/actions.js: -------------------------------------------------------------------------------- 1 | import { 2 | REGISTER_REQUEST, 3 | REGISTER_SUCCESS, 4 | REGISTER_FAILURE, 5 | } from './constants'; 6 | 7 | export const onRegisterRequest = user => ({ type: REGISTER_REQUEST, user }); 8 | 9 | export const onRegisterSuccess = user => ({ type: REGISTER_SUCCESS, user }); 10 | 11 | export const onRegisterFailure = message => ({ 12 | type: REGISTER_FAILURE, 13 | message, 14 | }); 15 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Register/actions.js: -------------------------------------------------------------------------------- 1 | import { 2 | REGISTER_REQUEST, 3 | REGISTER_SUCCESS, 4 | REGISTER_FAILURE, 5 | } from './constants'; 6 | 7 | export const onRegisterRequest = user => ({ type: REGISTER_REQUEST, user }); 8 | 9 | export const onRegisterSuccess = user => ({ type: REGISTER_SUCCESS, user }); 10 | 11 | export const onRegisterFailure = message => ({ 12 | type: REGISTER_FAILURE, 13 | message, 14 | }); 15 | -------------------------------------------------------------------------------- /Chapter05/app/components/Header/NavBar.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export default styled.div` 4 | display: flex; 5 | padding-right: 10px; 6 | align-items: center; 7 | background-color: #204666; 8 | 9 | & > div { 10 | flex: 1; 11 | display: flex; 12 | 13 | &:last-child { 14 | justify-content: flex-end; 15 | } 16 | } 17 | 18 | & > button { 19 | line-height: 0; 20 | } 21 | `; 22 | -------------------------------------------------------------------------------- /Chapter05/app/containers/Register/actions.js: -------------------------------------------------------------------------------- 1 | import { 2 | REGISTER_REQUEST, 3 | REGISTER_SUCCESS, 4 | REGISTER_FAILURE, 5 | } from './constants'; 6 | 7 | export const onRegisterRequest = user => 8 | console.log(user) || { type: REGISTER_REQUEST, user }; 9 | 10 | export const onRegisterSuccess = user => ({ type: REGISTER_SUCCESS, user }); 11 | 12 | export const onRegisterFailure = message => ({ 13 | type: REGISTER_FAILURE, 14 | message, 15 | }); 16 | -------------------------------------------------------------------------------- /Chapter06/app/containers/LanguageProvider/tests/selectors.test.js: -------------------------------------------------------------------------------- 1 | import { fromJS } from 'immutable'; 2 | 3 | import { selectLanguage } from '../selectors'; 4 | 5 | describe('selectLanguage', () => { 6 | it('should select the global state', () => { 7 | const globalState = fromJS({}); 8 | const mockedState = fromJS({ 9 | language: globalState, 10 | }); 11 | expect(selectLanguage(mockedState)).toEqual(globalState); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /Chapter07/app/containers/LanguageProvider/tests/selectors.test.js: -------------------------------------------------------------------------------- 1 | import { fromJS } from 'immutable'; 2 | 3 | import { selectLanguage } from '../selectors'; 4 | 5 | describe('selectLanguage', () => { 6 | it('should select the global state', () => { 7 | const globalState = fromJS({}); 8 | const mockedState = fromJS({ 9 | language: globalState, 10 | }); 11 | expect(selectLanguage(mockedState)).toEqual(globalState); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /Chapter01/getting-started/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | module.exports = { 3 | mode: "development", 4 | entry: "./src/app/app.js", 5 | output: { 6 | path: path.resolve("dist"), 7 | filename: "main.js" 8 | }, 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.jsx?$/, 13 | use: { 14 | loader: "babel-loader" 15 | }, 16 | exclude: /node_modules/ 17 | } 18 | ] 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /Chapter04/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { render } from "react-dom"; 3 | import { createStore } from "redux"; 4 | import { Provider } from "react-redux"; 5 | 6 | import App from "./components/App"; 7 | import rootReducer from "./reducers"; 8 | 9 | import "./App.css"; 10 | 11 | const store = createStore(rootReducer); 12 | 13 | render( 14 | 15 | 16 | , 17 | document.getElementById("root") 18 | ); 19 | -------------------------------------------------------------------------------- /Chapter06/app/components/LoadingIndicator/tests/index.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | import 'jest-styled-components'; 4 | 5 | import LoadingIndicator from '../index'; 6 | 7 | describe('', () => { 8 | it('should match the snapshot', () => { 9 | const renderedComponent = renderer.create().toJSON(); 10 | expect(renderedComponent).toMatchSnapshot(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /Chapter07/app/components/LoadingIndicator/tests/index.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | import 'jest-styled-components'; 4 | 5 | import LoadingIndicator from '../index'; 6 | 7 | describe('', () => { 8 | it('should match the snapshot', () => { 9 | const renderedComponent = renderer.create().toJSON(); 10 | expect(renderedComponent).toMatchSnapshot(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /Chapter02/app/React/Header.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "react-router-dom/Link"; 3 | 4 | const Header = () => ( 5 |
    6 |
  • 7 | Home 8 |
  • 9 |
  • 10 | Services 11 |
  • 12 |
  • 13 | Contact Us 14 |
  • 15 |
  • 16 | Login 17 |
  • 18 |
19 | ); 20 | 21 | export default Header; 22 | -------------------------------------------------------------------------------- /Chapter03/app/containers/HomePage/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import renderer from "react-test-renderer"; 3 | import HomePage from "../index"; 4 | 5 | jest.mock("react-router-dom", () => ({ 6 | Link: "Link", 7 | Route: ({ children, path }) => children({ match: path === "/link-path" }) 8 | })); 9 | 10 | it("should render correctly", () => { 11 | const component = renderer.create(); 12 | expect(component.toJSON()).toMatchSnapshot(); 13 | }); 14 | -------------------------------------------------------------------------------- /Chapter05/app/containers/HomePage/__tests__/index-test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import renderer from "react-test-renderer"; 3 | import HomePage from "../index"; 4 | 5 | jest.mock("react-router-dom", () => ({ 6 | Link: "Link", 7 | Route: ({ children, path }) => children({ match: path === "/link-path" }) 8 | })); 9 | 10 | it("should render correctly", () => { 11 | const component = renderer.create(); 12 | expect(component.toJSON()).toMatchSnapshot(); 13 | }); 14 | -------------------------------------------------------------------------------- /Chapter06/app/containers/App/tests/actions.test.js: -------------------------------------------------------------------------------- 1 | import { IS_USER_AUTHENTICATED } from '../constants'; 2 | 3 | import { onApplicationLoad } from '../actions'; 4 | 5 | describe('App Actions', () => { 6 | describe('onApplicationLoad', () => { 7 | it('should return the correct type', () => { 8 | const expectedResult = { 9 | type: IS_USER_AUTHENTICATED, 10 | }; 11 | 12 | expect(onApplicationLoad()).toEqual(expectedResult); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /Chapter07/app/containers/App/tests/actions.test.js: -------------------------------------------------------------------------------- 1 | import { IS_USER_AUTHENTICATED } from '../constants'; 2 | 3 | import { onApplicationLoad } from '../actions'; 4 | 5 | describe('App Actions', () => { 6 | describe('onApplicationLoad', () => { 7 | it('should return the correct type', () => { 8 | const expectedResult = { 9 | type: IS_USER_AUTHENTICATED, 10 | }; 11 | 12 | expect(onApplicationLoad()).toEqual(expectedResult); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /Chapter05/app/containers/User/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Switch, Route } from 'react-router-dom'; 3 | 4 | import All from './All'; 5 | import AddUser from './Add'; 6 | import EditUser from './Edit'; 7 | 8 | const User = () => ( 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | 16 | export default User; 17 | -------------------------------------------------------------------------------- /Chapter06/app/components/Header/NavBar.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export default styled.div` 4 | display: flex; 5 | padding-right: 10px; 6 | align-items: center; 7 | background-color: #204666; 8 | 9 | & > div { 10 | flex-shrink: 0; 11 | display: flex; 12 | align-items: center; 13 | 14 | &:last-child { 15 | flex: 1; 16 | justify-content: flex-end; 17 | } 18 | } 19 | 20 | button { 21 | line-height: 0; 22 | } 23 | `; 24 | -------------------------------------------------------------------------------- /Chapter07/app/components/Header/NavBar.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export default styled.div` 4 | display: flex; 5 | padding-right: 10px; 6 | align-items: center; 7 | background-color: #204666; 8 | 9 | & > div { 10 | flex-shrink: 0; 11 | display: flex; 12 | align-items: center; 13 | 14 | &:last-child { 15 | flex: 1; 16 | justify-content: flex-end; 17 | } 18 | } 19 | 20 | button { 21 | line-height: 0; 22 | } 23 | `; 24 | -------------------------------------------------------------------------------- /Chapter05/app/components/Footer/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import A from 'components/A'; 4 | import Wrapper from './Wrapper'; 5 | 6 | function Footer() { 7 | return ( 8 | 9 |
This project is licensed under the MIT license.
10 |
11 | Made with love by : 12 | S.K. Mukhiya 13 |
14 |
15 | ); 16 | } 17 | 18 | export default Footer; 19 | -------------------------------------------------------------------------------- /Chapter06/app/containers/App/tests/reducer.test.js: -------------------------------------------------------------------------------- 1 | import { fromJS } from 'immutable'; 2 | 3 | import appReducer from '../reducer'; 4 | 5 | describe('appReducer', () => { 6 | let state; 7 | beforeEach(() => { 8 | state = fromJS({ 9 | loading: false, 10 | currentUser: {}, 11 | }); 12 | }); 13 | 14 | it('should return the initial state', () => { 15 | const expectedResult = state; 16 | expect(appReducer(undefined, {})).toEqual(expectedResult); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /Chapter06/app/containers/LanguageProvider/tests/actions.test.js: -------------------------------------------------------------------------------- 1 | import { changeLocale } from '../actions'; 2 | 3 | import { CHANGE_LOCALE } from '../constants'; 4 | 5 | describe('LanguageProvider actions', () => { 6 | describe('Change Local Action', () => { 7 | it('has a type of CHANGE_LOCALE', () => { 8 | const expected = { 9 | type: CHANGE_LOCALE, 10 | locale: 'de', 11 | }; 12 | expect(changeLocale('de')).toEqual(expected); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /Chapter06/app/containers/NotFoundPage/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * NotFoundPage 3 | * 4 | * This is the page we show when the user visits a url that doesn't have a route 5 | */ 6 | 7 | import React from 'react'; 8 | import { FormattedMessage } from 'react-intl'; 9 | import messages from './messages'; 10 | 11 | export default function NotFound() { 12 | return ( 13 |
14 |

15 | 16 |

17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /Chapter07/app/containers/App/tests/reducer.test.js: -------------------------------------------------------------------------------- 1 | import { fromJS } from 'immutable'; 2 | 3 | import appReducer from '../reducer'; 4 | 5 | describe('appReducer', () => { 6 | let state; 7 | beforeEach(() => { 8 | state = fromJS({ 9 | loading: false, 10 | currentUser: {}, 11 | }); 12 | }); 13 | 14 | it('should return the initial state', () => { 15 | const expectedResult = state; 16 | expect(appReducer(undefined, {})).toEqual(expectedResult); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /Chapter07/app/containers/LanguageProvider/tests/actions.test.js: -------------------------------------------------------------------------------- 1 | import { changeLocale } from '../actions'; 2 | 3 | import { CHANGE_LOCALE } from '../constants'; 4 | 5 | describe('LanguageProvider actions', () => { 6 | describe('Change Local Action', () => { 7 | it('has a type of CHANGE_LOCALE', () => { 8 | const expected = { 9 | type: CHANGE_LOCALE, 10 | locale: 'de', 11 | }; 12 | expect(changeLocale('de')).toEqual(expected); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /Chapter07/app/containers/NotFoundPage/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * NotFoundPage 3 | * 4 | * This is the page we show when the user visits a url that doesn't have a route 5 | */ 6 | 7 | import React from 'react'; 8 | import { FormattedMessage } from 'react-intl'; 9 | import messages from './messages'; 10 | 11 | export default function NotFound() { 12 | return ( 13 |
14 |

15 | 16 |

17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /Chapter06/app/containers/Doctor/actions.js: -------------------------------------------------------------------------------- 1 | import { 2 | DOCTOR_SEARCH_REQUEST, 3 | DOCTOR_SEARCH_SUCCESS, 4 | DOCTOR_SEARCH_FAILURE, 5 | } from './constants'; 6 | 7 | export const onSearchRequest = params => ({ 8 | type: DOCTOR_SEARCH_REQUEST, 9 | params, 10 | }); 11 | 12 | export const onSearchSuccess = doctors => ({ 13 | type: DOCTOR_SEARCH_SUCCESS, 14 | doctors, 15 | }); 16 | 17 | export const onSearchFailure = message => ({ 18 | type: DOCTOR_SEARCH_FAILURE, 19 | message, 20 | }); 21 | -------------------------------------------------------------------------------- /Chapter07/app/containers/DevTools.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createDevTools } from 'redux-devtools'; 3 | import LogMonitor from 'redux-devtools-log-monitor'; 4 | import DockMonitor from 'redux-devtools-dock-monitor'; 5 | 6 | const DevTools = createDevTools( 7 | 12 | 13 | , 14 | ); 15 | 16 | export default DevTools; 17 | -------------------------------------------------------------------------------- /Chapter07/app/containers/Doctor/actions.js: -------------------------------------------------------------------------------- 1 | import { 2 | DOCTOR_SEARCH_REQUEST, 3 | DOCTOR_SEARCH_SUCCESS, 4 | DOCTOR_SEARCH_FAILURE, 5 | } from './constants'; 6 | 7 | export const onSearchRequest = params => ({ 8 | type: DOCTOR_SEARCH_REQUEST, 9 | params, 10 | }); 11 | 12 | export const onSearchSuccess = doctors => ({ 13 | type: DOCTOR_SEARCH_SUCCESS, 14 | doctors, 15 | }); 16 | 17 | export const onSearchFailure = message => ({ 18 | type: DOCTOR_SEARCH_FAILURE, 19 | message, 20 | }); 21 | -------------------------------------------------------------------------------- /Chapter02/readme.MD: -------------------------------------------------------------------------------- 1 | # Chapter 2: Testing 2 | 3 | ## Lists of Topics 4 | 5 | - Setting up with Jest 6 | - Testing ES6 Functions 7 | - Testing a Function 8 | - General testing scenario 9 | - Time mocks 10 | - Testing React Components 11 | - React component and mocking Component 12 | - Multiple React Component 13 | - Testing event handlers 14 | - Testing Redux 15 | - Testing action creators 16 | - Testing reducers 17 | - Testing Higher order functions 18 | - Summary 19 | - Further Reading 20 | -------------------------------------------------------------------------------- /Chapter03/readme.MD: -------------------------------------------------------------------------------- 1 | # Chapter 3: Routing 2 | 3 | The main topics covered in this chapter are given below: 4 | 5 | - What is routing and why do we need it? 6 | - Using `react-router-dom` in our application. 7 | - Using `connected-react-router/immutable` 8 | - Further study 9 | 10 | ## References 11 | 12 | - [`react-router-dom`](https://github.com/ReactTraining/react-router/tree/master/packages/react-router-dom) 13 | - [`connected-react-router/immutable`](https://github.com/supasate/connected-react-router) 14 | -------------------------------------------------------------------------------- /starter/app/containers/App/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | * AppConstants 3 | * Each action has a corresponding type, which the reducer knows and picks up on. 4 | * To avoid weird typos between the reducer and the actions, we save them as 5 | * constants here. We prefix them with 'yourproject/YourComponent' so we avoid 6 | * reducers accidentally picking up actions they shouldn't. 7 | * 8 | * Follow this format: 9 | * export const YOUR_ACTION_CONSTANT = 'yourproject/YourContainer/YOUR_ACTION_CONSTANT'; 10 | */ 11 | -------------------------------------------------------------------------------- /Chapter06/app/containers/App/style.css: -------------------------------------------------------------------------------- 1 | h1 { 2 | font-size: 2em; 3 | margin-bottom: 0.25em; 4 | } 5 | 6 | .logo-header { 7 | width: 50px; 8 | height: 50px; 9 | display: block; 10 | } 11 | 12 | form.normal-form { 13 | width: 100%; 14 | margin: auto; 15 | max-width: 400px; 16 | padding: 50px 10px; 17 | } 18 | 19 | .normal-form .ant-form-item-label { 20 | line-height: 0; 21 | } 22 | 23 | .center { 24 | text-align: center; 25 | } 26 | 27 | .normal-form .btn-submit { 28 | width: 100%; 29 | } 30 | -------------------------------------------------------------------------------- /Chapter07/app/containers/App/style.css: -------------------------------------------------------------------------------- 1 | h1 { 2 | font-size: 2em; 3 | margin-bottom: 0.25em; 4 | } 5 | 6 | .logo-header { 7 | width: 50px; 8 | height: 50px; 9 | display: block; 10 | } 11 | 12 | form.normal-form { 13 | width: 100%; 14 | margin: auto; 15 | max-width: 400px; 16 | padding: 50px 10px; 17 | } 18 | 19 | .normal-form .ant-form-item-label { 20 | line-height: 0; 21 | } 22 | 23 | .center { 24 | text-align: center; 25 | } 26 | 27 | .normal-form .btn-submit { 28 | width: 100%; 29 | } 30 | -------------------------------------------------------------------------------- /Chapter06/app/utils/withIntl.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { intlShape, injectIntl } from 'react-intl'; 3 | 4 | export const withIntl = Component => { 5 | const newComponent = props => { 6 | const args = { ...props }; 7 | args.formatMessage = message => props.intl.formatMessage(message); 8 | return ; 9 | }; 10 | 11 | newComponent.propTypes = { 12 | intl: intlShape.isRequired, 13 | }; 14 | 15 | return injectIntl(newComponent); 16 | }; 17 | 18 | export default withIntl; 19 | -------------------------------------------------------------------------------- /Chapter07/app/utils/withIntl.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { intlShape, injectIntl } from 'react-intl'; 3 | 4 | export const withIntl = Component => { 5 | const newComponent = props => { 6 | const args = { ...props }; 7 | args.formatMessage = message => props.intl.formatMessage(message); 8 | return ; 9 | }; 10 | 11 | newComponent.propTypes = { 12 | intl: intlShape.isRequired, 13 | }; 14 | 15 | return injectIntl(newComponent); 16 | }; 17 | 18 | export default withIntl; 19 | -------------------------------------------------------------------------------- /Chapter02/app/React/__tests__/HeaderNav-test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import renderer from "react-test-renderer"; 3 | 4 | import HeaderNav from "../HeaderNav"; 5 | 6 | jest.mock("react-router-dom/Link", () => "Link"); 7 | jest.mock("../Header", () => "Header"); 8 | jest.mock("../SocialMediaLinks", () => "SocialMediaLinks"); 9 | jest.mock("../Logo", () => "Logo"); 10 | 11 | it("should render correctly", () => { 12 | const component = renderer.create(); 13 | expect(component.toJSON()).toMatchSnapshot(); 14 | }); 15 | -------------------------------------------------------------------------------- /Chapter02/app/Redux/__tests__/actionCreators-test.js: -------------------------------------------------------------------------------- 1 | import * as actions from "../actionCreators"; 2 | 3 | describe("actions", () => { 4 | it("should create an action to add a doctor", () => { 5 | const newDoctorData = { 6 | name: "Dr. Yoshmi Mukhiya", 7 | email: "yoshmi@gmail.com", 8 | age: 22 9 | }; 10 | 11 | const expectedAction = { 12 | type: "ADD_NEW_DOCTOR", 13 | newDoctorData 14 | }; 15 | expect(actions.addNewDoctor(newDoctorData)).toEqual(expectedAction); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /Chapter02/app/Redux/reducers.js: -------------------------------------------------------------------------------- 1 | import { ADD_NEW_DOCTOR } from "./actionTypes"; 2 | 3 | const initialState = [ 4 | { 5 | newDoctorData: {}, 6 | completed: false 7 | } 8 | ]; 9 | 10 | export default function addDoctor(state = initialState, action) { 11 | switch (action.type) { 12 | case ADD_NEW_DOCTOR: 13 | return [ 14 | { 15 | completed: false, 16 | data: action.newDoctorData 17 | }, 18 | ...state 19 | ]; 20 | 21 | default: 22 | return state; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chapter03/app/reducers.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux-immutable'; 2 | import { connectRouter } from 'connected-react-router/immutable'; 3 | 4 | import history from 'utils/history'; 5 | import globalReducer from 'containers/App/reducer'; 6 | 7 | export default function createReducer(injectedReducers = {}) { 8 | const rootReducer = combineReducers({ 9 | global: globalReducer, 10 | ...injectedReducers, 11 | }); 12 | 13 | const mergeWithRouterState = connectRouter(history); 14 | return mergeWithRouterState(rootReducer); 15 | } 16 | -------------------------------------------------------------------------------- /Chapter06/README.md: -------------------------------------------------------------------------------- 1 | # Rask Lege 2 | 3 | ## DB Schema 4 | 5 | https://www.lucidchart.com/invitations/accept/f7325a1b-cff5-4d30-946a-79984348537c 6 | 7 | screenshot 2018-11-26 at 11 21 27 8 | 9 | # Getting Started 10 | 11 | ## Install dependencies 12 | 13 | ``` 14 | yarn install 15 | ``` 16 | 17 | ## Start the web 18 | 19 | ``` 20 | yarn start 21 | ``` 22 | 23 | The web admin should be available at http://localhost:3000/ 24 | -------------------------------------------------------------------------------- /Chapter06/app/components/Footer/tests/__snapshots__/Wrapper.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should match snapshot 1`] = ` 4 | .c0 { 5 | display: -webkit-box; 6 | display: -webkit-flex; 7 | display: -ms-flexbox; 8 | display: flex; 9 | -webkit-box-pack: justify; 10 | -webkit-justify-content: space-between; 11 | -ms-flex-pack: justify; 12 | justify-content: space-between; 13 | padding: 3em 0; 14 | border-top: 1px solid #666; 15 | } 16 | 17 |