diff --git a/README.md b/README.md
index cc5679b..86a087e 100644
--- a/README.md
+++ b/README.md
@@ -24,16 +24,24 @@ Documentation for the project is hosted [here](https://osp-web-docs.surge.sh/).
**Note:** Before setting up the frontend make sure to have Setup the [Backend Repo](https://github.com/anitab-org/open-source-programs-backend).
-1. To start the server:
+1. Create a `.env` file in the project root directory and add **Client ID** and **Callback URL** of GitHub App like this:
+
+```
+REACT_APP_GITHUB_CLIENT_ID=< GitHub App Client ID >
+REACT_APP_GITHUB_CALLBACK_URL=< GitHub App Callback URL >
+```
+
+To get **Client ID** and **Callback URL** of GitHub App follow [this docs](https://docs.github.com/en/developers/apps/creating-a-github-app).
+
+2. To start the server:
```
-cd open-source-programs-web
npm install
npm start
```
-2. Navigate to `http://localhost:3000/` in your browser.
-3. You can terminate the process by `Ctrl+C` in your terminal.
+3. Navigate to `http://localhost:3000/` in your browser.
+4. You can terminate the process by `Ctrl+C` in your terminal.
## Contributing
diff --git a/package.json b/package.json
index 0824938..2fe4589 100644
--- a/package.json
+++ b/package.json
@@ -7,16 +7,18 @@
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"aws-sdk": "^2.734.0",
- "axios": "^0.19.2",
+ "axios": "^0.21.1",
"dotenv": "^8.2.0",
+ "github-login": "^1.0.12",
"moment": "^2.27.0",
"prop-types": "^15.7.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
+ "react-github-login": "^1.0.3",
"react-redux": "^7.2.0",
"react-router-dom": "^5.2.0",
"react-router-redux": "^4.0.8",
- "react-scripts": "3.4.1",
+ "react-scripts": "^4.0.3",
"redux": "^4.0.5",
"redux-api-middleware": "^3.2.1",
"redux-persist": "^6.0.0",
diff --git a/src/actions/login.js b/src/actions/login.js
index c2edb5c..b2e6e36 100644
--- a/src/actions/login.js
+++ b/src/actions/login.js
@@ -1,5 +1,5 @@
import axios from 'axios';
-import { urlLogin, urlRegister } from '../urls';
+import { urlLogin, urlRegister, urlGithubLogin } from '../urls';
import { LOGIN, REGISTER, LOGIN_ERRORS, REGISTER_ERRORS } from './types';
export const postLogin = (data, callback) => async (dispatch) => {
@@ -48,3 +48,27 @@ export const postRegister = (data, callback) => async (dispatch) => {
callback();
}
};
+
+export const postGithubCode = (data, callback) => async (dispatch) => {
+ try {
+ const config = {
+ headers: {
+ 'content-type': 'application/json',
+ },
+ };
+ const res = await axios.post(urlGithubLogin(), data, config);
+ dispatch({
+ type: LOGIN,
+ payload: res.data,
+ });
+
+ localStorage.setItem('token', res.data.access_token);
+ callback();
+ } catch (err) {
+ dispatch({
+ type: LOGIN_ERRORS,
+ payload: err.response,
+ });
+ callback();
+ }
+};
diff --git a/src/components/GitHubAuth.js b/src/components/GitHubAuth.js
new file mode 100644
index 0000000..8627799
--- /dev/null
+++ b/src/components/GitHubAuth.js
@@ -0,0 +1,131 @@
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import PropTypes from 'prop-types';
+import GitHubLogin from 'react-github-login';
+import { postGithubCode } from '../actions/login';
+import { withRouter } from 'react-router';
+import { Icon, Message } from 'semantic-ui-react';
+
+class GitHubAuth extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ code: '',
+ error: null,
+ posted: false,
+ errorText: '',
+ };
+ this.postCode = this.postCode.bind(this);
+ this.GithubError = this.GithubError.bind(this);
+ }
+
+ postCode = (response) => {
+ console.log(response.code);
+ this.setState({
+ code: response.code,
+ });
+ const data = {
+ code: this.state.code,
+ };
+ this.props.postGithubCode(data, this.callback);
+ this.setState({
+ code: '',
+ });
+ };
+
+ callback = () => {
+ this.setState({
+ error: this.props.loginerror ? true : false,
+ posted: true,
+ errorText: 'Server Error: try again.',
+ });
+ console.log(this.state.error, this.state.posted);
+ if (!this.state.error) {
+ this.props.history.push('/');
+ }
+ setTimeout(() => {
+ this.setState({
+ error: false,
+ posted: false,
+ });
+ }, 4000);
+ };
+
+ icon = () => {
+ return (
+
+ Log in with GitHub
+
+ );
+ };
+
+ GithubError = (response) => {
+ console.log(response);
+ this.setState({
+ error: true,
+ posted: true,
+ errorText: 'GitHub API Error.',
+ });
+ setTimeout(() => {
+ this.setState({
+ error: false,
+ posted: false,
+ });
+ }, 4000);
+ };
+
+ UNSAFE_componentWillMount() {
+ this.setState({
+ code: '',
+ error: null,
+ posted: false,
+ errorText: '',
+ });
+ }
+
+ componentWillUnmount() {
+ // eslint-disable-next-line
+ this.setState = (state, callback) => {
+ return;
+ };
+ }
+
+ render() {
+ const {
+ REACT_APP_GITHUB_CLIENT_ID,
+ REACT_APP_GITHUB_CALLBACK_URL,
+ } = process.env;
+ const { error, posted, errorText } = this.state;
+ const onFailure = (response) => this.GithubError(response);
+ return (
+ <>
+ {error && posted ? (
+
+ ) : (
+
+ {this.icon()}
+
+ )}
+ >
+ );
+ }
+}
+
+GitHubAuth.propTypes = {
+ postGithubCode: PropTypes.func.isRequired,
+};
+
+const mapStateToProps = (state) => ({
+ login: state.login.login,
+ loginerror: state.login.loginerror,
+});
+
+export default connect(mapStateToProps, { postGithubCode })(
+ withRouter(GitHubAuth)
+);
diff --git a/src/components/Login.js b/src/components/Login.js
index 4884f45..1d255a3 100644
--- a/src/components/Login.js
+++ b/src/components/Login.js
@@ -10,11 +10,13 @@ import {
Icon,
Message,
Button,
+ Segment,
} from 'semantic-ui-react';
import PropTypes from 'prop-types';
import './../styles/Login.css';
import orgLogo from '../assets/org-logo.jpg';
import { register } from '../urls';
+import GitHubAuth from './GitHubAuth';
class Login extends Component {
constructor(props) {
@@ -168,6 +170,9 @@ class Login extends Component {
) : null}
+
+
+
Don't have an account?{' '}
Register here.
diff --git a/src/urls.js b/src/urls.js
index 6831eec..f75c1c3 100644
--- a/src/urls.js
+++ b/src/urls.js
@@ -47,6 +47,10 @@ export function urlRegister() {
return `${urlBaseBackend()}/token_auth/register/`;
}
+export function urlGithubLogin() {
+ return `${urlBaseBackend()}/token_auth/github/`;
+}
+
export function urlInfo() {
return `${urlBaseBackend()}/info/`;
}