mirror of
https://github.com/Telecominfraproject/wlan-cloud-ui.git
synced 2025-10-29 09:52:36 +00:00
TW-166 Login Done
This commit is contained in:
29
LICENSE
Normal file
29
LICENSE
Normal file
@@ -0,0 +1,29 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2020, Telecom Infra Project
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
20
README.md
20
README.md
@@ -1,19 +1,23 @@
|
||||
# TIP WLAN Cloud Portal
|
||||
|
||||
## Set up environment:
|
||||
|
||||
Install Dependencies
|
||||
`npm install`
|
||||
|
||||
To link cu-ui package locally for development:
|
||||
`npm link ../cu-ui`
|
||||
Install Dependencies
|
||||
`npm install`
|
||||
|
||||
To link wlan-cloud-ui-library package locally for development:
|
||||
`npm link ../wlan-cloud-ui-library`
|
||||
|
||||
## Run:
|
||||
### Development
|
||||
|
||||
### Development
|
||||
|
||||
`npm start`
|
||||
|
||||
### Tests
|
||||
### Tests
|
||||
|
||||
`npm run test`
|
||||
|
||||
### Production
|
||||
### Production
|
||||
|
||||
`npm run build`
|
||||
|
||||
@@ -3,9 +3,10 @@ import T from 'prop-types';
|
||||
import { Route, Redirect } from 'react-router-dom';
|
||||
|
||||
import MasterLayout from 'containers/MasterLayout';
|
||||
import { getItem } from 'utils/localStorage';
|
||||
import { AUTH_TOKEN } from 'constants/index';
|
||||
|
||||
import { getItem } from 'utils/localStorage';
|
||||
|
||||
const ProtectedRouteWithLayout = ({ component: Component, ...rest }) => (
|
||||
<Route
|
||||
{...rest}
|
||||
|
||||
@@ -2,11 +2,13 @@ import React from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
|
||||
import { ThemeProvider, Login, Dashboard } from 'cu-ui';
|
||||
import { ThemeProvider, Dashboard } from 'wlan-cloud-ui-library';
|
||||
|
||||
import logo from 'images/logo-light.png';
|
||||
import logoMobile from 'images/logoxmobile.jpg';
|
||||
|
||||
import Login from 'containers/Login';
|
||||
|
||||
import ProtectedRouteWithLayout from './components/ProtectedRouteWithLayout';
|
||||
|
||||
const App = () => (
|
||||
|
||||
33
app/containers/Login/index.js
Normal file
33
app/containers/Login/index.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import React from 'react';
|
||||
import gql from 'graphql-tag';
|
||||
import { useMutation, useApolloClient } from '@apollo/react-hooks';
|
||||
|
||||
import { Login as LoginPage } from 'wlan-cloud-ui-library';
|
||||
|
||||
import { AUTH_TOKEN } from 'constants/index';
|
||||
|
||||
import { setItem } from 'utils/localStorage';
|
||||
|
||||
const AUTHENTICATE_USER = gql`
|
||||
mutation AuthenticateUser($email: String!, $password: String!) {
|
||||
authenticateUser(email: $email, password: $password) {
|
||||
token
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const Login = () => {
|
||||
const client = useApolloClient();
|
||||
const [authenticateUser] = useMutation(AUTHENTICATE_USER);
|
||||
|
||||
const handleLogin = (email, password) => {
|
||||
authenticateUser({ variables: { email, password } }).then(({ data }) => {
|
||||
client.resetStore();
|
||||
setItem(AUTH_TOKEN, data.authenticateUser.token, data.authenticateUser.token.expires_in);
|
||||
});
|
||||
};
|
||||
|
||||
return <LoginPage onLogin={handleLogin} />;
|
||||
};
|
||||
|
||||
export default Login;
|
||||
@@ -1,13 +1,25 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useApolloClient } from '@apollo/react-hooks';
|
||||
|
||||
import { AppLayout as Layout } from 'cu-ui';
|
||||
import { AppLayout as Layout } from 'wlan-cloud-ui-library';
|
||||
|
||||
import { AUTH_TOKEN } from 'constants/index';
|
||||
|
||||
import { removeItem } from 'utils/localStorage';
|
||||
|
||||
const MasterLayout = ({ children }) => {
|
||||
const client = useApolloClient();
|
||||
const location = useLocation();
|
||||
|
||||
const handleLogout = () => {
|
||||
removeItem(AUTH_TOKEN);
|
||||
client.resetStore();
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout onLogout={() => {}} locationState={location}>
|
||||
<Layout onLogout={handleLogout} locationState={location}>
|
||||
{children}
|
||||
</Layout>
|
||||
);
|
||||
|
||||
53
app/index.js
53
app/index.js
@@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import ApolloClient from 'apollo-boost';
|
||||
import { ApolloProvider } from '@apollo/react-hooks';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import 'styles/antd.less';
|
||||
import 'styles/index.scss';
|
||||
@@ -10,27 +11,65 @@ import 'styles/index.scss';
|
||||
import App from 'containers/App';
|
||||
import { AUTH_TOKEN } from 'constants/index';
|
||||
|
||||
import { getItem } from 'utils/localStorage';
|
||||
|
||||
const MOUNT_NODE = document.getElementById('root');
|
||||
|
||||
const REFRESH_TOKEN = gql`
|
||||
mutation UpdateToken($refreshToken: String!) {
|
||||
updateToken(refreshToken: $refreshToken) {
|
||||
token
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const client = new ApolloClient({
|
||||
// uri: ""
|
||||
uri: 'http://localhost:4000/',
|
||||
request: operation => {
|
||||
const token = localStorage.getItem(AUTH_TOKEN);
|
||||
const token = getItem(AUTH_TOKEN);
|
||||
operation.setContext({
|
||||
headers: {
|
||||
authorization: token ? `Bearer ${token}` : '',
|
||||
authorization: token ? `Bearer ${token.access_token}` : '',
|
||||
},
|
||||
});
|
||||
},
|
||||
onError: ({ graphQLErrors, operation, forward }) => {
|
||||
if (graphQLErrors) {
|
||||
graphQLErrors.forEach(err => {
|
||||
// handle errors differently based on its error code
|
||||
switch (err.extensions.code) {
|
||||
case 'UNAUTHENTICATED':
|
||||
operation.setContext({
|
||||
headers: {
|
||||
...operation.getContext().headers,
|
||||
authorization: client
|
||||
.mutate({
|
||||
mutation: REFRESH_TOKEN,
|
||||
variables: {
|
||||
refreshToken: getItem(AUTH_TOKEN).refresh_token,
|
||||
},
|
||||
})
|
||||
.then(data => {
|
||||
return data.updateToken.token;
|
||||
}),
|
||||
},
|
||||
});
|
||||
return forward(operation);
|
||||
default:
|
||||
return forward(operation);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const render = () => {
|
||||
ReactDOM.render(
|
||||
<ApolloProvider client={client}>
|
||||
<Router>
|
||||
<Router>
|
||||
<ApolloProvider client={client}>
|
||||
<App />
|
||||
</Router>
|
||||
</ApolloProvider>,
|
||||
</ApolloProvider>
|
||||
</Router>,
|
||||
MOUNT_NODE
|
||||
);
|
||||
};
|
||||
|
||||
@@ -22,17 +22,15 @@ export const removeItem = key => {
|
||||
};
|
||||
|
||||
export const getItem = key => {
|
||||
let value;
|
||||
let value = null;
|
||||
try {
|
||||
value = JSON.parse(window.localStorage.getItem(key) || '{}');
|
||||
value = JSON.parse(window.localStorage.getItem(key));
|
||||
} catch (err) {
|
||||
removeItem();
|
||||
|
||||
return {};
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isItemExpired(value)) {
|
||||
return removeItem();
|
||||
return removeItem(key);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
75
package-lock.json
generated
75
package-lock.json
generated
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "cu-portal",
|
||||
"name": "wlan-cloud-ui",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
@@ -49,6 +49,63 @@
|
||||
"tslib": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"@apollo/react-components": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/react-components/-/react-components-3.1.4.tgz",
|
||||
"integrity": "sha512-dLZFeJ+x48nPuo2BjFjfbl8afQyazoqU8xBTidMnYy99w9DcTHtnURTw18o2dT5jkfuIJEWjbTfxyjJnHk+clw==",
|
||||
"requires": {
|
||||
"@apollo/react-common": "^3.1.4",
|
||||
"@apollo/react-hooks": "^3.1.4",
|
||||
"prop-types": "^15.7.2",
|
||||
"ts-invariant": "^0.4.4",
|
||||
"tslib": "^1.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/react-common": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/react-common/-/react-common-3.1.4.tgz",
|
||||
"integrity": "sha512-X5Kyro73bthWSCBJUC5XYQqMnG0dLWuDZmVkzog9dynovhfiVCV4kPSdgSIkqnb++cwCzOVuQ4rDKVwo2XRzQA==",
|
||||
"requires": {
|
||||
"ts-invariant": "^0.4.4",
|
||||
"tslib": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"@apollo/react-hooks": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/react-hooks/-/react-hooks-3.1.4.tgz",
|
||||
"integrity": "sha512-yamD5a1Gu9fGQjZYEQn2nSG+BRyde4dy055agtYOvP/5/njJBSJ25tRFbjxKf7+YW9fsu2Xguib3anoQTuesNg==",
|
||||
"requires": {
|
||||
"@apollo/react-common": "^3.1.4",
|
||||
"@wry/equality": "^0.1.9",
|
||||
"ts-invariant": "^0.4.4",
|
||||
"tslib": "^1.10.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@apollo/react-hoc": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/react-hoc/-/react-hoc-3.1.4.tgz",
|
||||
"integrity": "sha512-dCzVM2/JzEWqwTocwozb9/msOgVY5EG7gh593IIXYcBfHcthSK21nIsbH/uDgwCcLSIZE2EOC3n0aKgDuoMtjA==",
|
||||
"requires": {
|
||||
"@apollo/react-common": "^3.1.4",
|
||||
"@apollo/react-components": "^3.1.4",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"ts-invariant": "^0.4.4",
|
||||
"tslib": "^1.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/react-common": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/react-common/-/react-common-3.1.4.tgz",
|
||||
"integrity": "sha512-X5Kyro73bthWSCBJUC5XYQqMnG0dLWuDZmVkzog9dynovhfiVCV4kPSdgSIkqnb++cwCzOVuQ4rDKVwo2XRzQA==",
|
||||
"requires": {
|
||||
"ts-invariant": "^0.4.4",
|
||||
"tslib": "^1.10.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@apollo/react-hooks": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/react-hooks/-/react-hooks-3.1.3.tgz",
|
||||
@@ -3650,10 +3707,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"cu-ui": {
|
||||
"version": "git+https://sean_macfarlane@bitbucket.org/connectustechnologies/connectus-wlan-ui-workspace.git#c7be790677869070cb390411bdd4ba453e788606",
|
||||
"from": "git+https://sean_macfarlane@bitbucket.org/connectustechnologies/connectus-wlan-ui-workspace.git"
|
||||
},
|
||||
"currently-unhandled": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
|
||||
@@ -6097,6 +6150,14 @@
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"requires": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"home-or-tmp": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
|
||||
@@ -13562,6 +13623,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"wlan-cloud-ui-library": {
|
||||
"version": "git+ssh://git@github.com/Telecominfraproject/wlan-cloud-ui-library.git#abbb7f2c8eaaeec30662331c0aed190be66c0de6",
|
||||
"from": "git+ssh://git@github.com/Telecominfraproject/wlan-cloud-ui-library.git"
|
||||
},
|
||||
"word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "cu-portal",
|
||||
"name": "wlan-cloud-ui",
|
||||
"version": "0.1.0",
|
||||
"author": "ConnectUs",
|
||||
"description": "",
|
||||
"description": "React Portal",
|
||||
"engines": {
|
||||
"npm": ">=5",
|
||||
"node": ">=8"
|
||||
@@ -17,12 +17,14 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.0.2",
|
||||
"@apollo/react-hoc": "^3.1.4",
|
||||
"@apollo/react-hooks": "^3.1.3",
|
||||
"antd": "^4.0.2",
|
||||
"apollo-boost": "^0.4.7",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"cu-ui": "git+https://sean_macfarlane@bitbucket.org/connectustechnologies/connectus-wlan-ui-workspace.git",
|
||||
"wlan-cloud-ui-library": "git+ssh://git@github.com/Telecominfraproject/wlan-cloud-ui-library.git",
|
||||
"graphql": "^14.6.0",
|
||||
"graphql-tag": "^2.10.3",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||
|
||||
@@ -43,12 +43,19 @@ module.exports = {
|
||||
modules: [
|
||||
'node_modules',
|
||||
'app',
|
||||
path.resolve(__dirname, '../', 'node_modules', 'cu-ui', 'src'),
|
||||
path.resolve(__dirname, '../', 'node_modules', 'wlan-cloud-ui-library', 'src'),
|
||||
],
|
||||
alias: {
|
||||
app: path.resolve(__dirname, '../', 'app'),
|
||||
react: path.resolve(__dirname, '../', 'node_modules', 'react'),
|
||||
'cu-ui': path.resolve(__dirname, '../', 'node_modules', 'cu-ui', 'src'),
|
||||
'react-router-dom': path.resolve('./node_modules/react-router-dom'),
|
||||
'wlan-cloud-ui-library': path.resolve(
|
||||
__dirname,
|
||||
'../',
|
||||
'node_modules',
|
||||
'wlan-cloud-ui-library',
|
||||
'src'
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user