I am new to react . I am hared coded the username and password into js pages . I am trying to redirect to user into admin pages on the text fields values. Here is mentioned that username and password Admin then i want to redirect the user into admin page else into home page but is not working . I also defined the router as well into app.js files.
Here is the app.js .
import React from 'react';
import { Router, Route, Switch, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { history } from '../_helpers';
import { alertActions } from '../_actions';
import { PrivateRoute } from '../_components';
import { HomePage } from '../HomePage';
import { LoginPage } from '../LoginPage';
import { RegisterPage } from '../RegisterPage';
import CreateEmployeeComponent from '../EmployeeComponets/CreateEmployeeComponent';
import ViewEmployeeComponent from '../EmployeeComponets/ViewEmployeeComponent';
import AdminComponent from '../EmployeeComponets/AdminComponent';
class App extends React.Component {
constructor(props) {
super(props);
history.listen((location, action) => {
// clear alert on location change
this.props.clearAlerts();
});
}
render() {
const { alert } = this.props;
return (
<div className="jumbotron">
<div className="container">
<div className="col-sm-8 col-sm-offset-2">
{alert.message &&
<div className={`alert ${alert.type}`}>{alert.message}</div>
}
<Router history={history}>
<Switch>
<PrivateRoute exact path="/" component={HomePage} />
<Route path = "/add-employee/:id" component = {CreateEmployeeComponent} />
<Route path = "/view-employee/:id" component = {ViewEmployeeComponent} />
<Route path="/login" component={LoginPage} />
<Route path="/register" component={RegisterPage} />
<Route path ="/admin" component={AdminComponent} />
<Redirect from="*" to="/" />
</Switch>
</Router>
</div>
</div>
</div>
);
}
}
function mapState(state) {
const { alert } = state;
return { alert };
}
const actionCreators = {
clearAlerts: alertActions.clear
};
const connectedApp = connect(mapState, actionCreators)(App);
export { connectedApp as App };
Here is the code for Login.js
import React from 'react';
import { Link, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { userActions } from '../_actions';
class LoginPage extends React.Component {
constructor(props) {
super(props);
// reset login status
this.props.logout();
this.state = {
username: '',
password: '',
submitted: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
const { name, value } = e.target;
this.setState({ [name]: value });
}
handleSubmit(e) {
e.preventDefault();
this.setState({ submitted: true });
const { username, password } = this.state;
if (username && password) {
this.props.login(username, password);
}
else if(username==="Admin" && password==="Admin"){
localStorage.setItem("token" , "shjsshhbhbh")
this.setState({
loggingIn:true
})
}
}
render() {
if(this.state.loggingIn){
return <Redirect to ="/admin" />
}
const { loggingIn } = this.props;
const { username, password, submitted } = this.state;
return (
<div className="col-md-6 col-md-offset-3">
<h2>Login</h2>
<form name="form" onSubmit={this.handleSubmit}>
<div className={'form-group' + (submitted && !username ? ' has-error' : '')}>
<label htmlFor="username">Username</label>
<input type="text" className="form-control" name="username" value={username} onChange={this.handleChange} />
{submitted && !username &&
<div className="help-block">Username is required</div>
}
</div>
<div className={'form-group' + (submitted && !password ? ' has-error' : '')}>
<label htmlFor="password">Password</label>
<input type="password" className="form-control" name="password" value={password} onChange={this.handleChange} />
{submitted && !password &&
<div className="help-block">Password is required</div>
}
</div>
<div className="form-group">
<button className="btn btn-primary">Login</button>
{loggingIn &&
}
<Link to="/register" className="btn btn-link">Register</Link>
</div>
</form>
</div>
);
}
}
function mapState(state) {
const { loggingIn } = state.authentication;
return { loggingIn };
}
const actionCreators = {
login: userActions.login,
logout: userActions.logout
};
const connectedLoginPage = connect(mapState, actionCreators)(LoginPage);
export { connectedLoginPage as LoginPage };
Here is the private route code
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
export const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
localStorage.getItem('user')
? <Component {...props} />
: <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
)} />
)
Here is the admin page .
import React, { Component } from 'react'
import { Redirect } from 'react-router-dom';
import EmployeeService from '../services/EmployeeService';
class AdminComponent extends Component {
constructor(props) {
super(props)
const token =localStorage.getItem("token")
let loggedIn = true
{
if(token == null){
loggedIn - false
}
this.state ={
loggedIn
}
}
this.state = {
// step 2
id: this.props.match.params.id,
firstName: '',
lastName: '',
emailId: ''
}
this.changeFirstNameHandler = this.changeFirstNameHandler.bind(this);
this.changeLastNameHandler = this.changeLastNameHandler.bind(this);
this.saveOrUpdateEmployee = this.saveOrUpdateEmployee.bind(this);
}
// step 3
componentDidMount(){
// step 4
if(this.state.id === '_add'){
return
}else{
EmployeeService.getEmployeeById(this.state.id).then( (res) =>{
let employee = res.data;
this.setState({firstName: employee.firstName,
lastName: employee.lastName,
emailId : employee.emailId
});
});
}
}
saveOrUpdateEmployee = (e) => {
e.preventDefault();
let employee = {emailId: this.state.emailId,firstName: this.state.firstName, lastName: this.state.lastName};
console.log('employee => ' + JSON.stringify(employee));
// step 5
if(this.state.id === '_add'){
EmployeeService.createEmployee(employee).then(res =>{
this.props.history.push('/employees');
});
}else{
EmployeeService.updateEmployee(employee, this.state.id).then( res => {
this.props.history.push('/employees');
});
}
}
changeFirstNameHandler= (event) => {
this.setState({firstName: event.target.value});
}
changeLastNameHandler= (event) => {
this.setState({lastName: event.target.value});
}
changeEmailHandler= (event) => {
this.setState({emailId: event.target.value});
}
cancel(){
this.props.history.push('/employees');
}
getTitle(){
if(this.state.id === '_add'){
return <h3 className="text-center">Add Employee</h3>
}else{
return <h3 className="text-center">Update Employee</h3>
}
}
render() {
if(this.state.loggedIn === false)
{
return <Redirect to ="/login" />
}
return (
<div>
<h1>Welcome to adimin </h1>
<br></br>
<div className = "container">
<div className = "row">
<div className = "card col-md-6 offset-md-3 offset-md-3">
{
this.getTitle()
}
<div className = "card-body">
<form>
<div className = "form-group">
<label> Email Id: </label>
<input placeholder="Email Address" name="emailId" className="form-control"
value={this.state.emailId} onChange={this.changeEmailHandler}/>
</div>
<div className = "form-group">
<label> First Name: </label>
<input placeholder="First Name" name="firstName" className="form-control"
value={this.state.firstName} onChange={this.changeFirstNameHandler}/>
</div>
<div className = "form-group">
<label> Last Name: </label>
<input placeholder="Last Name" name="lastName" className="form-control"
value={this.state.lastName} onChange={this.changeLastNameHandler}/>
</div>
<button className="btn btn-success" onClick={this.saveOrUpdateEmployee}>Save</button>
<button className="btn btn-danger" onClick={this.cancel.bind(this)} style={{marginLeft: "10px"}}>Cancel</button>
</form>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default AdminComponent
in your handleSubmit function always first if is true and after that javascript didn't check another else if.
Also you need add another state isAdmin and use it like this:
const { username, password } = this.state;
if (username==="Admin" && password==="Admin") {
this.props.login(username, password);
localStorage.setItem("token" , "adminsaddad")
this.setState({
loggingIn:true,
isAdmin:true
})
} else if (username && password) {
this.props.login(username, password);
localStorage.setItem("token" , "shjsshhbhbh")
this.setState({
loggingIn:true
})
}
Then check if the user is admin or not:
if(this.state.loggingIn){
if(this.state.isAdmin)
return <Redirect to ="/admin" />
else
return <Redirect to ="/" />
}
But this is not a safe way for the admin page, should also add the admin component in your PrivateRoute and check the token then redirect user.
Related
I've created login page, but my issue is after clicking the submit button it is not redirecting my main Dashboard page.
Authentication/login.js
import React, { Component } from 'react'
import { Field, reduxForm } from 'redux-form';
import renderField from 'components/FormInputs/renderField';
import axios from "axios";
import { Route, router } from 'react-router-dom';
import { withRouter } from 'react-router-dom';
class Login extends Component {
constructor(props) {
super(props)
this.state = {
email: '',
password: '',
}
}
changeHandler = e => {
this.setState({ [e.target.name]: e.target.value })
}
submitHandler = e => {
e.preventDefault()
console.log(this.state)
`axios.post('http://localhost/api/validuser2', {
user: {
"email": this.state.email,
"password": this.state.password
}
},
{ withCredentials: true })`
.then(res => {
console.log(res.data[0])
if (res.data[0] === true) {
alert('Login Successful')
`this.props.handleSuccessfulAuth(res.data[0])`
alert('Logged in')
}
})
.catch(error => {
console.log(error)
})
}
render() {
const { email, password } = this.state
return (
<div className="card">
<div className="header">
<h4>Login</h4>
</div>
<div className="content">
<form className="form-horizontal" onSubmit = {this.submitHandler} >
<div className="form-group">
<label className="control-label col-md-3">Email</label>
<div className="col-md-9">
<Field
name="email"
type="email"
value={email}
//error={errors.email}
component={renderField}
onChange={ this.changeHandler } />
</div>
</div>
<div className="form-group">
<label className="control-label col-md-3">Password</label>
<div className="col-md-9">
<Field
name="password"
type="password"
value={password}
//error={errors.password}
component={renderField}
onChange={ this.changeHandler } />
</div>
</div>
<button className="btn btn-success btn-fill btn-wd">Success</button>
</form>
</div>
</div>
)
}
}
export default reduxForm({
form: 'formElements'
})(Login);
Authentication/index.js
import React, { Component } from 'react';
import Login from './Login';
import Footer from './Footer';
class Authentication extends Component {
constructor(props) {
super(props);
this.handleSuccessfulAuth = this.handleSuccessfulAuth.bind(this);
}
handleSuccessfulAuth(data) {
this.props.handleLogin(data);
`this.props.history.push("../main")`
}
render() {
return (
<div className="wrapper">
<div className="content">
<div className="container-fluid">
<div className="row-md-2">
<div className="col-md-8">
<div className="main-panel">
<Login handleSuccessfulAuth={this.handleSuccessfulAuth} />
</div>
</div>
<div className="main-panel">
<Footer />
</div>
</div>
</div>
</div>
</div>
)
}
}
export default Authentication;
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import { HashRouter } from 'react-router-dom';
import './assets/styles/base.scss';
import 'sweetalert/dist/sweetalert.css';
import Authentication from './pages/Authentication';
import configureStore from './config/configureStore';
import { Provider } from 'react-redux';
const store = configureStore();
const rootElement = document.getElementById('root');
const renderApp = Component => {
ReactDOM.render(
<Provider store={store}>
<HashRouter>
<Component />
</HashRouter>
</Provider>,
rootElement
);
};
renderApp(Authentication);
if (module.hot) {
`module.hot.accept('./pages/Authentication', () => {
const NextApp = require('./pages/Authentication').default
renderApp(NextApp);`
});
}
registerServiceWorker();
can use window.location.href and also this.props.history.push("../dashboard")
submitHandler = e => {
e.preventDefault()
console.log(this.state)
`axios.post('http://localhost/api/validuser2', {
user: {
"email": this.state.email,
"password": this.state.password
}
},
{ withCredentials: true })`
.then(res => {
console.log(res.data[0])
if (res.data[0] === true) {
alert('Login Successful')
//window.location.href = dashboardUrl;
`this.props.handleSuccessfulAuth(res.data[0])`
alert('Logged in')
}
})
.catch(error => {
console.log(error)
})
}
I use React refs in my code and the end goal is to simulate a click on selected refs (you will see how they are selected in my code).
I tried to use the method ".click()" on my element, but the console shows me Uncaught TypeError: pinterest.click is not a function
When I log the "pinterest" var in the loop, I get a "Component".
[![enter image description here][1]][1]
Here is my code :
import React, { Component } from 'react'
import InterestBox from './InterestBox'
import Axios from 'axios'
export class InterestList extends Component {
constructor(props) {
super(props);
this.state = {pinterests: []}
this.pinterestRefs = React.createRef()
this.pinterestRefs.current = [];
}
componentDidMount() {
Axios.get('http://localhost:8000/api/interests')
.then((success) => {
this.setState({pinterests: success.data.data.interests});
})
}
componentDidUpdate(prevProps) {
console.log(JSON.stringify(prevProps));
console.log(JSON.stringify(this.props))
if(this.props.alreadyChecked != prevProps.alreadyChecked) {
this.props.alreadyChecked.forEach((item) => {
this.pinterestRefs.current.forEach((pinterest) => {
if(item == pinterest.props.id) {
console.log(pinterest)
pinterest.click();
}
})
console.log(item)
})
}
console.log(this.pin)
}
render() {
return (
<React.Fragment>
{Object.keys(this.state.pinterests).map((interest, i) => {
var pinterest = this.state.pinterests[interest];
var callbackRef = node => this.pinterestRefs.current[i] = node;
return <InterestBox id={pinterest.id} onClick={this.props.onClick} icon={pinterest.picture_src} title={pinterest.name} ref={callbackRef} />
})}
</React.Fragment>
)
}
}
export default InterestList
How can I simulate a click ?
Thank you !
PARENT CODE :
import axios from 'axios';
import * as Cookies from 'js-cookie';
import React, { Component } from 'react';
import Button from '../../components/Button';
import Dashboard from '../Dashboard';
import ErrorContainer from '../../components/ErrorContainer';
import InterestList from '../../components/register/InterestList';
export class EditUser extends Component {
constructor(props) {
super(props);
this.state = {loading: true, interests: []}
this.addInterest = this.addInterest.bind(this);
this.logState = this.logState.bind(this);
}
addInterest(id, name) {
var mid = 'm' + id;
console.log(this.state.interests[mid] == undefined)
if(this.state.interests[mid] == undefined) {
console.log(this.state);
this.setState((state) => {
state.interests[mid] = name;
return {interests: state.interests}
})
} else {
console.log('deleted')
var newInterest = this.state.interests;
delete newInterest[mid]
this.setState({interests: newInterest})
}
console.log(this.state.interests)
}
componentDidMount() {
var token = Cookies.get('token');
axios.get('http://localhost:8000/api/details', {headers: {"Accept": 'application/json', "Authorization": `Bearer ${token}`}}).then(
(success) => {
this.setState({
loading: false,
firstname : success.data.data.user.firstname,
lastname: success.data.data.user.lastname,
email: success.data.data.user.email,
dob: success.data.data.user.dob,
address: success.data.data.user.address,
uinterests: success.data.data.interests
})
}, (error) => {
this.props.history.push('/deconnexion');
}
)
var places = require('places.js');
var placesAutocomplete = places({
appId: "plZJLSHIW8M5",
apiKey: "0eddd2fc93b5429f5012ee49bcf8807a",
container: document.querySelector('#address-input')
});
}
logState() {
console.log(this.state);
}
render() {
return (
<Dashboard loading={this.state.loading}>
<h1 className="title">Modifier mon profil</h1>
<form className="user-form offer-update-form" onSubmit={this.handleSubmit}>
<label>Prénom :</label>
<input type="text" name="firstname" value={this.state.firstname} onChange={this.handleChange}></input> <br />
<label>Nom de famille :</label>
<input type="text" name="lastname" value={this.state.lastname} onChange={this.handleChange}></input> <br />
<label>Email :</label>
<input type="email" name="email" value={this.state.email} onChange={this.handleChange} /><br />
<label>Adresse :</label>
<input type="address" id="address-input" name="address" value={this.state.address} onChange={this.handleChange} /><br />
<label>Date de naissance :</label>
<input type="date" name="dob" value={this.state.dob} onChange={this.handleChange} /><br />
<InterestList alreadyChecked={this.state.uinterests} onClick={this.addInterest} />
<ErrorContainer errors={this.state.errors} />
<Button type="primary">Soumettre les changements</Button>
</form>
<Button type="danger" onClick={this.logState} />
</Dashboard>
)
}
}
export default EditUser
```
CHILDREN CODE :
```
import React, { Component } from 'react'
export class InterestBox extends Component {
constructor(props) {
super(props);
this.images = require('../../img/interests/*.svg');
this.state = {activated: false};
this.interest_box_content = React.createRef();
this.interest_text = React.createRef();
this.handleClick = this.handleClick.bind(this);
this.updateDimensions = this.updateDimensions.bind(this);
}
handleClick() {
this.props.handleClick(this.props.id, this.props.title);
this.setState(prevState => ({
activated: !prevState.activated
}))
}
updateDimensions() {
console.log((window.getComputedStyle(this.refs.interest_box_content).width))
this.refs.interest_text = (window.getComputedStyle(this.refs.interest_box_content).width)
}
render() {
return (
<div className="column is-one-fifth-desktop is-half-touch">
<div className="interest-box">
<div className="interest-box-adjuster">
<div ref={"interest_box_content"} className={"interest-box-content " + (this.state.activated == true ? 'interest-box-activated' : '')} onClick={this.handleClick}>
<img className="interest-icon" src={this.images[this.props.icon]} style={{'height': '50%'}}></img>
<i className="activated-icon fas fa-check"></i>
<span ref={"interest_text"} className="interest-text">{this.props.title}</span>
</div>
</div>
</div>
</div>
)
}
}
export default InterestBox
```
[1]: https://i.stack.imgur.com/hHiPv.png
I am a beginner in React and was implementing a function where on a button click in the render method, I go to a function foo. In that function, I am sending the username and password to a server.
If the username and password are correct, it returns a JSON object like
{"Result":1,"Cookie":"COOKIE!!!"}
I am trying to redirect it to another class component I have made (Flood) if result is 1. Can someone kindly help me
I tried redirecting it after render and before return but I get an error
Error: Invariant failed: You should not use <Redirect> outside a <Router>
import React from 'react';
import './style.scss';
import LoginImage from './LoginImage.png'
import Button from 'react-bootstrap/Button'
import Form from 'react-bootstrap/Form'
import {Redirect, Router} from 'react-router-dom'
//import Logfailed from './Logfailed'
import Flood from './Flood'
class UserLogin extends React.Component {
constructor(props) {
super(props);
this.state = {userName:'', password:'', act:'l', flag:0, txt:''};
this.handleChange1 = this.handleChange1.bind(this);
this.handleChange2 = this.handleChange2.bind(this);
this.handleClick = this.handleClick.bind(this);
}
async handleClick(e) {
const url = 'http://52.8.557.164/user'
const data = {username:this.state.userName, password:this.state.password, action:this.state.act};
try {
const response = await fetch(url,
{
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
},
});
const json = await response.json();
if(json['Result'] === 1) {
this.setState({flag: 1, txt:''});
}
else {
this.setState({flag:2, txt:'Wrong username and Password'});
}
console.log('Success', JSON.stringify(json));
console.log(json['Cookie']);
} catch (error) {
console.error('Error', error);
}
}
handleChange1(e) {
this.setState({userName: e.target.value})
}
handleChange2(e) {
this.setState({password: e.target.value})
}
render() {
if (this.state.flag === 1) {
return <Redirect to='/Flood' />
}
return (
<div className = 'outer-container' ref={this.props.containerRef}>
<div className = 'header'> Login </div>
<div className="content">
<div className="image">
<img src={LoginImage} />
</div>
<Form className = 'form'>
<Form.Group controlId="formBasicEmail" className = 'form-group'>
<Form.Label style={{marginTop: '90px'}}>Username</Form.Label>
<Form.Text className="text-muted" htmlFor="username"></Form.Text>
<input type="text" value = {this.state.userName} name="username" placeholder="username" onChange={this.handleChange1}/>
</Form.Group>
<Form.Group controlId="formBasicPassword" className = 'form-group'>
<Form.Label>Password</Form.Label>
<Form.Text className="text-muted" htmlFor="password"></Form.Text>
<input type="password" value = {this.state.password} name="password" placeholder="password" onChange={this.handleChange2} />
<br></br>
<span>{this.state.txt}</span>
</Form.Group>
</Form>
</div>
<div className="footer">
<Button variant="outline-primary" size="lg" onClick={this.handleClick} className="btn" block>
Login
</Button>
</div>
</div>
);
}
}
export default UserLogin;
import React from 'react';
class Flood extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<h1>gg</h1>
)}
}
export default Flood;
import React from 'react';
import './App.css';
import UserLogin from './UserLogin';
import Register from './Register'
import { Router, Redirect} from 'react-router-dom'
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
login: true
};
}
componentDidMount() {
this.rightSide.classList.add("right");
}
changeState() {
const { login } = this.state;
if (login) {
this.rightSide.classList.remove("right");
this.rightSide.classList.add("left");
} else {
this.rightSide.classList.remove("left");
this.rightSide.classList.add("right");
}
this.setState(prevState => ({ login: !prevState.login }));
}
render() {
const {login} = this.state;
const curr = login ? "Register" : "Login";
const currentActive = login ? "login" : "register";
return (
<div className="App">
<div className="login">
<div className="container" ref={ref => (this.container = ref)}>
{login && (
<UserLogin containerRef={ref => (this.curr = ref)} />
)}
{!login && (
<Register containerRef={ref => (this.curr = ref)} />
)}
</div>
<RightSide
curr={curr}
currentActive={currentActive}
containerRef={ref => (this.rightSide = ref)}
onClick={this.changeState.bind(this)}
/>
</div>
</div>
);
}
}
const RightSide = props => {
return (
<div
className="right-side"
ref={props.containerRef}
onClick={props.onClick}
>
<div className="inner-container">
<div className="text">{props.curr}</div>
</div>
</div>
);
};
export default App;
BrowserRouter is the provider to be used in React Router for usage of anything related to routing. To add it to your component:
import { BrowserRouter as Router } from "react-router-dom";
class App extends React.Component {
render() {
return (
<Router>
// Rest of the App component here.
</Router>
);
}
}
Note that there needs to be only one wrapping Router in an application (generally) and hence it makes sense to wrap the entry component in it.
Basic Routing Example - React Routing
First of all, you need to wrap your component using withRouter tag
import { withRouter } from 'react-router-dom'
then wrap your component/class when you're exporting
export default withRouter(yourComponent);
ok, now back to the issue:
To redirect, you can simply push something to the history object
history.push('/redirect-location');
I have a small React app which has a header component shared across the app from the index.js where the routing is set. I want to check on a specific page (Admin.js) if I'm logged in (Facebook auth already done with Firebase and working fine) and if so, show on the header component the log out button and Facebook profile pic.
index.js (imports omitted):
const Root = () => {
return (
<div>
<Header />
<main>
<Router>
<Switch>
<Route path="/" component={App} exact />
<Route path="/admin" component={Admin} exact />
</Switch>
</Router>
</main>
</div>
);
};
render(<Root/>, document.querySelector('#root'));
Header.js:
import React from 'react';
class Header extends React.Component {
render() {
return (
<header className="header">Header Home
<img src={image prop here or something...} alt=""/>
</header>
)
}
}
export default Header
Admin.js
class Admin extends React.Component {
constructor() {
super();
this.addPicture = this.addPicture.bind(this);
// getinitialstate
this.state = {
pictures: [],
uid: null,
avatar: ''
}
}
// firebase syncing
componentWillMount() {
this.ref = base.syncState('pictures', {
context: this,
state: 'pictures',
});
}
componentDidMount() {
firebase.auth().onAuthStateChanged((user) => {
if(user) {
this.authHandler(null, { user });
}
})
}
authenticate() {
firebase.auth().signInWithPopup(provider).then(() => {this.authHandler});
}
logout = () => {
firebase.auth().signOut().then(() => {
this.setState({
uid: null,
avatar: ''
});
});
}
authHandler(err, authData) {
console.log(authData)
if (err) {
return;
}
this.setState({
uid: authData.user.uid,
avatar: authData.user.photoURL
});
}
renderLogin() {
return (
<nav>
<h2>Please log in to access the Admin Area</h2>
<button className="c-form__btn" onClick={() => this.authenticate()}>Log in</button>
</nav>
)
}
addPicture(e) {
e.preventDefault();
const picsRef = firebase.database().ref('pictures');
const picture = {
title: this.title.value,
url: this.url.value,
category: this.category.value
}
picsRef.push(picture);
this.picForm.reset();
}
removePicture = (key) => {
const pictures = {...this.state.pictures};
pictures[key] = null;
this.setState({ pictures });
}
renderTable = () => {
return Object
.keys(this.state.pictures)
.map(key => <Table key={key} index={key} details={this.state.pictures[key]} removePic={() => this.removePicture(key)}/>)
}
render() {
const logout = <button className="c-form__btn secondary" onClick={this.logout}>Log Out!</button>
// check if ther're no logged id at all
if(!this.state.uid) {
return <div>{this.renderLogin()}</div>
}
// check if they are the owner of the app
if(this.state.uid !== USER_UID) {
return (
<div>
<h3>Access not allowed!</h3>
{logout}
</div>
)
}
return (
<div>
<h1>Admin</h1>
<p>{logout}</p>
<img src={this.state.avatar} alt="User" style={{width: '50px'}}/>
<form ref={(input) => this.picForm = input} className="c-form" onSubmit={(e) => this.addPicture(e)}>
<div className="c-form__field"><input ref={(input) => this.title =input} type="text" placeholder="title" className="c-form__input"/></div>
<div className="c-form__field"><input ref={(input) => this.url =input} type="text" placeholder="Image url" className="c-form__input"/></div>
<div className="c-form__field">
<select ref={(input) => this.category =input} className="c-form__input">
<option value=" " disabled>Select a category</option>
{catOptions()}
</select>
</div>
<div className="c-form__field"><button className="c-form__btn" type="submit">Add Item</button></div>
</form>
<div className="table">
<div className="table__row t_header">
{tableHeader()}
</div>
{this.renderTable()}
</div>
</div>
)
}
}
export default Admin
How do I show the logout button and the Facebook profile pic (this.state avatar) on the Header component?
You need to lift the state up. For example:
class Root extends React.Component {
state = {
isLogged: false
img: null,
username: '',
}
login = (username, img) => {
this.setState({
img,
username,
isLogged: true,
});
}
logout = () => {
this.setState({
img: null,
username: '',
isLogged: false,
})
}
render() {
return (
<div>
<Header
username={this.state.username}
img={this.state.img}
isLogged={this.state.isLogged}
logout={this.logout}
/>
<main>
<Router>
<Switch>
<Route path="/" component={App} exact />
<Route
exact
path="/admin"
render={props => <Admin {...props} login={this.login} />}
/>
</Switch>
</Router>
</main>
</div>
);
}
};
Now you can update state in Root with updater function passed to Admin. From now on you just pass props to whatever you want. You get the idea...
I'm new to React, I'm building an Electron app.
In the code below, I check to see if there's a signed in user, and if so, I render Home, if they haven't logged in yet or signed up, I render SignIn
(this code lives in app.js)
if (JSON.parse(localStorage.cookies).user_id === undefined) {
render((
<Provider store={store}>
<SignIn />
</Provider>
), document.getElementById('content'));
} else {
render((
<Provider store={store}>
<Home />
</Provider>
), document.getElementById('content'));
}
When the user signs up or logs in, I want to take them to Home right afterwards. I can do that in development my refreshing my Electron window. How do I achieve this in my code?
Here is the code for SignIn.js
import React, { Component, PropTypes } from 'react';
import {connect} from 'react-redux';
import {signUp, logIn} from '../entities/auth/actions';
class SignIn extends Component {
constructor(props) {
super(props);
this.logIn = this.logIn.bind(this);
this.signUp = this.signUp.bind(this);
this.state = {
registration: {
username: '',
password: '',
email: '',
},
login: {
username: '',
password: '',
},
};
}
signUp() {
this.props.dispatch(signUp(this.state.registration));
}
logIn() {
this.props.dispatch(logIn(this.state.login));
}
render() {
const {registration, login} = this.state;
return (
<div className="sign-in">
<h1>MyApp</h1>
<form id="login-form" onSubmit={(e) => {
e.preventDefault();
}}>
<input type="username" value={login.username} placeholder="Enter username" onChange={e => this.setState({login: {...login, username: e.target.value}})}/>
<input type="password" value={login.password} placeholder="Enter password" onChange={e => this.setState({login: {...login, password: e.target.value}})}/>
<button onClick={this.logIn}>Log in</button>
</form>
<form id="registration-form" onSubmit={(e) => {
e.preventDefault();
}}>
<input type="text" value={registration.username} placeholder="Enter user name" onChange={e => this.setState({registration: {...registration, username: e.target.value}})}/>
<input type="password" value={registration.password} placeholder="Enter password" onChange={e => this.setState({registration: {...registration, password: e.target.value}})}/>
<input type="email" value={registration.email} placeholder="Enter email" onChange={e => this.setState({registration: {...registration, email: e.target.value}})}/>
<button onClick={this.signUp}>Sign up</button>
</form>
</div>
);
}
}
SignIn.propTypes = {
dispatch: PropTypes.func,
};
const mapStateToProps = () => {
return {};
};
export default connect(mapStateToProps)(SignIn);
Thanks!
Assuming you don't want to use react-router, a way to approach this problem would be to have a higher component that renders either Login or Home by checking the cookies. This component could have a state value loggedIn. For example:
class Application extends React.Component {
constructor(props) {
super(props);
this.handleLogin = this.handleLogin.bind(this);
const isLoggedIn = JSON.parse(localStorage.cookies).user_id === undefined;
this.state = {
loggedIn: isLoggedIn,
}
}
handleLogin() {
//if login was successful, do:
this.setState({ loggedIn: true })
}
render() {
return (
<div>
{
this.state.loggedIn
? <Home />
: <LoggedIn handleLogin={this.handleLogin}>
}
</div>
)
}
}
Then trigger handleLogin in your Login component somehow:
signUp() {
this.props.dispatch(signUp(this.state.registration, this.props.handleLogin));
}
logIn() {
this.props.dispatch(logIn(this.state.login, this.props.handleLogin));
}
render() {
const {registration, login} = this.state;
This will update the parent state and rerender the appropriate component.
Also need to change
render((
<Provider store={store}>
<Application />
</Provider>
), document.getElementById('content'));