From f9caeb619e07a6e2b4b492cfefc6be88411f44a3 Mon Sep 17 00:00:00 2001
From: Delucse <46593742+Delucse@users.noreply.github.com>
Date: Wed, 9 Dec 2020 18:10:45 +0100
Subject: [PATCH] connect to MyBadges-account
---
.env | 2 +
src/actions/authActions.js | 53 ++++++-
src/actions/types.js | 2 +
src/components/Route/Routes.js | 6 +-
src/components/User/MyBadges.js | 260 ++++++++++++++++++++++++++++++++
src/reducers/authReducer.js | 9 +-
6 files changed, 326 insertions(+), 6 deletions(-)
create mode 100644 src/components/User/MyBadges.js
diff --git a/.env b/.env
index 9af8f29..3ba890f 100644
--- a/.env
+++ b/.env
@@ -2,5 +2,7 @@ REACT_APP_COMPILER_URL=https://compiler.sensebox.de
REACT_APP_BOARD=sensebox-mcu
REACT_APP_BLOCKLY_API=https://api.blockly.sensebox.de
+REACT_APP_MYBADGES=https://mybadges.org
+
# in days
REACT_APP_SHARE_LINK_EXPIRES=30
diff --git a/src/actions/authActions.js b/src/actions/authActions.js
index c29f7cf..cb06139 100644
--- a/src/actions/authActions.js
+++ b/src/actions/authActions.js
@@ -1,4 +1,4 @@
-import { USER_LOADED, USER_LOADING, AUTH_ERROR, LOGIN_SUCCESS, LOGIN_FAIL, LOGOUT_SUCCESS, LOGOUT_FAIL, REFRESH_TOKEN_SUCCESS } from '../actions/types';
+import { MYBADGES_CONNECT, MYBADGES_DISCONNECT, USER_LOADED, USER_LOADING, AUTH_ERROR, LOGIN_SUCCESS, LOGIN_FAIL, LOGOUT_SUCCESS, LOGOUT_FAIL, REFRESH_TOKEN_SUCCESS } from '../actions/types';
import axios from 'axios';
import { returnErrors, returnSuccess } from './messageActions'
@@ -64,8 +64,6 @@ export const login = ({ email, password }) => (dispatch) => {
dispatch(returnSuccess(res.data.message, res.status, 'LOGIN_SUCCESS'));
})
.catch(err => {
- console.log('hier');
- console.log(err);
dispatch(returnErrors(err.response.data.message, err.response.status, 'LOGIN_FAIL'));
dispatch({
type: LOGIN_FAIL
@@ -74,6 +72,55 @@ export const login = ({ email, password }) => (dispatch) => {
};
+// Connect to MyBadges-Account
+export const connectMyBadges = ({ username, password }) => (dispatch, getState) => {
+ // Headers
+ const config = {
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ };
+ // Request Body
+ const body = JSON.stringify({ username, password });
+ axios.post(`${process.env.REACT_APP_BLOCKLY_API}/user/badge`, body, config)
+ .then(res => {
+ var user = getState().auth.user;
+ user.badge = res.data.account;
+ dispatch({
+ type: MYBADGES_CONNECT,
+ payload: user
+ });
+ dispatch(returnSuccess(res.data.message, res.status, 'MYBADGES_CONNECT_SUCCESS'));
+ })
+ .catch(err => {
+ dispatch(returnErrors(err.response.data.message, err.response.status, 'MYBADGES_CONNECT_FAIL'));
+ });
+};
+
+// Disconnect MyBadges-Account
+export const disconnectMyBadges = () => (dispatch, getState) => {
+ // Headers
+ const config = {
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ };
+ axios.put(`${process.env.REACT_APP_BLOCKLY_API}/user/badge`, config)
+ .then(res => {
+ var user = getState().auth.user;
+ user.badge = null;
+ dispatch({
+ type: MYBADGES_DISCONNECT,
+ payload: user
+ });
+ dispatch(returnSuccess(res.data.message, res.status, 'MYBADGES_DISCONNECT_SUCCESS'));
+ })
+ .catch(err => {
+ dispatch(returnErrors(err.response.data.message, err.response.status, 'MYBADGES_DISCONNECT_FAIL'));
+ });
+};
+
+
// Logout User
export const logout = () => (dispatch) => {
const config = {
diff --git a/src/actions/types.js b/src/actions/types.js
index 34d5889..9172b4a 100644
--- a/src/actions/types.js
+++ b/src/actions/types.js
@@ -8,6 +8,8 @@ export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
export const LOGOUT_FAIL = 'LOGOUT_FAIL';
export const REFRESH_TOKEN_FAIL = 'REFRESH_TOKEN_FAIL';
export const REFRESH_TOKEN_SUCCESS = 'REFRESH_TOKEN_SUCCESS';
+export const MYBADGES_CONNECT = 'MYBADGES_CONNECT';
+export const MYBADGES_DISCONNECT = 'MYBADGES_DISCONNECT';
export const NEW_CODE = 'NEW_CODE';
export const CHANGE_WORKSPACE = 'CHANGE_WORKSPACE';
diff --git a/src/components/Route/Routes.js b/src/components/Route/Routes.js
index 25e9aff..3121edf 100644
--- a/src/components/Route/Routes.js
+++ b/src/components/Route/Routes.js
@@ -21,6 +21,7 @@ import Impressum from '../Impressum';
import Privacy from '../Privacy';
import Login from '../User/Login';
import Account from '../User/Account';
+import MyBadges from '../User/MyBadges';
class Routes extends Component {
@@ -57,7 +58,10 @@ class Routes extends Component {
-
+
+
+
+
{/* settings */}
diff --git a/src/components/User/MyBadges.js b/src/components/User/MyBadges.js
new file mode 100644
index 0000000..4d7dc47
--- /dev/null
+++ b/src/components/User/MyBadges.js
@@ -0,0 +1,260 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import { connectMyBadges, disconnectMyBadges } from '../../actions/authActions';
+
+import axios from 'axios';
+import { withRouter } from 'react-router-dom';
+
+import Breadcrumbs from '../Breadcrumbs';
+import Alert from '../Alert';
+
+import { withStyles } from '@material-ui/core/styles';
+import Paper from '@material-ui/core/Paper';
+import Button from '@material-ui/core/Button';
+import IconButton from '@material-ui/core/IconButton';
+import TextField from '@material-ui/core/TextField';
+import Divider from '@material-ui/core/Divider';
+import InputAdornment from '@material-ui/core/InputAdornment';
+import Link from '@material-ui/core/Link';
+import Typography from '@material-ui/core/Typography';
+import Grid from '@material-ui/core/Grid';
+import Avatar from '@material-ui/core/Avatar';
+
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
+
+const styles = (theme) => ({
+ root: {
+ '& label.Mui-focused': {
+ color: '#aed9c8'
+ },
+ '& .MuiOutlinedInput-root': {
+ '&.Mui-focused fieldset': {
+ borderColor: '#aed9c8'
+ },
+ borderRadius: '0.75rem'
+ }
+ },
+ text: {
+ fontFamily: [
+ '"Open Sans"',
+ 'BlinkMacSystemFont',
+ '"Segoe UI"',
+ 'Roboto',
+ '"Helvetica Neue"',
+ 'Arial',
+ 'sans-serif',
+ '"Apple Color Emoji"',
+ '"Segoe UI Emoji"',
+ '"Segoe UI Symbol"',
+ ].join(','),
+ fontSize: 16
+ }
+});
+
+export class MyBadges extends Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ username: '',
+ password: '',
+ showPassword: false,
+ msg: '',
+ badges: [],
+ progress: false
+ };
+ }
+
+ componentDidMount(){
+ if(this.props.user.badge){
+ this.getBadges();
+ }
+ }
+
+ componentDidUpdate(props){
+ const { message } = this.props;
+ if (message !== props.message) {
+ // Check for login error
+ if(message.id === 'MYBADGES_CONNECT_FAIL'){
+ this.setState({msg: 'Der Benutzername oder das Passwort ist nicht korrekt.', username: '', password: '', showPassword: false});
+ }
+ else if(message.id === 'MYBADGES_CONNECT_SUCCESS'){
+ this.getBadges();
+ }
+ else if(message.id === 'MYBADGES_DISCONNECT_SUCCESS' || message.id === 'MYBADGES_DISCONNECT_FAIL'){
+ this.setState({progress: false});
+ }
+ else {
+ this.setState({msg: null});
+ }
+ }
+ }
+
+ getBadges = () => {
+ this.setState({progress: true});
+ axios.get(`${process.env.REACT_APP_BLOCKLY_API}/user/badge`)
+ .then(res => {
+ this.setState({badges: res.data.badges, progress: false});
+ })
+ .catch(err => {
+ this.setState({progress: false});
+ console.log(err);
+ });
+ };
+
+ onChange = e => {
+ this.setState({ [e.target.name]: e.target.value, msg: '' });
+ };
+
+ onSubmit = e => {
+ e.preventDefault();
+ const {username, password} = this.state;
+ // create user object
+ const user = {
+ username,
+ password
+ };
+ this.props.connectMyBadges(user);
+ };
+
+ handleClickShowPassword = () => {
+ this.setState({ showPassword: !this.state.showPassword });
+ };
+
+ handleMouseDownPassword = (e) => {
+ e.preventDefault();
+ };
+
+ render(){
+ return(
+
+
+
+
+
+ {!this.props.user.badge ?
+
+ Du kannst dein Blockly-Konto mit deinem MyBadges-Konto verknüpfen, um Badges erwerben zu können.
+
+ : null}
+
+
+
+
+
+ {!this.props.user.badge ?
+
+ {this.state.msg ?
+
+ {this.state.msg}
+
: null
+ }
+
+
+
+
+
+
+ }}
+ onChange={this.onChange}
+ fullWidth={true}
+ />
+
+
+ Anmelden
+
+
+
+ Passwort vergessen?
+
+
+
+ Du hast noch kein Konto? Registrieren
+
+
+ :
+ MyBadges-Konto ist erfolgreich verknüpft.
+ {this.props.disconnectMyBadges(); this.setState({badges: [], progress: true});}}>Konto trennen
+
}
+
+
+
+
+ {this.props.user.badge && !this.state.progress ?
+
+
+ {this.state.badges && this.state.badges.length > 0 ?
+
+ Du hast {this.state.badges.length} {this.state.badges.length === 1 ? 'Badge' : 'Badges'} im Kontext Blockly for senseBox erreicht.
+
+ : null}
+
+
+ {this.state.badges && this.state.badges.length > 0 ?
+ this.state.badges.map(badge => (
+
+
+ {badge.image && badge.image.path ?
+
+ : }
+
+ {badge.name}
+
+
+
+ ))
+ :
+
+
+ Du hast noch keine Badges im Kontext senseBox for Blockly erreicht.
+
+ }
+
+
+ : null}
+
+
+ );
+ }
+}
+
+MyBadges.propTypes = {
+ connectMyBadges: PropTypes.func.isRequired,
+ disconnectMyBadges: PropTypes.func.isRequired,
+ message: PropTypes.object.isRequired,
+ user: PropTypes.object.isRequired
+};
+
+const mapStateToProps = state => ({
+ message: state.message,
+ user: state.auth.user
+});
+
+export default connect(mapStateToProps, { connectMyBadges, disconnectMyBadges })(withStyles(styles, { withTheme: true })(withRouter(MyBadges)));
diff --git a/src/reducers/authReducer.js b/src/reducers/authReducer.js
index 653ecb0..482af0c 100644
--- a/src/reducers/authReducer.js
+++ b/src/reducers/authReducer.js
@@ -1,4 +1,4 @@
-import { USER_LOADED, USER_LOADING, AUTH_ERROR, LOGIN_SUCCESS, LOGIN_FAIL, LOGOUT_SUCCESS, LOGOUT_FAIL, REFRESH_TOKEN_SUCCESS } from '../actions/types';
+import { MYBADGES_CONNECT, MYBADGES_DISCONNECT, USER_LOADED, USER_LOADING, AUTH_ERROR, LOGIN_SUCCESS, LOGIN_FAIL, LOGOUT_SUCCESS, LOGOUT_FAIL, REFRESH_TOKEN_SUCCESS } from '../actions/types';
const initialState = {
@@ -27,7 +27,6 @@ export default function(state = initialState, action){
case REFRESH_TOKEN_SUCCESS:
localStorage.setItem('token', action.payload.token);
localStorage.setItem('refreshToken', action.payload.refreshToken);
- console.log(action.payload);
return {
...state,
user: action.payload.user,
@@ -36,6 +35,12 @@ export default function(state = initialState, action){
isAuthenticated: true,
progress: false
};
+ case MYBADGES_CONNECT:
+ case MYBADGES_DISCONNECT:
+ return {
+ ...state,
+ user: action.payload
+ };
case AUTH_ERROR:
case LOGIN_FAIL:
case LOGOUT_SUCCESS: