Skip to content

Commit

Permalink
Frontend packages (#4)
Browse files Browse the repository at this point in the history
* Updating the versions and installing the basic packages we'll be using

* Updated the versions

* Configured eslint rules and applied to front-end files

* Added Login check

* Code cleanup. Should no longer pretend you're not logged in after refreshing on the browser

* More code cleanup. Installed BC Sans font. Installed bootstrap
  • Loading branch information
amichard authored and kuanfandevops committed Dec 12, 2019
1 parent 782b70c commit 48cecf7
Show file tree
Hide file tree
Showing 21 changed files with 393 additions and 210 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ build/
package-lock.json
.env
.DS_Store
.vscode/
1 change: 1 addition & 0 deletions frontend/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/generated/**
30 changes: 30 additions & 0 deletions frontend/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = {
env: {
browser: true,
es6: true,
},
extends: [
'plugin:react/recommended',
'airbnb',
],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
},
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
sourceType: 'module',
},
plugins: [
'react',
'@typescript-eslint',
],
rules: {
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"import/no-extraneous-dependencies": ["error", { "devDependencies": true }]
},
};
70 changes: 43 additions & 27 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,68 @@
"version": "0.0.1",
"private": true,
"dependencies": {
"@fortawesome/fontawesome": "^1.1.8",
"@fortawesome/fontawesome-svg-core": "^1.2.25",
"@fortawesome/free-brands-svg-icons": "^5.11.2",
"@fortawesome/free-regular-svg-icons": "^5.11.2",
"@fortawesome/free-solid-svg-icons": "^5.11.2",
"@fortawesome/react-fontawesome": "^0.1.7",
"@hot-loader/react-dom": "^16.9.0",
"@types/react": "^16.9.16",
"classnames": "^2.2.6",
"google-protobuf": "^3.10.0",
"google-protobuf": "^3.11.1",
"grpc-web": "^1.0.7",
"history": "^4.9.0",
"keycloak-js": "^7.0.1",
"history": "^4.10.1",
"keycloak-js": "^8.0.1",
"moment": "^2.24.0",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-hot-loader": "^4.12.11",
"react-keycloak": "^7.0.1-191016",
"react-router": "^5.0.1",
"react-router-dom": "^5.0.1"
"moment-timezone": "^0.5.27",
"prop-types": "^15.7.2",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-hot-loader": "^4.12.18",
"react-keycloak": "^8.0.0-191118",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2"
},
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/plugin-proposal-object-rest-spread": "^7.5.5",
"@babel/polyfill": "^7.4.4",
"@babel/preset-env": "^7.5.5",
"@babel/preset-react": "^7.0.0",
"@babel/core": "^7.7.5",
"@babel/plugin-proposal-object-rest-spread": "^7.7.4",
"@babel/polyfill": "^7.7.0",
"@babel/preset-env": "^7.7.6",
"@babel/preset-react": "^7.7.4",
"@typescript-eslint/eslint-plugin": "^2.11.0",
"@typescript-eslint/parser": "^2.11.0",
"babel-eslint": "^10.0.2",
"babel-jest": "^24.9.0",
"babel-loader": "^8.0.6",
"css-loader": "^3.2.0",
"css-loader": "^3.3.0",
"dotenv": "^8.1.0",
"eslint": "^6.1.0",
"eslint-config-airbnb-standard": "^3.0.1",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jest": "^22.15.1",
"eslint": "^6.7.2",
"eslint-config-airbnb": "^18.0.1",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-jest": "^22.21.0",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-node": "^9.1.0",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.14.3",
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-react-hooks": "^1.7.0",
"eslint-plugin-standard": "^4.0.1",
"file-loader": "^4.2.0",
"file-loader": "^5.0.2",
"html-webpack-plugin": "^3.2.0",
"html-webpack-template": "^6.2.0",
"jest": "^24.9.0",
"mini-css-extract-plugin": "^0.8.0",
"node-sass": "^4.12.0",
"sass-loader": "^7.2.0",
"webpack": "^4.39.2",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.0"
"node-sass": "^4.13.0",
"sass-loader": "^8.0.0",
"typescript": "^3.7.3",
"url-loader": "^3.0.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0",
"webpack-subresource-integrity": "^1.3.4"
},
"scripts": {
"prepare": "eslint src",
"start": "node start",
"dist": "webpack --production",
"test": "jest --coverage"
Expand Down
Binary file added frontend/src/.DS_Store
Binary file not shown.
Binary file added frontend/src/app/.DS_Store
Binary file not shown.
38 changes: 38 additions & 0 deletions frontend/src/app/Login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import CONFIG from './config';

const Login = () => {
let url = `${CONFIG.KEYCLOAK.URL}/realms/${CONFIG.KEYCLOAK.REALM}`;
url += '/protocol/openid-connect/auth?response_type=token';
url += `&client_id=${CONFIG.KEYCLOAK.CLIENT_ID}`;
url += `&redirect_uri=${window.location.href}`;

return (
<div id="login">
<div id="header">
<div id="header-wrapper" className="login-zeva-page-header-text">Zero Emission Vehicle Reporting System</div>
</div>
<div className="login-zeva-page">
<div className="login-zeva-brand" />
<div className="card-zeva">
<div className="buttons-section">
<div className="oidc">
<a href={`${url}&kc_idp_hint=bceid`} id="link-bceid" className="oidc">
<span className="text"> Login with </span>
<span className="display-name"> BCeID </span>
</a>
</div>
<div className="oidc">
<a href={`${url}&kc_idp_hint=idir`} id="link-idir" className="oidc">
<span className="text">Login with</span>
<span className="display-name"> IDIR </span>
</a>
</div>
</div>
</div>
</div>
</div>
);
};

export default Login;
73 changes: 48 additions & 25 deletions frontend/src/app/PageLayout.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,55 @@
import React, {Component} from 'react';
import {hot} from 'react-hot-loader/root';
import './css/App.scss';
import {withRouter} from "react-router";
import {withKeycloak} from "react-keycloak";
import React from 'react';
import { hot } from 'react-hot-loader/root';
import { withRouter } from 'react-router';
import PropTypes from 'prop-types';

class PageLayout extends Component {
const PageLayout = (props) => {
const { children, keycloak } = props;

render() {
return (
<div>
{this.props.keycloak.authenticated && <>
<span>Authenticated</span>
<strong>Authenticated</strong>
Active Roles
return (
<div>
{keycloak.authenticated && (
<div>
<strong>Authenticated</strong>
<ul>
{this.props.keycloak.realmAccess.roles.map(role => (<li>{role}</li>))}
{keycloak.realmAccess.roles.map((role) => (
<li>{role}</li>
))}
</ul>
</>
}
{this.props.keycloak.authenticated || <div>
</div>
)}
{keycloak.authenticated || (
<div>
<span>Not Authenticated</span>
<button onClick={() => this.props.keycloak.login()}>Login</button>
</div>}
{this.props.children}
</div>
);
}
}
<button
onClick={() => keycloak.login()}
type="button"
>
Login
</button>
</div>
)}
{children}
</div>
);
};

PageLayout.defaultProps = {
children: [],
};

export default hot(withRouter(withKeycloak(PageLayout)));
PageLayout.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]),
keycloak: PropTypes.shape({
authenticated: PropTypes.bool,
login: PropTypes.func,
realmAccess: PropTypes.shape({
roles: PropTypes.arrayOf(PropTypes.string),
}),
}).isRequired,
};

export default hot(withRouter(PageLayout));
59 changes: 44 additions & 15 deletions frontend/src/app/app.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,49 @@
import React, { Component } from 'react';
import Keycloak from 'keycloak-js';
import {KeycloakProvider} from 'react-keycloak';
import Router from "./router";
import React from "react";

// Setup Keycloak instance as needed
const keycloak = new Keycloak({
url: 'http://localhost:8888/auth',
realm: 'zeva',
clientId: 'zeva-app'

import CONFIG from './config';
import Login from './Login';
import Router from './router';

class App extends Component {
constructor(props) {
super(props);
this.state = {
authenticated: false,
keycloak: null,
};
}

componentDidMount() {
const keycloak = Keycloak({
clientId: CONFIG.KEYCLOAK.CLIENT_ID,
realm: CONFIG.KEYCLOAK.REALM,
url: CONFIG.KEYCLOAK.URL,
});

keycloak.init({ onLoad: 'check-sso', checkLoginIframe: false, promiseType: 'native' }).then((authenticated) => {
this.setState({
keycloak,
authenticated,
});
});
}
);

const App = () => (
<KeycloakProvider keycloak={keycloak} initConfig={{promiseType: 'native'}}>
<Router/>
</KeycloakProvider>
);
render() {
const { authenticated, keycloak } = this.state;

if (!keycloak) {
return <div>Loading...</div>;
}

if (keycloak && !authenticated) {
return <Login />;
}

return (
<Router keycloak={keycloak} />
);
}
}

export default App;
Loading

0 comments on commit 48cecf7

Please sign in to comment.