├── src ├── static │ ├── Staticfile │ ├── robots.txt │ ├── storm.png │ ├── favicon.ico │ ├── images │ │ ├── background.png │ │ └── weather │ │ │ ├── 0.png │ │ │ ├── 1.png │ │ │ ├── 10.png │ │ │ ├── 11.png │ │ │ ├── 12.png │ │ │ ├── 13.png │ │ │ ├── 14.png │ │ │ ├── 15.png │ │ │ ├── 16.png │ │ │ ├── 17.png │ │ │ ├── 18.png │ │ │ ├── 19.png │ │ │ ├── 2.png │ │ │ ├── 20.png │ │ │ ├── 21.png │ │ │ ├── 22.png │ │ │ ├── 23.png │ │ │ ├── 24.png │ │ │ ├── 25.png │ │ │ ├── 26.png │ │ │ ├── 27.png │ │ │ ├── 28.png │ │ │ ├── 29.png │ │ │ ├── 3.png │ │ │ ├── 30.png │ │ │ ├── 31.png │ │ │ ├── 32.png │ │ │ ├── 33.png │ │ │ ├── 34.png │ │ │ ├── 35.png │ │ │ ├── 36.png │ │ │ ├── 37.png │ │ │ ├── 38.png │ │ │ ├── 39.png │ │ │ ├── 4.png │ │ │ ├── 40.png │ │ │ ├── 41.png │ │ │ ├── 42.png │ │ │ ├── 43.png │ │ │ ├── 44.png │ │ │ ├── 45.png │ │ │ ├── 46.png │ │ │ ├── 47.png │ │ │ ├── 5.png │ │ │ ├── 6.png │ │ │ ├── 7.png │ │ │ ├── 8.png │ │ │ ├── 9.png │ │ │ └── na.png │ ├── humans.txt │ ├── manifest.yml │ ├── .htaccess │ ├── docker-nginx.conf │ └── nginx.conf ├── routes │ ├── Home │ │ ├── components │ │ │ ├── HomeView.scss │ │ │ ├── LandingPage │ │ │ │ ├── index.js │ │ │ │ ├── LandingPage.scss │ │ │ │ ├── assets │ │ │ │ │ └── img │ │ │ │ │ │ ├── mockup.png │ │ │ │ │ │ ├── background.png │ │ │ │ │ │ ├── architecture.png │ │ │ │ │ │ ├── Circles_2.svg │ │ │ │ │ │ ├── Circles_1.svg │ │ │ │ │ │ ├── Circles_3.svg │ │ │ │ │ │ ├── Circles_4.svg │ │ │ │ │ │ ├── Circles_10.svg │ │ │ │ │ │ ├── Circles_6.svg │ │ │ │ │ │ ├── Circles_9.svg │ │ │ │ │ │ ├── Circles_8.svg │ │ │ │ │ │ ├── Circles_5.svg │ │ │ │ │ │ └── Circles_7.svg │ │ │ │ ├── Footer │ │ │ │ │ ├── Footer.jsx │ │ │ │ │ └── Footer.scss │ │ │ │ ├── LandingPage.test.js │ │ │ │ ├── LandingPage.jsx │ │ │ │ ├── ArchDiagram │ │ │ │ │ ├── ArchDiagram.jsx │ │ │ │ │ └── ArchDiagram.scss │ │ │ │ ├── IconSection │ │ │ │ │ ├── IconSection.scss │ │ │ │ │ └── IconSection.jsx │ │ │ │ ├── LogisticsWizard │ │ │ │ │ ├── LogisticsWizard.jsx │ │ │ │ │ └── LogisticsWizard.scss │ │ │ │ ├── LandingPage.story.js │ │ │ │ └── Header │ │ │ │ │ ├── Header.scss │ │ │ │ │ └── Header.jsx │ │ │ └── HomeView.jsx │ │ ├── index.js │ │ └── index.test.js │ ├── Dashboard │ │ ├── components │ │ │ ├── Map │ │ │ │ ├── index.js │ │ │ │ ├── PopUpCard │ │ │ │ │ ├── DCCard │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── DCCard.test.js │ │ │ │ │ │ ├── DCCard.story.js │ │ │ │ │ │ └── DCCard.jsx │ │ │ │ │ ├── index.js │ │ │ │ │ ├── StormCard │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── StormCard.story.js │ │ │ │ │ │ ├── StormCard.jsx │ │ │ │ │ │ └── StormCard.test.js │ │ │ │ │ ├── RetailerCard │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── RetailerCard.story.js │ │ │ │ │ │ ├── RetailerCard.test.js │ │ │ │ │ │ └── RetailerCard.jsx │ │ │ │ │ ├── ShipmentCard │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── ShipmentCard.story.js │ │ │ │ │ │ └── ShipmentCard.jsx │ │ │ │ │ ├── PopUpCard.test.js │ │ │ │ │ ├── PopUpCard.scss │ │ │ │ │ └── PopUpCard.jsx │ │ │ │ ├── MapMarker │ │ │ │ │ ├── index.js │ │ │ │ │ ├── MapMarker.story.js │ │ │ │ │ ├── MapMarker.test.js │ │ │ │ │ ├── MapMarker.scss │ │ │ │ │ └── MapMarker.jsx │ │ │ │ ├── Map.scss │ │ │ │ ├── Map.test.js │ │ │ │ ├── Map.story.js │ │ │ │ └── Map.style.json │ │ │ ├── AlertsCard │ │ │ │ ├── index.js │ │ │ │ ├── AlertsCard.scss │ │ │ │ └── AlertsCard.jsx │ │ │ ├── NumberCard │ │ │ │ ├── index.jsx │ │ │ │ ├── NumberCard.scss │ │ │ │ └── NumberCard.jsx │ │ │ ├── ShipmentsTable │ │ │ │ ├── index.js │ │ │ │ └── ShipmentsTable.jsx │ │ │ ├── RetailSummaryCard │ │ │ │ ├── RetailSummaryCard.scss │ │ │ │ └── RetailSummaryCard.jsx │ │ │ ├── Dashboard.story.js │ │ │ ├── NameResolver.jsx │ │ │ ├── Dashboard.scss │ │ │ ├── Dashboard.test.js │ │ │ ├── NameResolver.test.js │ │ │ └── Dashboard.jsx │ │ ├── index.test.js │ │ ├── index.js │ │ └── modules │ │ │ └── Dashboard.test.js │ └── index.js ├── components │ ├── GlobalNav │ │ ├── RoleSwitcher │ │ │ ├── RoleSwitcher.scss │ │ │ ├── index.js │ │ │ ├── RoleSwitcher.test.js │ │ │ ├── RoleItem.scss │ │ │ ├── RoleItem.test.js │ │ │ ├── RoleItem.jsx │ │ │ └── RoleSwitcher.jsx │ │ ├── index.js │ │ ├── GlobalNav.scss │ │ ├── GlobalNav.min.css │ │ ├── GlobalNav.test.js │ │ ├── GlobalNav.story.js │ │ └── GlobalNav.jsx │ ├── GhostButton │ │ ├── index.js │ │ ├── GhostButton.story.js │ │ ├── GhostButton.test.js │ │ └── GhostButton.jsx │ └── LoadingSpinner │ │ ├── index.js │ │ ├── LoadingSpinner.story.js │ │ ├── LoadingSpinner.test.js │ │ └── LoadingSpinner.jsx ├── layouts │ └── CoreLayout │ │ ├── index.js │ │ └── CoreLayout.jsx ├── styles │ ├── _base.scss │ ├── core.scss │ ├── base │ │ ├── _colors.scss │ │ ├── _variables.scss │ │ └── _typography.scss │ └── muiTheme.js ├── containers │ ├── RoleSwitcherContainer.js │ └── AppContainer.jsx ├── store │ ├── sagas.js │ ├── reducers.js │ └── createStore.js ├── index.html ├── services │ ├── mockApi.js │ ├── index.js │ └── index.test.js ├── main.js └── framework.test.js ├── .storybook ├── .babelrc ├── config.js └── stories │ └── typography.js ├── nodemon.json ├── .eslintignore ├── blueprints ├── component │ ├── files │ │ └── src │ │ │ └── components │ │ │ └── __name__ │ │ │ ├── __name__.scss │ │ │ ├── index.js │ │ │ ├── __name__.story.js │ │ │ ├── __name__.jsx │ │ │ └── __name__.test.js │ └── index.js ├── route │ ├── files │ │ └── src │ │ │ └── routes │ │ │ └── __name__ │ │ │ ├── components │ │ │ ├── __name__.scss │ │ │ ├── __name__.jsx │ │ │ ├── __name__.story.js │ │ │ └── __name__.test.js │ │ │ ├── index.test.js │ │ │ ├── containers │ │ │ └── __name__Container.js │ │ │ ├── index.js │ │ │ └── modules │ │ │ └── __name__.js │ └── index.js └── duck │ ├── index.js │ └── files │ └── src │ └── modules │ └── __name__.js ├── .gitignore ├── Notice.txt ├── .dockerignore ├── .reduxrc ├── config ├── .env-example ├── webpack-compiler.js ├── environments.js ├── ava.config.js └── index.js ├── .travis.yml ├── bin ├── server.js └── compile.js ├── .babelrc ├── server ├── libs │ └── apply-express-middleware.js ├── middleware │ ├── webpack-hmr.js │ └── webpack-dev.js └── main.js ├── Dockerfile ├── License.txt ├── .bluemix ├── pipeline-DEPLOY.sh └── pipeline-BUILD.sh ├── onestep.Dockerfile ├── .editorconfig ├── .eslintrc └── README.md /src/static/Staticfile: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/routes/Home/components/HomeView.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /src/components/GlobalNav/RoleSwitcher/RoleSwitcher.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.storybook/.babelrc: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "presets": ["es2015", "react", "stage-0"] 4 | } 5 | -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "verbose": false, 3 | "ignore": ["dist", "coverage", "tests", "src"] 4 | } 5 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Map/index.js: -------------------------------------------------------------------------------- 1 | import Map from './Map'; 2 | 3 | export default Map; 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage/** 2 | node_modules/** 3 | dist/** 4 | src/index.html 5 | server/** 6 | *.spec.js 7 | -------------------------------------------------------------------------------- /blueprints/component/files/src/components/__name__/__name__.scss: -------------------------------------------------------------------------------- 1 | .<%= camelEntityName %> { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /blueprints/route/files/src/routes/__name__/components/__name__.scss: -------------------------------------------------------------------------------- 1 | .<%= camelEntityName %> { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/static/storm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/storm.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Client 2 | .DS_STORE 3 | node_modules 4 | dist 5 | coverage/ 6 | .nyc_output/ 7 | *.log 8 | .env 9 | -------------------------------------------------------------------------------- /src/components/GlobalNav/index.js: -------------------------------------------------------------------------------- 1 | import GlobalNav from './GlobalNav'; 2 | 3 | export default GlobalNav; 4 | -------------------------------------------------------------------------------- /src/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/favicon.ico -------------------------------------------------------------------------------- /Notice.txt: -------------------------------------------------------------------------------- 1 | This product includes software originally developed by IBM Corporation 2 | Copyright 2016 IBM Corp. 3 | -------------------------------------------------------------------------------- /src/components/GhostButton/index.js: -------------------------------------------------------------------------------- 1 | import GhostButton from './GhostButton'; 2 | 3 | export default GhostButton; 4 | -------------------------------------------------------------------------------- /src/layouts/CoreLayout/index.js: -------------------------------------------------------------------------------- 1 | import CoreLayoutComponent from './CoreLayout'; 2 | 3 | export default CoreLayoutComponent; 4 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Map/PopUpCard/DCCard/index.js: -------------------------------------------------------------------------------- 1 | import DCCard from './DCCard'; 2 | 3 | export default DCCard; 4 | -------------------------------------------------------------------------------- /src/components/GlobalNav/RoleSwitcher/index.js: -------------------------------------------------------------------------------- 1 | import RoleSwitcher from './RoleSwitcher'; 2 | 3 | export default RoleSwitcher; 4 | -------------------------------------------------------------------------------- /src/components/LoadingSpinner/index.js: -------------------------------------------------------------------------------- 1 | import LoadingSpinner from './LoadingSpinner'; 2 | 3 | export default LoadingSpinner; 4 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/AlertsCard/index.js: -------------------------------------------------------------------------------- 1 | import AlertsCard from './AlertsCard'; 2 | 3 | export default AlertsCard; 4 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Map/MapMarker/index.js: -------------------------------------------------------------------------------- 1 | import MapMarker from './MapMarker'; 2 | 3 | export default MapMarker; 4 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Map/PopUpCard/index.js: -------------------------------------------------------------------------------- 1 | import PopUpCard from './PopUpCard'; 2 | 3 | export default PopUpCard; 4 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/NumberCard/index.jsx: -------------------------------------------------------------------------------- 1 | import NumberCard from './NumberCard'; 2 | 3 | export default NumberCard; 4 | -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/index.js: -------------------------------------------------------------------------------- 1 | import LandingPage from './LandingPage'; 2 | 3 | export default LandingPage; 4 | -------------------------------------------------------------------------------- /src/static/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/background.png -------------------------------------------------------------------------------- /src/static/images/weather/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/0.png -------------------------------------------------------------------------------- /src/static/images/weather/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/1.png -------------------------------------------------------------------------------- /src/static/images/weather/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/10.png -------------------------------------------------------------------------------- /src/static/images/weather/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/11.png -------------------------------------------------------------------------------- /src/static/images/weather/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/12.png -------------------------------------------------------------------------------- /src/static/images/weather/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/13.png -------------------------------------------------------------------------------- /src/static/images/weather/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/14.png -------------------------------------------------------------------------------- /src/static/images/weather/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/15.png -------------------------------------------------------------------------------- /src/static/images/weather/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/16.png -------------------------------------------------------------------------------- /src/static/images/weather/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/17.png -------------------------------------------------------------------------------- /src/static/images/weather/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/18.png -------------------------------------------------------------------------------- /src/static/images/weather/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/19.png -------------------------------------------------------------------------------- /src/static/images/weather/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/2.png -------------------------------------------------------------------------------- /src/static/images/weather/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/20.png -------------------------------------------------------------------------------- /src/static/images/weather/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/21.png -------------------------------------------------------------------------------- /src/static/images/weather/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/22.png -------------------------------------------------------------------------------- /src/static/images/weather/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/23.png -------------------------------------------------------------------------------- /src/static/images/weather/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/24.png -------------------------------------------------------------------------------- /src/static/images/weather/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/25.png -------------------------------------------------------------------------------- /src/static/images/weather/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/26.png -------------------------------------------------------------------------------- /src/static/images/weather/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/27.png -------------------------------------------------------------------------------- /src/static/images/weather/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/28.png -------------------------------------------------------------------------------- /src/static/images/weather/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/29.png -------------------------------------------------------------------------------- /src/static/images/weather/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/3.png -------------------------------------------------------------------------------- /src/static/images/weather/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/30.png -------------------------------------------------------------------------------- /src/static/images/weather/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/31.png -------------------------------------------------------------------------------- /src/static/images/weather/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/32.png -------------------------------------------------------------------------------- /src/static/images/weather/33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/33.png -------------------------------------------------------------------------------- /src/static/images/weather/34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/34.png -------------------------------------------------------------------------------- /src/static/images/weather/35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/35.png -------------------------------------------------------------------------------- /src/static/images/weather/36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/36.png -------------------------------------------------------------------------------- /src/static/images/weather/37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/37.png -------------------------------------------------------------------------------- /src/static/images/weather/38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/38.png -------------------------------------------------------------------------------- /src/static/images/weather/39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/39.png -------------------------------------------------------------------------------- /src/static/images/weather/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/4.png -------------------------------------------------------------------------------- /src/static/images/weather/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/40.png -------------------------------------------------------------------------------- /src/static/images/weather/41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/41.png -------------------------------------------------------------------------------- /src/static/images/weather/42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/42.png -------------------------------------------------------------------------------- /src/static/images/weather/43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/43.png -------------------------------------------------------------------------------- /src/static/images/weather/44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/44.png -------------------------------------------------------------------------------- /src/static/images/weather/45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/45.png -------------------------------------------------------------------------------- /src/static/images/weather/46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/46.png -------------------------------------------------------------------------------- /src/static/images/weather/47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/47.png -------------------------------------------------------------------------------- /src/static/images/weather/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/5.png -------------------------------------------------------------------------------- /src/static/images/weather/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/6.png -------------------------------------------------------------------------------- /src/static/images/weather/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/7.png -------------------------------------------------------------------------------- /src/static/images/weather/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/8.png -------------------------------------------------------------------------------- /src/static/images/weather/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/9.png -------------------------------------------------------------------------------- /src/static/images/weather/na.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/static/images/weather/na.png -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Client 2 | .DS_STORE 3 | node_modules 4 | dist 5 | coverage/ 6 | .nyc_output/ 7 | *.log 8 | .env 9 | .git 10 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Map/PopUpCard/StormCard/index.js: -------------------------------------------------------------------------------- 1 | import StormCard from './StormCard'; 2 | 3 | export default StormCard; 4 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/ShipmentsTable/index.js: -------------------------------------------------------------------------------- 1 | import ShipmentsTable from './ShipmentsTable'; 2 | 3 | export default ShipmentsTable; 4 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Map/PopUpCard/RetailerCard/index.js: -------------------------------------------------------------------------------- 1 | import RetailerCard from './RetailerCard'; 2 | 3 | export default RetailerCard; 4 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Map/PopUpCard/ShipmentCard/index.js: -------------------------------------------------------------------------------- 1 | import ShipmentCard from './ShipmentCard'; 2 | 3 | export default ShipmentCard; 4 | -------------------------------------------------------------------------------- /.reduxrc: -------------------------------------------------------------------------------- 1 | { 2 | "sourceBase":"src", 3 | "testBase":"tests", 4 | "smartPath":"containers", 5 | "dumbPath":"components", 6 | "fileCasing":"pascal" 7 | } 8 | -------------------------------------------------------------------------------- /blueprints/component/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | description() { 3 | return 'Creates a component with sass file, story, and test'; 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /src/routes/Home/index.js: -------------------------------------------------------------------------------- 1 | import HomeView from './components/HomeView'; 2 | 3 | // Sync route definition 4 | export default { 5 | component: HomeView, 6 | }; 7 | -------------------------------------------------------------------------------- /blueprints/duck/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | description() { 3 | return 'Creates a syncronous "duck" file: Actions, Reducer, and Sagas'; 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/LandingPage.scss: -------------------------------------------------------------------------------- 1 | .landingPage { 2 | font-family: 'Libre Franklin', sans-serif; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | -------------------------------------------------------------------------------- /src/static/humans.txt: -------------------------------------------------------------------------------- 1 | # Check it out: http://humanstxt.org/ 2 | 3 | # TEAM 4 | 5 | -- -- 6 | 7 | # THANKS 8 | 9 | 10 | -------------------------------------------------------------------------------- /blueprints/component/files/src/components/__name__/index.js: -------------------------------------------------------------------------------- 1 | import <%= pascalEntityName %> from './<%= pascalEntityName %>'; 2 | 3 | export default <%= pascalEntityName %>; 4 | -------------------------------------------------------------------------------- /blueprints/route/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | description() { 3 | return 'Generates a route with components, modules, containers, tests, and stories'; 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/assets/img/mockup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/routes/Home/components/LandingPage/assets/img/mockup.png -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/assets/img/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/routes/Home/components/LandingPage/assets/img/background.png -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/assets/img/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM-Cloud/logistics-wizard-webui/HEAD/src/routes/Home/components/LandingPage/assets/img/architecture.png -------------------------------------------------------------------------------- /src/routes/Home/index.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import HomeRoute from './'; 3 | 4 | test('should return a route config object', t => { 5 | t.is(typeof (HomeRoute), 'object'); 6 | }); 7 | -------------------------------------------------------------------------------- /src/static/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | - name: logistics-wizard 4 | memory: 64M 5 | buildpack: staticfile_buildpack 6 | host: logistics-wizard 7 | env: 8 | NODE_ENV: production 9 | -------------------------------------------------------------------------------- /src/routes/Home/components/HomeView.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import LandingPage from './LandingPage'; 3 | 4 | export const HomeView = () => ( 5 | 6 | ); 7 | 8 | export default HomeView; 9 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/RetailSummaryCard/RetailSummaryCard.scss: -------------------------------------------------------------------------------- 1 | @import '~styles/base/colors'; 2 | @import '../Dashboard.scss'; 3 | 4 | .shipmentsWrapper { 5 | margin-right: 0rem; 6 | } 7 | 8 | .icon { 9 | font-size: 14px; 10 | } 11 | -------------------------------------------------------------------------------- /config/.env-example: -------------------------------------------------------------------------------- 1 | // Copy this file and name it `.env` to set up local dev config 2 | 3 | module.exports = { 4 | controller_service: '', 5 | google_maps_key: '', 6 | } 7 | -------------------------------------------------------------------------------- /src/components/LoadingSpinner/LoadingSpinner.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@kadira/storybook'; 3 | import LoadingSpinner from './LoadingSpinner'; 4 | 5 | storiesOf('LoadingSpinner', module) 6 | .add('default', () => ( 7 | 8 | )); 9 | -------------------------------------------------------------------------------- /src/static/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | RewriteEngine On 4 | RewriteBase / 5 | RewriteRule ^index\.html$ - [L] 6 | RewriteCond %{REQUEST_FILENAME} !-f 7 | RewriteCond %{REQUEST_FILENAME} !-d 8 | RewriteCond %{REQUEST_FILENAME} !-l 9 | RewriteRule . /index.html [L] 10 | 11 | 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "6.9.1" 5 | 6 | cache: 7 | directories: 8 | - node_modules 9 | 10 | install: 11 | - npm install 12 | 13 | script: 14 | - npm run lint:fix 15 | - npm run test 16 | - npm run check-coverage 17 | 18 | after_success: 19 | - npm run coveralls 20 | -------------------------------------------------------------------------------- /src/components/GlobalNav/GlobalNav.scss: -------------------------------------------------------------------------------- 1 | @import '~styles/base/colors'; 2 | 3 | .title { 4 | margin-left: 0; 5 | padding-left: 24px; 6 | color: $alternateTextColor; 7 | } 8 | 9 | .github { 10 | font-size: 1.7rem; 11 | color: $primary3Color; 12 | 13 | &:hover { 14 | color: $alternateTextColor; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/styles/_base.scss: -------------------------------------------------------------------------------- 1 | /* 2 | Application Settings Go Here 3 | ------------------------------------ 4 | This file acts as a bundler for all variables/mixins/themes, so they 5 | can easily be swapped out without `core.scss` ever having to know. 6 | */ 7 | 8 | @import './base/variables'; 9 | @import './base/typography'; 10 | @import './base/colors'; 11 | -------------------------------------------------------------------------------- /bin/server.js: -------------------------------------------------------------------------------- 1 | import _debug from 'debug'; 2 | import config from '../config'; 3 | import server from '../server/main'; 4 | 5 | const debug = _debug('app:bin:server'); 6 | const port = config.server_port; 7 | const host = config.server_host; 8 | 9 | server.listen(port); 10 | debug(`Server is now running at http://${host}:${port}.`); 11 | debug(`Server accessible via localhost:${port}`); 12 | -------------------------------------------------------------------------------- /src/components/GlobalNav/GlobalNav.min.css: -------------------------------------------------------------------------------- 1 | .globalNav p{color:#fff}.title{padding-left:2rem}.separator{background-color:#b8dee4}.github{font-size:1.9rem;color:#b8dee4}.github:hover{color:#fff}.stack{position:relative;cursor:pointer;margin-right:30px}.stack .user{font-size:1.2rem;color:#0f93a6;line-height:3.3rem;margin-left:.3rem}.stack:hover .circle{color:#fff}.stack .circle{font-size:1.9rem;color:#b8dee4;line-height:3.3rem} 2 | -------------------------------------------------------------------------------- /src/components/GhostButton/GhostButton.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@kadira/storybook'; 3 | import GhostButton from './GhostButton'; 4 | 5 | storiesOf('GhostButton', module) 6 | .add('Primary', () => ( 7 | 8 | )) 9 | .add('Secondary', () => ( 10 | 14 | )); 15 | -------------------------------------------------------------------------------- /blueprints/route/files/src/routes/__name__/index.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import <%= pascalEntityName %>Route from './'; 3 | 4 | test('(Route) should return a route config object', t => { 5 | t.is(typeof (<%= pascalEntityName %>Route({})), 'object'); 6 | }); 7 | 8 | test('(Route) Config should contain path "<%= dashesEntityName %>"', t => { 9 | t.is(<%= pascalEntityName %>Route({}).path, '<%= dashesEntityName %>'); 10 | }); 11 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/NumberCard/NumberCard.scss: -------------------------------------------------------------------------------- 1 | @import '~styles/base/colors'; 2 | 3 | .card { 4 | text-align: center; 5 | border-right: 1px solid $borderColor; 6 | } 7 | 8 | .value { 9 | font-size: 2.6rem; 10 | color: $accent1Color; 11 | font-weight: 300; 12 | } 13 | 14 | .label { 15 | font-size: 13px; 16 | font-weight: 600; 17 | color: $primary1Color; 18 | 19 | i { 20 | margin-right: 5px; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/routes/index.js: -------------------------------------------------------------------------------- 1 | import CoreLayout from '../layouts/CoreLayout/CoreLayout'; 2 | import Home from './Home'; 3 | import DashboardRoute from './Dashboard'; 4 | 5 | export const createRoutes = (store) => ({ 6 | path: '/', 7 | indexRoute: Home, 8 | childRoutes: [ 9 | { component: CoreLayout, 10 | childRoutes: [ 11 | DashboardRoute(store), 12 | ], 13 | }, 14 | ], 15 | }); 16 | 17 | export default createRoutes; 18 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | // NOTE: These options are overriden by the babel-loader configuration 2 | // for webpack, which can be found in ~/config/webpack.config. 3 | // 4 | // Why? The react-transform-hmr plugin depends on HMR (and throws if 5 | // module.hot is disabled), so keeping it and related plugins contained 6 | // within webpack helps prevent unexpected errors. 7 | { 8 | "presets": ["es2015", "react", "stage-0"], 9 | "plugins": ["transform-runtime"] 10 | } 11 | -------------------------------------------------------------------------------- /src/containers/RoleSwitcherContainer.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { login, createUser } from 'modules/demos'; 3 | import RoleSwitcher from 'components/GlobalNav/RoleSwitcher'; 4 | 5 | const mapActionCreators = { 6 | login, 7 | createUser, 8 | }; 9 | 10 | const mapStateToProps = (state) => ({ 11 | users: state.demoSession.users, 12 | }); 13 | 14 | export default connect(mapStateToProps, mapActionCreators)(RoleSwitcher); 15 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Dashboard.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf, action } from '@kadira/storybook'; 3 | import Dashboard from './Dashboard'; 4 | 5 | storiesOf('Dashboard', module) 6 | .add('default state', () => ( 7 | 13 | )); 14 | -------------------------------------------------------------------------------- /server/libs/apply-express-middleware.js: -------------------------------------------------------------------------------- 1 | // Based on: https://github.com/dayAlone/koa-webpack-hot-middleware/blob/master/index.js 2 | export default function applyExpressMiddleware(fn, req, res) { 3 | const originalEnd = res.end; 4 | 5 | return new Promise((resolve) => { 6 | res.end = function () { 7 | originalEnd.apply(this, arguments); 8 | resolve(false); 9 | }; 10 | fn(req, res, function () { 11 | resolve(true); 12 | }); 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /src/store/sagas.js: -------------------------------------------------------------------------------- 1 | import { fork } from 'redux-saga/effects'; 2 | 3 | export const makeRootSaga = asyncSagas => function *rootSaga() { 4 | yield [ 5 | ...asyncSagas, 6 | ].map(saga => fork(saga)); 7 | }; 8 | 9 | export const injectSagas = (store, { key, sagas }) => { 10 | if (store.asyncSagas[key]) { 11 | return; 12 | } 13 | store.asyncSagas[key] = sagas; //eslint-disable-line 14 | store.runSaga(makeRootSaga(sagas)); 15 | }; 16 | 17 | export default makeRootSaga; 18 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logistics Wizard 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/styles/core.scss: -------------------------------------------------------------------------------- 1 | :global { 2 | @import '~normalize.css/normalize'; 3 | @import 'base'; 4 | // Some best-practice CSS that's useful for most apps 5 | // Just remove them if they're not what you want 6 | html { 7 | box-sizing: border-box; 8 | } 9 | 10 | html, 11 | body { 12 | background-color: $backgroundColor; 13 | margin: 0; 14 | padding: 0; 15 | height: 100%; 16 | } 17 | 18 | *, 19 | *:before, 20 | *:after { 21 | box-sizing: inherit; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Map/MapMarker/MapMarker.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@kadira/storybook'; 3 | import MapMarker from './MapMarker'; 4 | 5 | storiesOf('MapMarker', module) 6 | .add('distributionCenter', () => ( 7 | 10 | )) 11 | .add('retailer', () => ( 12 | 15 | )) 16 | .add('shipment', () => ( 17 | 20 | )); 21 | -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/Footer/Footer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import GhostButton from 'components/GhostButton'; 3 | import classes from './Footer.scss'; 4 | 5 | export const Footer = () => ( 6 |
7 |
8 |

Learn more on the Logistics Wizard repository

9 | 10 | 11 | 12 |
13 | ); 14 | 15 | export default Footer; 16 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # build 2 | FROM node:6-alpine AS build 3 | 4 | WORKDIR /app 5 | COPY . . 6 | 7 | ARG CONTROLLER_SERVICE=http://lw-controller:8080 8 | ENV CONTROLLER_SERVICE="${CONTROLLER_SERVICE}" 9 | 10 | RUN cd /app \ 11 | && apk add --no-cache --virtual .build-deps alpine-sdk python \ 12 | && npm install \ 13 | && npm run deploy:prod \ 14 | && apk del .build-deps 15 | 16 | # run 17 | FROM nginx:stable 18 | 19 | COPY --from=build /app/dist/ /var/www/ 20 | COPY --from=build /app/dist/docker-nginx.conf /etc/nginx/conf.d/default.conf 21 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/NameResolver.jsx: -------------------------------------------------------------------------------- 1 | export const NameResolver = (dashboard) => ({ 2 | resolve: (type, id) => { 3 | switch (type) { 4 | case 'distributionCenter': 5 | return dashboard['distribution-centers'] 6 | .find(dc => dc.id === id).address.city; 7 | case 'retailer': 8 | return dashboard.retailers 9 | .find(retailer => retailer.id === id).address.city; 10 | default: 11 | return `*${id}*`; 12 | } 13 | }, 14 | }); 15 | 16 | export default NameResolver; 17 | -------------------------------------------------------------------------------- /src/routes/Dashboard/index.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import DashboardRoute from './'; 3 | 4 | test('(Route) should return a route config object', t => { 5 | t.is(typeof (DashboardRoute({})), 'object'); 6 | }); 7 | 8 | test('(Route) Config should contain path "dashboard/:guid"', t => { 9 | t.is(DashboardRoute({}).path, 'dashboard/:guid'); 10 | }); 11 | 12 | test('(Route) Config should contain logic to dispatch getDemo action', t => { 13 | t.pass(); 14 | // t.is(DashboardRoute({}).onEnter, Test Function Somehow?); 15 | }); 16 | -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/LandingPage.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import React from 'react'; 3 | import { shallow } from 'enzyme'; 4 | import LandingPage from './LandingPage'; 5 | 6 | const setup = () => { 7 | const spies = { 8 | }; 9 | const props = { 10 | }; 11 | const component = shallow(); 12 | 13 | return { component, props, spies }; 14 | }; 15 | 16 | test('(Component) Has expected elements.', t => { 17 | const { component } = setup(); 18 | t.is(component.find('LogisticsWizard').length, 1); 19 | }); 20 | -------------------------------------------------------------------------------- /src/components/LoadingSpinner/LoadingSpinner.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import React from 'react'; 3 | import { shallow } from 'enzyme'; 4 | import LoadingSpinner from './LoadingSpinner'; 5 | 6 | const setup = () => { 7 | const spies = { 8 | }; 9 | const props = { 10 | }; 11 | const component = shallow(); 12 | 13 | return { component, props, spies }; 14 | }; 15 | 16 | test('(Component) Has expected elements.', t => { 17 | const { component } = setup(); 18 | t.is(component.find('CircularProgress').length, 1); 19 | }); 20 | -------------------------------------------------------------------------------- /src/components/GhostButton/GhostButton.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import React from 'react'; 3 | import { shallow } from 'enzyme'; 4 | import GhostButton from './GhostButton'; 5 | 6 | const setup = () => { 7 | const spies = { 8 | }; 9 | const props = { 10 | }; 11 | const component = shallow(); 12 | 13 | return { component, props, spies }; 14 | }; 15 | 16 | test('(Component) Has expected elements.', t => { 17 | const { component } = setup(); 18 | t.is(component.find('RaisedButton').length, 1); 19 | }); 20 | -------------------------------------------------------------------------------- /src/store/reducers.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import { routerReducer as router } from 'react-router-redux'; 3 | import demos from 'modules/demos'; 4 | 5 | export const makeRootReducer = (asyncReducers) => 6 | combineReducers({ 7 | demoSession: demos, 8 | router, 9 | ...asyncReducers, 10 | }); 11 | 12 | export const injectReducer = (store, { key, reducer }) => { 13 | store.asyncReducers[key] = reducer; //eslint-disable-line 14 | store.replaceReducer(makeRootReducer(store.asyncReducers)); 15 | }; 16 | 17 | export default makeRootReducer; 18 | -------------------------------------------------------------------------------- /blueprints/route/files/src/routes/__name__/containers/__name__Container.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { getQuote } from '../modules/<%= pascalEntityName %>'; 3 | import <%= pascalEntityName %> from '../components/<%= pascalEntityName %>'; 4 | 5 | const mapActionCreators = { 6 | actionAndSaga: () => getQuote(), 7 | }; 8 | 9 | const mapStateToProps = (state) => ({ 10 | title: state.<%= camelEntityName %>.title, 11 | quote: state.<%= camelEntityName %>.quote, 12 | }); 13 | 14 | export default connect(mapStateToProps, mapActionCreators)(<%= pascalEntityName %>); 15 | -------------------------------------------------------------------------------- /src/components/LoadingSpinner/LoadingSpinner.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import CircularProgress from 'material-ui/CircularProgress'; 3 | import { palette } from 'styles/muiTheme'; 4 | 5 | const LoadingSpinner = (props) => ( 6 | 11 | ); 12 | 13 | LoadingSpinner.propTypes = { 14 | size: React.PropTypes.number, 15 | style: React.PropTypes.object, 16 | color: React.PropTypes.string, 17 | }; 18 | 19 | export default LoadingSpinner; 20 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Copyright 2016 IBM Corp. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /blueprints/component/files/src/components/__name__/__name__.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf, action } from '@kadira/storybook'; 3 | import <%= pascalEntityName %> from './<%= pascalEntityName %>'; 4 | 5 | storiesOf('<%= pascalEntityName %>', module) 6 | .add('default', () => ( 7 | <<%= pascalEntityName %> 8 | clicky={action('You clicked the button.')} 9 | /> 10 | )) 11 | .add('custom prop', () => ( 12 | <<%= pascalEntityName %> 13 | customProp="What a fancy example!" 14 | clicky={action('You clicked the button.')} 15 | /> 16 | )); 17 | -------------------------------------------------------------------------------- /src/components/GlobalNav/RoleSwitcher/RoleSwitcher.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import React from 'react'; 3 | import { shallow } from 'enzyme'; 4 | import RoleSwitcher from './RoleSwitcher'; 5 | 6 | const setup = () => { 7 | const spies = { 8 | }; 9 | const props = { 10 | }; 11 | const component = shallow(); 12 | 13 | return { component, props, spies }; 14 | }; 15 | 16 | test('(Component) Has expected elements.', t => { 17 | const { component } = setup(); 18 | t.is(component.find('div').length, 1); 19 | t.is(component.find('LoadingSpinner').length, 1); 20 | }); 21 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/NumberCard/NumberCard.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classes from './NumberCard.scss'; 3 | 4 | export const NumberCard = (props) => ( 5 |
6 |
{props.value}
7 |
8 | 9 | {props.label} 10 |
11 |
12 | ); 13 | 14 | NumberCard.propTypes = { 15 | icon: React.PropTypes.string, 16 | label: React.PropTypes.string, 17 | value: React.PropTypes.number, 18 | }; 19 | 20 | export default NumberCard; 21 | -------------------------------------------------------------------------------- /blueprints/component/files/src/components/__name__/__name__.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classes from './<%= pascalEntityName %>.scss'; 3 | 4 | export const <%= pascalEntityName %> = (props) => ( 5 |
}> 6 |

<%= pascalEntityName %>

7 |

Prop: {props.customProp || 'no prop given.'}

8 | 9 |
10 | ); 11 | 12 | <%= pascalEntityName %>.propTypes = { 13 | customProp: React.PropTypes.string, 14 | clicky: React.PropTypes.func.isRequired, 15 | }; 16 | 17 | export default <%= pascalEntityName %>; 18 | -------------------------------------------------------------------------------- /src/components/GlobalNav/GlobalNav.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import React from 'react'; 3 | import { shallow } from 'enzyme'; 4 | import { GlobalNav } from './GlobalNav'; 5 | 6 | const setup = () => { 7 | const spies = { 8 | }; 9 | const props = { 10 | }; 11 | const component = shallow(); 12 | 13 | return { component, props, spies }; 14 | }; 15 | 16 | test('(Component) Has expected elements.', t => { 17 | const { component } = setup(); 18 | t.is(component.find('Connect(RoleSwitcher)').length, 1); 19 | t.is(component.find('Link').length, 1); 20 | t.is(component.find('Link').first().props().to, '/'); 21 | }); 22 | -------------------------------------------------------------------------------- /server/middleware/webpack-hmr.js: -------------------------------------------------------------------------------- 1 | import WebpackHotMiddleware from 'webpack-hot-middleware'; 2 | import _debug from 'debug'; 3 | import applyExpressMiddleware from '../libs/apply-express-middleware'; 4 | 5 | const debug = _debug('app:server:webpack-hmr'); 6 | 7 | export default function (compiler, opts) { 8 | debug('Enable Webpack Hot Module Replacement (HMR).'); 9 | 10 | const middleware = WebpackHotMiddleware(compiler, opts); 11 | return async function koaWebpackHMR(ctx, next) { 12 | const hasNext = await applyExpressMiddleware(middleware, ctx.req, ctx.res); 13 | 14 | if (hasNext && next) { 15 | await next(); 16 | } 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/AlertsCard/AlertsCard.scss: -------------------------------------------------------------------------------- 1 | @import '~styles/base/colors'; 2 | 3 | .wrapper { 4 | border: 1px solid $map2Primary; 5 | background-color: $map2Accent; 6 | color: $map2Primary; 7 | font-size: 14px; 8 | width: 300px; 9 | position: absolute; 10 | top: 25px; 11 | padding: 10px; 12 | // left: 50px 13 | right: 10px; 14 | } 15 | 16 | .title { 17 | 18 | } 19 | 20 | .content { 21 | font-size: 0.875rem; 22 | display: flex; 23 | justify-content: space-between; 24 | 25 | } 26 | 27 | .closeIcon { 28 | font-size: 18px; 29 | line-height: 21px; 30 | cursor: pointer; 31 | } 32 | 33 | .hidden { display:none; } 34 | -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/LandingPage.jsx: -------------------------------------------------------------------------------- 1 | import 'styles/core.scss'; 2 | import React from 'react'; 3 | import Header from './Header/Header'; 4 | import LogisticsWizard from './LogisticsWizard/LogisticsWizard'; 5 | import IconSection from './IconSection/IconSection'; 6 | import ArchDiagram from './ArchDiagram/ArchDiagram'; 7 | import Footer from './Footer/Footer'; 8 | import classes from './LandingPage.scss'; 9 | 10 | export const LandingPage = () => ( 11 |
12 |
13 | 14 | 15 | 16 |
17 |
18 | ); 19 | 20 | export default LandingPage; 21 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Dashboard.scss: -------------------------------------------------------------------------------- 1 | @import '~styles/base/colors'; 2 | 3 | .wrapper { 4 | flex-direction: column; 5 | display: flex; 6 | flex-grow: 1; 7 | overflow: hidden; 8 | } 9 | 10 | .cardSection { 11 | background-color: white; 12 | display: flex; 13 | flex-direction: row; 14 | padding: .5rem; 15 | border-bottom: 1px solid $borderColor; 16 | } 17 | 18 | .cardSection > div { 19 | flex: 1; 20 | } 21 | 22 | .viewMode { 23 | display: flex; 24 | align-content: center; 25 | flex-direction: row; 26 | } 27 | 28 | .viewMode > div { 29 | text-align: center; 30 | align-self: center; 31 | flex: 1; 32 | } 33 | 34 | .shipmentsTable { 35 | margin: 1rem; 36 | } 37 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Dashboard.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | /* 3 | import sinon from 'sinon'; 4 | import React from 'react'; 5 | import { shallow } from 'enzyme'; 6 | import Dashboard from './Dashboard'; 7 | 8 | const setup = () => { 9 | const spies = { 10 | simulateStorm: sinon.spy(), 11 | }; 12 | const props = { 13 | demoName: 'Test Demo', 14 | shipments: [], 15 | retailers: [], 16 | distributionCenters: [], 17 | storms: [], 18 | token: '1234', 19 | }; 20 | const component = shallow(); 21 | 22 | return { spies, props, component }; 23 | }; 24 | */ 25 | 26 | test.todo('write tests for dashboard elements once complete.'); 27 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/NameResolver.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import NameResolver from './NameResolver'; 3 | 4 | const dashboard = { 5 | 'distribution-centers': [ 6 | { 7 | id: 1, 8 | address: { 9 | city: 'DC', 10 | }, 11 | }, 12 | ], 13 | retailers: [ 14 | { 15 | id: 1, 16 | address: { 17 | city: 'Retailer', 18 | }, 19 | }, 20 | ], 21 | }; 22 | 23 | test('Resolves names', t => { 24 | t.is('DC', NameResolver(dashboard).resolve('distributionCenter', 1)); 25 | t.is('Retailer', NameResolver(dashboard).resolve('retailer', 1)); 26 | t.is('*123*', NameResolver(dashboard).resolve('unknownType', 123)); 27 | }); 28 | -------------------------------------------------------------------------------- /blueprints/route/files/src/routes/__name__/components/__name__.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classes from './<%= pascalEntityName %>.scss'; 3 | 4 | export const <%= pascalEntityName %> = (props) => ( 5 |
}> 6 |

<%= pascalEntityName %> - {props.title}

7 | 8 |

{props.quote || 'Click button to receive a quote.'}

9 |
10 | ); 11 | 12 | <%= pascalEntityName %>.propTypes = { 13 | title: React.PropTypes.string.isRequired, 14 | quote: React.PropTypes.string, 15 | actionAndSaga: React.PropTypes.func.isRequired, 16 | }; 17 | 18 | export default <%= pascalEntityName %>; 19 | -------------------------------------------------------------------------------- /src/layouts/CoreLayout/CoreLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import GlobalNav from 'components/GlobalNav'; 3 | import 'styles/core.scss'; 4 | 5 | const styles = { 6 | wrapper: { 7 | display: 'flex', 8 | flexDirection: 'column', 9 | flexGrow: 1, 10 | }, 11 | content: { 12 | display: 'flex', 13 | flexDirection: 'column', 14 | flexGrow: 1, 15 | }, 16 | }; 17 | 18 | export const CoreLayout = ({ children }) => ( 19 |
20 | 21 |
22 | {children} 23 |
24 |
25 | ); 26 | 27 | CoreLayout.propTypes = { 28 | children: React.PropTypes.element.isRequired, 29 | }; 30 | 31 | export default CoreLayout; 32 | -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/ArchDiagram/ArchDiagram.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Card, CardMedia } from 'material-ui/Card'; 3 | import Diagram from '../assets/img/architecture.png'; 4 | import Graph from '../assets/img/graph.svg'; 5 | import classes from './ArchDiagram.scss'; 6 | 7 | export const ArchDiagram = () => ( 8 |
9 |

Logistics Wizard Architecture

10 | 11 | 12 | Architecture Diagram 13 | 14 | 15 | 16 | 17 |
18 | ); 19 | 20 | export default ArchDiagram; 21 | -------------------------------------------------------------------------------- /.bluemix/pipeline-DEPLOY.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo Login IBM Cloud api=$CF_TARGET_URL org=$CF_ORG space=$CF_SPACE 3 | ibmcloud login -a "$CF_TARGET_URL" --apikey "$IAM_API_KEY" -o "$CF_ORG" -s "$CF_SPACE" 4 | 5 | # Push the app 6 | if ! ibmcloud cf app $CF_APP; then 7 | ibmcloud cf push $CF_APP -n $CF_APP 8 | else 9 | OLD_CF_APP=${CF_APP}-OLD-$(date +"%s") 10 | rollback() { 11 | set +e 12 | if ibmcloud cf app $OLD_CF_APP; then 13 | ibmcloud cf logs $CF_APP --recent 14 | ibmcloud cf delete $CF_APP -f 15 | ibmcloud cf rename $OLD_CF_APP $CF_APP 16 | fi 17 | exit 1 18 | } 19 | set -e 20 | trap rollback ERR 21 | ibmcloud cf rename $CF_APP $OLD_CF_APP 22 | ibmcloud cf push $CF_APP -n $CF_APP 23 | ibmcloud cf delete $OLD_CF_APP -f 24 | fi 25 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/Map/Map.scss: -------------------------------------------------------------------------------- 1 | @import '~styles/base/colors'; 2 | 3 | .mapContainer { 4 | flex-grow: 1; 5 | position: relative; 6 | } 7 | 8 | .map { 9 | position: absolute; 10 | top: 0; 11 | left: 0; 12 | width: 100%; 13 | height: 100%; 14 | border-bottom: 1px solid $borderColor; 15 | border-left: 1px solid $borderColor; 16 | border-right: 1px solid $borderColor; 17 | margin-bottom: 1.5rem; 18 | } 19 | 20 | .simulateButton { 21 | position: absolute; 22 | bottom: 30px; 23 | right: 10px; 24 | font-size: .75rem; 25 | } 26 | 27 | .simulateLoading { 28 | background-color: white; 29 | opacity: 0.9; 30 | padding: 20px; 31 | border-radius: 20px; 32 | position: absolute; 33 | top: calc(50% - 52px); 34 | left: calc(50% - 52px); 35 | } 36 | -------------------------------------------------------------------------------- /src/routes/Dashboard/index.js: -------------------------------------------------------------------------------- 1 | import { injectReducer } from 'store/reducers'; 2 | import { injectSagas } from 'store/sagas'; 3 | import { getDemoSession } from 'modules/demos'; 4 | 5 | export default (store) => ({ 6 | path: 'dashboard/:guid', 7 | getComponent(nextState, cb) { 8 | require.ensure([], (require) => { 9 | const Dashboard = require('./components/Dashboard').default; 10 | const reducer = require('./modules/Dashboard').default; 11 | const sagas = require('./modules/Dashboard').sagas; 12 | 13 | injectReducer(store, { key: 'dashboard', reducer }); 14 | injectSagas(store, { key: 'dashboard', sagas }); 15 | 16 | store.dispatch(getDemoSession(nextState.params.guid)); 17 | cb(null, Dashboard); 18 | }, 'dashboard'); 19 | }, 20 | }); 21 | -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/IconSection/IconSection.scss: -------------------------------------------------------------------------------- 1 | @import "~styles/base/colors"; 2 | 3 | .iconSection { 4 | background: $primary1Color; 5 | 6 | display: flex; 7 | flex-direction: column; 8 | flex-wrap: nowrap; 9 | justify-content: center; 10 | 11 | padding: 0; 12 | 13 | .iconContainer { 14 | margin: 0 5%; 15 | text-align: center; 16 | 17 | & h4 { 18 | color: $alternateTextColor; 19 | text-transform: uppercase; 20 | } 21 | 22 | & p { 23 | color: $alternateTextColor; 24 | font-weight: 300; 25 | } 26 | } 27 | 28 | @media screen and (min-width: 800px) { 29 | flex-direction: row; 30 | 31 | .iconContainer { 32 | width: 20%; 33 | } 34 | } 35 | } 36 | 37 | 38 | .icon { 39 | min-height: 151px; 40 | } 41 | -------------------------------------------------------------------------------- /blueprints/route/files/src/routes/__name__/index.js: -------------------------------------------------------------------------------- 1 | import { injectReducer } from 'store/reducers'; 2 | import { injectSagas } from 'store/sagas'; 3 | 4 | export default (store) => ({ 5 | path: '<%= dashesEntityName %>', 6 | getComponent(nextState, cb) { 7 | require.ensure([], (require) => { 8 | const <%= pascalEntityName %> = require('./containers/<%= pascalEntityName %>Container').default; 9 | const reducer = require('./modules/<%= pascalEntityName %>').default; 10 | const sagas = require('./modules/<%= pascalEntityName %>').sagas; 11 | 12 | injectReducer(store, { key: '<%= camelEntityName %>', reducer }); 13 | injectSagas(store, { key: '<%= camelEntityName %>', sagas }); 14 | 15 | cb(null, <%= pascalEntityName %>); 16 | }, '<%= camelEntityName %>'); 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/LogisticsWizard/LogisticsWizard.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Mockup from '../assets/img/mockup.png'; 3 | import classes from './LogisticsWizard.scss'; 4 | 5 | export const LogisticsWizard = () => ( 6 |
7 |
8 |

Logistics Wizard

9 |

10 | A cognitive logistics solution that analyzes real-time data, provides 11 | intelligent recommendations, and presents your employees with a beautiful 12 | monitoring dashboard to help lead your supply chain management system into the future. 13 |

14 |
15 | 16 |
17 | 18 |
19 |
20 | ); 21 | 22 | export default LogisticsWizard; 23 | -------------------------------------------------------------------------------- /src/components/GlobalNav/GlobalNav.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@kadira/storybook'; 3 | import GlobalNav from './GlobalNav'; 4 | import RoleSwitcher from './RoleSwitcher'; 5 | 6 | const users = [ 7 | { 8 | id: 1, 9 | role: 'supplychainmanager', 10 | loggedIn: true, 11 | }, 12 | { 13 | id: 2, 14 | role: 'retailstoremanager', 15 | location: 'Austin, TX', 16 | }, 17 | ]; 18 | 19 | storiesOf('GlobalNav', module) 20 | .addDecorator((story) => ( 21 |
22 | {story()} 23 |
24 | )) 25 | .add('Not Logged in', () => ( 26 | 27 | )) 28 | .add('Logged in', () => ( 29 | 30 | )) 31 | .add('Role Switcher', () => ( 32 | 33 | )); 34 | -------------------------------------------------------------------------------- /src/static/docker-nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default_server; 3 | server_name localhost; 4 | 5 | root /var/www; 6 | index index.html index.htm; 7 | 8 | location ~* \.(?:manifest|appcache|html?|xml|json)$ { 9 | expires -1; 10 | # access_log logs/static.log; # I don't usually include a static log 11 | } 12 | 13 | location ~* \.(?:css|js)$ { 14 | try_files $uri =404; 15 | expires 1y; 16 | add_header Cache-Control "public"; 17 | access_log off; 18 | } 19 | 20 | # Any route containing a file extension (e.g. /devicesfile.js) 21 | location ~ ^.+\..+$ { 22 | try_files $uri =404; 23 | } 24 | 25 | # Any route that doesn't have a file extension (e.g. /devices) 26 | location / { 27 | try_files $uri $uri/ /index.html; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /onestep.Dockerfile: -------------------------------------------------------------------------------- 1 | # similar to Dockerfile, but uses Apache HTTPd and does not use multi-stage build 2 | FROM httpd:2.4 3 | 4 | ARG CONTROLLER_SERVICE=http://lw-controller:8080 5 | ENV CONTROLLER_SERVICE="${CONTROLLER_SERVICE}" 6 | RUN echo "Using ${CONTROLLER_SERVICE}" 7 | 8 | WORKDIR /app 9 | COPY . . 10 | 11 | RUN apt-get update \ 12 | && apt-get install -y curl gnupg \ 13 | && (curl -sL https://deb.nodesource.com/setup_8.x | bash -) \ 14 | && apt-get update \ 15 | && apt-get install -y python build-essential nodejs \ 16 | && npm install \ 17 | && npm run deploy:prod \ 18 | && rm -rf node_modules \ 19 | && mv -f /app/dist/* /usr/local/apache2/htdocs/ \ 20 | && apt-get remove -y python build-essential nodejs curl 21 | 22 | # Listen on 8080 23 | RUN sed -i "s/Listen 80/Listen 8080/g" /usr/local/apache2/conf/httpd.conf 24 | EXPOSE 8080 25 | -------------------------------------------------------------------------------- /src/styles/base/_colors.scss: -------------------------------------------------------------------------------- 1 | $navColor: #047CC0; 2 | $primary1Color: #047CC0; 3 | $primary2Color: rgba(72, 85, 102, 1); 4 | $primary3Color: #E7F4F6; 5 | $accent1Color: #73A22C; 6 | $alternateTextColor: rgba(255, 255, 255, 1); 7 | $borderColor: rgba(218, 221, 224, 1); 8 | $textColor: $primary2Color; 9 | $backgroundColor: rgba(239, 242, 245, 1); 10 | $map1Primary: #DB7C00; 11 | $map1Accent: #FAF1E8; 12 | $map2Primary: #749C68; 13 | $map2Accent: #F4F9F2; 14 | $map3Primary: #9320A2; 15 | $map3Accent: #F6ECF5; 16 | 17 | :export { navColor: $navColor; } 18 | :export { primary1Color: $primary1Color; } 19 | :export { primary2Color: $primary2Color; } 20 | :export { primary3Color: $primary3Color; } 21 | :export { accent1Color: $accent1Color; } 22 | :export { alternateTextColor: $alternateTextColor; } 23 | :export { borderColor: $borderColor; } 24 | :export { textColor: $textColor; } 25 | -------------------------------------------------------------------------------- /bin/compile.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs-extra'; 2 | import _debug from 'debug'; 3 | import webpackCompiler from '../config/webpack-compiler'; 4 | import webpackConfig from '../config/webpack.config'; 5 | import config from '../config'; 6 | 7 | const debug = _debug('app:bin:compile'); 8 | const paths = config.utils_paths; 9 | 10 | ;(async function () { 11 | try { 12 | debug('Run compiler'); 13 | const stats = await webpackCompiler(webpackConfig); 14 | if (stats.warnings.length && config.compiler_fail_on_warning) { 15 | debug('Config set to fail on warning, exiting with status code "1".'); 16 | process.exit(1); 17 | } 18 | debug('Copy static assets to dist folder.'); 19 | fs.copySync(paths.client('static'), paths.dist()); 20 | } 21 | catch (e) { 22 | debug('Compiler encountered an error.', e); 23 | process.exit(1); 24 | } 25 | })(); 26 | -------------------------------------------------------------------------------- /src/routes/Dashboard/components/AlertsCard/AlertsCard.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import classes from './AlertsCard.scss'; 4 | 5 | export const AlertsCard = ({ storms }) => ( 6 |
0 ? classes.wrapper : classes.hidden}> 7 |
8 |
{storms.length} storm(s) detected!
9 | {/* */} 10 |
11 |
12 | ); 13 | 14 | AlertsCard.propTypes = { 15 | storms: React.PropTypes.array, 16 | }; 17 | 18 | // ------------------------------------ 19 | // Connect Component to Redux 20 | // ------------------------------------ 21 | 22 | const mapStateToProps = (state) => ({ 23 | storms: state.dashboard.storms, 24 | }); 25 | 26 | export default connect(mapStateToProps, {})(AlertsCard); 27 | -------------------------------------------------------------------------------- /src/routes/Home/components/LandingPage/LandingPage.story.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@kadira/storybook'; 3 | import LandingPage from './LandingPage'; 4 | import { Header } from './Header/Header'; 5 | import LogisticsWizard from './LogisticsWizard/LogisticsWizard'; 6 | import IconSection from './IconSection/IconSection'; 7 | import ArchDiagram from './ArchDiagram/ArchDiagram'; 8 | import Footer from './Footer/Footer'; 9 | 10 | storiesOf('LandingPage', module) 11 | .add('Default', () => ( 12 | 13 | )) 14 | .add('Header', () => ( 15 |
16 | )) 17 | .add('Logistics Wizard', () => ( 18 | 19 | )) 20 | .add('Icon Section', () => ( 21 | 22 | )) 23 | .add('Architecture Diagram', () => ( 24 | 25 | )) 26 | .add('Footer', () => ( 27 |