KashGit / Latest

0 stars 0 forks source link

sample #2

Open KashGit opened 8 years ago

KashGit commented 7 years ago

Hi this is not done.

KashGit commented 7 years ago

import React, { PropTypes } from 'react'; import { Provider } from 'react-redux'; import App from './App';

const Root = ({ store }) => (

);

Root.propTypes = { store: PropTypes.object };

export default Root;

import React, { Component, PropTypes } from 'react'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import * as SummaryActions from '../actions/SummaryActions'; import Actions from './Actions'; import Contact from './Contact'; import Networth from './Networth'; import Messages from './Messages'; import Spending from './Spending'; import AnnuityAndIncomePlan from './AnnuityAndIncomePlan'; import Investments from './Investments'; import GroupPlans from './GroupPlans'; import AccessFunds from './AccessFunds'; import TermsAndConditions from './TermsAndConditions'; import IsaCard from './Billing'; import Exception from './Exception'; import Title from './Title'; import NetworthOvertime from './NetworthOvertime';

class App extends Component {

componentDidMount() {
    this.props.getSessionStorageData('dismissedSysMessages');
}

render() {
    return (<main>
        <div className="grid-container">
            <div className="row" id="summary-title">
                <Title />
            </div>
            <div className="row" id="card-content">
                <div className="large-24 col">                                             
                    <Actions />
                    <GroupPlans />                                               
                </div>
            </div>
        </div>
    </main>);
}

}

function mapDispatchToProps(dispatch) { return bindActionCreators(SummaryActions, dispatch); }

App.propTypes = { getSessionStorageData: PropTypes.func };

export default connect(null, mapDispatchToProps)(App);

--functional-- import React from 'react';

const Title = () => (

ABC Company Summary

);

export default Title;

KashGit commented 7 years ago

import { createStore, applyMiddleware, compose } from 'redux'; import rootReducer from '../reducers'; import IS_BROWSER from '../utils/isBrowser'; import thunk from 'redux-thunk'; import adobedtm from '../middleware/adobedtm'; import optimizely from '../middleware/optimizely'; import { analyticsReporter, crashReporter, errorReporter } from '../middleware/newrelic';

const newrelicMiddleware = (IS_BROWSER && window.newrelic) ? [crashReporter, analyticsReporter, errorReporter] : []; const middleware = [thunk, ...newrelicMiddleware, adobedtm, optimizely];

const enhancer = compose( applyMiddleware(...middleware), IS_BROWSER && window.devToolsExtension ? window.devToolsExtension() : (f) => f );

export default function configureStore(initialState = {}) { const store = createStore(rootReducer, initialState, enhancer); if (module.hot) { module.hot.accept('../reducers', () => { const nextRootReducer = require('../reducers').default; // eslint-disable-line store.replaceReducer(nextRootReducer); }); } return store; }

KashGit commented 7 years ago

import React, { Component, PropTypes } from 'react'; import classNames from 'classnames'; import { deleteAction, addAction } from '../../actions/MainActions';

export default class Accounts extends Component { renderLinkedAccounts(data) {}

renderAccountsWithErrors(data) {}

render() {
    const { data } = this.props;

    const classes = classNames('active', 'center', 'xlarge');
    const addData = this.renderAdd(data);
    const deleteData = this.renderDelete(data);
    return (
        <div className={classes}>
            {addData}
            {deleteData}
        </div>
    );
}

}

Accounts.propTypes = { data: PropTypes.object };

KashGit commented 7 years ago

Tech Stack Used: JavaScript is written in ES6 and transpiled with Babel.

KashGit commented 7 years ago

postcss.config.js module.exports = { plugins: [ require('autoprefixer')({ / ...options / }) ] }

KashGit commented 7 years ago

package.json { "name": "bx-group-detail", "version": "0.0.0", "description": "A fantastic micro app for BX group to see your financials", "scripts": { "build": "npm run build:client", "build:client": "BABEL_ENV=production webpack --progress --config ./webpack/webpack.client.babel.js", "start": "BABEL_ENV=production babel-node ./src/server", "start:mock": "NODE_ENV=development BABEL_ENV=development babel-node ./src/server/mock", "dev": "NODE_ENV=development BABEL_ENV=development babel-node ./webpack/webpack-dev-server.js & NODE_ENV=development BABEL_ENV=development babel-node ./src/server & npm run start:mock", "dev:int": "NODE_ENV=development NODE_APP_INSTANCE=int BABEL_ENV=development babel-node ./webpack/webpack-dev-server.js & NODE_ENV=development NODE_APP_INSTANCE=int BABEL_ENV=development babel-watch --exclude src/client ./src/server & npm run start:mock", "clean": "rm -r ./build ./node_modules", "lint": "eslint src -f junit > ./test_results/eslint.xml", "lint:watch": "eslint src", "lint:fix": "eslint src --fix", "test": "NODE_ENV=development BABEL_ENV=development mocha --opts test/mocha.opts --bail", "test:watch": "npm test -- --watch --reporter list" }, "private": true, "devDependencies": { "autoprefixer": "6.7.7", "babel-core": "6.24.1", "babel-eslint": "7.2.1", "babel-loader": "6.4.1", "babel-plugin-transform-object-assign": "6.22.0", "babel-plugin-transform-object-rest-spread": "6.23.0", "babel-plugin-transform-react-constant-elements": "6.23.0", "babel-plugin-transform-react-inline-elements": "6.22.0", "babel-plugin-transform-react-remove-prop-types": "0.3.3", "babel-plugin-transform-runtime": "6.23.0", "babel-polyfill": "6.23.0", "babel-preset-es2015": "6.24.1", "babel-preset-react": "6.24.1", "babel-preset-react-hmre": "1.1.1", "babel-register": "6.24.1", "babel-watch": "2.0.6", "case-sensitive-paths-webpack-plugin": "2.0.0", "chai": "3.5.0", "clean-webpack-plugin": "0.1.16", "cookie-parser": "1.4.3", "css-loader": "0.28.0", "enzyme": "2.8.0", "es6-promise": "4.1.0", "eslint": "3.19.0", "eslint-config-airbnb": "14.1.0", "eslint-plugin-babel": "4.1.1", "eslint-plugin-import": "2.2.0", "eslint-plugin-jsx-a11y": "4.0.0", "eslint-plugin-react": "6.10.3", "extract-text-webpack-plugin": "2.1.0", "fetch-mock": "5.9.4", "file-loader": "0.11.1", "html-tagged-literals": "1.0.2", "image-webpack-loader": "3.3.0", "imports-loader": "0.7.1", "jsdom": "9.12.0", "json-loader": "0.5.4", "mocha": "3.2.0", "mocha-junit-reporter": "1.13.0", "node-sass": "3.8.0", "numeral": "2.0.6", "postcss-loader": "1.3.3", "proxyquire": "1.7.11", "react-addons-css-transition-group": "15.5.2", "react-addons-test-utils": "15.5.1", "react-css-transition-replace": "2.2.0", "reselect": "3.0.0", "sass-loader": "4.0.2", "sinon": "2.1.0", "style-loader": "0.16.1", "supertest": "3.0.0", "ui-toolkit": "1.10.0", "url-loader": "0.5.8", "webpack": "2.3.3", "webpack-assets-manifest": "0.6.2", "webpack-dev-server": "2.4.2" }, "dependencies": { "babel-cli": "6.24.1", "classnames": "2.2.5", "compression": "1.6.2", "config": "1.25.1", "cookie-parser": "1.4.3", "d3": "4.7.4", "express": "4.15.2", "isomorphic-fetch": "2.2.1", "json-server": "0.9.6", "keymirror": "0.1.1", "lodash": "4.17.4", "moment": "2.18.1", "moment-timezone": "0.5.13", "newrelic": "1.38.2", "nuka-carousel": "2.0.4", "numeral": "2.0.6", "react": "15.5.4", "react-addons-css-transition-group": "15.5.2", "react-dom": "15.5.4", "react-redux": "5.0.4", "react-responsive": "1.2.7", "redux": "3.6.0", "redux-mock-store": "1.2.3", "redux-persist": "4.6.0", "redux-reporter": "0.1.1", "redux-thunk": "2.2.0", "run-middleware": "0.6.6", "useragent": "2.1.13", "winston": "2.3.1" } }

KashGit commented 7 years ago

.npmrc registry:path save-exact=true

KashGit commented 7 years ago

.eslintrc { "ecmaFeatures": { "jsx": true, "modules": true }, "env": { "browser": true, "node": true }, "extends": "airbnb", "parser": "babel-eslint", "rules": { "no-use-before-define": ["error", { "functions": false, "classes": false }], "class-methods-use-this": [0], "comma-dangle": [2, "never"], "indent": [2, 4, { "SwitchCase": 1 }], "jsx-a11y/no-static-element-interactions": [0], "jsx-a11y/tabindex-no-positive": [0], "max-len": [1, 150], "no-console": [0], "arrow-body-style": ["error", "as-needed"], "no-param-reassign": [0], "no-underscore-dangle": [0], "import/no-named-as-default": [0], "new-cap": [0], "no-shadow": [0], "react/jsx-no-target-blank": [0], "react/jsx-closing-bracket-location": [2, "after-props"], "react/forbid-prop-types": [0], "react/no-danger": [0], "react/jsx-indent": [0], "react/jsx-indent-props": [0], "react/jsx-no-bind": [2, { "ignoreRefs": true, "allowArrowFunctions": true, "allowBind": true }], "react/jsx-first-prop-new-line": [0], "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }] }, "plugins": [ "babel", "react" ] }

KashGit commented 7 years ago

.editorconfig root = true

[*] charset = utf-8 indent_size = 4 indent_style = space insert_final_newline = true trim_trailing_whitespace = true

[*.md] trim_trailing_whitespace = false

[{.eslintrc,package.json}]

The indent size used in the package.json file cannot be changed

https://github.com/npm/npm/pull/3180#issuecomment-16336516

indent_size = 2 indent_style = space max_line_length = 150

KashGit commented 7 years ago

.babelrc { "presets": [ ["es2015", { "es2015": { "loose": true, "modules": false } }], "react" ], "plugins": [ "transform-object-assign", "transform-object-rest-spread", "transform-runtime" ], "env": { "production": { "plugins": [ "transform-react-remove-prop-types", "transform-react-constant-elements" ] } } }

KashGit commented 7 years ago

webpack Folder

KashGit commented 7 years ago

status-webpack-plugin.js const webpack = require('webpack');

module.exports = function(name, doneMessage){

return new webpack.ProgressPlugin(function(percentage, message) {
  var MOVE_LEFT = new Buffer('1b5b3130303044', 'hex').toString();
  var CLEAR_LINE = new Buffer('1b5b304b', 'hex').toString();
  process.stdout.write(CLEAR_LINE + 'webpack compiling ['+name+']: ' + Math.round(percentage * 100) + '%: ' + message + MOVE_LEFT);
  if(percentage == 1){
      setTimeout(function(){
        process.stdout.write(doneMessage || "webpack say good, fire up...\n");
      },0);
  }
});

}

KashGit commented 7 years ago

uglifyjs.json { "compress": { "warnings": false, "screw_ie8": true, "sequences": true, "dead_code": true, "drop_debugger": true, "comparisons": true, "conditionals": true, "evaluate": true, "booleans": true, "loops": true, "unused": true, "hoist_funs": true, "if_return": true, "join_vars": true, "cascade": true, "drop_console": true }, "output": { "comments": false } }

KashGit commented 7 years ago

web-pack-dev-server.js import webpack from 'webpack'; import DevServer from 'webpack-dev-server'; import config from './webpack.client.babel';

const { port, host } = config.devServer;

const devServer = new DevServer(webpack(config), config.devServer) .listen(port, () => { console.log(HMR server on ${host}:${port} [${process.env.NODE_ENV}]); });

KashGit commented 7 years ago

webpack-client.babel.js

const IS_DEV = require('../src/server/utils/isDev'); const path = require('path'); const webpack = require('webpack'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const WebpackAssetsManifest = require('webpack-assets-manifest'); const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); const StatusWebpackPlugin = require('./status-webpack-plugin'); const config = require('config'); const fs = require('fs');

const basePath = config.basePath; const hash = IS_DEV ? '[name]' : '[name]-[chunkhash]'; const root = process.cwd(); const styleLoaders = ['css-loader?minimize&sourceMap&importLoaders=5', 'postcss-loader', 'sass-loader?sourceMap']; const prefetches = ['react', 'redux']; const port = 8081; const host = 'http://localhost'; const contentBase = ${host}:${port}; const publicPath = IS_DEV ? ${contentBase}${basePath}/assets/ : ${basePath}/assets/; let babelrc = JSON.parse(fs.readFileSync(path.join(root, '.babelrc'), 'utf8'));

var plugins = [ new webpack.IgnorePlugin(/\/server\//), new WebpackAssetsManifest({ output: path.join(root, '/build/assets', 'asset-manifest.json'), writeToDisk: true }), new CaseSensitivePathsPlugin(), new CleanWebpackPlugin(['build/assets'], { 'root': path.join(__dirname, '../'), 'verbose': false }), new webpack.DefinePlugin({ 'IS_BROWSER': true, 'IS_DEV': IS_DEV, 'process.env.NODE_ENV': JSON.stringify(IS_DEV ? 'development' : 'production'), 'process.env.NODE_APP_INSTANCE': JSON.stringify(process.env.NODE_APP_INSTANCE) }), ...prefetches.map((i) => new webpack.PrefetchPlugin(i)), ...(IS_DEV ? [ new webpack.HotModuleReplacementPlugin(), new webpack.SourceMapDevToolPlugin({filename: "[file].map", append: \n//# sourceMappingURL=${basePath}/assets/[url], exclude: ["vendors.js"]}), new StatusWebpackPlugin('client') ] : [ new webpack.ContextReplacementPlugin(/.$/, /NEVER_MATCH^/), // ignore dynamic reqires new webpack.optimize.OccurrenceOrderPlugin(), new webpack.optimize.AggressiveMergingPlugin(), new ExtractTextPlugin({filename: public/${hash}.css, disable: false, allChunks: true}), new webpack.optimize.UglifyJsPlugin(require('./uglifyjs.json')) ]), // new OfflinePlugin({publicPath:${basePath}/assets/, relativePaths: false, caches: {main: ["GuardianSans-Thin-Web.woff"]}, safeToUseOptionalCaches: true, AppCache: false }) ];

module.exports = { devServer: { host, port, proxy: { "*": ${host}:${port} }, quiet: true, noInfo: true, hot: true, inline: true, lazy: false, publicPath, headers: { 'Access-Control-Allow-Origin': '' }, stats: { colors: true } }, context: path.join(root, 'src'), entry: { main: IS_DEV ? ["webpack/hot/dev-server", webpack-dev-server/client?${contentBase}, './client/js/index.js', './client/scss/index.scss'] : [ './client/js/index.js', './client/scss/index.scss' ], criticalpath: ['./client/scss/blur.scss', './client/scss/loaders.scss', './client/scss/fonts.scss'] }, output: { path: path.join(root, '/build/assets'), publicPath, // needed so fonts can be found filename: hash + '.js', chunkFilename: hash + '.js' }, externals: { 'window.newrelic': 'newrelic' }, plugins: plugins, module: { rules: [ { test: /.js$/, loader: 'babel-loader', include: path.join(root, 'src'), options: { cacheDirectory: false, babelrc: false, ...(IS_DEV) ? Object.assign({}, babelrc, { presets: [].concat(babelrc.presets, ['react-hmre']) }) : babelrc } }, { test: /.json$/, loader: 'json-loader' }, { test: /.(jpe?g|png|gif)([\?]?.)$/, include: [path.join(root, 'src/client')], use: ['url-loader?limit=100', 'image-webpack-loader?bypassOnDebug&optimizationLevel=7&interlaced=false'], }, { test: /.(woff|woff2|eot|ttf|svg)([?]?.)$/, use: 'file-loader?name=[name].[ext]', //name fonts to enable de-dup shared header/footer fonts }, { test: /.s?css$/, include: [ path.join(root, 'src/client'), path.resolve(root, 'node_modules') ], loader: IS_DEV ? 'style-loader!' + styleLoaders.join('!') : ExtractTextPlugin.extract({fallback: 'style-loader', use: styleLoaders}) } ] } };

KashGit commented 7 years ago

Test Folder

KashGit commented 7 years ago

env_setup.js

import { jsdom } from 'jsdom';

let exposedProperties = ['window', 'navigator', 'document'];

global.document = jsdom(''); global.window = document.defaultView; Object.keys(document.defaultView).forEach((property) => { if (typeof global[property] === 'undefined') { exposedProperties.push(property); global[property] = document.defaultView[property]; } });

global.navigator = { userAgent: 'node.js' };

KashGit commented 7 years ago

mocha.opts test/*/.test.js --require test/env_setup.js --recursive --timeout 30000 --reporter spec --compilers js:babel-register

KashGit commented 7 years ago

Client Folder

KashGit commented 7 years ago

components->groupDettail Folder

KashGit commented 7 years ago

group.test.js

import React from 'react'; import { expect } from 'chai'; import { shallow, mount, render } from 'enzyme'; import { GroupDetail } from './../../../../src/client/js/components/GroupDetail';

import { mockState } from './../mock/mock-state';

describe('', function () { it('Should render', () => { const groups = shallow(); expect(groups.html().length).to.be.greaterThan(1); }); });

KashGit commented 7 years ago

server Folder app.test.js

import request from 'supertest'; import { expect } from 'chai'; import { Router } from 'express'; import proxyquire from 'proxyquire';

let fake = new Router(); fake.use(function (req, res) { res.json({}); });

let app = proxyquire .noCallThru() .load('../../src/server/app', { './routes/health': fake, './routes/info': fake, './routes/root': fake, './routes/api/frsummary': fake, }).default;

describe('test the main application', function() {

// it('should be registered for a health route', function (done) {
//     request(app)
//         .get('/summary/health')
//         .expect('Content-Type', /json/)
//         .expect(200)
//         .end(function (err, res) {
//             if (err) {
//                 return done(err);
//             }
//             expect(res.body).to.deep.equal({});
//             done();
//         });
// });
//
// it('should be registered for a info route', function (done) {
//     request(app)
//         .get('/summary/info')
//         .expect('Content-Type', /json/)
//         .expect(200)
//         .end(function (err, res) {
//             if (err) {
//                 return done(err);
//             }
//             expect(res.body).to.deep.equal({});
//             done();
//         });
// });
//
// it('should be registered for a spending route', function (done) {
//     request(app)
//         .get('/summary/api/spending')
//         .expect('Content-Type', /json/)
//         .expect(200)
//         .end(function (err, res) {
//             if (err) {
//                 return done(err);
//             }
//             expect(res.body).to.deep.equal({});
//             done();
//         });
// });
//
// it('should be registered for a networth route', function (done) {
//     request(app)
//         .get('/summary/api/networth')
//         .expect('Content-Type', /json/)
//         .expect(200)
//         .end(function (err, res) {
//             if (err) {
//                 return done(err);
//             }
//             expect(res.body).to.deep.equal({});
//             done();
//         });
// });
//
// it('should be registered for a frsummary route', function (done) {
//     request(app)
//         .get('/summary/api/frsummary')
//         .expect('Content-Type', /json/)
//         .expect(200)
//         .end(function (err, res) {
//             if (err) {
//                 return done(err);
//             }
//             expect(res.body).to.deep.equal({});
//             done();
//         });
// });
//
// it('should be registered for a accounts route', function (done) {
//     request(app)
//         .get('/summary/api/accounts')
//         .expect('Content-Type', /json/)
//         .expect(200)
//         .end(function (err, res) {
//             if (err) {
//                 return done(err);
//             }
//             expect(res.body).to.deep.equal({});
//             done();
//         });
// });

// it('should be registered to handle 404', function (done) {
//     request(app)
//         .get('/summary/api/junk')
//         .expect('Content-Type', /json/)
//         .expect(404)
//         .end(function (err, res) {
//             if (err) {
//                 return done(err);
//             }
//             done();
//         });
// });

});

KashGit commented 7 years ago

test file: import React from 'react'; import { expect } from 'chai'; import { shallow, mount, render } from 'enzyme'; import ULife from './../../../../src/client/js/components/groupDetail/ULife'; import SortHeader from './../../../../src/client/js/components/SortHeader'; import { mockState } from './../mock/mock-state';

const mockGroupData = mockState.accounts; const ulife = shallow();

describe('', function () { it('Should render when it has data', () => { expect(ulife.find('table').length).to.be.equal(1); });

it('Should not render when it doesnt have data', () => {
    const ulife = shallow(<ULife ulifeData={[]} />);
    expect(ulife.find('table').length).to.be.equal(0);
});

it('Should have 8 policy numbers in group details', () => {
    expect(ulife.find('ChildRow').length).to.be.equal(8);
});

it('Should display the Ulife group details', () => {
    const tableRows = ulife.find('.solo-row');
    tableRows.forEach((row, index) => {
        const rowData = row.find('td');
        const groupPolicy = mockGroupData[index];
        const expectedgroupPolicyData = [
            `${groupPolicy.clientName}`,
            `${groupPolicy.accountNumberMasked}`,
            `${groupPolicy.policyDate}`,
            `${groupPolicy.netDeathBenefit}`,
            `${groupPolicy.contractFundValue}`,
            `${groupPolicy.netCashSurrenderValue}`,
            `${groupPolicy.netCostBasisValue}`];
        rowData.forEach((column, index) => {
            expect(column.text().trim()).to.be.equal(expectedgroupPolicyData[index]);
        });
    });
});
it('Should display the Ulife group details header', () => {
    const tableRows = ulife.find('.group-table');
    tableRows.forEach((row) => {
        const rowData = row.find('th');
        const expectedgroupDetailHeader = [
            'Policy Number',
            'Policy Date',
            'Net Death Benefit',
            'Contract Fund Value',
            'Net Cash Surrender Value',
            'Net Cost Basis'
        ];
        rowData.forEach((column, index) => {
            expect(column.text().trim()).to.be.equal(expectedgroupDetailHeader[index]);
        });
    });
});
it('Should contain SortHeader component', () => {
    expect(ulife.find(SortHeader).length).to.be.equal(1);
});

});

KashGit commented 7 years ago

config folder default.json { "basePath": "/groupdetail", "apikey": "", "assets": "/assets", "domains": { "nmc": "", "nmlvhub": "http://nmapi", "plan": "" }, "nmlvhub": { "groupDetail": "/groupDetails" } }

KashGit commented 7 years ago

Docker folder Dockerfile

BEGIN COMMON

FROM ubuntu:16.04

ENV DEBIAN_FRONTEND=noninteractive \ LANG=en_US.UTF-8 \ TERM=xterm RUN echo "export > /etc/envvars" >> /root/.bashrc && \ echo "export PS1='\e[1;31m]\u@\h:\w\$[\e[0m] '" | tee -a /root/.bashrc /etc/bash.bashrc && \ echo "alias tcurrent='tail /var/log/*/current -f'" | tee -a /root/.bashrc /etc/bash.bashrc

RUN apt-get update RUN apt-get install -y locales && locale-gen en_US en_US.UTF-8

Runit

RUN apt-get install -y --no-install-recommends runit CMD export > /etc/envvars && /usr/sbin/runsvdir-start

Utilities

RUN apt-get install -y --no-install-recommends vim less net-tools inetutils-ping wget curl git telnet nmap socat dnsutils netcat tree htop unzip sudo software-properties-common jq psmisc iproute python ssh rsync

END COMMON

Node

RUN wget -O - http://nodejs.org/dist/v5.8.0/node-v5.8.0-linux-x64.tar.gz | tar xz RUN mv node* node && \ ln -s /node/bin/node /usr/local/bin/node && \ ln -s /node/bin/npm /usr/local/bin/npm ENV NODE_PATH /usr/local/lib/node_modules RUN npm config set loglevel info

Required for PhantomJS

RUN apt-get install -y libfontconfig1

Point to internal npm reqistry to enable internal module installs

ADD .npmrc /app/.npmrc

Install dependencies

ADD package.json /app/package.json RUN cd /app && \ npm install

Build

ADD . /app RUN cd /app && \ npm run build

Test

RUN cd /app && \ npm run test

Add runit services

ADD docker/sv /etc/service

KashGit commented 7 years ago

Server folder

KashGit commented 7 years ago

server.js import app from './app';

const PORT = 8080;

const httpServer = app.listen(PORT, () => { console.log(Micro-App on http://localhost:${PORT} [${app.settings.env}]); });

process.on('SIGTERM', () => { httpServer.close(() => { process.exit(0); }); });

KashGit commented 7 years ago

index.js import './server';

KashGit commented 7 years ago

app.js import 'newrelic'; import compression from 'compression'; import { basePath } from 'config'; import cookieParser from 'cookie-parser'; import express from 'express'; import path from 'path'; import attachRunMiddleware from 'run-middleware'; import { cacheControl, handleErrors, notFound, newrelic } from './middleware'; import groups from './routes/api'; import health from './routes/health'; import root from './routes/root'; import IS_DEV from './utils/isDev';

const app = express();

attachRunMiddleware(app);

app.use(cookieParser()); app.disable('x-powered-by'); app.use(compression()); app.use(newrelic()); app.use(${basePath}/assets, express.static(path.join(dirname, '/../../build/assets'), { maxAge: '365d' })); app.use(${basePath}/whatsnew, express.static(path.join(dirname, '/routes/whatsnew'), { maxAge: '365d' })); app.use(cacheControl());

app.use(${basePath}/health, health);

app.use(${basePath}/api/groupDetails, groups); app.use(${basePath}, root);

if (IS_DEV) { let times = 0;

app.use('/checksession', (req, res) => {
    // simulate checksession scenario in dev
    times === 1 ? //eslint-disable-line
res.status(200).send()
:
times;
    times++;// eslint-disable-line
    res.status(403).send();
});
app.use('/aspping.aspx', (req, res) => {
    res.status(200).send();
});
app.use('/clientinit', (req, res) => {
    res.redirect(302, '/summary');
});
app.use('/whatsnew/frame.js', (req, res) => {
    res.status(200).send();
});

}

// use mock route in non prod env for testing purposes

app.use(notFound()); app.use(handleErrors());

export default app;

KashGit commented 7 years ago

routes folder

KashGit commented 7 years ago

root.js import { Router } from 'express'; import fs from 'fs'; import React from 'react'; import newrelic from 'newrelic'; import { renderToString } from 'react-dom/server';

import Root from '../../client/js/components/Root'; import createStore from '../../client/js/store/createStore';

import AppShell from '../components/AppShell'; import clientConfig from './../utils/clientConfig'; import { getBrowser, getHeaders, getLoginId, getUniqueId, getIdHash } from './../utils/headersUtils'; import getGroupDetails from '../utils/groups'; import IS_DEV from './../utils/isDev';

const router = Router();

let assets; function readSyncAssetManifest() { if (!assets) { const assetManifest = JSON.parse(fs.readFileSync('./build/assets/asset-manifest.json', 'utf8')); assets = { mainJS: assetManifest['main.js'], mainCSS: (IS_DEV) ? null : assetManifest['main.css'], inlineCSS: (IS_DEV) ? null : fs.readFileSync(./build/assets/${assetManifest['criticalpath.css']}, 'utf8') }; } return assets; }

function getMeta(idHash, ua, uniqueId, loginId, groupId) { return { title: 'GroupDetail', idHash, loginId, uniqueId, groupId, ua }; }

router.get('/:groupId', (req, res, next) => { const nreumJS = newrelic.getBrowserTimingHeader(); const idHash = getIdHash(req); const loginId = getLoginId(req); const ua = getBrowser(req); const uniqueId = getUniqueId(req); const assetManifest = readSyncAssetManifest(); const store = createStore({ meta: getMeta(idHash, ua, uniqueId, loginId, req.params.groupId) }); const options = { headers: getHeaders(req) }; Promise.resolve(getGroupDetails(options, req.params.groupId)).then((data) => { Promise.resolve(store.dispatch({ type: 'GROUPS_ACCOUNTS_SUCCESS', payload: data, meta: { receivedAt: Date.now() } })).then(() => { const currentState = store.getState(); const rootHtml = renderToString(); const htmlReponse = AppShell(assetManifest, ua, clientConfig, rootHtml, currentState, nreumJS); res.send(htmlReponse); }); }).catch(err => next(new Error(Error fetching group details\n ${err.stack}))); });

export default router;

KashGit commented 7 years ago

health.js import { Router } from 'express';

const router = Router();

router.get('/', (req, res) => { res.json({ status: 'UP' }); });

export default router;

KashGit commented 7 years ago

api folder

KashGit commented 7 years ago

groups.js import { Router } from 'express'; import { fetchGroupDetail } from '../../models/groupDetail';

const router = Router();

router.get('/:id', (req, res, next) => { fetchGroupDetail(req) .then(data => res.json(data)) .catch(err => next(err)); });

export default router;

KashGit commented 7 years ago

index.js import groups from './groups';

export default groups;

KashGit commented 7 years ago

model folder groupDetail.js

import { domains } from 'config'; import fetch from 'isomorphic-fetch'; import formatAsDollars from '../utils/stringUtils'; import { getHeaders } from './../utils/headersUtils'; import { parseResponse, checkStatus, normalizeJSON } from './../utils/apiUtils';

export function createUrl(req) { return ${domains.nmlvhub}/business/groups/${req.params.id}/accounts; }

export function parseGroupsJSON(json) { return { groupType: json.groupType, groupNumberMasked: json.groupNumberMasked, groupName: json.groupName, accounts: json.accounts.map(account => ({ accountNumber: account.accountNumber, accountNumberMasked: account.accountNumberMasked, clientName: account.clientName, policyDate: account.policyDate, netDeathBenefit:formatAsDollars(account.netDeathBenefit), contractFundValue:formatAsDollars(account.contractFundValue), netCashSurrenderValue:formatAsDollars(account.netCashSurrenderValue), netCostBasisValue:formatAsDollars(account.netCostBasisValue) })) }; }

export function fetchGroupDetail(req) { const headers = getHeaders(req); const url = createUrl(req);

return fetch(url, { headers })
    .then(parseResponse)
    .then(checkStatus)
    .then(normalizeJSON)
    .then(parseGroupsJSON);

}

KashGit commented 7 years ago

mock folder index.js import express from 'express'; import jsonServer from 'json-server'; import groupAccounts from './group-accounts.json';

const PORT = process.env.PORT || 8090; const app = express(); const db = { groupAccounts };

// don't actaully want to save anything here and json server doesn't handle responses of post operations super great // build our routes for this by hand

app.use(jsonServer.defaults());

app.use(jsonServer.rewriter({ '/mock/api/business/groups/:id/accounts': '/mock/api/groupAccounts' }));

app.use('/mock/api', jsonServer.router(db));

const httpServer = app.listen(PORT, () => { console.log(Mock API on http://localhost:${PORT} [${app.settings.env}]); });

process.on('SIGTERM', () => { httpServer.close(() => { process.exit(0); }); });

KashGit commented 7 years ago

group-accounts.json Json object containing data

KashGit commented 7 years ago

middleware folder index.js

export { default as cacheControl } from './cacheControl'; export { default as handleErrors } from './handleErrors'; export { default as newrelic } from './newrelic'; export { default as notFound } from './notFound';

KashGit commented 7 years ago

cacheControl.js export default () => (req, res, next) => { res.header('Cache-Control', 'no-cache, no-store, must-revalidate'); next(); };

KashGit commented 7 years ago

handleErrors.js import newrelic from 'newrelic';

import IS_DEV from './../utils/isDev';

export default () => (err, req, res, next) => { // eslint-disable-line no-unused-vars newrelic.noticeError(err); console.log(err.stack); res.status(500).send((IS_DEV) ? err.stack : 'Internal application error'); };

KashGit commented 7 years ago

notfound.js export default () => (req, res) => { const err = Not found: ${req.originalUrl}; console.log(err); res.status(404).send(err); };

KashGit commented 7 years ago

Utils clientconfig.js import config from 'config';

const createClientConfig = { / basePath: config.basePath, nmcDomain: config.domains.nmc, planDomain: config.domains.plan
};

export default createClientConfig;

isProd.js module.exports = (process.env.NODE_ENV && process.env.NODE_ENV === 'production');

isDev.js module.exports = (process.env.BABEL_ENV && process.env.BABEL_ENV === 'development');

group.js import { basePath, nmlvhub } from 'config'; import makeFetch from '../../client/js/utils/makeFetch';

export default function getGroupDetails(options, groupId) { const url = ${basePath}/api${nmlvhub.groupDetail}/${groupId}; return makeFetch(url, { options }) .catch(error => Promise.reject(new Error(Failed to fetch group details ${error.stack}))); }

apiUtil.js export function parseResponse(response) { return response.json().then(json => ({ json, response }) ); // provide parsed response and original response }

export function checkStatus({ json, response }) { if (!response.ok) { // status in the range 200-299 or not // reject & let catch decide how to handle/throw return Promise.reject(new Error(${response.statusText} ${response.url} || 'Status not OK')); }

return { json, response };

}

export function normalizeJSON({ json }) { return json; }

KashGit commented 7 years ago

components - Folder AppShell.js

/eslint-disable/ import { minify } from 'html-tagged-literals'; import { assetPath } from 'config';

import { name, version } from '../../../package'

const AppShell = ({ mainJS, mainCSS, inlineCSS}, ua, clientConfig, rootHtml, initialState, nreumJS) => { return minify` <!DOCTYPE html>

${initialState.meta.title} ${(ua.chrome) ? ` ${mainCSS ? `` : ''} ` : ` ${mainCSS ? `` : ''} `} ${nreumJS} ${inlineCSS ? `` : ''} ${mainCSS ? `` : ''}
${rootHtml}
`; }; export default AppShell; // //
KashGit commented 7 years ago

src-clinet-js Index.js import React from 'react'; import ReactDom from 'react-dom'; import Root from './components/Root'; import checkSession from './utils/checkSession';

checkSession(() => { const createStore = require('./store/createStore').default; // eslint-disable-line const ensurePolyfills = require('./utils/ensurePolyfills').default; // eslint-disable-line const store = createStore(window.STATE); // eslint-disable-line

if (window.newrelic) {
    window.newrelic.setCustomAttribute('nmUniqueId', window.__STATE__.meta.uniqueId);
}

ReactDom.render(
    <Root store={store} />,
    document.getElementById('root')
);

});