├── .eslintrc.json
├── .gitignore
├── .prettierrc.js
├── .travis.yml
├── LICENSE
├── README.md
├── babel.config.js
├── config
├── config.default.json
└── config.js
├── docs
├── 715.7dd94fe17002b841b25c.css
├── 896.7dd94fe17002b841b25c.css
├── 956.7dd94fe17002b841b25c.css
├── components-Sections-ReactRouter-Routes-DecrementRoute.b39cfef421931f6623fe.js
├── components-Sections-ReactRouter-Routes-IncrementRoute.b39cfef421931f6623fe.js
├── components-Sections-ReactRouter-Routes-ResetRoute.b39cfef421931f6623fe.js
├── favicon.ico
├── index.html
├── main.b39cfef421931f6623fe.js
├── main.e6747817a710beefd9ef.css
├── manifest.b39cfef421931f6623fe.js
├── vendor.b39cfef421931f6623fe.js
└── vendor.b39cfef421931f6623fe.js.LICENSE.txt
├── package-lock.json
├── package.json
├── postcss.config.js
├── scripts
└── buildInfo.js
├── server.js
├── src
├── Bootstrap.tsx
├── Root.tsx
├── assets
│ ├── favicon.ico
│ └── logo.png
├── components
│ ├── App.tsx
│ ├── Footer
│ │ ├── Footer.tsx
│ │ ├── GithubButtons
│ │ │ ├── GithubButton.tsx
│ │ │ ├── GithubButtons.tsx
│ │ │ ├── index.ts
│ │ │ └── styles
│ │ │ │ ├── GithubButton.scss
│ │ │ │ └── GithubButtons.scss
│ │ └── index.ts
│ ├── Sections
│ │ ├── GenericSection.tsx
│ │ ├── ReactRouter
│ │ │ ├── AsyncTabbedRouter.js
│ │ │ ├── ChunkLoadingIcon.tsx
│ │ │ ├── ReactRouter.tsx
│ │ │ ├── Routes
│ │ │ │ ├── DecrementRoute.tsx
│ │ │ │ ├── IncrementRoute.tsx
│ │ │ │ ├── ResetRoute.tsx
│ │ │ │ ├── RouteContent.tsx
│ │ │ │ └── styles
│ │ │ │ │ └── RouteContent.scss
│ │ │ ├── index.ts
│ │ │ └── styles
│ │ │ │ └── ChunkLoadingIcon.scss
│ │ ├── ReduxEntity
│ │ │ ├── Entities.tsx
│ │ │ ├── Entity.tsx
│ │ │ ├── Entity
│ │ │ │ ├── EntityData.tsx
│ │ │ │ ├── EntityFailure.tsx
│ │ │ │ ├── EntityLoading.tsx
│ │ │ │ ├── EntityMissing.tsx
│ │ │ │ └── EntityReset.tsx
│ │ │ ├── ReduxEntity.tsx
│ │ │ ├── index.ts
│ │ │ └── styles
│ │ │ │ └── ReduxEntity.scss
│ │ └── ReduxState
│ │ │ ├── ReduxState.tsx
│ │ │ └── index.ts
│ ├── common
│ │ ├── Button.tsx
│ │ ├── Icon.tsx
│ │ ├── Link.tsx
│ │ ├── bulma
│ │ │ ├── NavBar.tsx
│ │ │ └── styles
│ │ │ │ └── NavBar.scss
│ │ └── index.ts
│ └── styles
│ │ └── App.scss
├── const
│ └── index.ts
├── global.ts
├── index.html
├── reducers
│ ├── counter
│ │ ├── actions.ts
│ │ └── reducer.ts
│ ├── entities
│ │ ├── actions.ts
│ │ ├── reducer.ts
│ │ └── types.ts
│ ├── index.ts
│ └── store
│ │ ├── configure-store.dev.ts
│ │ ├── configure-store.prod.ts
│ │ └── index.ts
├── services
│ ├── common
│ │ ├── config-service.js
│ │ └── node-service.js
│ ├── data
│ │ ├── ajax-service.ts
│ │ └── data-access-service.ts
│ ├── domain
│ │ └── domain-service.ts
│ └── util
│ │ └── index.ts
└── styles
│ ├── global.scss
│ └── mixins.scss
├── tsconfig.json
└── webpack.config.js
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "node": true,
5 | "jest": true,
6 | "es6": true
7 | },
8 | "globals": {
9 | "_": true
10 | },
11 | "parser": "@typescript-eslint/parser",
12 | "parserOptions": {
13 | "ecmaVersion": 7,
14 | "sourceType": "module",
15 | "ecmaFeatures": {
16 | "jsx": true
17 | }
18 | },
19 | "plugins": ["react", "@typescript-eslint"],
20 | "extends": ["eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended"],
21 | "settings": {
22 | "react": {
23 | "pragma": "React",
24 | "version": "16.6.3"
25 | }
26 | },
27 | "overrides": [
28 | {
29 | "files": ["*.js"],
30 | "rules": {
31 | "@typescript-eslint/no-var-requires": "off"
32 | }
33 | }
34 | ],
35 | "rules": {
36 | "eqeqeq": [2, "always"],
37 | "no-console": ["error", { "allow": ["log", "warn", "error"] }],
38 | "no-debugger": 2,
39 | "no-var": 1,
40 | "quotes": [2, "single"],
41 | "semi": [2, "always"],
42 | "space-before-function-paren": ["off"],
43 | "max-len": ["error", { "code": 120 }],
44 | "comma-dangle": ["off"]
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .jekyll-metadata
2 | .htaccess
3 | .DS_Store
4 | .sass-cache
5 | Gemfile.lock
6 | _site/
7 | _drafts/
8 |
9 | # Logs
10 | logs
11 | *.log
12 |
13 | # Dependency directory
14 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
15 | node_modules
16 |
17 | # Build
18 | dist
19 |
20 | # IntelliJ
21 | .idea
22 | /*.iml
23 |
24 | # Coverage reports
25 | /.nyc-coverage
26 | /.nyc-coverage-temp
27 | /lint-report.html
28 | /.nyc_output/
29 |
30 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | trailingComma: 'es5',
3 | tabWidth: 2,
4 | singleQuote: true,
5 | printWidth: 120,
6 | };
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '10'
4 | - '12'
5 | after_success: npm run coverage
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2020 Mike Chabot
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #
2 |
3 | A slightly opinionated yet dead simple boilerplate for ReactJS, Webpack 4, and React Router v4.
4 |
5 | :heart: Async chunk loading
6 |
7 | :heart: Typescript
8 |
9 | :heart: React 17
10 |
11 | :heart: Webpack 5
12 |
13 | :heart: React Router v5
14 |
15 | :heart: Redux v4
16 |
17 | :heart: Code splitting
18 |
19 |
20 |
31 |
32 | ---
33 |
34 | ## Table of Contents
35 |
36 | - [Live Demo](#live-demo)
37 | - [Features](#features)
38 | - [Getting Started](#getting-started)
39 | - [Custom Configuration](#custom-config)
40 |
41 | ## Live Demo
42 |
43 | http://mikechabot.github.io/react-boilerplate
44 |
45 | ---
46 |
47 | ## Features
48 |
49 | #### Build Process
50 |
51 | - [Typescript](https://www.typescriptlang.org/) support
52 | - Bundled with [webpack 5](https://webpack.js.org/configuration/)
53 | - Implements async chunk loading via [@loadable/react](https://loadable-components.com/)
54 | - Supports ES6 via [Babel](https://babeljs.io/) transpiling
55 |
56 | #### State Management
57 |
58 | - [redux-entity](https://github.com/mikechabot/redux-entity) for domain entity management
59 | - [redux-thunk](https://github.com/gaearon/redux-thunk) for [asynchronous actions](https://github.com/mikechabot/react-boilerplate/blob/master/src/reducers/entities/actions.ts)
60 | - [redux-logger](https://github.com/theaqua/redux-logger) for capturing actions
61 |
62 | #### Routing
63 |
64 | - [react-router v5](https://github.com/reactjs/react-router) for client-side [routing](https://github.com/mikechabot/react-boilerplate/blob/master/src/Root.tsx#L12)
65 | - [Async chunk loading](https://github.com/mikechabot/react-boilerplate/blob/master/src/components/Sections/ReactRouter/AsyncTabbedRouter.js#L15) at the `react-router` level
66 |
67 | #### HTTP
68 |
69 | - [Customizable](https://github.com/mikechabot/react-boilerplate/blob/master/src/services/data/ajax-service.js#L8), [Promise-based](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) HTTP support via [Axios](https://github.com/mzabriskie/axios)
70 | - Utilizes a [a generic data service](https://github.com/mikechabot/react-boilerplate/blob/master/src/services/data/data-access-service.ts#L30) to easily fetch data
71 | - Example of [implementing the data service](https://github.com/mikechabot/react-boilerplate/blob/master/src/services/domain/domain-service.ts#L7)
72 |
73 | #### Styling
74 |
75 | - Supports [SCSS & SASS](http://sass-lang.com/) syntax
76 | - Browser compatibility via [autoprefixing](https://github.com/postcss/autoprefixer)
77 | - [Bulma](https://bulma.io/documentation/overview/start/) for out-of-the-box styling
78 |
79 | #### Develop & Deploy
80 |
81 | - Environmental configurations for both webpack and redux
82 | - **Dev**: [webpack-dev-server](https://webpack.js.org/configuration/dev-server/) with [react-refresh-webpack-plugin](https://github.com/pmmmwh/react-refresh-webpack-plugin). `redux-logger` enabled
83 | - **Prod**: [Express](http://expressjs.com/) server with `redux-logger` disabled
84 |
85 | ---
86 |
87 | ## Getting Started
88 |
89 | 1. `$ git clone https://github.com/mikechabot/react-boilerplate.git`
90 | 2. `$ npm install`
91 | 3. Launch environment:
92 | - **Production**: `$ npm start`
93 | - **Development**: `$ npm run dev`
94 | - Available at http://localhost:3060
95 | > Update port via [config.default.json](https://github.com/mikechabot/react-boilerplate/blob/master/config/config.default.json#L3), or override via [Custom Configuration](#custom-config)
96 | 4. Build assets for production:
97 | - `$ npm run build:prod`
98 |
99 | ---
100 |
101 | ## Custom Configuration
102 |
103 | Use [`cross-env`](https://github.com/kentcdodds/cross-env) or a comparable library/command to set the `ENV_CONFIG_PATH` to the path of your JSON configuration file:
104 |
105 | `$ cross-env ENV_CONFIG_PATH=/path/to/config.json npm start`
106 |
107 | > **Note**: This path is made available to Webpack **only**, however the contents of the file are stamped on a global variable during the build process (`process.env.APP_CONFIG`, see [webpack.config.js](https://github.com/mikechabot/react-boilerplate/blob/master/webpack.config.js#L46)), which is then accessible via the [ConfigService](https://github.com/mikechabot/react-boilerplate/blob/master/src/services/common/config-service.js#L19).
108 |
109 | If your configuration is loaded successfully, you can expect to see the following indicator during startup:
110 |
111 | ```
112 | ** Using custom configuration located at "/path/to/config.json" **
113 | ```
114 |
115 | #### Example
116 |
117 | Using configuration file @ `C:\_workspaces\custom-config.json`
118 |
119 | ```bash
120 | $ cross-env ENV_CONFIG_PATH="C:\_workspaces\custom-config.json" npm start
121 |
122 | > react-boilerplate@5.0.0 start C:\_workspaces\react-boilerplate
123 | > npm run build:prod && npm run start-prod-server
124 |
125 |
126 | > react-boilerplate@5.0.0 build:prod C:\_workspaces\react-boilerplate
127 | > npm run clean && cross-env NODE_ENV=production webpack --progress --colors
128 |
129 |
130 | > react-boilerplate@5.0.0 clean C:\_workspaces\react-boilerplate
131 | > rm -rf ./docs
132 |
133 | ** Using custom configuration located at "C:\_workspaces\custom-config.json" **
134 | __ __ _ __ __ __
135 | _______ ___ _____/ /_____/ / ___ (_) /__ _______ / /__ _/ /____
136 | / __/ -_) _ `/ __/ __/___/ _ \/ _ \/ / / -_) __/ _ \/ / _ `/ __/ -_)
137 | /_/ \__/\_,_/\__/\__/ /_.__/\___/_/_/\__/_/ / .__/_/\_,_/\__/\__/
138 | /_/
139 | ┌────────────────────────────────────────────────────────────────────┐
140 | │ │
141 | │ Mike Chabot | Version 5.0.0 | License MIT │
142 | │ │
143 | └────────────────────────────────────────────────────────────────────┘
144 | [webpack.Progress] 0% compiling
145 | [webpack.Progress] 10% building 0/0 modules 0 active
146 | ```
147 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | const presets = [
2 | [
3 | '@babel/env',
4 | {
5 | targets: {
6 | esmodules: true,
7 | },
8 | useBuiltIns: 'entry',
9 | corejs: '3',
10 | },
11 | ],
12 | ['@babel/react'],
13 | ];
14 |
15 | const plugins = [
16 | '@babel/plugin-syntax-dynamic-import',
17 | '@babel/plugin-proposal-class-properties',
18 | '@loadable/babel-plugin',
19 | ];
20 |
21 | module.exports = { presets, plugins };
22 |
--------------------------------------------------------------------------------
/config/config.default.json:
--------------------------------------------------------------------------------
1 | {
2 | "example": {
3 | "port": 3060,
4 | "baseUrl": "http://localhost:3020/",
5 | "publicBasename": "react-boilerplate/"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/config/config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const DEFAULT_CONFIG_PATH = './config.default.json';
4 |
5 | let configPath = DEFAULT_CONFIG_PATH;
6 | const customPath = process.env.ENV_CONFIG_PATH;
7 |
8 | if (customPath) {
9 | console.log(`** Using custom configuration located at "${customPath}" ** `);
10 | configPath = customPath;
11 | }
12 |
13 | module.exports = require(configPath);
14 |
--------------------------------------------------------------------------------
/docs/715.7dd94fe17002b841b25c.css:
--------------------------------------------------------------------------------
1 | .route-content--container {
2 | display: flex;
3 | flex-direction: column;
4 | padding: 10px;
5 | }
6 | .route-content--container .route-content--header,
7 | .route-content--container .route-content--counter {
8 | display: flex;
9 | align-content: center;
10 | }
11 |
--------------------------------------------------------------------------------
/docs/896.7dd94fe17002b841b25c.css:
--------------------------------------------------------------------------------
1 | .route-content--container {
2 | display: flex;
3 | flex-direction: column;
4 | padding: 10px;
5 | }
6 | .route-content--container .route-content--header,
7 | .route-content--container .route-content--counter {
8 | display: flex;
9 | align-content: center;
10 | }
11 |
--------------------------------------------------------------------------------
/docs/956.7dd94fe17002b841b25c.css:
--------------------------------------------------------------------------------
1 | .route-content--container {
2 | display: flex;
3 | flex-direction: column;
4 | padding: 10px;
5 | }
6 | .route-content--container .route-content--header,
7 | .route-content--container .route-content--counter {
8 | display: flex;
9 | align-content: center;
10 | }
11 |
--------------------------------------------------------------------------------
/docs/components-Sections-ReactRouter-Routes-DecrementRoute.b39cfef421931f6623fe.js:
--------------------------------------------------------------------------------
1 | (self.webpackChunkreact_boilerplate = self.webpackChunkreact_boilerplate || []).push([
2 | [896],
3 | {
4 | 3843: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5 | 'use strict';
6 | __webpack_require__.r(__webpack_exports__);
7 | },
8 | 2522: function (__unused_webpack_module, exports, __webpack_require__) {
9 | 'use strict';
10 | var __importDefault =
11 | (this && this.__importDefault) ||
12 | function (mod) {
13 | return mod && mod.__esModule ? mod : { default: mod };
14 | };
15 | Object.defineProperty(exports, '__esModule', { value: !0 });
16 | const react_1 = __importDefault(__webpack_require__(7294)),
17 | RouteContent_1 = __importDefault(__webpack_require__(3672)),
18 | actions_1 = __webpack_require__(750);
19 | exports.default = () =>
20 | react_1.default.createElement(RouteContent_1.default, {
21 | icon: 'minus',
22 | path: '/decrement',
23 | label: 'Decrement',
24 | action: actions_1.decrementAction,
25 | });
26 | },
27 | 3672: function (__unused_webpack_module, exports, __webpack_require__) {
28 | 'use strict';
29 | var __importDefault =
30 | (this && this.__importDefault) ||
31 | function (mod) {
32 | return mod && mod.__esModule ? mod : { default: mod };
33 | };
34 | Object.defineProperty(exports, '__esModule', { value: !0 });
35 | const react_1 = __importDefault(__webpack_require__(7294)),
36 | bind_1 = __importDefault(__webpack_require__(7166)),
37 | react_redux_1 = __webpack_require__(8629),
38 | Icon_1 = __importDefault(__webpack_require__(8055)),
39 | RouteContent_scss_1 = __importDefault(__webpack_require__(3843)),
40 | cx = bind_1.default.bind(RouteContent_scss_1.default);
41 | exports.default = ({ path, label, action, icon }) => {
42 | const dispatch = react_redux_1.useDispatch(),
43 | counter = react_redux_1.useSelector((state) => state.counter);
44 | return react_1.default.createElement(
45 | 'div',
46 | { className: cx('route-content--container') },
47 | react_1.default.createElement(
48 | 'div',
49 | { className: cx('route-content--heading') },
50 | react_1.default.createElement(Icon_1.default, { icon: 'angle-right' }),
51 | ' Connected to the Redux store at the ',
52 | react_1.default.createElement('code', null, path || '/'),
53 | ' route'
54 | ),
55 | react_1.default.createElement(
56 | 'div',
57 | { className: `${cx('route-content--counter')} m-t-xs` },
58 | react_1.default.createElement(Icon_1.default, { icon: 'angle-right' }),
59 | ' ',
60 | react_1.default.createElement('code', null, 'counter'),
61 | ': ',
62 | react_1.default.createElement('code', null, counter)
63 | ),
64 | react_1.default.createElement('br', null),
65 | react_1.default.createElement(
66 | 'div',
67 | { className: 'm-t-sm' },
68 | react_1.default.createElement(
69 | 'button',
70 | { className: 'button', onClick: () => dispatch(action()) },
71 | react_1.default.createElement(Icon_1.default, { icon }),
72 | ' ',
73 | label,
74 | ' counter'
75 | )
76 | )
77 | );
78 | };
79 | },
80 | 750: function (__unused_webpack_module, exports, __webpack_require__) {
81 | 'use strict';
82 | Object.defineProperty(exports, '__esModule', { value: !0 }),
83 | (exports.resetAction = exports.decrementAction = exports.incrementAction = void 0);
84 | const reducer_1 = __webpack_require__(9269);
85 | exports.incrementAction = () => ({ type: reducer_1.INCREMENT_COUNTER });
86 | exports.decrementAction = () => ({ type: reducer_1.DECREMENT_COUNTER });
87 | exports.resetAction = () => ({ type: reducer_1.RESET_COUNTER });
88 | },
89 | },
90 | ]);
91 |
--------------------------------------------------------------------------------
/docs/components-Sections-ReactRouter-Routes-IncrementRoute.b39cfef421931f6623fe.js:
--------------------------------------------------------------------------------
1 | (self.webpackChunkreact_boilerplate = self.webpackChunkreact_boilerplate || []).push([
2 | [715],
3 | {
4 | 3843: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5 | 'use strict';
6 | __webpack_require__.r(__webpack_exports__);
7 | },
8 | 6769: function (__unused_webpack_module, exports, __webpack_require__) {
9 | 'use strict';
10 | var __importDefault =
11 | (this && this.__importDefault) ||
12 | function (mod) {
13 | return mod && mod.__esModule ? mod : { default: mod };
14 | };
15 | Object.defineProperty(exports, '__esModule', { value: !0 });
16 | const react_1 = __importDefault(__webpack_require__(7294)),
17 | RouteContent_1 = __importDefault(__webpack_require__(3672)),
18 | actions_1 = __webpack_require__(750);
19 | exports.default = () =>
20 | react_1.default.createElement(RouteContent_1.default, {
21 | icon: 'plus',
22 | path: '/',
23 | label: 'Increment',
24 | action: actions_1.incrementAction,
25 | });
26 | },
27 | 3672: function (__unused_webpack_module, exports, __webpack_require__) {
28 | 'use strict';
29 | var __importDefault =
30 | (this && this.__importDefault) ||
31 | function (mod) {
32 | return mod && mod.__esModule ? mod : { default: mod };
33 | };
34 | Object.defineProperty(exports, '__esModule', { value: !0 });
35 | const react_1 = __importDefault(__webpack_require__(7294)),
36 | bind_1 = __importDefault(__webpack_require__(7166)),
37 | react_redux_1 = __webpack_require__(8629),
38 | Icon_1 = __importDefault(__webpack_require__(8055)),
39 | RouteContent_scss_1 = __importDefault(__webpack_require__(3843)),
40 | cx = bind_1.default.bind(RouteContent_scss_1.default);
41 | exports.default = ({ path, label, action, icon }) => {
42 | const dispatch = react_redux_1.useDispatch(),
43 | counter = react_redux_1.useSelector((state) => state.counter);
44 | return react_1.default.createElement(
45 | 'div',
46 | { className: cx('route-content--container') },
47 | react_1.default.createElement(
48 | 'div',
49 | { className: cx('route-content--heading') },
50 | react_1.default.createElement(Icon_1.default, { icon: 'angle-right' }),
51 | ' Connected to the Redux store at the ',
52 | react_1.default.createElement('code', null, path || '/'),
53 | ' route'
54 | ),
55 | react_1.default.createElement(
56 | 'div',
57 | { className: `${cx('route-content--counter')} m-t-xs` },
58 | react_1.default.createElement(Icon_1.default, { icon: 'angle-right' }),
59 | ' ',
60 | react_1.default.createElement('code', null, 'counter'),
61 | ': ',
62 | react_1.default.createElement('code', null, counter)
63 | ),
64 | react_1.default.createElement('br', null),
65 | react_1.default.createElement(
66 | 'div',
67 | { className: 'm-t-sm' },
68 | react_1.default.createElement(
69 | 'button',
70 | { className: 'button', onClick: () => dispatch(action()) },
71 | react_1.default.createElement(Icon_1.default, { icon }),
72 | ' ',
73 | label,
74 | ' counter'
75 | )
76 | )
77 | );
78 | };
79 | },
80 | 750: function (__unused_webpack_module, exports, __webpack_require__) {
81 | 'use strict';
82 | Object.defineProperty(exports, '__esModule', { value: !0 }),
83 | (exports.resetAction = exports.decrementAction = exports.incrementAction = void 0);
84 | const reducer_1 = __webpack_require__(9269);
85 | exports.incrementAction = () => ({ type: reducer_1.INCREMENT_COUNTER });
86 | exports.decrementAction = () => ({ type: reducer_1.DECREMENT_COUNTER });
87 | exports.resetAction = () => ({ type: reducer_1.RESET_COUNTER });
88 | },
89 | },
90 | ]);
91 |
--------------------------------------------------------------------------------
/docs/components-Sections-ReactRouter-Routes-ResetRoute.b39cfef421931f6623fe.js:
--------------------------------------------------------------------------------
1 | (self.webpackChunkreact_boilerplate = self.webpackChunkreact_boilerplate || []).push([
2 | [956],
3 | {
4 | 3843: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5 | 'use strict';
6 | __webpack_require__.r(__webpack_exports__);
7 | },
8 | 9021: function (__unused_webpack_module, exports, __webpack_require__) {
9 | 'use strict';
10 | var __importDefault =
11 | (this && this.__importDefault) ||
12 | function (mod) {
13 | return mod && mod.__esModule ? mod : { default: mod };
14 | };
15 | Object.defineProperty(exports, '__esModule', { value: !0 });
16 | const react_1 = __importDefault(__webpack_require__(7294)),
17 | RouteContent_1 = __importDefault(__webpack_require__(3672)),
18 | actions_1 = __webpack_require__(750);
19 | exports.default = () =>
20 | react_1.default.createElement(RouteContent_1.default, {
21 | icon: 'history',
22 | path: '/reset',
23 | label: 'Reset',
24 | action: actions_1.resetAction,
25 | });
26 | },
27 | 3672: function (__unused_webpack_module, exports, __webpack_require__) {
28 | 'use strict';
29 | var __importDefault =
30 | (this && this.__importDefault) ||
31 | function (mod) {
32 | return mod && mod.__esModule ? mod : { default: mod };
33 | };
34 | Object.defineProperty(exports, '__esModule', { value: !0 });
35 | const react_1 = __importDefault(__webpack_require__(7294)),
36 | bind_1 = __importDefault(__webpack_require__(7166)),
37 | react_redux_1 = __webpack_require__(8629),
38 | Icon_1 = __importDefault(__webpack_require__(8055)),
39 | RouteContent_scss_1 = __importDefault(__webpack_require__(3843)),
40 | cx = bind_1.default.bind(RouteContent_scss_1.default);
41 | exports.default = ({ path, label, action, icon }) => {
42 | const dispatch = react_redux_1.useDispatch(),
43 | counter = react_redux_1.useSelector((state) => state.counter);
44 | return react_1.default.createElement(
45 | 'div',
46 | { className: cx('route-content--container') },
47 | react_1.default.createElement(
48 | 'div',
49 | { className: cx('route-content--heading') },
50 | react_1.default.createElement(Icon_1.default, { icon: 'angle-right' }),
51 | ' Connected to the Redux store at the ',
52 | react_1.default.createElement('code', null, path || '/'),
53 | ' route'
54 | ),
55 | react_1.default.createElement(
56 | 'div',
57 | { className: `${cx('route-content--counter')} m-t-xs` },
58 | react_1.default.createElement(Icon_1.default, { icon: 'angle-right' }),
59 | ' ',
60 | react_1.default.createElement('code', null, 'counter'),
61 | ': ',
62 | react_1.default.createElement('code', null, counter)
63 | ),
64 | react_1.default.createElement('br', null),
65 | react_1.default.createElement(
66 | 'div',
67 | { className: 'm-t-sm' },
68 | react_1.default.createElement(
69 | 'button',
70 | { className: 'button', onClick: () => dispatch(action()) },
71 | react_1.default.createElement(Icon_1.default, { icon }),
72 | ' ',
73 | label,
74 | ' counter'
75 | )
76 | )
77 | );
78 | };
79 | },
80 | 750: function (__unused_webpack_module, exports, __webpack_require__) {
81 | 'use strict';
82 | Object.defineProperty(exports, '__esModule', { value: !0 }),
83 | (exports.resetAction = exports.decrementAction = exports.incrementAction = void 0);
84 | const reducer_1 = __webpack_require__(9269);
85 | exports.incrementAction = () => ({ type: reducer_1.INCREMENT_COUNTER });
86 | exports.decrementAction = () => ({ type: reducer_1.DECREMENT_COUNTER });
87 | exports.resetAction = () => ({ type: reducer_1.RESET_COUNTER });
88 | },
89 | },
90 | ]);
91 |
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikechabot/react-boilerplate/c45505edb9209a9d9ec5dd8b8ba176ba6f85fbee/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
18 |
19 |
20 |
21 |
24 | react-boilerplate
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/docs/main.b39cfef421931f6623fe.js:
--------------------------------------------------------------------------------
1 | (self.webpackChunkreact_boilerplate = self.webpackChunkreact_boilerplate || []).push([
2 | [179],
3 | {
4 | 9024: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5 | 'use strict';
6 | __webpack_require__.r(__webpack_exports__);
7 | var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7294),
8 | p_min_delay__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2959),
9 | p_min_delay__WEBPACK_IMPORTED_MODULE_1___default = __webpack_require__.n(
10 | p_min_delay__WEBPACK_IMPORTED_MODULE_1__
11 | ),
12 | _loadable_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2168),
13 | classnames_bind__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7166),
14 | classnames_bind__WEBPACK_IMPORTED_MODULE_3___default = __webpack_require__.n(
15 | classnames_bind__WEBPACK_IMPORTED_MODULE_3__
16 | ),
17 | react_router_dom__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(5977),
18 | react_tabify__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5817),
19 | react_tabify__WEBPACK_IMPORTED_MODULE_4___default = __webpack_require__.n(
20 | react_tabify__WEBPACK_IMPORTED_MODULE_4__
21 | ),
22 | _components_Sections_ReactRouter_ChunkLoadingIcon__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1746),
23 | _components_Sections_ReactRouter_ChunkLoadingIcon__WEBPACK_IMPORTED_MODULE_5___default = __webpack_require__.n(
24 | _components_Sections_ReactRouter_ChunkLoadingIcon__WEBPACK_IMPORTED_MODULE_5__
25 | ),
26 | DELAY = 500,
27 | options = {
28 | fallback: react__WEBPACK_IMPORTED_MODULE_0__.createElement(
29 | _components_Sections_ReactRouter_ChunkLoadingIcon__WEBPACK_IMPORTED_MODULE_5___default(),
30 | null
31 | ),
32 | },
33 | AsyncIncrement = (0, _loadable_component__WEBPACK_IMPORTED_MODULE_2__.ZP)(
34 | {
35 | resolved: {},
36 | chunkName: () => 'components-Sections-ReactRouter-Routes-IncrementRoute',
37 | isReady(props) {
38 | var key = this.resolve(props);
39 | return !0 === this.resolved[key] && !!__webpack_require__.m[key];
40 | },
41 | importAsync: () =>
42 | p_min_delay__WEBPACK_IMPORTED_MODULE_1___default()(
43 | __webpack_require__.e(715).then(__webpack_require__.t.bind(__webpack_require__, 6769, 23)),
44 | DELAY
45 | ),
46 | requireAsync(props) {
47 | var key = this.resolve(props);
48 | return (
49 | (this.resolved[key] = !1),
50 | this.importAsync(props).then((resolved) => ((this.resolved[key] = !0), resolved))
51 | );
52 | },
53 | requireSync(props) {
54 | var id = this.resolve(props);
55 | return __webpack_require__(id);
56 | },
57 | resolve() {
58 | return 6769;
59 | },
60 | },
61 | options
62 | ),
63 | AsyncDecrement = (0, _loadable_component__WEBPACK_IMPORTED_MODULE_2__.ZP)(
64 | {
65 | resolved: {},
66 | chunkName: () => 'components-Sections-ReactRouter-Routes-DecrementRoute',
67 | isReady(props) {
68 | var key = this.resolve(props);
69 | return !0 === this.resolved[key] && !!__webpack_require__.m[key];
70 | },
71 | importAsync: () =>
72 | p_min_delay__WEBPACK_IMPORTED_MODULE_1___default()(
73 | __webpack_require__.e(896).then(__webpack_require__.t.bind(__webpack_require__, 2522, 23)),
74 | DELAY
75 | ),
76 | requireAsync(props) {
77 | var key = this.resolve(props);
78 | return (
79 | (this.resolved[key] = !1),
80 | this.importAsync(props).then((resolved) => ((this.resolved[key] = !0), resolved))
81 | );
82 | },
83 | requireSync(props) {
84 | var id = this.resolve(props);
85 | return __webpack_require__(id);
86 | },
87 | resolve() {
88 | return 2522;
89 | },
90 | },
91 | options
92 | ),
93 | AsyncReset = (0, _loadable_component__WEBPACK_IMPORTED_MODULE_2__.ZP)(
94 | {
95 | resolved: {},
96 | chunkName: () => 'components-Sections-ReactRouter-Routes-ResetRoute',
97 | isReady(props) {
98 | var key = this.resolve(props);
99 | return !0 === this.resolved[key] && !!__webpack_require__.m[key];
100 | },
101 | importAsync: () =>
102 | p_min_delay__WEBPACK_IMPORTED_MODULE_1___default()(
103 | __webpack_require__.e(956).then(__webpack_require__.t.bind(__webpack_require__, 9021, 23)),
104 | DELAY
105 | ),
106 | requireAsync(props) {
107 | var key = this.resolve(props);
108 | return (
109 | (this.resolved[key] = !1),
110 | this.importAsync(props).then((resolved) => ((this.resolved[key] = !0), resolved))
111 | );
112 | },
113 | requireSync(props) {
114 | var id = this.resolve(props);
115 | return __webpack_require__(id);
116 | },
117 | resolve() {
118 | return 9021;
119 | },
120 | },
121 | options
122 | ),
123 | AsyncTabbedRouter = () => {
124 | var location = (0, react_router_dom__WEBPACK_IMPORTED_MODULE_6__.TH)(),
125 | history = (0, react_router_dom__WEBPACK_IMPORTED_MODULE_6__.k6)();
126 | return react__WEBPACK_IMPORTED_MODULE_0__.createElement(
127 | 'div',
128 | { className: 'notification m-t-sm' },
129 | react__WEBPACK_IMPORTED_MODULE_0__.createElement(
130 | react_tabify__WEBPACK_IMPORTED_MODULE_4__.Tabs,
131 | {
132 | id: 'router-example-tabs',
133 | activeKey: location.pathname,
134 | onSelect: (eventKey) => history.push(eventKey),
135 | },
136 | react__WEBPACK_IMPORTED_MODULE_0__.createElement(
137 | react_tabify__WEBPACK_IMPORTED_MODULE_4__.Tab,
138 | { eventKey: '/', label: 'Increment' },
139 | react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_6__.AW, {
140 | exact: !0,
141 | path: '/',
142 | component: AsyncIncrement,
143 | })
144 | ),
145 | react__WEBPACK_IMPORTED_MODULE_0__.createElement(
146 | react_tabify__WEBPACK_IMPORTED_MODULE_4__.Tab,
147 | { eventKey: '/decrement', label: 'Decrement' },
148 | react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_6__.AW, {
149 | exact: !0,
150 | path: '/decrement',
151 | component: AsyncDecrement,
152 | })
153 | ),
154 | react__WEBPACK_IMPORTED_MODULE_0__.createElement(
155 | react_tabify__WEBPACK_IMPORTED_MODULE_4__.Tab,
156 | { eventKey: '/reset', label: 'Reset' },
157 | react__WEBPACK_IMPORTED_MODULE_0__.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_6__.AW, {
158 | exact: !0,
159 | path: '/reset',
160 | component: AsyncReset,
161 | })
162 | )
163 | )
164 | );
165 | };
166 | __webpack_exports__.default = AsyncTabbedRouter;
167 | },
168 | 3018: function (module, __unused_webpack_exports, __webpack_require__) {
169 | var NodeUtils = __webpack_require__(8720),
170 | get = __webpack_require__(7361);
171 | module.exports = {
172 | getConfig: () => ({
173 | example: { port: 3060, baseUrl: 'http://localhost:3020/', publicBasename: 'react-boilerplate/' },
174 | }),
175 | getProperty(key) {
176 | if (!key) throw new Error('Key cannot be null/undefined');
177 | return get(this.getConfig(), key);
178 | },
179 | getRequiredProperty(key) {
180 | var value = this.getProperty(key);
181 | if (value) return value;
182 | if (!NodeUtils.isTest()) throw new Error('Missing required property: "'.concat(key, '"'));
183 | },
184 | getPort() {
185 | return this.getRequiredProperty('example.port');
186 | },
187 | getBasePath() {
188 | return this.getRequiredProperty('example.basePath');
189 | },
190 | getBaseUrl() {
191 | return this.getRequiredProperty('example.baseUrl');
192 | },
193 | getPublicBasename() {
194 | return NodeUtils.isGhPages() ? this.getRequiredProperty('example.publicBasename') : '/';
195 | },
196 | };
197 | },
198 | 8720: function (module) {
199 | 'use strict';
200 | module.exports = {
201 | getNodeEnv: function getNodeEnv() {
202 | return {
203 | NODE_ENV: 'gh-pages',
204 | APP_CONFIG: {
205 | example: { port: 3060, baseUrl: 'http://localhost:3020/', publicBasename: 'react-boilerplate/' },
206 | },
207 | };
208 | },
209 | getNodeEnvByKey: function getNodeEnvByKey(key) {
210 | if (!key) throw new Error('Key cannot be null/undefined');
211 | return {
212 | NODE_ENV: 'gh-pages',
213 | APP_CONFIG: {
214 | example: { port: 3060, baseUrl: 'http://localhost:3020/', publicBasename: 'react-boilerplate/' },
215 | },
216 | }[key];
217 | },
218 | getNodeEnvMode: function getNodeEnvMode() {
219 | return this.getNodeEnvByKey('NODE_ENV') || 'test';
220 | },
221 | isProduction: function isProduction() {
222 | return 'production' === this.getNodeEnvMode();
223 | },
224 | isDevelopment: function isDevelopment() {
225 | return 'development' === this.getNodeEnvMode();
226 | },
227 | isGhPages: function isGhPages() {
228 | return 'gh-pages' === this.getNodeEnvMode();
229 | },
230 | isTest: function isTest() {
231 | return !this.getNodeEnvMode() || 'test' === this.getNodeEnvMode();
232 | },
233 | };
234 | },
235 | 5834: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
236 | 'use strict';
237 | __webpack_require__.r(__webpack_exports__), (__webpack_exports__.default = __webpack_require__.p + 'favicon.ico');
238 | },
239 | 9234: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
240 | 'use strict';
241 | __webpack_require__.r(__webpack_exports__);
242 | },
243 | 8395: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
244 | 'use strict';
245 | __webpack_require__.r(__webpack_exports__);
246 | },
247 | 1914: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
248 | 'use strict';
249 | __webpack_require__.r(__webpack_exports__);
250 | },
251 | 4689: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
252 | 'use strict';
253 | __webpack_require__.r(__webpack_exports__);
254 | },
255 | 9938: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
256 | 'use strict';
257 | __webpack_require__.r(__webpack_exports__);
258 | },
259 | 3334: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
260 | 'use strict';
261 | __webpack_require__.r(__webpack_exports__);
262 | },
263 | 5094: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
264 | 'use strict';
265 | __webpack_require__.r(__webpack_exports__);
266 | },
267 | 3463: function (__unused_webpack_module, exports, __webpack_require__) {
268 | 'use strict';
269 | var __createBinding =
270 | (this && this.__createBinding) ||
271 | (Object.create
272 | ? function (o, m, k, k2) {
273 | void 0 === k2 && (k2 = k),
274 | Object.defineProperty(o, k2, {
275 | enumerable: !0,
276 | get: function () {
277 | return m[k];
278 | },
279 | });
280 | }
281 | : function (o, m, k, k2) {
282 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
283 | }),
284 | __setModuleDefault =
285 | (this && this.__setModuleDefault) ||
286 | (Object.create
287 | ? function (o, v) {
288 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
289 | }
290 | : function (o, v) {
291 | o.default = v;
292 | }),
293 | __importStar =
294 | (this && this.__importStar) ||
295 | function (mod) {
296 | if (mod && mod.__esModule) return mod;
297 | var result = {};
298 | if (null != mod)
299 | for (var k in mod)
300 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
301 | return __setModuleDefault(result, mod), result;
302 | },
303 | __importDefault =
304 | (this && this.__importDefault) ||
305 | function (mod) {
306 | return mod && mod.__esModule ? mod : { default: mod };
307 | };
308 | Object.defineProperty(exports, '__esModule', { value: !0 });
309 | const React = __importStar(__webpack_require__(7294)),
310 | react_dom_1 = __importDefault(__webpack_require__(3935)),
311 | react_hot_loader_1 = __webpack_require__(5053),
312 | store_1 = __importDefault(__webpack_require__(5908)),
313 | Root_1 = __importDefault(__webpack_require__(2556));
314 | __webpack_require__(5094),
315 | __webpack_require__(5834),
316 | react_dom_1.default.render(
317 | React.createElement(
318 | react_hot_loader_1.AppContainer,
319 | null,
320 | React.createElement(Root_1.default, { store: store_1.default })
321 | ),
322 | document.getElementById('example-app')
323 | );
324 | },
325 | 2556: function (__unused_webpack_module, exports, __webpack_require__) {
326 | 'use strict';
327 | var __createBinding =
328 | (this && this.__createBinding) ||
329 | (Object.create
330 | ? function (o, m, k, k2) {
331 | void 0 === k2 && (k2 = k),
332 | Object.defineProperty(o, k2, {
333 | enumerable: !0,
334 | get: function () {
335 | return m[k];
336 | },
337 | });
338 | }
339 | : function (o, m, k, k2) {
340 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
341 | }),
342 | __setModuleDefault =
343 | (this && this.__setModuleDefault) ||
344 | (Object.create
345 | ? function (o, v) {
346 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
347 | }
348 | : function (o, v) {
349 | o.default = v;
350 | }),
351 | __importStar =
352 | (this && this.__importStar) ||
353 | function (mod) {
354 | if (mod && mod.__esModule) return mod;
355 | var result = {};
356 | if (null != mod)
357 | for (var k in mod)
358 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
359 | return __setModuleDefault(result, mod), result;
360 | },
361 | __importDefault =
362 | (this && this.__importDefault) ||
363 | function (mod) {
364 | return mod && mod.__esModule ? mod : { default: mod };
365 | };
366 | Object.defineProperty(exports, '__esModule', { value: !0 });
367 | const React = __importStar(__webpack_require__(7294)),
368 | react_redux_1 = __webpack_require__(8629),
369 | react_router_dom_1 = __webpack_require__(3727),
370 | config_service_1 = __importDefault(__webpack_require__(3018)),
371 | App_1 = __importDefault(__webpack_require__(78));
372 | exports.default = ({ store }) =>
373 | React.createElement(
374 | react_redux_1.Provider,
375 | { store },
376 | React.createElement(
377 | react_router_dom_1.BrowserRouter,
378 | { basename: config_service_1.default.getPublicBasename() },
379 | React.createElement(App_1.default, null)
380 | )
381 | );
382 | },
383 | 78: function (__unused_webpack_module, exports, __webpack_require__) {
384 | 'use strict';
385 | var __importDefault =
386 | (this && this.__importDefault) ||
387 | function (mod) {
388 | return mod && mod.__esModule ? mod : { default: mod };
389 | };
390 | Object.defineProperty(exports, '__esModule', { value: !0 });
391 | const react_1 = __importDefault(__webpack_require__(7294)),
392 | bind_1 = __importDefault(__webpack_require__(7166)),
393 | Navbar_1 = __importDefault(__webpack_require__(975)),
394 | Footer_1 = __importDefault(__webpack_require__(2181)),
395 | ReactRouter_1 = __importDefault(__webpack_require__(6231)),
396 | ReduxEntity_1 = __importDefault(__webpack_require__(2323)),
397 | ReduxState_1 = __importDefault(__webpack_require__(1198)),
398 | App_scss_1 = __importDefault(__webpack_require__(3334)),
399 | cx = bind_1.default.bind(App_scss_1.default);
400 | exports.default = () =>
401 | react_1.default.createElement(
402 | 'section',
403 | { className: cx('react-boilerplate') },
404 | react_1.default.createElement(Navbar_1.default, null),
405 | react_1.default.createElement(
406 | 'section',
407 | { className: `section ${cx('section--body')}` },
408 | react_1.default.createElement(
409 | 'div',
410 | { className: 'container' },
411 | react_1.default.createElement(
412 | 'div',
413 | { className: 'columns' },
414 | react_1.default.createElement(
415 | 'div',
416 | { className: 'column' },
417 | react_1.default.createElement(ReactRouter_1.default, null)
418 | )
419 | ),
420 | react_1.default.createElement(
421 | 'div',
422 | { className: 'columns' },
423 | react_1.default.createElement(
424 | 'div',
425 | { className: 'column' },
426 | react_1.default.createElement(ReduxEntity_1.default, null)
427 | ),
428 | react_1.default.createElement(
429 | 'div',
430 | { className: 'column' },
431 | react_1.default.createElement(ReduxState_1.default, null)
432 | )
433 | )
434 | )
435 | ),
436 | react_1.default.createElement(Footer_1.default, null)
437 | );
438 | },
439 | 6418: function (__unused_webpack_module, exports, __webpack_require__) {
440 | 'use strict';
441 | var __createBinding =
442 | (this && this.__createBinding) ||
443 | (Object.create
444 | ? function (o, m, k, k2) {
445 | void 0 === k2 && (k2 = k),
446 | Object.defineProperty(o, k2, {
447 | enumerable: !0,
448 | get: function () {
449 | return m[k];
450 | },
451 | });
452 | }
453 | : function (o, m, k, k2) {
454 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
455 | }),
456 | __setModuleDefault =
457 | (this && this.__setModuleDefault) ||
458 | (Object.create
459 | ? function (o, v) {
460 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
461 | }
462 | : function (o, v) {
463 | o.default = v;
464 | }),
465 | __importStar =
466 | (this && this.__importStar) ||
467 | function (mod) {
468 | if (mod && mod.__esModule) return mod;
469 | var result = {};
470 | if (null != mod)
471 | for (var k in mod)
472 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
473 | return __setModuleDefault(result, mod), result;
474 | },
475 | __importDefault =
476 | (this && this.__importDefault) ||
477 | function (mod) {
478 | return mod && mod.__esModule ? mod : { default: mod };
479 | };
480 | Object.defineProperty(exports, '__esModule', { value: !0 });
481 | const React = __importStar(__webpack_require__(7294)),
482 | common_1 = __webpack_require__(1256),
483 | GithubButtons_1 = __importDefault(__webpack_require__(6707)),
484 | const_1 = __webpack_require__(5365),
485 | Repository = () =>
486 | React.createElement(
487 | 'strong',
488 | { className: 'has-text-grey-light' },
489 | React.createElement(common_1.Icon, { icon: 'cloud' }),
490 | ' react-boilerplate'
491 | ),
492 | DemoLink = () => React.createElement(common_1.Link, { url: const_1.URL.DEMO }, 'source code'),
493 | GithubLink = () => React.createElement(common_1.Link, { url: const_1.URL.GITHUB }, 'Mike Chabot'),
494 | LicenseLink = () => React.createElement(common_1.Link, { url: const_1.URL.LICENSE }, 'MIT');
495 | exports.default = () =>
496 | React.createElement(
497 | 'footer',
498 | { className: 'footer has-text-grey-light' },
499 | React.createElement(
500 | 'div',
501 | { className: 'container has-text-centered' },
502 | React.createElement(
503 | 'div',
504 | null,
505 | React.createElement(Repository, null),
506 | ' by ',
507 | React.createElement(GithubLink, null)
508 | ),
509 | React.createElement(
510 | 'div',
511 | { className: 'm-t-xs' },
512 | 'The ',
513 | React.createElement(DemoLink, null),
514 | ' is licensed under ',
515 | React.createElement(LicenseLink, null)
516 | ),
517 | React.createElement(GithubButtons_1.default, null)
518 | )
519 | );
520 | },
521 | 7695: function (__unused_webpack_module, exports, __webpack_require__) {
522 | 'use strict';
523 | var __createBinding =
524 | (this && this.__createBinding) ||
525 | (Object.create
526 | ? function (o, m, k, k2) {
527 | void 0 === k2 && (k2 = k),
528 | Object.defineProperty(o, k2, {
529 | enumerable: !0,
530 | get: function () {
531 | return m[k];
532 | },
533 | });
534 | }
535 | : function (o, m, k, k2) {
536 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
537 | }),
538 | __setModuleDefault =
539 | (this && this.__setModuleDefault) ||
540 | (Object.create
541 | ? function (o, v) {
542 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
543 | }
544 | : function (o, v) {
545 | o.default = v;
546 | }),
547 | __importStar =
548 | (this && this.__importStar) ||
549 | function (mod) {
550 | if (mod && mod.__esModule) return mod;
551 | var result = {};
552 | if (null != mod)
553 | for (var k in mod)
554 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
555 | return __setModuleDefault(result, mod), result;
556 | },
557 | __importDefault =
558 | (this && this.__importDefault) ||
559 | function (mod) {
560 | return mod && mod.__esModule ? mod : { default: mod };
561 | };
562 | Object.defineProperty(exports, '__esModule', { value: !0 });
563 | const React = __importStar(__webpack_require__(7294)),
564 | bind_1 = __importDefault(__webpack_require__(7166)),
565 | GithubButton_scss_1 = __importDefault(__webpack_require__(9234)),
566 | cx = bind_1.default.bind(GithubButton_scss_1.default);
567 | exports.default = ({ label, icon, href, ariaLabel }) =>
568 | React.createElement(
569 | 'div',
570 | { className: cx('github-button--container') },
571 | React.createElement(
572 | 'a',
573 | {
574 | className: 'github-button',
575 | href: `https://github.com/${href}`,
576 | 'data-icon': icon,
577 | 'data-size': 'large',
578 | 'data-show-count': !0,
579 | 'aria-label': ariaLabel,
580 | },
581 | label
582 | )
583 | );
584 | },
585 | 969: function (__unused_webpack_module, exports, __webpack_require__) {
586 | 'use strict';
587 | var __createBinding =
588 | (this && this.__createBinding) ||
589 | (Object.create
590 | ? function (o, m, k, k2) {
591 | void 0 === k2 && (k2 = k),
592 | Object.defineProperty(o, k2, {
593 | enumerable: !0,
594 | get: function () {
595 | return m[k];
596 | },
597 | });
598 | }
599 | : function (o, m, k, k2) {
600 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
601 | }),
602 | __setModuleDefault =
603 | (this && this.__setModuleDefault) ||
604 | (Object.create
605 | ? function (o, v) {
606 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
607 | }
608 | : function (o, v) {
609 | o.default = v;
610 | }),
611 | __importStar =
612 | (this && this.__importStar) ||
613 | function (mod) {
614 | if (mod && mod.__esModule) return mod;
615 | var result = {};
616 | if (null != mod)
617 | for (var k in mod)
618 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
619 | return __setModuleDefault(result, mod), result;
620 | },
621 | __importDefault =
622 | (this && this.__importDefault) ||
623 | function (mod) {
624 | return mod && mod.__esModule ? mod : { default: mod };
625 | };
626 | Object.defineProperty(exports, '__esModule', { value: !0 });
627 | const React = __importStar(__webpack_require__(7294)),
628 | bind_1 = __importDefault(__webpack_require__(7166)),
629 | GithubButton_1 = __importDefault(__webpack_require__(7695)),
630 | GithubButtons_scss_1 = __importDefault(__webpack_require__(8395)),
631 | cx = bind_1.default.bind(GithubButtons_scss_1.default);
632 | exports.default = () =>
633 | React.createElement(
634 | 'div',
635 | { className: `${cx('github-buttons')} m-t-sm` },
636 | React.createElement(GithubButton_1.default, {
637 | label: 'Star',
638 | icon: 'octicon-star',
639 | href: 'mikechabot/react-boilerplate',
640 | ariaLabel: 'Star mikechabot/react-boilerplate on GitHub',
641 | }),
642 | React.createElement(GithubButton_1.default, {
643 | label: 'Fork',
644 | icon: 'octicon-repo-forked',
645 | href: 'mikechabot/react-boilerplate/fork',
646 | ariaLabel: 'Fork mikechabot/react-boilerplate on GitHub',
647 | }),
648 | React.createElement(GithubButton_1.default, {
649 | label: 'Watch',
650 | icon: 'octicon-eye',
651 | href: 'mikechabot/react-boilerplate/subscription',
652 | ariaLabel: 'Watch mikechabot/react-boilerplate on GitHub',
653 | })
654 | );
655 | },
656 | 6707: function (__unused_webpack_module, exports, __webpack_require__) {
657 | 'use strict';
658 | var __importDefault =
659 | (this && this.__importDefault) ||
660 | function (mod) {
661 | return mod && mod.__esModule ? mod : { default: mod };
662 | };
663 | Object.defineProperty(exports, '__esModule', { value: !0 }), (exports.default = void 0);
664 | var GithubButtons_1 = __webpack_require__(969);
665 | Object.defineProperty(exports, 'default', {
666 | enumerable: !0,
667 | get: function () {
668 | return __importDefault(GithubButtons_1).default;
669 | },
670 | });
671 | },
672 | 2181: function (__unused_webpack_module, exports, __webpack_require__) {
673 | 'use strict';
674 | var __importDefault =
675 | (this && this.__importDefault) ||
676 | function (mod) {
677 | return mod && mod.__esModule ? mod : { default: mod };
678 | };
679 | Object.defineProperty(exports, '__esModule', { value: !0 }), (exports.default = void 0);
680 | var Footer_1 = __webpack_require__(6418);
681 | Object.defineProperty(exports, 'default', {
682 | enumerable: !0,
683 | get: function () {
684 | return __importDefault(Footer_1).default;
685 | },
686 | });
687 | },
688 | 347: function (__unused_webpack_module, exports, __webpack_require__) {
689 | 'use strict';
690 | var __createBinding =
691 | (this && this.__createBinding) ||
692 | (Object.create
693 | ? function (o, m, k, k2) {
694 | void 0 === k2 && (k2 = k),
695 | Object.defineProperty(o, k2, {
696 | enumerable: !0,
697 | get: function () {
698 | return m[k];
699 | },
700 | });
701 | }
702 | : function (o, m, k, k2) {
703 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
704 | }),
705 | __setModuleDefault =
706 | (this && this.__setModuleDefault) ||
707 | (Object.create
708 | ? function (o, v) {
709 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
710 | }
711 | : function (o, v) {
712 | o.default = v;
713 | }),
714 | __importStar =
715 | (this && this.__importStar) ||
716 | function (mod) {
717 | if (mod && mod.__esModule) return mod;
718 | var result = {};
719 | if (null != mod)
720 | for (var k in mod)
721 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
722 | return __setModuleDefault(result, mod), result;
723 | },
724 | __importDefault =
725 | (this && this.__importDefault) ||
726 | function (mod) {
727 | return mod && mod.__esModule ? mod : { default: mod };
728 | };
729 | Object.defineProperty(exports, '__esModule', { value: !0 });
730 | const React = __importStar(__webpack_require__(7294)),
731 | Icon_1 = __importDefault(__webpack_require__(8055));
732 | exports.default = ({ title, subtitle, icon, children }) =>
733 | React.createElement(
734 | React.Fragment,
735 | null,
736 | React.createElement(
737 | 'div',
738 | null,
739 | React.createElement(
740 | 'h1',
741 | { className: 'title' },
742 | React.createElement(Icon_1.default, { icon, className: 'has-text-info' }),
743 | ' ',
744 | title
745 | ),
746 | React.createElement(
747 | 'h2',
748 | { className: 'subtitle ' },
749 | React.createElement(Icon_1.default, { icon: 'angle-right' }),
750 | ' ',
751 | subtitle
752 | )
753 | ),
754 | children
755 | );
756 | },
757 | 1746: function (__unused_webpack_module, exports, __webpack_require__) {
758 | 'use strict';
759 | var __importDefault =
760 | (this && this.__importDefault) ||
761 | function (mod) {
762 | return mod && mod.__esModule ? mod : { default: mod };
763 | };
764 | Object.defineProperty(exports, '__esModule', { value: !0 });
765 | const react_1 = __importDefault(__webpack_require__(7294)),
766 | bind_1 = __importDefault(__webpack_require__(7166)),
767 | Icon_1 = __webpack_require__(8055),
768 | ChunkLoadingIcon_scss_1 = __importDefault(__webpack_require__(1914)),
769 | cx = bind_1.default.bind(ChunkLoadingIcon_scss_1.default);
770 | exports.default = () =>
771 | react_1.default.createElement(
772 | 'div',
773 | { className: `p-t-md ${cx('chunk-loading--icon')}` },
774 | react_1.default.createElement(Icon_1.CogIcon, { size: 'fa-2x', className: 'has-text-info' })
775 | );
776 | },
777 | 1860: function (__unused_webpack_module, exports, __webpack_require__) {
778 | 'use strict';
779 | var __createBinding =
780 | (this && this.__createBinding) ||
781 | (Object.create
782 | ? function (o, m, k, k2) {
783 | void 0 === k2 && (k2 = k),
784 | Object.defineProperty(o, k2, {
785 | enumerable: !0,
786 | get: function () {
787 | return m[k];
788 | },
789 | });
790 | }
791 | : function (o, m, k, k2) {
792 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
793 | }),
794 | __setModuleDefault =
795 | (this && this.__setModuleDefault) ||
796 | (Object.create
797 | ? function (o, v) {
798 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
799 | }
800 | : function (o, v) {
801 | o.default = v;
802 | }),
803 | __importStar =
804 | (this && this.__importStar) ||
805 | function (mod) {
806 | if (mod && mod.__esModule) return mod;
807 | var result = {};
808 | if (null != mod)
809 | for (var k in mod)
810 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
811 | return __setModuleDefault(result, mod), result;
812 | },
813 | __importDefault =
814 | (this && this.__importDefault) ||
815 | function (mod) {
816 | return mod && mod.__esModule ? mod : { default: mod };
817 | };
818 | Object.defineProperty(exports, '__esModule', { value: !0 });
819 | const React = __importStar(__webpack_require__(7294)),
820 | GenericSection_1 = __importDefault(__webpack_require__(347)),
821 | AsyncTabbedRouter_1 = __importDefault(__webpack_require__(9024)),
822 | const_1 = __webpack_require__(5365);
823 | exports.default = () =>
824 | React.createElement(
825 | GenericSection_1.default,
826 | {
827 | icon: 'link',
828 | title: 'Router',
829 | subtitle: React.createElement(
830 | 'span',
831 | null,
832 | 'Utilizes ',
833 | React.createElement('a', { href: const_1.URL.REACT_ROUTER }, 'react-router'),
834 | ' v5 for client-side routing'
835 | ),
836 | },
837 | React.createElement(AsyncTabbedRouter_1.default, null)
838 | );
839 | },
840 | 6231: function (__unused_webpack_module, exports, __webpack_require__) {
841 | 'use strict';
842 | var __importDefault =
843 | (this && this.__importDefault) ||
844 | function (mod) {
845 | return mod && mod.__esModule ? mod : { default: mod };
846 | };
847 | Object.defineProperty(exports, '__esModule', { value: !0 }), (exports.default = void 0);
848 | var ReactRouter_1 = __webpack_require__(1860);
849 | Object.defineProperty(exports, 'default', {
850 | enumerable: !0,
851 | get: function () {
852 | return __importDefault(ReactRouter_1).default;
853 | },
854 | });
855 | },
856 | 3187: function (__unused_webpack_module, exports, __webpack_require__) {
857 | 'use strict';
858 | var __importDefault =
859 | (this && this.__importDefault) ||
860 | function (mod) {
861 | return mod && mod.__esModule ? mod : { default: mod };
862 | };
863 | Object.defineProperty(exports, '__esModule', { value: !0 });
864 | const react_1 = __importDefault(__webpack_require__(7294)),
865 | bind_1 = __importDefault(__webpack_require__(7166)),
866 | react_redux_1 = __webpack_require__(8629),
867 | Entity_1 = __importDefault(__webpack_require__(3670)),
868 | actions_1 = __webpack_require__(6186),
869 | types_1 = __webpack_require__(55),
870 | ReduxEntity_scss_1 = __importDefault(__webpack_require__(4689)),
871 | cx = bind_1.default.bind(ReduxEntity_scss_1.default);
872 | exports.default = () => {
873 | const dispatch = react_redux_1.useDispatch(),
874 | entities = react_redux_1.useSelector((state) => state.entities),
875 | getLoadEntityThunk = (type) => {
876 | switch (type) {
877 | case types_1.EntityType.Foo:
878 | return () => dispatch(actions_1.fetchFoo());
879 | case types_1.EntityType.Bar:
880 | return () => dispatch(actions_1.fetchBar());
881 | case types_1.EntityType.Baz:
882 | return () => dispatch(actions_1.fetchBaz());
883 | }
884 | };
885 | return react_1.default.createElement(
886 | 'div',
887 | { className: `${cx('redux-entity--container')} notification is-light m-t-sm` },
888 | Object.values(types_1.EntityType).map((key) =>
889 | react_1.default.createElement(Entity_1.default, {
890 | key,
891 | name: key,
892 | append: key === types_1.EntityType.Bar,
893 | entity: entities[key],
894 | fetchEntity: getLoadEntityThunk(key),
895 | })
896 | )
897 | );
898 | };
899 | },
900 | 3670: function (__unused_webpack_module, exports, __webpack_require__) {
901 | 'use strict';
902 | var __createBinding =
903 | (this && this.__createBinding) ||
904 | (Object.create
905 | ? function (o, m, k, k2) {
906 | void 0 === k2 && (k2 = k),
907 | Object.defineProperty(o, k2, {
908 | enumerable: !0,
909 | get: function () {
910 | return m[k];
911 | },
912 | });
913 | }
914 | : function (o, m, k, k2) {
915 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
916 | }),
917 | __setModuleDefault =
918 | (this && this.__setModuleDefault) ||
919 | (Object.create
920 | ? function (o, v) {
921 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
922 | }
923 | : function (o, v) {
924 | o.default = v;
925 | }),
926 | __importStar =
927 | (this && this.__importStar) ||
928 | function (mod) {
929 | if (mod && mod.__esModule) return mod;
930 | var result = {};
931 | if (null != mod)
932 | for (var k in mod)
933 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
934 | return __setModuleDefault(result, mod), result;
935 | },
936 | __importDefault =
937 | (this && this.__importDefault) ||
938 | function (mod) {
939 | return mod && mod.__esModule ? mod : { default: mod };
940 | };
941 | Object.defineProperty(exports, '__esModule', { value: !0 });
942 | const react_1 = __importStar(__webpack_require__(7294)),
943 | react_redux_1 = __webpack_require__(8629),
944 | isEmpty_1 = __importDefault(__webpack_require__(1609)),
945 | common_1 = __webpack_require__(1256),
946 | EntityData_1 = __importDefault(__webpack_require__(9857)),
947 | EntityReset_1 = __importDefault(__webpack_require__(1065)),
948 | EntityMissing_1 = __importDefault(__webpack_require__(9197)),
949 | EntityFailure_1 = __importDefault(__webpack_require__(467)),
950 | EntityLoading_1 = __importDefault(__webpack_require__(3387)),
951 | redux_entity_1 = __webpack_require__(7694);
952 | exports.default = ({ name, append, entity, fetchEntity }) => {
953 | const dispatch = react_redux_1.useDispatch();
954 | if (
955 | (react_1.useEffect(() => {
956 | fetchEntity();
957 | }, []),
958 | isEmpty_1.default(entity))
959 | )
960 | return react_1.default.createElement(EntityMissing_1.default, { name, fetchEntity });
961 | const { isFetching, data, error, lastUpdated } = entity;
962 | let body;
963 | return (
964 | (body = error
965 | ? react_1.default.createElement(EntityFailure_1.default, { name, error })
966 | : isFetching
967 | ? react_1.default.createElement(EntityLoading_1.default, null)
968 | : isEmpty_1.default(data)
969 | ? react_1.default.createElement(EntityReset_1.default, { name })
970 | : react_1.default.createElement(EntityData_1.default, { name, append, lastUpdated })),
971 | react_1.default.createElement(
972 | 'div',
973 | { className: 'm-b-sm' },
974 | body,
975 | react_1.default.createElement(
976 | 'div',
977 | { className: 'field has-addons' },
978 | react_1.default.createElement(
979 | common_1.Button,
980 | { icon: 'download', onClick: fetchEntity, disabled: isFetching, loading: isFetching, theme: 'is-info' },
981 | 'Fetch'
982 | ),
983 | react_1.default.createElement(
984 | common_1.Button,
985 | { icon: 'history', onClick: () => dispatch(redux_entity_1.ResetEntity(name)), disabled: isFetching },
986 | 'Reset'
987 | ),
988 | react_1.default.createElement(
989 | common_1.Button,
990 | {
991 | icon: 'trash',
992 | onClick: () => dispatch(redux_entity_1.DeleteEntity(name)),
993 | disabled: isFetching,
994 | theme: 'is-danger',
995 | },
996 | 'Delete'
997 | )
998 | )
999 | )
1000 | );
1001 | };
1002 | },
1003 | 9857: function (__unused_webpack_module, exports, __webpack_require__) {
1004 | 'use strict';
1005 | var __createBinding =
1006 | (this && this.__createBinding) ||
1007 | (Object.create
1008 | ? function (o, m, k, k2) {
1009 | void 0 === k2 && (k2 = k),
1010 | Object.defineProperty(o, k2, {
1011 | enumerable: !0,
1012 | get: function () {
1013 | return m[k];
1014 | },
1015 | });
1016 | }
1017 | : function (o, m, k, k2) {
1018 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
1019 | }),
1020 | __setModuleDefault =
1021 | (this && this.__setModuleDefault) ||
1022 | (Object.create
1023 | ? function (o, v) {
1024 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
1025 | }
1026 | : function (o, v) {
1027 | o.default = v;
1028 | }),
1029 | __importStar =
1030 | (this && this.__importStar) ||
1031 | function (mod) {
1032 | if (mod && mod.__esModule) return mod;
1033 | var result = {};
1034 | if (null != mod)
1035 | for (var k in mod)
1036 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
1037 | return __setModuleDefault(result, mod), result;
1038 | };
1039 | Object.defineProperty(exports, '__esModule', { value: !0 });
1040 | const React = __importStar(__webpack_require__(7294)),
1041 | date_fns_1 = __webpack_require__(1613),
1042 | Icon_1 = __webpack_require__(8055);
1043 | exports.default = ({ name, append, lastUpdated }) => {
1044 | const action = append ? 'Appending to ' : 'Fetch for ',
1045 | date = lastUpdated && date_fns_1.format(new Date(lastUpdated), 'pp');
1046 | return React.createElement(
1047 | 'div',
1048 | { className: 'm-t-sm m-b-sm' },
1049 | React.createElement(Icon_1.CheckIcon, null),
1050 | ' ',
1051 | action,
1052 | ' ',
1053 | React.createElement('code', null, name),
1054 | ' @ ',
1055 | React.createElement('code', null, date)
1056 | );
1057 | };
1058 | },
1059 | 467: function (__unused_webpack_module, exports, __webpack_require__) {
1060 | 'use strict';
1061 | var __createBinding =
1062 | (this && this.__createBinding) ||
1063 | (Object.create
1064 | ? function (o, m, k, k2) {
1065 | void 0 === k2 && (k2 = k),
1066 | Object.defineProperty(o, k2, {
1067 | enumerable: !0,
1068 | get: function () {
1069 | return m[k];
1070 | },
1071 | });
1072 | }
1073 | : function (o, m, k, k2) {
1074 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
1075 | }),
1076 | __setModuleDefault =
1077 | (this && this.__setModuleDefault) ||
1078 | (Object.create
1079 | ? function (o, v) {
1080 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
1081 | }
1082 | : function (o, v) {
1083 | o.default = v;
1084 | }),
1085 | __importStar =
1086 | (this && this.__importStar) ||
1087 | function (mod) {
1088 | if (mod && mod.__esModule) return mod;
1089 | var result = {};
1090 | if (null != mod)
1091 | for (var k in mod)
1092 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
1093 | return __setModuleDefault(result, mod), result;
1094 | };
1095 | Object.defineProperty(exports, '__esModule', { value: !0 });
1096 | const React = __importStar(__webpack_require__(7294)),
1097 | Icon_1 = __webpack_require__(8055);
1098 | exports.default = ({ name, error }) =>
1099 | React.createElement(
1100 | 'div',
1101 | { className: 'm-t-sm m-b-sm' },
1102 | React.createElement(Icon_1.ExclamationIcon, null),
1103 | ' Failed to fetch ',
1104 | React.createElement('code', null, name),
1105 | ' due to',
1106 | ' ',
1107 | React.createElement('code', { className: 'has-text-danger' }, error.toString())
1108 | );
1109 | },
1110 | 3387: function (__unused_webpack_module, exports, __webpack_require__) {
1111 | 'use strict';
1112 | var __createBinding =
1113 | (this && this.__createBinding) ||
1114 | (Object.create
1115 | ? function (o, m, k, k2) {
1116 | void 0 === k2 && (k2 = k),
1117 | Object.defineProperty(o, k2, {
1118 | enumerable: !0,
1119 | get: function () {
1120 | return m[k];
1121 | },
1122 | });
1123 | }
1124 | : function (o, m, k, k2) {
1125 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
1126 | }),
1127 | __setModuleDefault =
1128 | (this && this.__setModuleDefault) ||
1129 | (Object.create
1130 | ? function (o, v) {
1131 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
1132 | }
1133 | : function (o, v) {
1134 | o.default = v;
1135 | }),
1136 | __importStar =
1137 | (this && this.__importStar) ||
1138 | function (mod) {
1139 | if (mod && mod.__esModule) return mod;
1140 | var result = {};
1141 | if (null != mod)
1142 | for (var k in mod)
1143 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
1144 | return __setModuleDefault(result, mod), result;
1145 | };
1146 | Object.defineProperty(exports, '__esModule', { value: !0 });
1147 | const React = __importStar(__webpack_require__(7294));
1148 | exports.default = () => React.createElement('div', { className: 'm-t-sm m-b-sm' }, 'Fetching fresh data!');
1149 | },
1150 | 9197: function (__unused_webpack_module, exports, __webpack_require__) {
1151 | 'use strict';
1152 | var __importDefault =
1153 | (this && this.__importDefault) ||
1154 | function (mod) {
1155 | return mod && mod.__esModule ? mod : { default: mod };
1156 | };
1157 | Object.defineProperty(exports, '__esModule', { value: !0 });
1158 | const react_1 = __importDefault(__webpack_require__(7294)),
1159 | Icon_1 = __importDefault(__webpack_require__(8055)),
1160 | common_1 = __webpack_require__(1256);
1161 | exports.default = ({ name, fetchEntity }) =>
1162 | react_1.default.createElement(
1163 | react_1.default.Fragment,
1164 | null,
1165 | react_1.default.createElement(
1166 | 'div',
1167 | { className: 'm-t-sm m-b-sm' },
1168 | react_1.default.createElement(Icon_1.default, {
1169 | icon: 'exclamation-triangle',
1170 | className: 'has-text-danger',
1171 | }),
1172 | ' Entity ',
1173 | react_1.default.createElement('code', null, name),
1174 | ' does not exist on ',
1175 | react_1.default.createElement('code', null, 'entities')
1176 | ),
1177 | react_1.default.createElement(
1178 | common_1.Button,
1179 | { icon: 'download', onClick: fetchEntity, theme: 'is-info' },
1180 | 'Fetch'
1181 | )
1182 | );
1183 | },
1184 | 1065: function (__unused_webpack_module, exports, __webpack_require__) {
1185 | 'use strict';
1186 | var __createBinding =
1187 | (this && this.__createBinding) ||
1188 | (Object.create
1189 | ? function (o, m, k, k2) {
1190 | void 0 === k2 && (k2 = k),
1191 | Object.defineProperty(o, k2, {
1192 | enumerable: !0,
1193 | get: function () {
1194 | return m[k];
1195 | },
1196 | });
1197 | }
1198 | : function (o, m, k, k2) {
1199 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
1200 | }),
1201 | __setModuleDefault =
1202 | (this && this.__setModuleDefault) ||
1203 | (Object.create
1204 | ? function (o, v) {
1205 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
1206 | }
1207 | : function (o, v) {
1208 | o.default = v;
1209 | }),
1210 | __importStar =
1211 | (this && this.__importStar) ||
1212 | function (mod) {
1213 | if (mod && mod.__esModule) return mod;
1214 | var result = {};
1215 | if (null != mod)
1216 | for (var k in mod)
1217 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
1218 | return __setModuleDefault(result, mod), result;
1219 | };
1220 | Object.defineProperty(exports, '__esModule', { value: !0 });
1221 | const React = __importStar(__webpack_require__(7294));
1222 | exports.default = ({ name }) =>
1223 | React.createElement(
1224 | 'div',
1225 | { className: 'm-t-sm m-b-sm' },
1226 | 'Entity ',
1227 | React.createElement('code', null, name),
1228 | ' has been cleared.'
1229 | );
1230 | },
1231 | 2961: function (__unused_webpack_module, exports, __webpack_require__) {
1232 | 'use strict';
1233 | var __createBinding =
1234 | (this && this.__createBinding) ||
1235 | (Object.create
1236 | ? function (o, m, k, k2) {
1237 | void 0 === k2 && (k2 = k),
1238 | Object.defineProperty(o, k2, {
1239 | enumerable: !0,
1240 | get: function () {
1241 | return m[k];
1242 | },
1243 | });
1244 | }
1245 | : function (o, m, k, k2) {
1246 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
1247 | }),
1248 | __setModuleDefault =
1249 | (this && this.__setModuleDefault) ||
1250 | (Object.create
1251 | ? function (o, v) {
1252 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
1253 | }
1254 | : function (o, v) {
1255 | o.default = v;
1256 | }),
1257 | __importStar =
1258 | (this && this.__importStar) ||
1259 | function (mod) {
1260 | if (mod && mod.__esModule) return mod;
1261 | var result = {};
1262 | if (null != mod)
1263 | for (var k in mod)
1264 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
1265 | return __setModuleDefault(result, mod), result;
1266 | },
1267 | __importDefault =
1268 | (this && this.__importDefault) ||
1269 | function (mod) {
1270 | return mod && mod.__esModule ? mod : { default: mod };
1271 | };
1272 | Object.defineProperty(exports, '__esModule', { value: !0 });
1273 | const React = __importStar(__webpack_require__(7294)),
1274 | GenericSection_1 = __importDefault(__webpack_require__(347)),
1275 | Entities_1 = __importDefault(__webpack_require__(3187)),
1276 | const_1 = __webpack_require__(5365);
1277 | exports.default = () =>
1278 | React.createElement(
1279 | GenericSection_1.default,
1280 | {
1281 | icon: 'sitemap',
1282 | title: 'State Management',
1283 | subtitle: React.createElement(
1284 | 'span',
1285 | null,
1286 | 'Utilizes ',
1287 | React.createElement('a', { href: const_1.URL.REDUX_ENTITY }, 'redux-entity'),
1288 | ' for domain entity management'
1289 | ),
1290 | },
1291 | React.createElement(Entities_1.default, null)
1292 | );
1293 | },
1294 | 2323: function (__unused_webpack_module, exports, __webpack_require__) {
1295 | 'use strict';
1296 | var __importDefault =
1297 | (this && this.__importDefault) ||
1298 | function (mod) {
1299 | return mod && mod.__esModule ? mod : { default: mod };
1300 | };
1301 | Object.defineProperty(exports, '__esModule', { value: !0 }), (exports.default = void 0);
1302 | var ReduxEntity_1 = __webpack_require__(2961);
1303 | Object.defineProperty(exports, 'default', {
1304 | enumerable: !0,
1305 | get: function () {
1306 | return __importDefault(ReduxEntity_1).default;
1307 | },
1308 | });
1309 | },
1310 | 6406: function (__unused_webpack_module, exports, __webpack_require__) {
1311 | 'use strict';
1312 | var __createBinding =
1313 | (this && this.__createBinding) ||
1314 | (Object.create
1315 | ? function (o, m, k, k2) {
1316 | void 0 === k2 && (k2 = k),
1317 | Object.defineProperty(o, k2, {
1318 | enumerable: !0,
1319 | get: function () {
1320 | return m[k];
1321 | },
1322 | });
1323 | }
1324 | : function (o, m, k, k2) {
1325 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
1326 | }),
1327 | __setModuleDefault =
1328 | (this && this.__setModuleDefault) ||
1329 | (Object.create
1330 | ? function (o, v) {
1331 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
1332 | }
1333 | : function (o, v) {
1334 | o.default = v;
1335 | }),
1336 | __importStar =
1337 | (this && this.__importStar) ||
1338 | function (mod) {
1339 | if (mod && mod.__esModule) return mod;
1340 | var result = {};
1341 | if (null != mod)
1342 | for (var k in mod)
1343 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
1344 | return __setModuleDefault(result, mod), result;
1345 | },
1346 | __importDefault =
1347 | (this && this.__importDefault) ||
1348 | function (mod) {
1349 | return mod && mod.__esModule ? mod : { default: mod };
1350 | };
1351 | Object.defineProperty(exports, '__esModule', { value: !0 });
1352 | const React = __importStar(__webpack_require__(7294)),
1353 | react_json_pretty_1 = __importDefault(__webpack_require__(7262)),
1354 | react_redux_1 = __webpack_require__(8629),
1355 | GenericSection_1 = __importDefault(__webpack_require__(347)),
1356 | themeProps = { keyStyle: 'color: #3298dc;' },
1357 | replacer = (key, value) => (value instanceof Error ? value.toString() : value);
1358 | exports.default = () => {
1359 | const state = react_redux_1.useSelector((state) => state);
1360 | return React.createElement(
1361 | GenericSection_1.default,
1362 | {
1363 | icon: 'tree',
1364 | title: 'State Tree',
1365 | subtitle: React.createElement('span', null, 'Open Console to view dispatched actions'),
1366 | },
1367 | React.createElement(react_json_pretty_1.default, Object.assign({}, themeProps, { data: state, replacer }))
1368 | );
1369 | };
1370 | },
1371 | 1198: function (__unused_webpack_module, exports, __webpack_require__) {
1372 | 'use strict';
1373 | var __importDefault =
1374 | (this && this.__importDefault) ||
1375 | function (mod) {
1376 | return mod && mod.__esModule ? mod : { default: mod };
1377 | };
1378 | Object.defineProperty(exports, '__esModule', { value: !0 }), (exports.default = void 0);
1379 | var ReduxState_1 = __webpack_require__(6406);
1380 | Object.defineProperty(exports, 'default', {
1381 | enumerable: !0,
1382 | get: function () {
1383 | return __importDefault(ReduxState_1).default;
1384 | },
1385 | });
1386 | },
1387 | 6253: function (__unused_webpack_module, exports, __webpack_require__) {
1388 | 'use strict';
1389 | var __importDefault =
1390 | (this && this.__importDefault) ||
1391 | function (mod) {
1392 | return mod && mod.__esModule ? mod : { default: mod };
1393 | };
1394 | Object.defineProperty(exports, '__esModule', { value: !0 });
1395 | const react_1 = __importDefault(__webpack_require__(7294)),
1396 | Icon_1 = __importDefault(__webpack_require__(8055));
1397 | exports.default = ({ icon, disabled, loading, onClick, children, theme = '' }) =>
1398 | react_1.default.createElement(
1399 | 'p',
1400 | { key: 'Fetch', className: 'control' },
1401 | react_1.default.createElement(
1402 | 'a',
1403 | { className: `button ${theme} ${loading && 'is-loading'}`, disabled, onClick },
1404 | react_1.default.createElement(
1405 | 'span',
1406 | { className: 'icon' },
1407 | react_1.default.createElement(Icon_1.default, { icon })
1408 | ),
1409 | react_1.default.createElement('span', null, children)
1410 | )
1411 | );
1412 | },
1413 | 8055: function (__unused_webpack_module, exports, __webpack_require__) {
1414 | 'use strict';
1415 | var __importDefault =
1416 | (this && this.__importDefault) ||
1417 | function (mod) {
1418 | return mod && mod.__esModule ? mod : { default: mod };
1419 | };
1420 | Object.defineProperty(exports, '__esModule', { value: !0 }),
1421 | (exports.CogIcon = exports.CheckIcon = exports.ExclamationIcon = void 0);
1422 | const react_1 = __importDefault(__webpack_require__(7294));
1423 | exports.ExclamationIcon = () =>
1424 | react_1.default.createElement(Icon, { icon: 'exclamation-triangle', className: 'has-text-danger' });
1425 | exports.CheckIcon = () => react_1.default.createElement(Icon, { icon: 'check', className: 'has-text-success' });
1426 | exports.CogIcon = ({ size, className }) =>
1427 | react_1.default.createElement(Icon, { icon: 'cog fa-spin', size, className });
1428 | const Icon = ({ icon, prefix, className, size = 'fa-1x' }) => {
1429 | const iconPrefix = prefix || 'fa';
1430 | return react_1.default.createElement(
1431 | 'span',
1432 | null,
1433 | react_1.default.createElement('i', { className: `${iconPrefix} fa-${icon} ${className || ''} ${size}` })
1434 | );
1435 | };
1436 | exports.default = Icon;
1437 | },
1438 | 3152: function (__unused_webpack_module, exports, __webpack_require__) {
1439 | 'use strict';
1440 | var __createBinding =
1441 | (this && this.__createBinding) ||
1442 | (Object.create
1443 | ? function (o, m, k, k2) {
1444 | void 0 === k2 && (k2 = k),
1445 | Object.defineProperty(o, k2, {
1446 | enumerable: !0,
1447 | get: function () {
1448 | return m[k];
1449 | },
1450 | });
1451 | }
1452 | : function (o, m, k, k2) {
1453 | void 0 === k2 && (k2 = k), (o[k2] = m[k]);
1454 | }),
1455 | __setModuleDefault =
1456 | (this && this.__setModuleDefault) ||
1457 | (Object.create
1458 | ? function (o, v) {
1459 | Object.defineProperty(o, 'default', { enumerable: !0, value: v });
1460 | }
1461 | : function (o, v) {
1462 | o.default = v;
1463 | }),
1464 | __importStar =
1465 | (this && this.__importStar) ||
1466 | function (mod) {
1467 | if (mod && mod.__esModule) return mod;
1468 | var result = {};
1469 | if (null != mod)
1470 | for (var k in mod)
1471 | 'default' !== k && Object.prototype.hasOwnProperty.call(mod, k) && __createBinding(result, mod, k);
1472 | return __setModuleDefault(result, mod), result;
1473 | };
1474 | Object.defineProperty(exports, '__esModule', { value: !0 });
1475 | const React = __importStar(__webpack_require__(7294));
1476 | exports.default = ({ url, children }) =>
1477 | React.createElement('a', { href: url, target: '_blank', rel: 'noopener noreferrer' }, children);
1478 | },
1479 | 975: function (__unused_webpack_module, exports, __webpack_require__) {
1480 | 'use strict';
1481 | var __importDefault =
1482 | (this && this.__importDefault) ||
1483 | function (mod) {
1484 | return mod && mod.__esModule ? mod : { default: mod };
1485 | };
1486 | Object.defineProperty(exports, '__esModule', { value: !0 });
1487 | const react_1 = __importDefault(__webpack_require__(7294)),
1488 | bind_1 = __importDefault(__webpack_require__(7166)),
1489 | common_1 = __webpack_require__(1256),
1490 | logo_png_1 = __importDefault(__webpack_require__(4439)),
1491 | const_1 = __webpack_require__(5365),
1492 | NavBar_scss_1 = __importDefault(__webpack_require__(9938)),
1493 | cx = bind_1.default.bind(NavBar_scss_1.default);
1494 | exports.default = () =>
1495 | react_1.default.createElement(
1496 | 'nav',
1497 | {
1498 | className: `navbar is-dark ${cx('nav-bar--container')}`,
1499 | role: 'navigation',
1500 | 'aria-label': 'main navigation',
1501 | },
1502 | react_1.default.createElement(
1503 | 'div',
1504 | { className: 'navbar-brand' },
1505 | react_1.default.createElement(
1506 | 'a',
1507 | { href: const_1.URL.REPOSITORY, className: 'navbar-item is-size-3' },
1508 | react_1.default.createElement('img', { src: logo_png_1.default, height: 64, width: 64 }),
1509 | react_1.default.createElement('span', null, 'react-boilerplate')
1510 | )
1511 | ),
1512 | react_1.default.createElement(
1513 | 'div',
1514 | { className: 'navbar-end' },
1515 | react_1.default.createElement(
1516 | 'div',
1517 | { className: 'navbar-item' },
1518 | react_1.default.createElement(
1519 | 'a',
1520 | { className: 'button is-dark', href: const_1.URL.NPM },
1521 | react_1.default.createElement(
1522 | 'span',
1523 | { className: 'icon is-small has-text-danger' },
1524 | react_1.default.createElement(common_1.Icon, { icon: 'npm', prefix: 'fab', size: 'fa-2x' })
1525 | )
1526 | )
1527 | ),
1528 | react_1.default.createElement(
1529 | 'div',
1530 | { className: 'navbar-item' },
1531 | react_1.default.createElement(
1532 | 'a',
1533 | { className: 'button is-dark', href: const_1.URL.REPOSITORY },
1534 | react_1.default.createElement(
1535 | 'span',
1536 | { className: 'icon is-small' },
1537 | react_1.default.createElement(common_1.Icon, { icon: 'github', prefix: 'fab', size: 'fa-2x' })
1538 | )
1539 | )
1540 | )
1541 | )
1542 | );
1543 | },
1544 | 1256: function (__unused_webpack_module, exports, __webpack_require__) {
1545 | 'use strict';
1546 | var __importDefault =
1547 | (this && this.__importDefault) ||
1548 | function (mod) {
1549 | return mod && mod.__esModule ? mod : { default: mod };
1550 | };
1551 | Object.defineProperty(exports, '__esModule', { value: !0 }),
1552 | (exports.Link = exports.Button = exports.Icon = void 0);
1553 | var Icon_1 = __webpack_require__(8055);
1554 | Object.defineProperty(exports, 'Icon', {
1555 | enumerable: !0,
1556 | get: function () {
1557 | return __importDefault(Icon_1).default;
1558 | },
1559 | });
1560 | var Button_1 = __webpack_require__(6253);
1561 | Object.defineProperty(exports, 'Button', {
1562 | enumerable: !0,
1563 | get: function () {
1564 | return __importDefault(Button_1).default;
1565 | },
1566 | });
1567 | var Link_1 = __webpack_require__(3152);
1568 | Object.defineProperty(exports, 'Link', {
1569 | enumerable: !0,
1570 | get: function () {
1571 | return __importDefault(Link_1).default;
1572 | },
1573 | });
1574 | },
1575 | 5365: function (__unused_webpack_module, exports) {
1576 | 'use strict';
1577 | Object.defineProperty(exports, '__esModule', { value: !0 }),
1578 | (exports.URL = void 0),
1579 | (exports.URL = {
1580 | GITHUB: 'https://github.com/mikechabot',
1581 | REPOSITORY: 'http://www.github.com/mikechabot/react-boilerplate',
1582 | NPM: 'https://www.npmjs.com/~mikechabot',
1583 | DEMO: 'https://github.com/mikechabot/react-boilerplate',
1584 | LICENSE: 'https://github.com/mikechabot/react-boilerplate/blob/master/LICENSE',
1585 | REDUX_ENTITY: 'https://github.com/mikechabot/redux-entity',
1586 | REACT_ROUTER: 'https://github.com/ReactTraining/react-router',
1587 | });
1588 | },
1589 | 9269: function (__unused_webpack_module, exports) {
1590 | 'use strict';
1591 | Object.defineProperty(exports, '__esModule', { value: !0 }),
1592 | (exports.RESET_COUNTER = exports.DECREMENT_COUNTER = exports.INCREMENT_COUNTER = void 0),
1593 | (exports.INCREMENT_COUNTER = 'react-boilerplate/counter/INCREMENT_COUNTER'),
1594 | (exports.DECREMENT_COUNTER = 'react-boilerplate/counter/DECREMENT_COUNTER'),
1595 | (exports.RESET_COUNTER = 'react-boilerplate/counter/RESET_COUNTER');
1596 | exports.default = (state = 0, action) => {
1597 | switch (action.type) {
1598 | case exports.INCREMENT_COUNTER:
1599 | return state + 1;
1600 | case exports.DECREMENT_COUNTER:
1601 | return state - 1;
1602 | case exports.RESET_COUNTER:
1603 | return 0;
1604 | default:
1605 | return state;
1606 | }
1607 | };
1608 | },
1609 | 6186: function (__unused_webpack_module, exports, __webpack_require__) {
1610 | 'use strict';
1611 | Object.defineProperty(exports, '__esModule', { value: !0 }),
1612 | (exports.fetchBaz = exports.fetchBar = exports.fetchFoo = void 0);
1613 | const redux_entity_1 = __webpack_require__(7694),
1614 | domain_service_1 = __webpack_require__(2819),
1615 | types_1 = __webpack_require__(55);
1616 | (exports.fetchFoo = function fetchFoo() {
1617 | return redux_entity_1.GetEntity(types_1.EntityType.Foo, domain_service_1.fetchMockData());
1618 | }),
1619 | (exports.fetchBar = function fetchBar() {
1620 | return redux_entity_1.GetEntity(types_1.EntityType.Bar, domain_service_1.fetchMockData(), { append: !0 });
1621 | }),
1622 | (exports.fetchBaz = function fetchBaz() {
1623 | return redux_entity_1.GetEntity(types_1.EntityType.Baz, domain_service_1.fetchMockData(!0));
1624 | });
1625 | },
1626 | 5318: function (__unused_webpack_module, exports, __webpack_require__) {
1627 | 'use strict';
1628 | Object.defineProperty(exports, '__esModule', { value: !0 }), (exports.default = void 0);
1629 | var lib_1 = __webpack_require__(7694);
1630 | Object.defineProperty(exports, 'default', {
1631 | enumerable: !0,
1632 | get: function () {
1633 | return lib_1.reducer;
1634 | },
1635 | });
1636 | },
1637 | 55: function (__unused_webpack_module, exports) {
1638 | 'use strict';
1639 | Object.defineProperty(exports, '__esModule', { value: !0 }),
1640 | (exports.EntityType = void 0),
1641 | (function (EntityType) {
1642 | (EntityType.Foo = 'foo'), (EntityType.Bar = 'bar'), (EntityType.Baz = 'baz');
1643 | })(exports.EntityType || (exports.EntityType = {}));
1644 | },
1645 | 8262: function (__unused_webpack_module, exports, __webpack_require__) {
1646 | 'use strict';
1647 | var __importDefault =
1648 | (this && this.__importDefault) ||
1649 | function (mod) {
1650 | return mod && mod.__esModule ? mod : { default: mod };
1651 | };
1652 | Object.defineProperty(exports, '__esModule', { value: !0 });
1653 | const redux_1 = __webpack_require__(4890),
1654 | reducer_1 = __importDefault(__webpack_require__(5318)),
1655 | reducer_2 = __importDefault(__webpack_require__(9269)),
1656 | rootReducer = redux_1.combineReducers({ counter: reducer_2.default, entities: reducer_1.default });
1657 | exports.default = rootReducer;
1658 | },
1659 | 234: function (__unused_webpack_module, exports, __webpack_require__) {
1660 | 'use strict';
1661 | var __importDefault =
1662 | (this && this.__importDefault) ||
1663 | function (mod) {
1664 | return mod && mod.__esModule ? mod : { default: mod };
1665 | };
1666 | Object.defineProperty(exports, '__esModule', { value: !0 });
1667 | const redux_1 = __webpack_require__(4890),
1668 | redux_thunk_1 = __importDefault(__webpack_require__(3894)),
1669 | redux_logger_1 = __importDefault(__webpack_require__(4500)),
1670 | index_1 = __importDefault(__webpack_require__(8262));
1671 | exports.default = function configureStore(initialState = {}) {
1672 | return redux_1.createStore(
1673 | index_1.default,
1674 | initialState,
1675 | redux_1.applyMiddleware(redux_thunk_1.default, redux_logger_1.default)
1676 | );
1677 | };
1678 | },
1679 | 169: function (__unused_webpack_module, exports, __webpack_require__) {
1680 | 'use strict';
1681 | var __importDefault =
1682 | (this && this.__importDefault) ||
1683 | function (mod) {
1684 | return mod && mod.__esModule ? mod : { default: mod };
1685 | };
1686 | Object.defineProperty(exports, '__esModule', { value: !0 });
1687 | const redux_1 = __webpack_require__(4890),
1688 | redux_thunk_1 = __importDefault(__webpack_require__(3894)),
1689 | index_1 = __importDefault(__webpack_require__(8262)),
1690 | redux_logger_1 = __importDefault(__webpack_require__(4500));
1691 | exports.default = function configureStore(initialState = {}) {
1692 | return redux_1.createStore(
1693 | index_1.default,
1694 | initialState,
1695 | redux_1.applyMiddleware(redux_thunk_1.default, redux_logger_1.default)
1696 | );
1697 | };
1698 | },
1699 | 5908: function (__unused_webpack_module, exports, __webpack_require__) {
1700 | 'use strict';
1701 | var __importDefault =
1702 | (this && this.__importDefault) ||
1703 | function (mod) {
1704 | return mod && mod.__esModule ? mod : { default: mod };
1705 | };
1706 | Object.defineProperty(exports, '__esModule', { value: !0 });
1707 | const node_service_1 = __importDefault(__webpack_require__(8720)),
1708 | configure_store_prod_1 = __importDefault(__webpack_require__(169)),
1709 | configure_store_dev_1 = __importDefault(__webpack_require__(234));
1710 | exports.default = node_service_1.default.isProduction()
1711 | ? configure_store_prod_1.default()
1712 | : configure_store_dev_1.default();
1713 | },
1714 | 3521: function (__unused_webpack_module, exports, __webpack_require__) {
1715 | 'use strict';
1716 | var __importDefault =
1717 | (this && this.__importDefault) ||
1718 | function (mod) {
1719 | return mod && mod.__esModule ? mod : { default: mod };
1720 | };
1721 | Object.defineProperty(exports, '__esModule', { value: !0 });
1722 | const axios_1 = __importDefault(__webpack_require__(9669)),
1723 | config_service_1 = __importDefault(__webpack_require__(3018)),
1724 | instance = axios_1.default.create({ baseURL: config_service_1.default.getBaseUrl(), timeout: 4e3 });
1725 | exports.default = { request: (options) => instance.request(options) };
1726 | },
1727 | 5334: function (__unused_webpack_module, exports, __webpack_require__) {
1728 | 'use strict';
1729 | var __importDefault =
1730 | (this && this.__importDefault) ||
1731 | function (mod) {
1732 | return mod && mod.__esModule ? mod : { default: mod };
1733 | };
1734 | Object.defineProperty(exports, '__esModule', { value: !0 }), (exports.post = exports.get = void 0);
1735 | const ajax_service_1 = __importDefault(__webpack_require__(3521));
1736 | var HttpMethod;
1737 | !(function (HttpMethod) {
1738 | (HttpMethod.GET = 'GET'), (HttpMethod.POST = 'POST'), (HttpMethod.PUT = 'PUT'), (HttpMethod.DELETE = 'DELETE');
1739 | })(HttpMethod || (HttpMethod = {}));
1740 | const request = (method, url, data, options) => {
1741 | const defaultOptions = { url, method, responseType: 'json' };
1742 | data &&
1743 | ((defaultOptions.data = JSON.stringify(data)),
1744 | (defaultOptions.headers = { 'Content-Type': 'application/json' }));
1745 | let requestOptions = defaultOptions;
1746 | return (
1747 | options && (requestOptions = Object.assign(Object.assign({}, defaultOptions), options)),
1748 | new Promise((resolve, reject) => {
1749 | ajax_service_1.default
1750 | .request(requestOptions)
1751 | .then(resolve)
1752 | .catch((error) =>
1753 | reject(
1754 | (function deriveError(error) {
1755 | return error
1756 | ? error.message
1757 | ? error
1758 | : `${error.status} ${error.statusText}`
1759 | : new Error('An unknown error occurred');
1760 | })(error)
1761 | )
1762 | );
1763 | })
1764 | );
1765 | };
1766 | exports.get = (url, options) => request(HttpMethod.GET, url, void 0, options);
1767 | exports.post = (url, data, options) => request(HttpMethod.POST, url, data, options);
1768 | },
1769 | 2819: function (__unused_webpack_module, exports, __webpack_require__) {
1770 | 'use strict';
1771 | Object.defineProperty(exports, '__esModule', { value: !0 }),
1772 | (exports.fetchMockData = exports.postFoo = exports.fetchFoo = void 0);
1773 | const data_access_service_1 = __webpack_require__(5334),
1774 | util_1 = __webpack_require__(4609),
1775 | fakeError = new Error('Fake Error!');
1776 | exports.fetchFoo = (id) => data_access_service_1.get(`/foo/${id}`);
1777 | exports.postFoo = (id, data) => data_access_service_1.post(`/foo/${id}`, data);
1778 | exports.fetchMockData = (doReject = !1) => {
1779 | const delay = util_1.randomNumber(),
1780 | payload = { delay };
1781 | return new Promise((resolve, reject) => {
1782 | setTimeout(() => (doReject ? reject(fakeError) : resolve(payload)), 1e3 * delay);
1783 | });
1784 | };
1785 | },
1786 | 4609: function (__unused_webpack_module, exports) {
1787 | 'use strict';
1788 | Object.defineProperty(exports, '__esModule', { value: !0 }), (exports.randomNumber = void 0);
1789 | exports.randomNumber = function randomNumber() {
1790 | return Number(2 * Math.random() + 1);
1791 | };
1792 | },
1793 | 4439: function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1794 | 'use strict';
1795 | __webpack_require__.r(__webpack_exports__),
1796 | (__webpack_exports__.default =
1797 | 'data:image/png;base64,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');
1798 | },
1799 | },
1800 | 0,
1801 | [[3463, 700, 736]],
1802 | ]);
1803 |
--------------------------------------------------------------------------------
/docs/manifest.b39cfef421931f6623fe.js:
--------------------------------------------------------------------------------
1 | !(function () {
2 | 'use strict';
3 | var leafPrototypes,
4 | getProto,
5 | inProgress,
6 | loadStylesheet,
7 | installedCssChunks,
8 | __webpack_modules__ = {},
9 | __webpack_module_cache__ = {};
10 | function __webpack_require__(moduleId) {
11 | if (__webpack_module_cache__[moduleId]) return __webpack_module_cache__[moduleId].exports;
12 | var module = (__webpack_module_cache__[moduleId] = { id: moduleId, loaded: !1, exports: {} });
13 | return (
14 | __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__),
15 | (module.loaded = !0),
16 | module.exports
17 | );
18 | }
19 | (__webpack_require__.m = __webpack_modules__),
20 | (__webpack_require__.x = function () {}),
21 | (__webpack_require__.n = function (module) {
22 | var getter =
23 | module && module.__esModule
24 | ? function () {
25 | return module.default;
26 | }
27 | : function () {
28 | return module;
29 | };
30 | return __webpack_require__.d(getter, { a: getter }), getter;
31 | }),
32 | (getProto = Object.getPrototypeOf
33 | ? function (obj) {
34 | return Object.getPrototypeOf(obj);
35 | }
36 | : function (obj) {
37 | return obj.__proto__;
38 | }),
39 | (__webpack_require__.t = function (value, mode) {
40 | if ((1 & mode && (value = this(value)), 8 & mode)) return value;
41 | if ('object' == typeof value && value) {
42 | if (4 & mode && value.__esModule) return value;
43 | if (16 & mode && 'function' == typeof value.then) return value;
44 | }
45 | var ns = Object.create(null);
46 | __webpack_require__.r(ns);
47 | var def = {};
48 | leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];
49 | for (
50 | var current = 2 & mode && value;
51 | 'object' == typeof current && !~leafPrototypes.indexOf(current);
52 | current = getProto(current)
53 | )
54 | Object.getOwnPropertyNames(current).forEach(function (key) {
55 | def[key] = function () {
56 | return value[key];
57 | };
58 | });
59 | return (
60 | (def.default = function () {
61 | return value;
62 | }),
63 | __webpack_require__.d(ns, def),
64 | ns
65 | );
66 | }),
67 | (__webpack_require__.d = function (exports, definition) {
68 | for (var key in definition)
69 | __webpack_require__.o(definition, key) &&
70 | !__webpack_require__.o(exports, key) &&
71 | Object.defineProperty(exports, key, { enumerable: !0, get: definition[key] });
72 | }),
73 | (__webpack_require__.f = {}),
74 | (__webpack_require__.e = function (chunkId) {
75 | return Promise.all(
76 | Object.keys(__webpack_require__.f).reduce(function (promises, key) {
77 | return __webpack_require__.f[key](chunkId, promises), promises;
78 | }, [])
79 | );
80 | }),
81 | (__webpack_require__.u = function (chunkId) {
82 | return (
83 | {
84 | 715: 'components-Sections-ReactRouter-Routes-IncrementRoute',
85 | 896: 'components-Sections-ReactRouter-Routes-DecrementRoute',
86 | 956: 'components-Sections-ReactRouter-Routes-ResetRoute',
87 | }[chunkId] +
88 | '.' +
89 | __webpack_require__.h() +
90 | '.js'
91 | );
92 | }),
93 | (__webpack_require__.miniCssF = function (chunkId) {
94 | return 715 === chunkId
95 | ? '715.7dd94fe17002b841b25c.css'
96 | : 896 === chunkId
97 | ? '896.7dd94fe17002b841b25c.css'
98 | : 956 === chunkId
99 | ? '956.7dd94fe17002b841b25c.css'
100 | : { 179: 'main', 700: 'manifest', 736: 'vendor' }[chunkId] +
101 | '.' +
102 | { 179: 'e6747817a710beefd9ef', 736: '31d6cfe0d16ae931b73c' }[chunkId] +
103 | '.css';
104 | }),
105 | (__webpack_require__.h = function () {
106 | return 'b39cfef421931f6623fe';
107 | }),
108 | (__webpack_require__.g = (function () {
109 | if ('object' == typeof globalThis) return globalThis;
110 | try {
111 | return this || new Function('return this')();
112 | } catch (e) {
113 | if ('object' == typeof window) return window;
114 | }
115 | })()),
116 | (__webpack_require__.hmd = function (module) {
117 | return (
118 | (module = Object.create(module)).children || (module.children = []),
119 | Object.defineProperty(module, 'exports', {
120 | enumerable: !0,
121 | set: function () {
122 | throw new Error(
123 | 'ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id
124 | );
125 | },
126 | }),
127 | module
128 | );
129 | }),
130 | (__webpack_require__.o = function (obj, prop) {
131 | return Object.prototype.hasOwnProperty.call(obj, prop);
132 | }),
133 | (inProgress = {}),
134 | (__webpack_require__.l = function (url, done, key) {
135 | if (inProgress[url]) inProgress[url].push(done);
136 | else {
137 | var script, needAttach;
138 | if (void 0 !== key)
139 | for (var scripts = document.getElementsByTagName('script'), i = 0; i < scripts.length; i++) {
140 | var s = scripts[i];
141 | if (s.getAttribute('src') == url || s.getAttribute('data-webpack') == 'react-boilerplate:' + key) {
142 | script = s;
143 | break;
144 | }
145 | }
146 | script ||
147 | ((needAttach = !0),
148 | ((script = document.createElement('script')).charset = 'utf-8'),
149 | (script.timeout = 120),
150 | __webpack_require__.nc && script.setAttribute('nonce', __webpack_require__.nc),
151 | script.setAttribute('data-webpack', 'react-boilerplate:' + key),
152 | (script.src = url)),
153 | (inProgress[url] = [done]);
154 | var onScriptComplete = function (prev, event) {
155 | (script.onerror = script.onload = null), clearTimeout(timeout);
156 | var doneFns = inProgress[url];
157 | if (
158 | (delete inProgress[url],
159 | script.parentNode && script.parentNode.removeChild(script),
160 | doneFns &&
161 | doneFns.forEach(function (fn) {
162 | return fn(event);
163 | }),
164 | prev)
165 | )
166 | return prev(event);
167 | },
168 | timeout = setTimeout(onScriptComplete.bind(null, void 0, { type: 'timeout', target: script }), 12e4);
169 | (script.onerror = onScriptComplete.bind(null, script.onerror)),
170 | (script.onload = onScriptComplete.bind(null, script.onload)),
171 | needAttach && document.head.appendChild(script);
172 | }
173 | }),
174 | (__webpack_require__.r = function (exports) {
175 | 'undefined' != typeof Symbol &&
176 | Symbol.toStringTag &&
177 | Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }),
178 | Object.defineProperty(exports, '__esModule', { value: !0 });
179 | }),
180 | (__webpack_require__.nmd = function (module) {
181 | return (module.paths = []), module.children || (module.children = []), module;
182 | }),
183 | (function () {
184 | var scriptUrl;
185 | __webpack_require__.g.importScripts && (scriptUrl = __webpack_require__.g.location + '');
186 | var document = __webpack_require__.g.document;
187 | if (!scriptUrl && document && (document.currentScript && (scriptUrl = document.currentScript.src), !scriptUrl)) {
188 | var scripts = document.getElementsByTagName('script');
189 | scripts.length && (scriptUrl = scripts[scripts.length - 1].src);
190 | }
191 | if (!scriptUrl) throw new Error('Automatic publicPath is not supported in this browser');
192 | (scriptUrl = scriptUrl
193 | .replace(/#.*$/, '')
194 | .replace(/\?.*$/, '')
195 | .replace(/\/[^\/]+$/, '/')),
196 | (__webpack_require__.p = scriptUrl);
197 | })(),
198 | (loadStylesheet = function (chunkId) {
199 | return new Promise(function (resolve, reject) {
200 | var href = __webpack_require__.miniCssF(chunkId),
201 | fullhref = __webpack_require__.p + href;
202 | if (
203 | (function (href, fullhref) {
204 | for (
205 | var existingLinkTags = document.getElementsByTagName('link'), i = 0;
206 | i < existingLinkTags.length;
207 | i++
208 | ) {
209 | var dataHref = (tag = existingLinkTags[i]).getAttribute('data-href') || tag.getAttribute('href');
210 | if ('stylesheet' === tag.rel && (dataHref === href || dataHref === fullhref)) return tag;
211 | }
212 | var existingStyleTags = document.getElementsByTagName('style');
213 | for (i = 0; i < existingStyleTags.length; i++) {
214 | var tag;
215 | if ((dataHref = (tag = existingStyleTags[i]).getAttribute('data-href')) === href || dataHref === fullhref)
216 | return tag;
217 | }
218 | })(href, fullhref)
219 | )
220 | return resolve();
221 | !(function (chunkId, fullhref, resolve, reject) {
222 | var linkTag = document.createElement('link');
223 | (linkTag.rel = 'stylesheet'),
224 | (linkTag.type = 'text/css'),
225 | (linkTag.onerror = linkTag.onload = function (event) {
226 | if (((linkTag.onerror = linkTag.onload = null), 'load' === event.type)) resolve();
227 | else {
228 | var errorType = event && ('load' === event.type ? 'missing' : event.type),
229 | realHref = (event && event.target && event.target.href) || fullhref,
230 | err = new Error('Loading CSS chunk ' + chunkId + ' failed.\n(' + realHref + ')');
231 | (err.code = 'CSS_CHUNK_LOAD_FAILED'),
232 | (err.type = errorType),
233 | (err.request = realHref),
234 | linkTag.parentNode.removeChild(linkTag),
235 | reject(err);
236 | }
237 | }),
238 | (linkTag.href = fullhref),
239 | document.head.appendChild(linkTag);
240 | })(chunkId, fullhref, resolve, reject);
241 | });
242 | }),
243 | (installedCssChunks = { 700: 0 }),
244 | (__webpack_require__.f.miniCss = function (chunkId, promises) {
245 | installedCssChunks[chunkId]
246 | ? promises.push(installedCssChunks[chunkId])
247 | : 0 !== installedCssChunks[chunkId] &&
248 | { 715: 1, 896: 1, 956: 1 }[chunkId] &&
249 | promises.push(
250 | (installedCssChunks[chunkId] = loadStylesheet(chunkId).then(
251 | function () {
252 | installedCssChunks[chunkId] = 0;
253 | },
254 | function (e) {
255 | throw (delete installedCssChunks[chunkId], e);
256 | }
257 | ))
258 | );
259 | }),
260 | (function () {
261 | var installedChunks = { 700: 0 },
262 | deferredModules = [];
263 | __webpack_require__.f.j = function (chunkId, promises) {
264 | var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : void 0;
265 | if (0 !== installedChunkData)
266 | if (installedChunkData) promises.push(installedChunkData[2]);
267 | else {
268 | var promise = new Promise(function (resolve, reject) {
269 | installedChunkData = installedChunks[chunkId] = [resolve, reject];
270 | });
271 | promises.push((installedChunkData[2] = promise));
272 | var url = __webpack_require__.p + __webpack_require__.u(chunkId),
273 | error = new Error();
274 | __webpack_require__.l(
275 | url,
276 | function (event) {
277 | if (
278 | __webpack_require__.o(installedChunks, chunkId) &&
279 | (0 !== (installedChunkData = installedChunks[chunkId]) && (installedChunks[chunkId] = void 0),
280 | installedChunkData)
281 | ) {
282 | var errorType = event && ('load' === event.type ? 'missing' : event.type),
283 | realSrc = event && event.target && event.target.src;
284 | (error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'),
285 | (error.name = 'ChunkLoadError'),
286 | (error.type = errorType),
287 | (error.request = realSrc),
288 | installedChunkData[1](error);
289 | }
290 | },
291 | 'chunk-' + chunkId
292 | );
293 | }
294 | };
295 | var checkDeferredModules = function () {},
296 | webpackJsonpCallback = function (parentChunkLoadingFunction, data) {
297 | for (
298 | var moduleId,
299 | chunkId,
300 | chunkIds = data[0],
301 | moreModules = data[1],
302 | runtime = data[2],
303 | executeModules = data[3],
304 | i = 0,
305 | resolves = [];
306 | i < chunkIds.length;
307 | i++
308 | )
309 | (chunkId = chunkIds[i]),
310 | __webpack_require__.o(installedChunks, chunkId) &&
311 | installedChunks[chunkId] &&
312 | resolves.push(installedChunks[chunkId][0]),
313 | (installedChunks[chunkId] = 0);
314 | for (moduleId in moreModules)
315 | __webpack_require__.o(moreModules, moduleId) && (__webpack_require__.m[moduleId] = moreModules[moduleId]);
316 | for (
317 | runtime && runtime(__webpack_require__), parentChunkLoadingFunction && parentChunkLoadingFunction(data);
318 | resolves.length;
319 |
320 | )
321 | resolves.shift()();
322 | return executeModules && deferredModules.push.apply(deferredModules, executeModules), checkDeferredModules();
323 | },
324 | chunkLoadingGlobal = (self.webpackChunkreact_boilerplate = self.webpackChunkreact_boilerplate || []);
325 | function checkDeferredModulesImpl() {
326 | for (var result, i = 0; i < deferredModules.length; i++) {
327 | for (var deferredModule = deferredModules[i], fulfilled = !0, j = 1; j < deferredModule.length; j++) {
328 | var depId = deferredModule[j];
329 | 0 !== installedChunks[depId] && (fulfilled = !1);
330 | }
331 | fulfilled &&
332 | (deferredModules.splice(i--, 1),
333 | (result = __webpack_require__((__webpack_require__.s = deferredModule[0]))));
334 | }
335 | return (
336 | 0 === deferredModules.length && (__webpack_require__.x(), (__webpack_require__.x = function () {})), result
337 | );
338 | }
339 | chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)),
340 | (chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)));
341 | var startup = __webpack_require__.x;
342 | __webpack_require__.x = function () {
343 | return (__webpack_require__.x = startup || function () {}), (checkDeferredModules = checkDeferredModulesImpl)();
344 | };
345 | })(),
346 | __webpack_require__.x();
347 | })();
348 |
--------------------------------------------------------------------------------
/docs/vendor.b39cfef421931f6623fe.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*
2 | object-assign
3 | (c) Sindre Sorhus
4 | @license MIT
5 | */
6 |
7 | /*!
8 | Copyright (c) 2017 Jed Watson.
9 | Licensed under the MIT License (MIT), see
10 | http://jedwatson.github.io/classnames
11 | */
12 |
13 | /*!
14 | * isobject
15 | *
16 | * Copyright (c) 2014-2017, Jon Schlinkert.
17 | * Released under the MIT License.
18 | */
19 |
20 | /**
21 | * Checks if an event is supported in the current execution environment.
22 | *
23 | * NOTE: This will not work correctly for non-generic events such as `change`,
24 | * `reset`, `load`, `error`, and `select`.
25 | *
26 | * Borrows from Modernizr.
27 | *
28 | * @param {string} eventNameSuffix Event name, e.g. "click".
29 | * @return {boolean} True if the event is supported.
30 | * @internal
31 | * @license Modernizr 3.0.0pre (Custom Build) | MIT
32 | */
33 |
34 | /** @license React v0.20.1
35 | * scheduler-tracing.development.js
36 | *
37 | * Copyright (c) Facebook, Inc. and its affiliates.
38 | *
39 | * This source code is licensed under the MIT license found in the
40 | * LICENSE file in the root directory of this source tree.
41 | */
42 |
43 | /** @license React v0.20.1
44 | * scheduler.development.js
45 | *
46 | * Copyright (c) Facebook, Inc. and its affiliates.
47 | *
48 | * This source code is licensed under the MIT license found in the
49 | * LICENSE file in the root directory of this source tree.
50 | */
51 |
52 | /** @license React v16.13.1
53 | * react-is.development.js
54 | *
55 | * Copyright (c) Facebook, Inc. and its affiliates.
56 | *
57 | * This source code is licensed under the MIT license found in the
58 | * LICENSE file in the root directory of this source tree.
59 | */
60 |
61 | /** @license React v17.0.1
62 | * react-dom.development.js
63 | *
64 | * Copyright (c) Facebook, Inc. and its affiliates.
65 | *
66 | * This source code is licensed under the MIT license found in the
67 | * LICENSE file in the root directory of this source tree.
68 | */
69 |
70 | /** @license React v17.0.1
71 | * react.development.js
72 | *
73 | * Copyright (c) Facebook, Inc. and its affiliates.
74 | *
75 | * This source code is licensed under the MIT license found in the
76 | * LICENSE file in the root directory of this source tree.
77 | */
78 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-boilerplate",
3 | "version": "5.1.0",
4 | "description": "A slightly opinionated yet dead simple boilerplate for ReactJS",
5 | "engines": {
6 | "node": ">= 10.0.0",
7 | "npm": ">= 6.0.0"
8 | },
9 | "scripts": {
10 | "start": "npm run build:prod && npm run start-prod-server",
11 | "dev": "npm run clean && cross-env NODE_ENV=development webpack serve --progress --color",
12 | "build:prod": "npm run clean && cross-env NODE_ENV=production webpack --progress --color",
13 | "build:gh-pages": "npm run clean && cross-env NODE_ENV=gh-pages webpack --progress --color",
14 | "start-prod-server": "cross-env NODE_ENV=production node server.js",
15 | "clean": "rimraf ./docs"
16 | },
17 | "author": "Mike Chabot",
18 | "license": "MIT",
19 | "repository": {
20 | "type": "git",
21 | "url": "git+https://github.com/mikechabot/react-boilerplate.git"
22 | },
23 | "bugs": {
24 | "url": "https://github.com/mikechabot/react-boilerplate/issues"
25 | },
26 | "browserslist": [
27 | "defaults"
28 | ],
29 | "husky": {
30 | "hooks": {
31 | "pre-commit": "pretty-quick --staged"
32 | }
33 | },
34 | "nyc": {
35 | "include": [
36 | "src/**/*.js"
37 | ],
38 | "reporter": [
39 | "text-summary",
40 | "html"
41 | ],
42 | "temp-directory": "./.nyc-coverage-temp",
43 | "report-dir": "./.nyc-coverage"
44 | },
45 | "dependencies": {
46 | "@loadable/babel-plugin": "^5.13.2",
47 | "@loadable/component": "^5.14.1",
48 | "axios": "^0.21.0",
49 | "bulma": "^0.9.1",
50 | "classnames": "^2.2.6",
51 | "core-js": "^3.8.1",
52 | "cross-env": "^7.0.3",
53 | "date-fns": "^2.16.1",
54 | "express": "^4.17.1",
55 | "lodash": "^4.17.20",
56 | "p-min-delay": "^3.1.0",
57 | "react": "^17.0.1",
58 | "react-dom": "^17.0.1",
59 | "react-json-pretty": "^2.2.0",
60 | "react-redux": "^7.2.2",
61 | "react-router-dom": "^5.2.0",
62 | "react-tabify": "0.1.25",
63 | "redux": "^4.0.5",
64 | "redux-entity": "^8.0.20",
65 | "redux-logger": "^3.0.6",
66 | "redux-thunk": "^2.3.0"
67 | },
68 | "devDependencies": {
69 | "@babel/cli": "^7.12.10",
70 | "@babel/core": "^7.12.10",
71 | "@babel/plugin-proposal-class-properties": "^7.12.1",
72 | "@babel/plugin-syntax-dynamic-import": "^7.8.3",
73 | "@babel/preset-env": "^7.12.10",
74 | "@babel/preset-react": "^7.12.10",
75 | "@babel/register": "^7.12.10",
76 | "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
77 | "@types/classnames": "^2.2.11",
78 | "@types/lodash": "^4.14.165",
79 | "@types/react": "^17.0.0",
80 | "@types/react-dom": "^17.0.0",
81 | "@types/react-redux": "^7.1.12",
82 | "@types/react-router-dom": "^5.1.6",
83 | "@types/redux-logger": "^3.0.8",
84 | "@typescript-eslint/eslint-plugin": "^4.9.1",
85 | "@typescript-eslint/parser": "^4.9.1",
86 | "autoprefixer": "^10.1.0",
87 | "babel-eslint": "^10.1.0",
88 | "babel-loader": "^8.2.2",
89 | "boxen": "^4.2.0",
90 | "chalk": "^4.1.0",
91 | "coveralls": "^3.1.0",
92 | "css-loader": "^5.0.1",
93 | "eslint": "^7.15.0",
94 | "eslint-config-standard": "^16.0.2",
95 | "eslint-loader": "^4.0.2",
96 | "eslint-plugin-import": "^2.22.1",
97 | "eslint-plugin-node": "^11.1.0",
98 | "eslint-plugin-promise": "^4.2.1",
99 | "eslint-plugin-react": "^7.21.5",
100 | "figlet": "^1.5.0",
101 | "file-loader": "^6.2.0",
102 | "html-webpack-plugin": "^4.5.0",
103 | "husky": "^4.3.5",
104 | "json-loader": "^0.5.7",
105 | "loadable-ts-transformer": "^1.0.0-alpha.3",
106 | "mini-css-extract-plugin": "^1.3.3",
107 | "node-sass": "^5.0.0",
108 | "postcss-loader": "^4.1.0",
109 | "prettier": "^2.2.1",
110 | "pretty-quick": "^2.0.2",
111 | "react-hot-loader": "^4.13.0",
112 | "react-refresh": "^0.9.0",
113 | "redux-mock-store": "^1.5.4",
114 | "rimraf": "^3.0.2",
115 | "sass-loader": "^10.1.0",
116 | "style-loader": "^2.0.0",
117 | "terser-webpack-plugin": "^5.0.3",
118 | "ts-loader": "^8.0.12",
119 | "typescript": "^4.1.3",
120 | "url-loader": "^4.1.1",
121 | "webpack": "^5.10.1",
122 | "webpack-cli": "^4.2.0",
123 | "webpack-dev-server": "^3.11.0"
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [require('autoprefixer')],
3 | };
4 |
--------------------------------------------------------------------------------
/scripts/buildInfo.js:
--------------------------------------------------------------------------------
1 | const boxen = require('boxen');
2 | const figlet = require('figlet');
3 | const chalk = require('chalk');
4 |
5 | const packageJson = require('../package.json');
6 | const NodeUtils = require('../src/services/common/node-service');
7 |
8 | /**
9 | * Boxen options as defined by https://www.npmjs.com/package/boxen
10 | * @type {{padding: {top: number, left: number, bottom: number, right: number}}}
11 | */
12 | const boxenOptions = {
13 | padding: {
14 | left: 13,
15 | right: 13,
16 | top: 1,
17 | bottom: 1,
18 | },
19 | };
20 |
21 | /**
22 | * Figlet options as defined by https://github.com/patorjk/figlet.js
23 | * @type {{horizontalLayout: string, font: string}}
24 | */
25 | const figletOptions = {
26 | font: 'Small Slant',
27 | horizontalLayout: 'controlled smushing',
28 | };
29 |
30 | const { name, version, author, license } = packageJson;
31 | const details = chalk.cyan(`${author} | Version ${version} | License ${license} `);
32 |
33 | module.exports = function () {
34 | console.log(chalk.cyan(figlet.textSync(name, figletOptions)));
35 | console.log(boxen(details, boxenOptions));
36 | };
37 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const config = require('./config/config');
4 | const NodeService = require('./src/services/common/node-service');
5 |
6 | const { example } = config;
7 | if (!example) throw new Error('configuration cannot be null/undefined');
8 |
9 | const PORT = example.port;
10 |
11 | const express = require('express');
12 | const path = require('path');
13 |
14 | const app = express();
15 |
16 | // Configure static resources
17 | app.use(express.static(path.join(__dirname, '/docs')));
18 |
19 | // Configure server-side routing
20 | app.get('*', (req, res) => {
21 | const dist = path.join(__dirname, '/docs/index.html');
22 | res.sendFile(dist);
23 | });
24 |
25 | // Open socket
26 | app.listen(PORT, () => {
27 | console.log(`Started Express server on port ${PORT}`);
28 | });
29 |
--------------------------------------------------------------------------------
/src/Bootstrap.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { AppContainer } from 'react-hot-loader';
4 |
5 | import store from '~reducers/store';
6 |
7 | import Root from '~app/Root';
8 |
9 | import '~app/styles/global.scss';
10 | import '~app/assets/favicon.ico';
11 |
12 | ReactDOM.render(
13 |
14 |
15 | ,
16 | document.getElementById('example-app')
17 | );
18 |
--------------------------------------------------------------------------------
/src/Root.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { Provider } from 'react-redux';
4 | import { BrowserRouter } from 'react-router-dom';
5 |
6 | import ConfigService from '~services/common/config-service';
7 |
8 | import App from '~components/App';
9 |
10 | const Root = ({ store }: { store: any }) => (
11 |
12 |
13 |
14 |
15 |
16 | );
17 |
18 | export default Root;
19 |
--------------------------------------------------------------------------------
/src/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikechabot/react-boilerplate/c45505edb9209a9d9ec5dd8b8ba176ba6f85fbee/src/assets/favicon.ico
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikechabot/react-boilerplate/c45505edb9209a9d9ec5dd8b8ba176ba6f85fbee/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classnames from 'classnames/bind';
3 |
4 | import NavBar from '~components/common/bulma/Navbar';
5 | import Footer from '~components/Footer';
6 |
7 | import ReactRouter from '~components/Sections/ReactRouter';
8 | import ReduxEntity from '~components/Sections/ReduxEntity';
9 | import ReduxState from '~components/Sections/ReduxState';
10 |
11 | import styles from '~components/styles/App.scss';
12 |
13 | const cx = classnames.bind(styles);
14 |
15 | const App = () => (
16 |
17 |
18 |
19 |
20 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | );
38 |
39 | export default App;
40 |
--------------------------------------------------------------------------------
/src/components/Footer/Footer.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { Icon, Link } from '~components/common';
4 | import GithubButtons from '~components/Footer/GithubButtons';
5 |
6 | import { URL } from '~app/const';
7 |
8 | const Repository = () => (
9 |
10 | react-boilerplate
11 |
12 | );
13 |
14 | const DemoLink = () => source code;
15 | const GithubLink = () => Mike Chabot;
16 | const LicenseLink = () => MIT;
17 |
18 | const Footer = () => {
19 | return (
20 |
31 | );
32 | };
33 |
34 | export default Footer;
35 |
--------------------------------------------------------------------------------
/src/components/Footer/GithubButtons/GithubButton.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import classnames from 'classnames/bind';
3 |
4 | import styles from '~components/Footer/GithubButtons/styles/GithubButton.scss';
5 |
6 | const cx = classnames.bind(styles);
7 |
8 | interface GithubButtonProps {
9 | label: string;
10 | icon: string;
11 | href: string;
12 | ariaLabel: string;
13 | }
14 |
15 | const GithubButton: React.FunctionComponent = ({
16 | label,
17 | icon,
18 | href,
19 | ariaLabel,
20 | }: GithubButtonProps) => {
21 | return (
22 |
34 | );
35 | };
36 |
37 | export default GithubButton;
38 |
--------------------------------------------------------------------------------
/src/components/Footer/GithubButtons/GithubButtons.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import classnames from 'classnames/bind';
3 |
4 | import GithubButton from '~components/Footer/GithubButtons/GithubButton';
5 |
6 | import styles from '~components/Footer/GithubButtons/styles/GithubButtons.scss';
7 |
8 | const cx = classnames.bind(styles);
9 |
10 | const GithubButtons = () => (
11 |
12 |
18 |
24 |
30 |
31 | );
32 |
33 | export default GithubButtons;
34 |
--------------------------------------------------------------------------------
/src/components/Footer/GithubButtons/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './GithubButtons';
2 |
--------------------------------------------------------------------------------
/src/components/Footer/GithubButtons/styles/GithubButton.scss:
--------------------------------------------------------------------------------
1 | .github-button--container {
2 | margin: 5px;
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/Footer/GithubButtons/styles/GithubButtons.scss:
--------------------------------------------------------------------------------
1 | .github-buttons {
2 | display: flex;
3 | justify-content: center;
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/Footer/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Footer';
2 |
--------------------------------------------------------------------------------
/src/components/Sections/GenericSection.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import Icon from '~components/common/Icon';
3 |
4 | interface GenericSectionProps {
5 | title: string;
6 | subtitle: string | React.ReactNode;
7 | icon: string;
8 | children?: React.ReactNode;
9 | }
10 |
11 | const GenericSection: React.FunctionComponent = ({
12 | title,
13 | subtitle,
14 | icon,
15 | children,
16 | }: GenericSectionProps) => (
17 | <>
18 |
19 |
20 | {title}
21 |
22 |
23 | {subtitle}
24 |
25 |
26 | {children}
27 | >
28 | );
29 |
30 | export default GenericSection;
31 |
--------------------------------------------------------------------------------
/src/components/Sections/ReactRouter/AsyncTabbedRouter.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import pMinDelay from 'p-min-delay';
3 | import loadable from '@loadable/component';
4 | import classNames from 'classnames/bind';
5 | import { Route, useHistory, useLocation } from 'react-router-dom';
6 | import { Tab, Tabs } from 'react-tabify';
7 |
8 | import ChunkLoadingIcon from '~components/Sections/ReactRouter/ChunkLoadingIcon';
9 |
10 | const DELAY = 500;
11 | const options = {
12 | fallback: ,
13 | };
14 |
15 | const AsyncIncrement = loadable(
16 | () => pMinDelay(import('~components/Sections/ReactRouter/Routes/IncrementRoute'), DELAY),
17 | options
18 | );
19 | const AsyncDecrement = loadable(
20 | () => pMinDelay(import('~components/Sections/ReactRouter/Routes/DecrementRoute'), DELAY),
21 | options
22 | );
23 | const AsyncReset = loadable(
24 | () => pMinDelay(import('~components/Sections/ReactRouter/Routes/ResetRoute'), DELAY),
25 | options
26 | );
27 |
28 | const AsyncTabbedRouter = () => {
29 | const location = useLocation();
30 | const history = useHistory();
31 |
32 | return (
33 |
34 | history.push(eventKey)}>
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | );
47 | };
48 |
49 | export default AsyncTabbedRouter;
50 |
--------------------------------------------------------------------------------
/src/components/Sections/ReactRouter/ChunkLoadingIcon.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classnames from 'classnames/bind';
3 |
4 | import { CogIcon } from '~components/common/Icon';
5 |
6 | import styles from '~components/Sections/ReactRouter/styles/ChunkLoadingIcon.scss';
7 |
8 | const cx = classnames.bind(styles);
9 |
10 | const ChunkLoadingIcon = () => (
11 |
12 |
13 |
14 | );
15 |
16 | export default ChunkLoadingIcon;
17 |
--------------------------------------------------------------------------------
/src/components/Sections/ReactRouter/ReactRouter.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import GenericSection from '~components/Sections/GenericSection';
4 | import AsyncTabbedRouter from '~components/Sections/ReactRouter/AsyncTabbedRouter';
5 |
6 | import { URL } from '~app/const';
7 |
8 | const ReactRouter = () => (
9 |
14 | Utilizes react-router v5 for client-side routing
15 |
16 | }
17 | >
18 |
19 |
20 | );
21 |
22 | export default ReactRouter;
23 |
--------------------------------------------------------------------------------
/src/components/Sections/ReactRouter/Routes/DecrementRoute.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import RouteContent from '~components/Sections/ReactRouter/Routes/RouteContent';
4 |
5 | import { decrementAction } from '~reducers/counter/actions';
6 |
7 | const DecrementRoute = () => ;
8 |
9 | export default DecrementRoute;
10 |
--------------------------------------------------------------------------------
/src/components/Sections/ReactRouter/Routes/IncrementRoute.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import RouteContent from '~components/Sections/ReactRouter/Routes/RouteContent';
4 |
5 | import { incrementAction } from '~reducers/counter/actions';
6 |
7 | const IncrementRoute = () => ;
8 |
9 | export default IncrementRoute;
10 |
--------------------------------------------------------------------------------
/src/components/Sections/ReactRouter/Routes/ResetRoute.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import RouteContent from '~components/Sections/ReactRouter/Routes/RouteContent';
4 |
5 | import { resetAction } from '~reducers/counter/actions';
6 |
7 | const ResetRoute = () => ;
8 |
9 | export default ResetRoute;
10 |
--------------------------------------------------------------------------------
/src/components/Sections/ReactRouter/Routes/RouteContent.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classnames from 'classnames/bind';
3 | import { connect, useSelector, useDispatch } from 'react-redux';
4 |
5 | import Icon from '~components/common/Icon';
6 |
7 | import { RootState } from '~app/reducers';
8 |
9 | import styles from '~components/Sections/ReactRouter/Routes/styles/RouteContent.scss';
10 |
11 | const cx = classnames.bind(styles);
12 |
13 | interface RouteContentProps {
14 | path: string;
15 | label: string;
16 | action: () => void;
17 | icon: string;
18 | }
19 |
20 | const RouteContent: React.FunctionComponent = ({ path, label, action, icon }: RouteContentProps) => {
21 | const dispatch = useDispatch();
22 | const counter = useSelector((state: RootState) => state.counter);
23 |
24 | return (
25 |
26 |
27 |
28 | Connected to the Redux store at the {path || '/'}
route
29 |
30 |
31 |
32 | counter
: {counter}
33 |
34 |
35 |
36 |
40 |
41 |
42 | );
43 | };
44 |
45 | export default RouteContent;
46 |
--------------------------------------------------------------------------------
/src/components/Sections/ReactRouter/Routes/styles/RouteContent.scss:
--------------------------------------------------------------------------------
1 | .route-content--container {
2 | display: flex;
3 | flex-direction: column;
4 | padding: 10px;
5 |
6 | .route-content--header,
7 | .route-content--counter {
8 | display: flex;
9 | align-content: center;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/Sections/ReactRouter/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ReactRouter';
2 |
--------------------------------------------------------------------------------
/src/components/Sections/ReactRouter/styles/ChunkLoadingIcon.scss:
--------------------------------------------------------------------------------
1 | .chunk-loading--icon {
2 | height: 60px;
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxEntity/Entities.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classnames from 'classnames/bind';
3 |
4 | import { useDispatch, useSelector } from 'react-redux';
5 |
6 | import Entity from '~components/Sections/ReduxEntity/Entity';
7 |
8 | import { fetchBar, fetchBaz, fetchFoo } from '~reducers/entities/actions';
9 |
10 | import { RootState } from '~app/reducers';
11 | import { EntityType } from '~reducers/entities/types';
12 |
13 | import styles from '~components/Sections/ReduxEntity/styles/ReduxEntity.scss';
14 |
15 | const cx = classnames.bind(styles);
16 |
17 | const Entities = () => {
18 | const dispatch = useDispatch();
19 | const entities = useSelector((state: RootState) => state.entities);
20 |
21 | /**
22 | * Get the fetch thunk based on the entity type
23 | * @param type
24 | */
25 | const getLoadEntityThunk = (type: EntityType) => {
26 | switch (type) {
27 | case EntityType.Foo:
28 | return () => dispatch(fetchFoo());
29 | case EntityType.Bar:
30 | return () => dispatch(fetchBar());
31 | case EntityType.Baz:
32 | return () => dispatch(fetchBaz());
33 | }
34 | };
35 |
36 | return (
37 |
38 | {Object.values(EntityType).map((key: string) => (
39 |
46 | ))}
47 |
48 | );
49 | };
50 |
51 | export default Entities;
52 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxEntity/Entity.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react';
2 | import { useDispatch } from 'react-redux';
3 |
4 | import isEmpty from 'lodash/isEmpty';
5 |
6 | import { Button } from '~components/common';
7 |
8 | import EntityData from '~components/Sections/ReduxEntity/Entity/EntityData';
9 | import EntityReset from '~components/Sections/ReduxEntity/Entity/EntityReset';
10 | import EntityMissing from '~components/Sections/ReduxEntity/Entity/EntityMissing';
11 | import EntityFailure from '~components/Sections/ReduxEntity/Entity/EntityFailure';
12 | import EntityLoading from '~components/Sections/ReduxEntity/Entity/EntityLoading';
13 |
14 | import { DeleteEntity, ResetEntity, EntityState } from 'redux-entity';
15 |
16 | interface EntityProps {
17 | name: string;
18 | append: boolean;
19 | entity: EntityState;
20 | fetchEntity: () => void;
21 | }
22 |
23 | const Entity: React.FunctionComponent = ({ name, append, entity, fetchEntity }: EntityProps) => {
24 | const dispatch = useDispatch();
25 |
26 | useEffect(() => {
27 | fetchEntity();
28 | }, []);
29 |
30 | if (isEmpty(entity)) {
31 | return ;
32 | }
33 |
34 | const { isFetching, data, error, lastUpdated } = entity;
35 |
36 | let body;
37 |
38 | if (error) {
39 | body = ;
40 | } else if (isFetching) {
41 | body = ;
42 | } else if (isEmpty(data)) {
43 | body = ;
44 | } else {
45 | body = ;
46 | }
47 |
48 | return (
49 |
50 | {body}
51 |
52 |
55 |
58 |
61 |
62 |
63 | );
64 | };
65 |
66 | export default Entity;
67 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxEntity/Entity/EntityData.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { format } from 'date-fns';
3 |
4 | import { Icon } from '~components/common';
5 | import { CheckIcon } from '~components/common/Icon';
6 |
7 | interface EntityDataProps {
8 | name: string;
9 | append: boolean;
10 | lastUpdated?: Date;
11 | }
12 |
13 | const EntityData: React.FunctionComponent = ({ name, append, lastUpdated }: EntityDataProps) => {
14 | const action = append ? 'Appending to ' : 'Fetch for ';
15 | const date = lastUpdated && format(new Date(lastUpdated), 'pp');
16 | return (
17 |
18 | {action} {name}
@ {date}
19 |
20 | );
21 | };
22 |
23 | export default EntityData;
24 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxEntity/Entity/EntityFailure.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { Icon } from '~components/common';
4 | import { ExclamationIcon } from '~components/common/Icon';
5 |
6 | interface EntityFailureProps {
7 | name: string;
8 | error: any;
9 | }
10 |
11 | const EntityFailure: React.FunctionComponent = ({ name, error }: EntityFailureProps) => (
12 |
13 | Failed to fetch {name}
due to{' '}
14 | {error.toString()}
15 |
16 | );
17 |
18 | export default EntityFailure;
19 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxEntity/Entity/EntityLoading.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | const EntityLoading = () => Fetching fresh data!
;
4 |
5 | export default EntityLoading;
6 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxEntity/Entity/EntityMissing.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Icon from '~components/common/Icon';
4 | import { Button } from '~components/common';
5 |
6 | interface NoEntityProps {
7 | name: string;
8 | fetchEntity: () => void;
9 | }
10 |
11 | const EntityMissing: React.FunctionComponent = ({ name, fetchEntity }: NoEntityProps) => (
12 | <>
13 |
14 |
15 | Entity {name}
does not exist on entities
16 |
17 |
20 | >
21 | );
22 |
23 | export default EntityMissing;
24 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxEntity/Entity/EntityReset.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | interface EntityReset {
4 | name: string;
5 | }
6 |
7 | const EntityReset: React.FunctionComponent = ({ name }: EntityReset) => (
8 |
9 | Entity {name}
has been cleared.
10 |
11 | );
12 |
13 | export default EntityReset;
14 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxEntity/ReduxEntity.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import GenericSection from '~components/Sections/GenericSection';
4 | import Entities from '~components/Sections/ReduxEntity/Entities';
5 |
6 | import { URL } from '~app/const';
7 |
8 | const ReduxEntity = () => (
9 |
14 | Utilizes redux-entity for domain entity management
15 |
16 | }
17 | >
18 |
19 |
20 | );
21 |
22 | export default ReduxEntity;
23 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxEntity/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ReduxEntity';
2 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxEntity/styles/ReduxEntity.scss:
--------------------------------------------------------------------------------
1 | .redux-entity--container {
2 | display: flex;
3 | flex-direction: column;
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxState/ReduxState.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import JSONPretty from 'react-json-pretty';
3 | import { useSelector } from 'react-redux';
4 |
5 | import GenericSection from '~components/Sections/GenericSection';
6 |
7 | const themeProps = {
8 | keyStyle: 'color: #3298dc;',
9 | };
10 |
11 | /**
12 | * Stringify errors
13 | * @param key
14 | * @param value
15 | */
16 | const replacer = (key: string, value: any) => {
17 | return value instanceof Error ? value.toString() : value;
18 | };
19 |
20 | const ReduxState = () => {
21 | const state = useSelector((state) => state);
22 | return (
23 | Open Console to view dispatched actions}>
24 |
25 |
26 | );
27 | };
28 |
29 | export default ReduxState;
30 |
--------------------------------------------------------------------------------
/src/components/Sections/ReduxState/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ReduxState';
2 |
--------------------------------------------------------------------------------
/src/components/common/Button.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Icon from '~components/common/Icon';
4 |
5 | interface ButtonProps {
6 | icon: string;
7 | disabled?: boolean;
8 | loading?: boolean;
9 | theme?: string;
10 | onClick: () => void;
11 | children: React.ReactNode;
12 | }
13 |
14 | const Button: React.FunctionComponent = ({
15 | icon,
16 | disabled,
17 | loading,
18 | onClick,
19 | children,
20 | theme = '',
21 | }: ButtonProps) => (
22 |
23 | {/* @ts-ignore */}
24 |
25 |
26 |
27 |
28 | {children}
29 |
30 |
31 | );
32 |
33 | export default Button;
34 |
--------------------------------------------------------------------------------
/src/components/common/Icon.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | interface IconProps {
4 | icon: string;
5 | prefix?: string;
6 | className?: string;
7 | size?: string;
8 | }
9 |
10 | export const ExclamationIcon = () => ;
11 | export const CheckIcon = () => ;
12 | export const CogIcon = ({ size, className }: { size?: string; className?: string }) => (
13 |
14 | );
15 |
16 | const Icon: React.FunctionComponent = ({ icon, prefix, className, size = 'fa-1x' }: IconProps) => {
17 | const iconPrefix = prefix || 'fa';
18 | return (
19 |
20 |
21 |
22 | );
23 | };
24 |
25 | export default Icon;
26 |
--------------------------------------------------------------------------------
/src/components/common/Link.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | interface LinkProps {
4 | url: string;
5 | children: React.ReactNode;
6 | }
7 |
8 | const Link: React.FunctionComponent = ({ url, children }: LinkProps) => (
9 |
10 | {children}
11 |
12 | );
13 |
14 | export default Link;
15 |
--------------------------------------------------------------------------------
/src/components/common/bulma/NavBar.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classname from 'classnames/bind';
3 |
4 | import { Icon } from '~components/common';
5 |
6 | import logo from '~assets/logo.png';
7 |
8 | import { URL } from '~app/const';
9 |
10 | import styles from '~components/common/bulma/styles/NavBar.scss';
11 |
12 | const cx = classname.bind(styles);
13 |
14 | const NavBar = () => {
15 | return (
16 |
40 | );
41 | };
42 |
43 | export default NavBar;
44 |
--------------------------------------------------------------------------------
/src/components/common/bulma/styles/NavBar.scss:
--------------------------------------------------------------------------------
1 | .nav-bar--container {
2 | flex-shrink: 0;
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/common/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Icon } from './Icon';
2 | export { default as Button } from './Button';
3 | export { default as Link } from './Link';
4 |
--------------------------------------------------------------------------------
/src/components/styles/App.scss:
--------------------------------------------------------------------------------
1 | .react-boilerplate {
2 | display: flex;
3 | flex-direction: column;
4 | height: 100%;
5 | }
6 |
7 | .section--body {
8 | height: 100%;
9 | }
10 |
--------------------------------------------------------------------------------
/src/const/index.ts:
--------------------------------------------------------------------------------
1 | export const URL = {
2 | GITHUB: 'https://github.com/mikechabot',
3 | REPOSITORY: 'http://www.github.com/mikechabot/react-boilerplate',
4 | NPM: 'https://www.npmjs.com/~mikechabot',
5 | DEMO: 'https://github.com/mikechabot/react-boilerplate',
6 | LICENSE: 'https://github.com/mikechabot/react-boilerplate/blob/master/LICENSE',
7 | REDUX_ENTITY: 'https://github.com/mikechabot/redux-entity',
8 | REACT_ROUTER: 'https://github.com/ReactTraining/react-router',
9 | };
10 |
--------------------------------------------------------------------------------
/src/global.ts:
--------------------------------------------------------------------------------
1 | declare module '*.scss' {
2 | const content: { [className: string]: string };
3 | export default content;
4 | }
5 |
6 | declare module '*.png';
7 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 | react-boilerplate
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/reducers/counter/actions.ts:
--------------------------------------------------------------------------------
1 | import { INCREMENT_COUNTER, DECREMENT_COUNTER, RESET_COUNTER } from '~reducers/counter/reducer';
2 |
3 | export const incrementAction = () => ({ type: INCREMENT_COUNTER });
4 | export const decrementAction = () => ({ type: DECREMENT_COUNTER });
5 | export const resetAction = () => ({ type: RESET_COUNTER });
6 |
--------------------------------------------------------------------------------
/src/reducers/counter/reducer.ts:
--------------------------------------------------------------------------------
1 | export const INCREMENT_COUNTER = 'react-boilerplate/counter/INCREMENT_COUNTER';
2 | export const DECREMENT_COUNTER = 'react-boilerplate/counter/DECREMENT_COUNTER';
3 | export const RESET_COUNTER = 'react-boilerplate/counter/RESET_COUNTER';
4 |
5 | const INITIAL_STATE = 0;
6 |
7 | /**
8 | * Reducer for the management of the counter
9 | * @param state
10 | * @param action
11 | */
12 | const reducer = (state = INITIAL_STATE, action: any) => {
13 | switch (action.type) {
14 | case INCREMENT_COUNTER: {
15 | return state + 1;
16 | }
17 | case DECREMENT_COUNTER: {
18 | return state - 1;
19 | }
20 | case RESET_COUNTER: {
21 | return INITIAL_STATE;
22 | }
23 | default: {
24 | return state;
25 | }
26 | }
27 | };
28 |
29 | export default reducer;
30 |
--------------------------------------------------------------------------------
/src/reducers/entities/actions.ts:
--------------------------------------------------------------------------------
1 | import { GetEntity } from 'redux-entity';
2 |
3 | import { fetchMockData } from '~services/domain/domain-service';
4 |
5 | import { EntityType } from '~reducers/entities/types';
6 |
7 | /**
8 | * Thunk action that simulates a delayed API call
9 | * @returns {Function} thunk
10 | */
11 | export function fetchFoo() {
12 | return GetEntity(EntityType.Foo, fetchMockData());
13 | }
14 |
15 | /**
16 | * Thunk action that simulates a delayed API call
17 | * @returns {Function} thunk
18 | */
19 | export function fetchBar() {
20 | return GetEntity(EntityType.Bar, fetchMockData(), { append: true });
21 | }
22 |
23 | /**
24 | * Thunk action that simulates a delayed, failed API call
25 | * @returns {Function} thunk
26 | */
27 | export function fetchBaz() {
28 | return GetEntity(EntityType.Baz, fetchMockData(true));
29 | }
30 |
--------------------------------------------------------------------------------
/src/reducers/entities/reducer.ts:
--------------------------------------------------------------------------------
1 | export { reducer as default } from 'redux-entity/lib';
2 |
--------------------------------------------------------------------------------
/src/reducers/entities/types.ts:
--------------------------------------------------------------------------------
1 | export enum EntityType {
2 | Foo = 'foo',
3 | Bar = 'bar',
4 | Baz = 'baz',
5 | }
6 |
--------------------------------------------------------------------------------
/src/reducers/index.ts:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 |
3 | import entities from '~reducers/entities/reducer';
4 | import counter from '~reducers/counter/reducer';
5 |
6 | const rootReducer = combineReducers({
7 | counter,
8 | entities,
9 | });
10 |
11 | export type RootState = ReturnType;
12 |
13 | export default rootReducer;
14 |
--------------------------------------------------------------------------------
/src/reducers/store/configure-store.dev.ts:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from 'redux';
2 | import thunk from 'redux-thunk';
3 | import logger from 'redux-logger';
4 |
5 | import rootReducer from '~reducers/index';
6 |
7 | /**
8 | * Development Redux store
9 | * @param {object} initialState Initial state of the Redux store
10 | * @return {object} Redux store
11 | */
12 | export default function configureStore(initialState: any = {}) {
13 | return createStore(rootReducer, initialState, applyMiddleware(thunk, logger));
14 | }
15 |
--------------------------------------------------------------------------------
/src/reducers/store/configure-store.prod.ts:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from 'redux';
2 | import thunk from 'redux-thunk';
3 |
4 | import rootReducer from '~reducers/index';
5 |
6 | /**
7 | * LOGGER IN PROD FOR DEMO PAGES ONLY!
8 | * > Remove this import and the middleware below before going live.
9 | * > https://mikechabot.github.io/react-boilerplate/
10 | */
11 | import logger from 'redux-logger';
12 |
13 | /**
14 | * Production Redux store
15 | * @param {object} initialState Initial state of the Redux store
16 | * @return {object} Redux store
17 | */
18 | export default function configureStore(initialState: any = {}) {
19 | return createStore(
20 | rootReducer,
21 | initialState,
22 | // applyMiddleware(thunk), // USE ME IN PROD!
23 | applyMiddleware(thunk, logger) // DON'T USE ME IN PROD!
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/src/reducers/store/index.ts:
--------------------------------------------------------------------------------
1 | import NodeService from '~services/common/node-service';
2 |
3 | import production from './configure-store.prod';
4 | import development from './configure-store.dev';
5 |
6 | /**
7 | * Determine which Redux store to provide based on the
8 | * Environment Type of Node.js
9 | * @return {object} Redux store
10 | */
11 |
12 | export default NodeService.isProduction() ? production() : development();
13 |
--------------------------------------------------------------------------------
/src/services/common/config-service.js:
--------------------------------------------------------------------------------
1 | const NodeUtils = require('./node-service');
2 | const get = require('lodash/get');
3 |
4 | module.exports = {
5 | getConfig() {
6 | return process.env.APP_CONFIG;
7 | },
8 | getProperty(key) {
9 | if (!key) throw new Error('Key cannot be null/undefined');
10 | return get(this.getConfig(), key);
11 | },
12 | getRequiredProperty(key) {
13 | const value = this.getProperty(key);
14 | if (value) return value;
15 | if (!NodeUtils.isTest()) {
16 | throw new Error(`Missing required property: "${key}"`);
17 | }
18 | },
19 | getPort() {
20 | return this.getRequiredProperty('example.port');
21 | },
22 | getBasePath() {
23 | return this.getRequiredProperty('example.basePath');
24 | },
25 | getBaseUrl() {
26 | return this.getRequiredProperty('example.baseUrl');
27 | },
28 | getPublicBasename() {
29 | return NodeUtils.isGhPages() ? this.getRequiredProperty('example.publicBasename') : '/';
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/src/services/common/node-service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | getNodeEnv: function () {
5 | return process.env;
6 | },
7 | getNodeEnvByKey: function (key) {
8 | if (!key) throw new Error('Key cannot be null/undefined');
9 | return process.env[key];
10 | },
11 | getNodeEnvMode: function () {
12 | return this.getNodeEnvByKey('NODE_ENV') || 'test';
13 | },
14 | isProduction: function () {
15 | return this.getNodeEnvMode() === 'production';
16 | },
17 | isDevelopment: function () {
18 | return this.getNodeEnvMode() === 'development';
19 | },
20 | isGhPages: function () {
21 | return this.getNodeEnvMode() === 'gh-pages';
22 | },
23 | isTest: function () {
24 | return !this.getNodeEnvMode() || this.getNodeEnvMode() === 'test';
25 | },
26 | };
27 |
--------------------------------------------------------------------------------
/src/services/data/ajax-service.ts:
--------------------------------------------------------------------------------
1 | import axios, { AxiosRequestConfig } from 'axios';
2 |
3 | import ConfigService from '~services/common/config-service';
4 |
5 | /**
6 | * Service for making AJAX requests.
7 | * Uses Axios (https://github.com/mzabriskie/axios)
8 | */
9 | const instance = axios.create({
10 | baseURL: ConfigService.getBaseUrl(),
11 | timeout: 4000,
12 | });
13 |
14 | export default {
15 | request: (options: AxiosRequestConfig) => instance.request(options),
16 | };
17 |
--------------------------------------------------------------------------------
/src/services/data/data-access-service.ts:
--------------------------------------------------------------------------------
1 | import AjaxService from './ajax-service';
2 |
3 | import { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';
4 |
5 | interface HttpError extends AxiosError, AxiosResponse {
6 | message: string;
7 | }
8 |
9 | enum HttpMethod {
10 | GET = 'GET',
11 | POST = 'POST',
12 | PUT = 'PUT',
13 | DELETE = 'DELETE',
14 | }
15 |
16 | function deriveError(error: HttpError) {
17 | if (!error) {
18 | return new Error('An unknown error occurred');
19 | } else if (!error.message) {
20 | return `${error.status} ${error.statusText}`;
21 | }
22 | return error;
23 | }
24 |
25 | /**
26 | * HTTP service capable of performing GET and POST requests
27 | * This service will be injected into domain services (e.g. PatientService, MedicationService)
28 | * Agnostic of prototype/production
29 | */
30 | const request = (method: HttpMethod, url: string, data?: any, options?: AxiosRequestConfig) => {
31 | const defaultOptions: AxiosRequestConfig = {
32 | url: url,
33 | method: method,
34 | responseType: 'json',
35 | };
36 |
37 | if (data) {
38 | defaultOptions.data = JSON.stringify(data);
39 | defaultOptions.headers = {
40 | 'Content-Type': 'application/json',
41 | };
42 | }
43 |
44 | let requestOptions = defaultOptions;
45 | if (options) {
46 | requestOptions = { ...defaultOptions, ...options };
47 | }
48 |
49 | // Resolve the original request, and wrap the response in another promise.
50 | // This allows allows us to peer into the response before giving it back
51 | // to the caller, which is helpful when handling situations where a response
52 | // is technically successful from an AJAX perspective (200 OK), but failed
53 | // server-side due an arbitrary error (i.e. validation error).
54 | return new Promise((resolve, reject) => {
55 | AjaxService.request(requestOptions)
56 | .then(resolve)
57 | .catch((error) => reject(deriveError(error)));
58 | });
59 | };
60 |
61 | export const get = (url: string, options?: AxiosRequestConfig) => request(HttpMethod.GET, url, undefined, options);
62 |
63 | export const post = (url: string, data?: any, options?: AxiosRequestConfig) =>
64 | request(HttpMethod.POST, url, data, options);
65 |
--------------------------------------------------------------------------------
/src/services/domain/domain-service.ts:
--------------------------------------------------------------------------------
1 | import { get, post } from '~services/data/data-access-service';
2 | import { randomNumber } from '~services/util';
3 |
4 | const fakeError = new Error('Fake Error!');
5 |
6 | /**
7 | * Example of utilizing DataAccessService
8 | */
9 | export const fetchFoo = (id: string) => get(`/foo/${id}`);
10 | export const postFoo = (id: string, data: any) => post(`/foo/${id}`, data);
11 |
12 | /**
13 | * Mock an API response
14 | * @param doReject
15 | */
16 | export const fetchMockData = (doReject = false) => {
17 | const delay: number = randomNumber();
18 | const payload = { delay };
19 | return new Promise((resolve, reject) => {
20 | setTimeout(() => (doReject ? reject(fakeError) : resolve(payload)), delay * 1000);
21 | });
22 | };
23 |
--------------------------------------------------------------------------------
/src/services/util/index.ts:
--------------------------------------------------------------------------------
1 | const MIN_DELAY = 1;
2 | const MAX_DELAY = 3;
3 |
4 | /**
5 | * Generate a random number between a min and max
6 | */
7 | export function randomNumber(): number {
8 | return Number(Math.random() * (MAX_DELAY - MIN_DELAY) + MIN_DELAY);
9 | }
10 |
--------------------------------------------------------------------------------
/src/styles/global.scss:
--------------------------------------------------------------------------------
1 | @import 'mixins';
2 |
3 | body,
4 | html {
5 | width: 100%;
6 | height: 100%;
7 | font: $font-stack;
8 | }
9 |
10 | #example-app {
11 | margin: 0;
12 | width: 100%;
13 | height: 100%;
14 | }
15 |
16 | code {
17 | font-size: 1.1rem;
18 | color: hsl(0, 0%, 29%);
19 | }
20 |
21 | .notification code {
22 | background: hsl(0, 0%, 90%);
23 | }
24 |
25 | $sizeUnit: rem;
26 | $marginKey: 'm';
27 | $paddingKey: 'p';
28 | $separator: '-';
29 | $sizes: (('none', 0), ('xxs', 0.125), ('xs', 0.25), ('sm', 0.5), ('md', 1), ('lg', 2), ('xl', 4), ('xxl', 8));
30 | $positions: (('t', 'top'), ('r', 'right'), ('b', 'bottom'), ('l', 'left'));
31 |
32 | @function sizeValue($key, $value) {
33 | @return if($key == 'none', 0, $value + $sizeUnit);
34 | }
35 |
36 | @each $size in $sizes {
37 | $sizeKey: nth($size, 1);
38 | $sizeValue: nth($size, 2);
39 | .#{$marginKey}#{$separator}#{$sizeKey} {
40 | margin: sizeValue($sizeKey, $sizeValue);
41 | }
42 | .#{$paddingKey}#{$separator}#{$sizeKey} {
43 | padding: sizeValue($sizeKey, $sizeValue);
44 | }
45 | @each $position in $positions {
46 | $posKey: nth($position, 1);
47 | $posValue: nth($position, 2);
48 | .#{$marginKey}#{$separator}#{$posKey}#{$separator}#{$sizeKey} {
49 | margin-#{$posValue}: sizeValue($sizeKey, $sizeValue);
50 | }
51 | .#{$paddingKey}#{$separator}#{$posKey}#{$separator}#{$sizeKey} {
52 | padding-#{$posValue}: sizeValue($sizeKey, $sizeValue);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/styles/mixins.scss:
--------------------------------------------------------------------------------
1 | @import '~bulma/sass/utilities/initial-variables';
2 | @import '~bulma/sass/utilities/functions';
3 |
4 | $family-serif: Inconsolata, Consolas, monospace;
5 | $link: hsl(204, 86%, 53%);
6 |
7 | @import '~bulma/bulma';
8 |
9 | .navbar-item img {
10 | max-height: none;
11 | }
12 |
13 | .notification a:not(.button) {
14 | text-decoration: none;
15 | }
16 |
17 | .navbar.is-dark .navbar-brand > a.navbar-item:hover {
18 | background: unset;
19 | }
20 |
21 | $font-stack: 1rem Inconsolata;
22 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["./src/**/*"],
3 | "exclude": ["./src/**/*.spec.ts"],
4 | "compilerOptions": {
5 | "target": "es6",
6 | "moduleResolution": "Node",
7 | "module": "commonjs",
8 | "lib": ["es6", "DOM"],
9 | "jsx": "react",
10 | "allowJs": true,
11 | "strict": true,
12 | "noImplicitAny": true,
13 | "esModuleInterop": true,
14 | "resolveJsonModule": true,
15 | "baseUrl": "src",
16 | "paths": {
17 | "~app/*": ["*"],
18 | "~assets/*": ["assets/*"],
19 | "~components/*": ["components/*"],
20 | "~reducers/*": ["reducers/*"],
21 | "~services/*": ["services/*"]
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const webpack = require('webpack');
5 | const HtmlWebpackPlugin = require('html-webpack-plugin');
6 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
7 | const TerserPlugin = require('terser-webpack-plugin');
8 | const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
9 |
10 | /**
11 | * react-boilerplate scripts
12 | */
13 | const NodeUtils = require('./src/services/common/node-service');
14 | const buildInfo = require('./scripts/buildInfo');
15 | const appConfig = require('./config/config');
16 |
17 | buildInfo();
18 |
19 | const APP_DIR = path.join(__dirname, 'src');
20 | const NODE_MODULES = path.join(__dirname, 'node_modules');
21 |
22 | const isDevelopment = NodeUtils.isDevelopment();
23 |
24 | /**
25 | * Get webpack plugins
26 | * @returns {*[]}
27 | */
28 | function getPlugins() {
29 | return [
30 | new MiniCssExtractPlugin({
31 | filename: isDevelopment ? '[name].css' : '[name].[contenthash].css',
32 | chunkFilename: isDevelopment ? '[id].css' : '[id].[contenthash].css',
33 | }),
34 |
35 | /**
36 | * Inject bundles and CSS directly into the HTML template
37 | */
38 | new HtmlWebpackPlugin({
39 | template: path.resolve(__dirname, 'src/index.html'),
40 | inject: 'body',
41 | }),
42 |
43 | /**
44 | * Pass NODE_ENV and APP_CONFIG to the application so that
45 | * "ConfigService" and "NodeService" can be used within TS/TSX files.
46 | */
47 | new webpack.DefinePlugin({
48 | 'process.env': {
49 | NODE_ENV: JSON.stringify(process.env.NODE_ENV),
50 | APP_CONFIG: JSON.stringify(appConfig),
51 | },
52 | }),
53 | ];
54 | }
55 |
56 | /**
57 | * Set up code splitting and chunking
58 | */
59 | function getCodeSplittingConfig() {
60 | return {
61 | splitChunks: {
62 | cacheGroups: {
63 | commons: {
64 | test: /[\\/]node_modules[\\/]/,
65 | name: 'vendor',
66 | chunks: 'initial',
67 | },
68 | },
69 | },
70 | runtimeChunk: {
71 | name: 'manifest',
72 | },
73 | minimizer: [
74 | new TerserPlugin({
75 | terserOptions: {
76 | ecma: 8,
77 | mangle: false,
78 | keep_classnames: true,
79 | keep_fnames: true,
80 | },
81 | }),
82 | ],
83 | };
84 | }
85 |
86 | /**
87 | * Get Webpack file parsing rules
88 | * @returns {*[]}
89 | */
90 | function getParserRules() {
91 | return [
92 | {
93 | test: /\.(sa|sc|c)ss$/,
94 | use: [
95 | {
96 | loader: MiniCssExtractPlugin.loader,
97 | options: {},
98 | },
99 | 'css-loader',
100 | 'postcss-loader',
101 | 'sass-loader',
102 | ],
103 | include: APP_DIR,
104 | exclude: NODE_MODULES,
105 | },
106 | {
107 | test: /\.(js|jsx)$/,
108 | use: 'babel-loader',
109 | include: APP_DIR,
110 | exclude: NODE_MODULES,
111 | },
112 | {
113 | test: /\.tsx?$/,
114 | use: 'ts-loader',
115 | include: APP_DIR,
116 | exclude: NODE_MODULES,
117 | },
118 | {
119 | test: /\.(eot|woff|woff2|ttf|svg|png|jpg)$/,
120 | use: 'url-loader?limit=10000&name=[name]-[hash].[ext]',
121 | include: APP_DIR,
122 | exclude: NODE_MODULES,
123 | },
124 | {
125 | test: /\.ico$/,
126 | use: 'file-loader?name=[name].[ext]',
127 | exclude: NODE_MODULES,
128 | },
129 | {
130 | test: /\.json$/,
131 | use: 'json-loader',
132 | include: APP_DIR,
133 | exclude: NODE_MODULES,
134 | },
135 | ];
136 | }
137 |
138 | const webpackConfig = {
139 | /**
140 | * Configure the output directory and bundle name
141 | */
142 | output: {
143 | path: path.join(__dirname, 'docs'),
144 | filename: '[name].[hash].js',
145 | },
146 | resolve: {
147 | /**
148 | * Allow webpack to automatically resolve import extensions
149 | */
150 | extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', 'scss'],
151 | /**
152 | * Define aliases to be used within import statements.
153 | * Be sure to update "tsconfig.json" if you add/update/delete aliases.
154 | */
155 | alias: {
156 | '~app': path.resolve(APP_DIR),
157 | '~assets': path.resolve(APP_DIR, 'assets/'),
158 | '~components': path.resolve(APP_DIR, 'components/'),
159 | '~reducers': path.resolve(APP_DIR, 'reducers/'),
160 | '~services': path.resolve(APP_DIR, 'services/'),
161 | },
162 | },
163 | /**
164 | * Set up code splitting and chunking
165 | */
166 | optimization: getCodeSplittingConfig(),
167 | /**
168 | * Set up webpack plugins
169 | */
170 | plugins: getPlugins(),
171 | /**
172 | * Set up module parsing rules
173 | */
174 | module: {
175 | rules: getParserRules(),
176 | },
177 | };
178 |
179 | /**
180 | * Add additional configurations based on NODE_ENV
181 | */
182 | if (!NodeUtils.isDevelopment()) {
183 | webpackConfig.entry = './src/Bootstrap';
184 | webpackConfig.mode = 'production';
185 | } else {
186 | webpackConfig.mode = 'development';
187 | webpackConfig.entry = [
188 | `webpack-dev-server/client?http://localhost:${appConfig.example.port}`,
189 | 'webpack/hot/only-dev-server',
190 | './src/Bootstrap',
191 | ];
192 | webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
193 | webpackConfig.plugins.push(new ReactRefreshWebpackPlugin({ overlay: false }));
194 |
195 | webpackConfig.devServer = {
196 | open: true,
197 | port: appConfig.example.port,
198 | stats: 'errors-only',
199 | inline: true,
200 | injectClient: false,
201 | historyApiFallback: true,
202 | };
203 | }
204 |
205 | module.exports = webpackConfig;
206 |
--------------------------------------------------------------------------------