Merge branch 'auth' of Asara/sudoscientist-js-frontend into master
This commit is contained in:
commit
430a53bbd9
8 changed files with 6365 additions and 6069 deletions
12152
package-lock.json
generated
12152
package-lock.json
generated
File diff suppressed because it is too large
Load diff
17
package.json
17
package.json
|
@ -3,17 +3,18 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
"axios": "^0.18.1",
|
||||
"github-markdown-css": "^3.0.1",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-markdown": "^4.0.8",
|
||||
"react-redux": "^7.0.3",
|
||||
"react-router-dom": "^5.0.1",
|
||||
"react": "^16.10.2",
|
||||
"react-cookie": "^4.0.1",
|
||||
"react-dom": "^16.10.2",
|
||||
"react-markdown": "^4.2.2",
|
||||
"react-redux": "^7.1.1",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-scripts": "3.0.0",
|
||||
"redux": "^4.0.1",
|
||||
"redux": "^4.0.4",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"semantic-ui-react": "^0.87.1"
|
||||
"semantic-ui-react": "^0.87.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
|
|
@ -17,3 +17,17 @@ export const fetchUserProfile = (user) => async (dispatch) => {
|
|||
const response = { ...profile.data, ...test }
|
||||
dispatch({ type: 'FETCH_USER', payload: response })
|
||||
};
|
||||
|
||||
export const userLogin = (username, password) => async (dispatch) => {
|
||||
const response = await sudoscientist.post('/auth/signin', {
|
||||
username: username,
|
||||
password: password
|
||||
}
|
||||
)
|
||||
if (response.status === 401) {
|
||||
console.log("Please check your credentials")
|
||||
}
|
||||
if (response.status === 200) {
|
||||
dispatch({ type: 'USER_LOGIN', payload: response })
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import axios from 'axios';
|
||||
|
||||
export default axios.create({
|
||||
baseURL: 'https://api.sudoscientist.com/v1/api/'
|
||||
baseURL: 'http://api.sudosci.test:8080/v1/api/',
|
||||
withCredentials: true
|
||||
});
|
||||
|
|
182
src/components/AuthMenu.js
Normal file
182
src/components/AuthMenu.js
Normal file
|
@ -0,0 +1,182 @@
|
|||
import React, { Component } from 'react';
|
||||
import Cookies from 'universal-cookie';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { userLogin } from '../actions';
|
||||
|
||||
class AuthMenu extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
user_authed: false,
|
||||
where_in_auth_menu: "requestUsername",
|
||||
username: "",
|
||||
password: "",
|
||||
email: ""
|
||||
}
|
||||
|
||||
this.handleInputChange = this.handleInputChange.bind(this)
|
||||
|
||||
this.handleEmailRequestForAccountCreation = this.handleEmailRequestForAccountCreation.bind(this)
|
||||
|
||||
this.handlePasswordForLogin = this.handlePasswordForLogin.bind(this)
|
||||
this.handlePasswordForAccountCreation = this.handlePasswordForAccountCreation.bind(this)
|
||||
|
||||
this.handleLogin = this.handleLogin.bind(this)
|
||||
this.handleCreateAccount = this.handleCreateAccount.bind(this)
|
||||
|
||||
this.authMenu = this.authMenu.bind(this)
|
||||
|
||||
}
|
||||
|
||||
|
||||
handleInputChange(event) {
|
||||
const target = event.target;
|
||||
const value = target.value;
|
||||
const name = target.name;
|
||||
|
||||
this.setState({
|
||||
[name]: value
|
||||
});
|
||||
}
|
||||
|
||||
handleEmailRequestForAccountCreation() {
|
||||
this.setState(state => ({
|
||||
where_in_auth_menu: "requestEmail",
|
||||
auth_menu_visible: true,
|
||||
}));
|
||||
}
|
||||
|
||||
handlePasswordForLogin() {
|
||||
this.setState(state => ({
|
||||
where_in_auth_menu: "requestPasswordForLogin",
|
||||
auth_menu_visible: true,
|
||||
}));
|
||||
}
|
||||
|
||||
handlePasswordForAccountCreation() {
|
||||
this.setState(state => ({
|
||||
where_in_auth_menu: "requestPasswordForCreation",
|
||||
auth_menu_visible: true,
|
||||
}));
|
||||
}
|
||||
|
||||
handleLogin() {
|
||||
const cookies = new Cookies();
|
||||
this.props.userLogin(this.state.username, this.state.password)
|
||||
.then(res => {
|
||||
this.setState(state => ({
|
||||
auth_menu_visible: false
|
||||
}))
|
||||
this.props.close()
|
||||
}
|
||||
)
|
||||
.then(console.log(cookies.getAll()))
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
handleCreateAccount() {
|
||||
this.setState(state => ({
|
||||
where_in_auth_menu: "requestPasswordForCreation",
|
||||
auth_menu_visible: true,
|
||||
}));
|
||||
}
|
||||
|
||||
authMenu() {
|
||||
if (!this.props.auth_menu_visible) {
|
||||
return null;
|
||||
}
|
||||
const { username, password, email } = this.state;
|
||||
switch(this.state.where_in_auth_menu) {
|
||||
case 'requestUsername':
|
||||
return (
|
||||
<div className="ui menu dropdown" style={{display: "inline"}}>
|
||||
<div className="ui left icon input">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
name="username"
|
||||
value={username}
|
||||
onChange={this.handleInputChange}
|
||||
></input>
|
||||
<i className="users icon"></i>
|
||||
</div>
|
||||
<div className="fluid ui buttons">
|
||||
<button onClick={this.handleEmailRequestForAccountCreation} className="blue ui button">Sign Up</button>
|
||||
<div className="or"></div>
|
||||
<button onClick={this.handlePasswordForLogin} className="ui teal button">Sign In</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
case 'requestPasswordForLogin':
|
||||
return (
|
||||
<div className="ui menu dropdown" style={{display: "inline"}}>
|
||||
<div className="ui left icon input">
|
||||
<input
|
||||
type={"password"}
|
||||
placeholder="Password"
|
||||
name="password"
|
||||
value={password}
|
||||
onChange={this.handleInputChange}
|
||||
></input>
|
||||
<i className="lock icon"></i>
|
||||
</div>
|
||||
<button onClick={this.handleLogin} className="fluid ui positive button">Log In</button>
|
||||
</div>
|
||||
)
|
||||
case 'requestEmail':
|
||||
return (
|
||||
<div className="ui menu dropdown" style={{display: "inline"}}>
|
||||
<div className="ui left icon input">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="email@address.tld"
|
||||
name="email"
|
||||
value={email}
|
||||
onChange={this.handleInputChange}
|
||||
></input>
|
||||
<i className="mail icon"></i>
|
||||
</div>
|
||||
<button onClick={this.handlePasswordForAccountCreation} className="fluid ui teal button">Next</button>
|
||||
</div>
|
||||
)
|
||||
case 'requestPasswordForCreation':
|
||||
return (
|
||||
<div className="ui menu dropdown" style={{display: "inline"}}>
|
||||
<div className="ui left icon input">
|
||||
<input
|
||||
type={"password"}
|
||||
placeholder="Password"
|
||||
name="password"
|
||||
value={password}
|
||||
onChange={this.handleInputChange}
|
||||
></input>
|
||||
<i className="lock icon"></i>
|
||||
</div>
|
||||
<button onClick={this.handleCreateAccount} className="fluid ui positive button">Create Account!</button>
|
||||
</div>
|
||||
)
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
this.authMenu(this.state.auth_menu_visible)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
username: state.username,
|
||||
};
|
||||
}
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
{ userLogin }
|
||||
)(AuthMenu);
|
|
@ -1,16 +1,48 @@
|
|||
import React, { Component } from 'react';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import AuthMenu from './AuthMenu';
|
||||
|
||||
class NavBar extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
logged_in: false,
|
||||
auth_menu_visible: false,
|
||||
}
|
||||
this.handleLoginDropdown = this.handleLoginDropdown.bind(this)
|
||||
}
|
||||
|
||||
handleLoginDropdown() {
|
||||
this.setState(state => ({
|
||||
auth_menu_visible: true
|
||||
}));
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="ui three item secondary menu">
|
||||
<NavLink exact to="/" className='item'>sudoscientist:~#</NavLink>
|
||||
<NavLink to="/posts/" className='item' activeClassName='active'>Posts</NavLink>
|
||||
<NavLink to="/about/" className='item' activeClassName='active'>About</NavLink>
|
||||
</div>
|
||||
<div>
|
||||
<div className="ui four item secondary menu">
|
||||
<NavLink exact to="/" className='item'>sudoscientist:~#</NavLink>
|
||||
<NavLink to="/posts/" className='item' activeClassName='active'>Posts</NavLink>
|
||||
<NavLink to="/about/" className='item' activeClassName='active'>About</NavLink>
|
||||
<div onClick={this.handleLoginDropdown} className='item ui button dropdown'>
|
||||
Login
|
||||
<i className="dropdown icon"></i>
|
||||
<AuthMenu auth_menu_visible={this.state.auth_menu_visible} close={ () => this.setState({auth_menu_visible: false})}></AuthMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default NavBar;
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
auth: state.auth
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
)(NavBar);
|
||||
|
|
18
src/reducers/authReducer.js
Normal file
18
src/reducers/authReducer.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
const initialState = {
|
||||
user_logged_in: false,
|
||||
username: '',
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case 'USER_LOGIN':
|
||||
return {...state, ...{
|
||||
username: action.payload.data.username,
|
||||
user_logged_in: true
|
||||
}}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
|
@ -1,8 +1,10 @@
|
|||
import { combineReducers } from 'redux';
|
||||
import postsReducer from './postsReducer';
|
||||
import userReducer from './userReducer';
|
||||
import authReducer from './authReducer';
|
||||
|
||||
export default combineReducers({
|
||||
posts: postsReducer,
|
||||
user: userReducer
|
||||
user: userReducer,
|
||||
auth: authReducer
|
||||
});
|
||||
|
|
Reference in a new issue