diff --git a/web/.eslintrc b/web/.eslintrc index e2cee78..0feb952 100644 --- a/web/.eslintrc +++ b/web/.eslintrc @@ -9,5 +9,5 @@ "config": "./webpack.config.base.js" } } - }, + } } diff --git a/web/package-lock.json b/web/package-lock.json new file mode 100644 index 0000000..18c6ccc --- /dev/null +++ b/web/package-lock.json @@ -0,0 +1,120 @@ +{ + "name": "web", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "history": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz", + "integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==", + "requires": { + "invariant": "^2.2.1", + "loose-envify": "^1.2.0", + "resolve-pathname": "^2.2.0", + "value-equal": "^0.4.0", + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "hoist-non-react-statics": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", + "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "requires": { + "isarray": "0.0.1" + } + }, + "prop-types": { + "version": "15.7.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.1.tgz", + "integrity": "sha512-f8Lku2z9kERjOCcnDOPm68EBJAO2K00Q5mSgPAUE/gJuBgsYLbVy6owSrtcHj90zt8PvW+z0qaIIgsIhHOa1Qw==", + "requires": { + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "react-is": { + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.1.tgz", + "integrity": "sha512-ioMCzVDWvCvKD8eeT+iukyWrBGrA3DiFYkXfBsVYIRdaREZuBjENG+KjrikavCLasozqRWTwFUagU/O4vPpRMA==" + }, + "react-router": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", + "integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==", + "requires": { + "history": "^4.7.2", + "hoist-non-react-statics": "^2.5.0", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.1", + "warning": "^4.0.1" + } + }, + "resolve-pathname": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz", + "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg==" + }, + "value-equal": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz", + "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw==" + }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + } + } +} diff --git a/web/package.json b/web/package.json index 9da40f5..dc8a7bd 100644 --- a/web/package.json +++ b/web/package.json @@ -11,10 +11,13 @@ "@babel/runtime": "7.3.1", "antd": "3.13.2", "core": "1.0.0", + "history": "^4.7.2", "react": "16.8.1", "react-dom": "16.8.1", "react-hot-loader": "4.6.5", "react-redux": "6.0.0", + "react-router": "^4.3.1", + "react-router-dom": "^4.3.1", "redux-logger": "3.0.6", "styled-components": "4.1.3" }, diff --git a/web/src/components/ErrorComponent/ErrorComponent.jsx b/web/src/components/ErrorComponent/ErrorComponent.jsx new file mode 100644 index 0000000..3e38ac6 --- /dev/null +++ b/web/src/components/ErrorComponent/ErrorComponent.jsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { + ErrorPageContainer, ErrorText, +} from './styled'; + + +const ErrorComponent = () => ( + + + 404 page not found + + +); + +export default ErrorComponent; diff --git a/web/src/components/ErrorComponent/index.js b/web/src/components/ErrorComponent/index.js new file mode 100644 index 0000000..48feb26 --- /dev/null +++ b/web/src/components/ErrorComponent/index.js @@ -0,0 +1,3 @@ +import ErrorComponent from './ErrorComponent'; + +export default ErrorComponent; diff --git a/web/src/components/ErrorComponent/styled/index.js b/web/src/components/ErrorComponent/styled/index.js new file mode 100644 index 0000000..77aedb1 --- /dev/null +++ b/web/src/components/ErrorComponent/styled/index.js @@ -0,0 +1,16 @@ +import styled from 'styled-components'; + +export const ErrorPageContainer = styled.div` + position: absolute; + display: flex; + justify-content:center; + align-items: center; + top: 0; + bottom: 0; + right: 0; + left: 0; +`; + +export const ErrorText = styled.span` + font-size: 30px; +`; diff --git a/web/src/components/ExampleComponent/ExampleComponent.jsx b/web/src/components/ExampleComponent/ExampleComponent.jsx index 9becffb..b754cad 100644 --- a/web/src/components/ExampleComponent/ExampleComponent.jsx +++ b/web/src/components/ExampleComponent/ExampleComponent.jsx @@ -4,6 +4,7 @@ import React from 'react'; import type { Node, } from 'react'; + import type { Action, } from 'core/types'; @@ -18,10 +19,7 @@ type Props = { generateRandomString: () => Action | void, }; -const ExampleComponent = ({ - randomString, - generateRandomString, -}: Props): Node => ( +const ExampleComponent = ({ randomString, generateRandomString }: Props): Node => (
{randomString} diff --git a/web/src/components/HomeComponent/HomeComponent.jsx b/web/src/components/HomeComponent/HomeComponent.jsx new file mode 100644 index 0000000..5fa52d3 --- /dev/null +++ b/web/src/components/HomeComponent/HomeComponent.jsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { + Link, +} from 'react-router-dom'; +import +{ + NavigationContainer, LinksElement, ListLinks, +} from './styled'; + + +const HomeComponent = () => ( + + + + + Products + + + + Generator + + + + +); + +export default HomeComponent; diff --git a/web/src/components/HomeComponent/index.js b/web/src/components/HomeComponent/index.js new file mode 100644 index 0000000..5f4534b --- /dev/null +++ b/web/src/components/HomeComponent/index.js @@ -0,0 +1,3 @@ +import HomeComponent from './HomeComponent'; + +export default HomeComponent; diff --git a/web/src/components/HomeComponent/styled/index.js b/web/src/components/HomeComponent/styled/index.js new file mode 100644 index 0000000..373ee18 --- /dev/null +++ b/web/src/components/HomeComponent/styled/index.js @@ -0,0 +1,36 @@ +import styled from 'styled-components'; + + +export const NavigationContainer = styled.div` + background: linear-gradient(45deg, rgba(255,255,255,1) 0%, rgba(0,255,255,1) 100%); + position: absolute; + display: flex; + justify-content: center; + align-items: center; + top: 0; + bottom:0; + right: 0; + left: 0; +`; + + +export const ListLinks = styled.ul` + list-style-type: none; + margin: 0 auto; + padding:0; +`; + + +export const LinksElement = styled.li` + display: inline; + margin: 20px; + font-size: 25px; + border-bottom: none; + transition: border-bottom 220ms ease-out; + + &:hover { + border-bottom: 2px solid white; + transition: border-bottom 220ms ease-out, color 220ms ease-out; + } + +`; diff --git a/web/src/containers/Base/Base.jsx b/web/src/containers/Base/Base.jsx index cb36cd2..7d307f0 100644 --- a/web/src/containers/Base/Base.jsx +++ b/web/src/containers/Base/Base.jsx @@ -1,8 +1,8 @@ // @flow import React, { - type Node, - type StatelessFunctionalComponent, + type Node, type StatelessFunctionalComponent, } from 'react'; + import { hot, } from 'react-hot-loader'; @@ -10,11 +10,38 @@ import { import ExampleContainer from 'web-containers/ExampleContainer'; import ProductsTableContainer from 'web-containers/ProductsTableContainer'; +import { + Route, Router, Switch, +} from 'react-router'; + +import createHistory from 'history/createBrowserHistory'; +import HomeComponent from 'web-components/HomeComponent'; +import ErrorComponent from 'web-components/ErrorComponent'; + + +const browserHistory = createHistory(); + const Base: StatelessFunctionalComponent<*> = (): Node => (
- - + + + + } + /> + } + /> + + +
); diff --git a/web/src/containers/ExampleContainer/ExampleContainer.jsx b/web/src/containers/ExampleContainer/ExampleContainer.jsx index 3adf762..16afb9a 100644 --- a/web/src/containers/ExampleContainer/ExampleContainer.jsx +++ b/web/src/containers/ExampleContainer/ExampleContainer.jsx @@ -3,39 +3,41 @@ import React from 'react'; import { connect, } from 'react-redux'; - import type { - State, - Dispatch, + State, Dispatch, } from 'core/types'; - import { uiActions, } from 'core/actions'; import { getUiState, } from 'core/selectors'; - import ExampleComponent from 'web-components/ExampleComponent'; type Props = { randomString: string, dispatch: Dispatch, + browserHistory: Object }; -const ExampleContainer = ({ - randomString, - dispatch, -}: Props) => ( - ( +
+ ( dispatch(uiActions.generateRandomString()) ) } - /> + /> + +
); const mapStateToProps = (state: State) => ({ diff --git a/web/src/containers/ProductsTableContainer/ProductsTableContainer.jsx b/web/src/containers/ProductsTableContainer/ProductsTableContainer.jsx index 1150787..f3236a2 100644 --- a/web/src/containers/ProductsTableContainer/ProductsTableContainer.jsx +++ b/web/src/containers/ProductsTableContainer/ProductsTableContainer.jsx @@ -35,14 +35,24 @@ const columns = [{ type Props = { dataSource: Array, + browserHistory: Object }; -const ProductsTableContainer = ({ dataSource }: Props) => ( - +const ProductsTableContainer = ({ dataSource, browserHistory }: Props) => ( +
+
+ + + ); const mapStateToProps = (state: State) => ({ diff --git a/web/src/index.jsx b/web/src/index.jsx index 5c5dab3..13af335 100644 --- a/web/src/index.jsx +++ b/web/src/index.jsx @@ -12,6 +12,10 @@ import type { ComponentType, } from 'react'; +import { + BrowserRouter, +} from 'react-router-dom'; + import store from './store'; import Base from './containers/Base'; @@ -21,7 +25,9 @@ const rootEl: HTMLElement = window.document.getElementById('root'); const render: Function = (Component: ComponentType<*>) => ( reactRender( - + + + , rootEl, ) diff --git a/web/stories/dataTable/index.jsx b/web/stories/dataTable/index.jsx index ef97e38..085fc6b 100644 --- a/web/stories/dataTable/index.jsx +++ b/web/stories/dataTable/index.jsx @@ -73,7 +73,8 @@ storiesOf('data-table', module) rowKey="id" dataSource={props.dataSource} columns={getColumns(true)} - />)} + /> + )} )) .add('placeholder-table', () => ( @@ -99,6 +100,7 @@ storiesOf('data-table', module) dataSource={props.dataSource} columns={getColumns(false)} /> - )} + + )} )); diff --git a/yarn.lock b/yarn.lock index 6f91ce3..f9639d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5586,6 +5586,17 @@ he@1.2.x: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +history@^4.7.2: + version "4.7.2" + resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b" + integrity sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA== + dependencies: + invariant "^2.2.1" + loose-envify "^1.2.0" + resolve-pathname "^2.2.0" + value-equal "^0.4.0" + warning "^3.0.0" + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -5979,7 +5990,7 @@ interpret@^1.0.0, interpret@^1.1.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= -invariant@^2.2.2, invariant@^2.2.4: +invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -6707,7 +6718,7 @@ loglevel@^1.4.1: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po= -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -7712,6 +7723,13 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + dependencies: + isarray "0.0.1" + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -8801,6 +8819,31 @@ react-redux@6.0.0: prop-types "^15.6.2" react-is "^16.6.3" +react-router-dom@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.3.1.tgz#4c2619fc24c4fa87c9fd18f4fb4a43fe63fbd5c6" + integrity sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA== + dependencies: + history "^4.7.2" + invariant "^2.2.4" + loose-envify "^1.3.1" + prop-types "^15.6.1" + react-router "^4.3.1" + warning "^4.0.1" + +react-router@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e" + integrity sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg== + dependencies: + history "^4.7.2" + hoist-non-react-statics "^2.5.0" + invariant "^2.2.4" + loose-envify "^1.3.1" + path-to-regexp "^1.7.0" + prop-types "^15.6.1" + warning "^4.0.1" + react-slick@~0.23.2: version "0.23.2" resolved "https://registry.yarnpkg.com/react-slick/-/react-slick-0.23.2.tgz#8d8bdbc77a6678e8ad36f50c32578c7c0f1c54f6" @@ -9272,6 +9315,11 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-pathname@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879" + integrity sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -10601,6 +10649,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +value-equal@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7" + integrity sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"