How to update state from firebase auth in my react application - reactjs

I can successfully login with the below code, however I don't believe react is receiving any auth data back form google to update the current user in react.
I know I am missing something here but I don't know what. Any help would be appreciated!
import {useState} from 'react'
import * as Yup from 'yup'
import clsx from 'clsx'
import {Link} from 'react-router-dom'
import {useFormik} from 'formik'
import {getUserByToken, login} from '../core/_requests'
import {toAbsoluteUrl} from '../../../../_metronic/helpers'
import {useAuth} from '../core/Auth'
import {
auth,
db,
signInWithGoogle,
logInWithEmailAndPassword,
registerWithEmailAndPassword,
sendPasswordReset,
logout,
} from "../../../../firebase.js";
import { Firestore } from 'firebase/firestore'
import { useNavigate } from 'react-router-dom';
const loginSchema = Yup.object().shape({
email: Yup.string()
.email('Wrong email format')
.min(3, 'Minimum 3 symbols')
.max(50, 'Maximum 50 symbols')
.required('Email is required'),
password: Yup.string()
.min(3, 'Minimum 3 symbols')
.max(50, 'Maximum 50 symbols')
.required('Password is required'),
})
const initialValues = {
email: 'admin#demo.com',
password: 'demo',
}
/*
Formik+YUP+Typescript:
https://jaredpalmer.com/formik/docs/tutorial#getfieldprops
https://medium.com/#maurice.de.beijer/yup-validation-and-typescript-and-formik-6c342578a20e
*/
export function Login() {
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
const formik = useFormik({
initialValues,
validationSchema: loginSchema,
onSubmit: async (values, { setStatus, setSubmitting }) => {
setLoading(true);
try {
await logInWithEmailAndPassword(values.email, values.password);
setLoading(false);
navigate('/dashboard');
} catch (error) {
console.error(error);
setSubmitting(false);
setLoading(false);
//setStatus(error.message);
}
},
});
return (
<form
className='form w-100'
onSubmit={formik.handleSubmit}
noValidate
id='kt_login_signin_form'
>
{/* begin::Heading */}
<div className='text-center mb-10'>
<h1 className='text-dark mb-3'>Sign In to Web Construct</h1>
<div className='text-gray-400 fw-bold fs-4'>
New Here?{' '}
<Link to='/auth/registration' className='link-primary fw-bolder'>
Create an Account
</Link>
</div>
</div>
{/* begin::Heading */}
{formik.status ? (
<div className='mb-lg-15 alert alert-danger'>
<div className='alert-text font-weight-bold'>{formik.status}</div>
</div>
) : (
<div className='mb-10 bg-light-info p-8 rounded'>
<div className='text-info'>
Use account <strong>admin#demo.com</strong> and password <strong>demo</strong> to
continue.
</div>
</div>
)}
{/* begin::Form group */}
<div className='fv-row mb-10'>
<label className='form-label fs-6 fw-bolder text-dark'>Email</label>
<input
placeholder='Email'
{...formik.getFieldProps('email')}
className={clsx(
'form-control form-control-lg form-control-solid',
{'is-invalid': formik.touched.email && formik.errors.email},
{
'is-valid': formik.touched.email && !formik.errors.email,
}
)}
type='email'
name='email'
autoComplete='off'
/>
{formik.touched.email && formik.errors.email && (
<div className='fv-plugins-message-container'>
<span role='alert'>{formik.errors.email}</span>
</div>
)}
</div>
{/* end::Form group */}
{/* begin::Form group */}
<div className='fv-row mb-10'>
<div className='d-flex justify-content-between mt-n5'>
<div className='d-flex flex-stack mb-2'>
{/* begin::Label */}
<label className='form-label fw-bolder text-dark fs-6 mb-0'>Password</label>
{/* end::Label */}
{/* begin::Link */}
<Link
to='/auth/forgot-password'
className='link-primary fs-6 fw-bolder'
style={{marginLeft: '5px'}}
>
Forgot Password ?
</Link>
{/* end::Link */}
</div>
</div>
<input
type='password'
autoComplete='off'
{...formik.getFieldProps('password')}
className={clsx(
'form-control form-control-lg form-control-solid',
{
'is-invalid': formik.touched.password && formik.errors.password,
},
{
'is-valid': formik.touched.password && !formik.errors.password,
}
)}
/>
{formik.touched.password && formik.errors.password && (
<div className='fv-plugins-message-container'>
<div className='fv-help-block'>
<span role='alert'>{formik.errors.password}</span>
</div>
</div>
)}
</div>
{/* end::Form group */}
{/* begin::Action */}
<div className='text-center'>
<button
type='submit'
id='kt_sign_in_submit'
className='btn btn-lg btn-primary w-100 mb-5 '
disabled={formik.isSubmitting || !formik.isValid}
>
{!loading && <span className='indicator-label'>Continue</span>}
{loading && (
<span className='indicator-progress' style={{display: 'block'}}>
Please wait...
<span className='spinner-border spinner-border-sm align-middle ms-2'></span>
</span>
)}
</button>
{/* begin::Separator */}
<div className='text-center text-muted text-uppercase fw-bolder mb-5'>or</div>
{/* end::Separator */}
{/* begin::Google link */}
<a className='btn btn-flex flex-center btn-light btn-lg w-100 mb-5'>
<img
alt='Logo'
src={toAbsoluteUrl('/media/svg/brand-logos/google-icon.svg')}
className='h-20px me-3'
/>
Continue with Google
</a>
{/* end::Google link */}
{/* begin::Google link */}
<a href='#' className='btn btn-flex flex-center btn-light btn-lg w-100 mb-5'>
<img
alt='Logo'
src={toAbsoluteUrl('/media/svg/brand-logos/facebook-4.svg')}
className='h-20px me-3'
/>
Continue with Facebook
</a>
{/* end::Google link */}
{/* begin::Google link */}
<a href='#' className='btn btn-flex flex-center btn-light btn-lg w-100'>
<img
alt='Logo'
src={toAbsoluteUrl('/media/svg/brand-logos/apple-black.svg')}
className='h-20px me-3'
/>
Continue with Apple
</a>
{/* end::Google link */}
</div>
{/* end::Action */}
</form>
)
}
Should firebase be sending back a token or something similar that is saved in the form of a cookie, or am I way off base?
My firebase.js
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
import {
GoogleAuthProvider,
getAuth,
signInWithPopup,
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
sendPasswordResetEmail,
signOut,
} from "firebase/auth";
import {
getFirestore,
query,
getDocs,
collection,
where,
addDoc,
} from "firebase/firestore";
const firebaseConfig = {
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const googleProvider = new GoogleAuthProvider();
const signInWithGoogle = async () => {
try {
const res = await signInWithPopup(auth, googleProvider);
const user = res.user;
const q = query(collection(db, "users"), where("uid", "==", user.uid));
const docs = await getDocs(q);
if (docs.docs.length === 0) {
await addDoc(collection(db, "users"), {
uid: user.uid,
name: user.displayName,
authProvider: "google",
email: user.email,
});
}
} catch (err) {
console.error(err);
alert(err.message);
}
};
const logInWithEmailAndPassword = async (email, password) => {
try {
await signInWithEmailAndPassword(auth, email, password);
} catch (err) {
console.error(err);
alert(err.message);
}
};
const registerWithEmailAndPassword = async (name, email, password) => {
try {
const res = await createUserWithEmailAndPassword(auth, email, password);
const user = res.user;
await addDoc(collection(db, "users"), {
uid: user.uid,
name,
authProvider: "local",
email,
});
} catch (err) {
console.error(err);
alert(err.message);
}
};
const sendPasswordReset = async (email) => {
try {
await sendPasswordResetEmail(auth, email);
alert("Password reset link sent!");
} catch (err) {
console.error(err);
alert(err.message);
}
};
const logout = () => {
signOut(auth);
};
export {
auth,
db,
signInWithGoogle,
logInWithEmailAndPassword,
registerWithEmailAndPassword,
sendPasswordReset,
logout,
};

You'll probably have to show us what's happening in your firebase.js where you're handling the auth.
From what i'm seeing right now, you're missing the firebase hooks that track your auth state - getAuth and onAuthStateChanged
Refer to docs here:
https://firebase.google.com/docs/auth/web/start
https://firebase.google.com/docs/auth/web/manage-users#get_a_users_profile
Example of how you might do it in firebase.js
const firebaseApp = initializeApp(firebaseConfig);
// this gets the FirebaseAuth object
const auth = getAuth(firebaseApp);
const db = getFirestore(firebaseApp);
try {
// Here you are passing it the auth object when you sign in
const res = await signInWithEmailAndPassword(auth, email, password);
// And you get the user returned from the successful authentication
const { user } = res;
} catch (err) {
if (err instanceof Error) {
console.error(err);
alert(err.message);
} else {
console.log(err);
}
}
Outside of firebase.js, for example in your current component:
For each of your app's pages that need information about the signed-in
user, attach an observer to the global authentication object. This
observer gets called whenever the user's sign-in state changes.
Attach the observer using the onAuthStateChanged method. When a user
successfully signs in, you can get information about the user in the
observer.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
// This observes and tracks the state of auth in your application
onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
// ...
} else {
// User is signed out
// ...
}
});
This should be the missing link between firebase and your React side of things - then you can handle it however you need on this side once you've connected the dots.

You need to check the return value of this function call
logInWithEmailAndPassword(values.email, values.password)!
Based on the response, you either authenticate the user and save the token that's sent or do not authenticate the user.

Related

my form won't refresh back to initial state or navigate to the feeds page after success full registration i'm i wrong using async?

my form won't refresh back to initial state or navigate to the feeds page after success full registration and now react is telling me Async await is only available in es8 please can i go about this i want the form to provide some kind of feedback after registration like to n avigate to the homepage and clear all field but it's not working
import { Link, useNavigate } from 'react-router-dom'
import { toast } from 'react-toastify'
import {
getAuth,
createUserWithEmailAndPassword,
updateProfile,
} from 'firebase/auth'
import { setDoc, doc, serverTimestamp } from 'firebase/firestore'
import { db } from '../firebase.config'
import OAuth from '../components/OAuth'
function SignUp() {
const [formData, setFormData] = useState({
name: '',
email: '',
password: '',
})
const { name, email, password } = formData
const navigate = useNavigate()
const onChange = (e) => {
setFormData((prevState) => ({
...prevState,
[e.target.id]: e.target.value,
}))
}
const onSubmit = async (e) => {
e.preventDefault()
try {
const auth = getAuth()
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
)
const user = userCredential.user
updateProfile(auth.currentUser, {
displayName: name,
})
const formDataCopy = { ...formData }
delete formDataCopy.password
formDataCopy.timestamp = serverTimestamp()
await setDoc(doc(db, 'users', user.uid), formDataCopy)
navigate('/')
} catch (error) {
toast.error('Something went wrong with registration')
}
}
return (
<>
<div className='pageContainer'>
<header>
<p className='pageHeader'>Welcome Back!</p>
</header>
<form onSubmit={onSubmit}>
<input
type='text'
className='nameInput'
placeholder='Name'
id='name'
value={name}
onChange={onChange}
/>
<input
type='email'
className='emailInput'
placeholder='Email'
id='email'
value={email}
onChange={onChange}
/>
<div className='passwordInputDiv'>
<input
type='password'
className='passwordInput'
placeholder='Password'
id='password'
value={password}
onChange={onChange}
/>
</div>
<Link to='/forgot-password' className='forgotPasswordLink'>
Forgot Password
</Link>
<div className='signUpBar'>
<p className='signUpText'>Sign Up</p>
<button className='signUpButton'>
Sign Up
</button>
</div>
</form>
<OAuth />
<Link to='/sign-in' className='registerLink'>
Sign In Instead
</Link>
</div>
</>
)
}
export default SignUp

Why doesn't my React app redirect after login?

I'm new to React and Typescript and what I'm trying to do is, after successfully logging in I want to redirect the user to the homepage, but navigate doesn't seem to work.
Here is my login component:
function Login() {
const auth = useRecoilValue(authAtom);
const { register, handleSubmit, formState } = useForm<IFormValues>();
const navigate = useNavigate();
const { isSubmitting } = formState;
console.log(isSubmitting);
function onSubmit(values: IFormValues ) {
const baseUrl = `${process.env.REACT_APP_API_URL}/users/authenticate`;
const creds = {
Username: values.username,
Password: values.password
};
return authenticateApi(baseUrl, creds)
.then(X => {
navigate('/');
});
}
useEffect(() => {
// redirect to home if already logged in
if (auth) navigate('/');
}, []);
return (
<div className="col-md-6 offset-md-3 mt-5">
<div className="card">
<h4 className="card-header">Login</h4>
<div className="card-body">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-group">
<label>Username</label>
<input type="text" {...register("username")} className={`form-control`} />
<div className="invalid-feedback"></div>
</div>
<div className="form-group">
<label>Password</label>
<input type="password" {...register("password")} className={`form-control`} />
<div className="invalid-feedback"></div>
</div>
<button disabled={isSubmitting} className="btn btn-primary">
{isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
Login
</button>
</form>
</div>
</div>
</div>
)
}
I have been stuck on this for a while, so any help would be greatly appreciated.
Do you ever actually import useNavigate()? It comes from the react-router-dom package, and can be used like so:
import { useNavigate } from 'react-router-dom';
function Login() {
// ...
const navigate = useNavigate();
// ...
}
Try this one it might work! or you can create a new function to redirect user to homepage after login
import { useNavigate } from "react-router-dom";
function Login() {
//This is for navifating user to home page
const navigate = useNavigate();
const auth = useRecoilValue(authAtom);
const { register, handleSubmit, formState } = useForm<IFormValues>();
const { isSubmitting } = formState;
console.log(isSubmitting);
const onSubmit = (values: IFormValues ) => {
const baseUrl = `${process.env.REACT_APP_API_URL}/users/authenticate`;
const creds = {
Username: values.username,
Password: values.password
};
return authenticateApi(baseUrl, creds)
.then(X => {
navigate('/');
});
}
const auth = () => {
// redirect to home if already logged in
navigate('/');
};
return (
<div className="col-md-6 offset-md-3 mt-5">
<div className="card">
<h4 className="card-header">Login</h4>
<div className="card-body">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-group">
<label>Username</label>
<input type="text" {...register("username")} className={`form-control`} />
<div className="invalid-feedback"></div>
</div>
<div className="form-group">
<label>Password</label>
<input type="password" {...register("password")} className={`form-control`} />
<div className="invalid-feedback"></div>
</div>
<button disabled={isSubmitting} className="btn btn-primary">
{isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
Login
</button>
</form>
</div>
</div>
</div>
)
}

page redirect problem in react, react-router-dom

import React, { useState } from "react";
import { Link } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import Message from "../../components/Message/Message";
import Loader from "../../components/Loader/Loader";
import { login } from "../../actions/userActions";
export default function Login({ history }) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const dispatch = useDispatch();
const userLogin = useSelector((state) => state.userLogin);
const { loading, error, userInfo } = userLogin;
const submitHandler = (e) => {
e.preventDefault();
dispatch(login(email, password));
if (userInfo) {
if (userInfo.isAdmin) {
history.push("/admin/dashboard");
} else {
history.push("/");
}
}
};
return (
<div className="login-wrapper">
<div className="container py-5">
<div className="login-form p-5 rounded-2">
<h2 className="pb-3 text-center">Sign In</h2>
{error && <Message className="alert alert-danger">{error}</Message>}
{loading && <Loader />}
<form onSubmit={submitHandler}>
<div className="mb-3">
<label for="email" className="form-label">
Email address
</label>
<input
type="email"
value={email}
className="form-control"
id="email"
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div class="mb-3">
<label for="password" className="form-label">
Password
</label>
<input
type="password"
className="form-control"
value={password}
id="password"
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<div className="d-grid ">
<button className="btn btn-submit p-2" type="submit">
CONTINUE
</button>
</div>
<div className="d-flex justify-content-between py-3">
<p className="">
New User?
<Link to="/register" className="ms-1">
Signup
</Link>
</p>
Forgot your password
</div>
</form>
</div>
</div>
</div>
);
}
After complete successful login and if a user is an admin I want to show /admin/dashboard in url. But it still showing the /login URL. Or user is not an admin I want to show the home page. it's working fine for a normal user. But for the admin URL is not update.
Note: After submitting the login form I store userInfo in localstorage. Then I get localstorage data for checking if user admin or not.
How can I solve this problem?
You need to redirect on your call back action in Login.
Example :
if (userInfo) {
if (userInfo.isAdmin) {
history.push("/admin/dashboard");
} else {
history.push("/");
}
}
In submitHandler After dispatch(login(email, password)); they not wait for the action complate and userInfo. isAdmin is still not available so It's not redirect to the /admin/dashboard page.
You can use the history object in your action and do that.
import React from 'react';
import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';
export const history = createBrowserHistory();
export const App: React.FC = () => {
return (
<Router history={history}>
<Routes /> // Your all routes
</Router>
);
};
Now you can use history on your action.
import { history } from './app';
const login = () => {
// do API stuff
history.push('/somewhere');
history.push({
pathname: '/somewhere',
search: '?some=search-string',
hash: '#howdy',
state: {
[userDefined]: true
}
});
};
Or you can listen to the userInfo in useEffect hooks and do that.
useEffect(() => {
if (userInfo.isAdmin) {
history.push("/admin/dashboard");
} else {
history.push("/");
}
}, [userInfo?.isAdmin]);

React: Why sign up form is not creating new user in firebase users?

Here I'm trying to build a signup form using the react-hook form. I'm trying to build a restaurant website for my own purpose. But I have tried many times. But I'm getting many errors. First of all when I sign up a new user then firebase is not creating a new user. The form is not validating completely. But I can't find out the problem. Where is the problem? Can anyone help, please?
Here is my signUp.js file
import React, { useEffect, useState } from 'react';
import { useAuth } from './useAuth'
import { useForm } from 'react-hook-form';
import logo from '../../Images/logo2.png';
import './SignUp.css'
const SignUp = () => {
const [returningUser, setReturningUser] = useState(false);
const {register, handleSubmit, watch, errors} = useForm();
const auth = useAuth();
const onSubmit = data => {
if(returningUser){
if(data.email && data.password){
auth.signIn(data.email, data.password)
}
}
else{
if(data.name && data.email && data.password){
auth.signUp(data.email, data.password, data.name)
}
}
}
return (
<div className="sign-up">
<div className="container">
<div className="logo-container ">
<img src={logo} alt=""/>
</div>
{
returningUser ?
<form onSubmit={handleSubmit(onSubmit) } action="" className="py-5">
{
auth && auth.user != null && <p className="text-danger">{auth.user.error}</p>
}
<div className="form-group">
<input name="email" className="form-control" {...register('email', {requried: true})} placeholder="Email"/>
{errors && errors.email && <span className="error">Email is Required</span>}
</div>
<div className="form-group">
<input type="password" name="password" className="form-control" {...register('password', {requried: true})} placeholder="password"/>
{errors&& errors.password && <span className="error">Password is Required</span>}
</div>
<div className="form-group">
<button className="btn btn-danger">Sign In</button>
</div>
<div className="option text-center">
<label onClick={() => setReturningUser(false)}>Create a new Account</label>
</div>
</form>
:
<form action="" onSubmit={handleSubmit(onSubmit)}>
<div className="form-group">
<input type="text" name="name" className="form-control"
{...register('name', {requried: true})} placeholder="Name"/>
{errors && errors.name && <span className="error">Name is Required</span>}
</div>
<div className="form-group">
<input type="email" name="email" className="form-control" {...register('email', {required: true})} placeholder="Email"/>
{errors && errors.email && <span className="error">Email is required</span>}
</div>
<div className="form-group">
<input type="password" name="password" className="form-control" {...register('password', {requried: true})} placeholder="Password"/>
{errors && errors.password && <span className="error">Password is Required</span>}
</div>
<div className="form-group">
<button className="btn btn-danger" type="submit">Sign Up</button>
</div>
<div className="option text-center">
<label onClick={() => setReturningUser(true)}>Already have an account!</label>
</div>
</form>
}
</div>
</div>
);
};
export default SignUp;
Here is my useAuth.js file
// import { faWindowRestore } from '#fortawesome/free-solid-svg-icons';
import firebase from "firebase/app";
import "firebase/auth";
import firebaseConfig from "../../firebase.config";
import { createContext, useContext, useEffect, useState } from "react";
import { Redirect, Route } from "react-router";
firebase.initializeApp(firebaseConfig);
const AuthContext = createContext();
export const AuthProvider = (props) => {
const auth = Auth();
return (
<AuthContext.Provider value={auth}>{props.children}</AuthContext.Provider>
);
};
export const useAuth = () => {
useContext(AuthContext);
};
export const PrivateRoute = ({ children, ...rest }) => {
let auth = useAuth();
return (
<Route
{...rest}
render={({ location }) =>
auth.user ? (
children
) : (
<Redirect
to={{
pathname: "/login",
state: { from: location },
}}
/>
)
}
/>
);
};
const Auth = () => {
const [user, setUser] = useState(null);
useEffect(() => {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const currentUser = user;
setUser(currentUser);
// ...
} else {
// User is signed out
// ...
}
});
}, []);
const signIn = (email, password) => {
return firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then((res) => {
// Signed in
setUser(res.user);
window.history.back();
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
});
};
const signUp = (email, password, name) => {
return firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((res) => {
// firebase
// .auth()
// .currentUser.updateProfile({
// displayName: name,
// })
// .then(() => {
setUser(res.user);
window.history.back();
})
// Signed in
// ...
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
// ..
});
};
const signOut = () => {
return firebase
.auth()
.signOut()
.then((res) => {
// Sign-out successful.
setUser(null);
})
.catch((error) => {
// An error happened.
});
};
return {
user,
signIn,
signUp,
signOut,
};
};
export default Auth;

React: POST API call embedding wrong path

I created my project using CRA react CLI and I have stored data in a local JSON file in the public folder.
I have a Login Component. This is where I am making all the POST API calls using Axios and I've also have some other stuff. This component is later being imported inside Auth Layout.
The problem is: On submit, it is sending the POST request to the wrong path. It should send to /data/api/v1/login.json instead it is sending to http://localhost:3000/auth/data/api/v1/login.json.
I think this could be since the login component is loading from the auth layout. but, not sure how to resolve it.
Login component
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
//api calls
import axios from "axios";
import { setUserSession } from "../../Common/Utils/Common.js";
import { Button, Form, Input, InputGroup, InputGroupAddon } from "reactstrap";
const Login = (props) => {
const [loading, setLoading] = useState(false);
const username = useFormInput("");
const password = useFormInput("");
const [error, setError] = useState(null);
const handleLogin = () => {
setError(null);
setLoading(true);
axios
.post("data/api/v1/login.json", {
username: username.value,
password: password.value,
})
.then((response) => {
console.log("response", response);
setLoading(false);
setUserSession(response.data.token, response.data.user);
props.history.push("/admin/dashboard");
})
.catch((error) => {
setLoading(false);
if (error.response.status === 401)
setError(error.response.data.message);
else setError("Something went wrong. Please try again later.");
});
};
return (
<div className="container-fluid backgroundContainer">
<div className="Login">
<div className="login-form-container">
<div className="logo">
<img src={Logo} className="App-logo" alt="logo" />
</div>
<div className="content">
<Form className="login-form">
<h3 className="form-title">Welcome</h3>
<InputGroup>
<InputGroupAddon
className="input-group-addon"
addonType="prepend"
>
<i className="fa fa-user"></i>
</InputGroupAddon>
<Input
autoFocus
type="email"
aria-label="Username"
aria-describedby="username"
aria-invalid="false"
placeholder="Username or Email"
{...username}
/>
</InputGroup>
<InputGroup>
<InputGroupAddon
className="input-group-addon"
addonType="prepend"
>
<i className="fa fa-lock"></i>
</InputGroupAddon>
<Input
value={password}
placeholder="Password"
aria-label="password"
aria-describedby="password"
{...password}
// onChange={(e) => setPassword(e.target.value)}
type="password"
/>
</InputGroup>
<div className="form-actions">
{error && (
<>
<small style={{ color: "red" }}>{error}</small>
<br />
</>
)}
<br />
<button
className="pull-right"
block="true"
type="submit"
value={loading ? "Loading..." : "Login"}
onClick={handleLogin}
disabled={loading}
>
Login
</button>
<br />
</div>
<div className="forgotPassword">
<Link to="/auth/resetpassword">Forgot password?</Link>
</div>
</Form>
</div>
</div>
</div>
</div>
);
};
const useFormInput = (initialValue) => {
const [value, setValue] = useState(initialValue);
const handleChange = (e) => {
setValue(e.target.value);
};
return {
value,
onChange: handleChange,
};
};
export default Login;
Auth layout
import React from "react";
import Login from "../../components/pages/login/Login";
class Pages extends React.Component {
render() {
return (
<div className="wrapper wrapper-full-page" ref="fullPages">
<div className="full-page">
<Login {...this.props}></Login>
</div>
</div>
);
}
}
export default Pages;
Common.js this is a common service using in the login component.
// return the user data from the session storage
export const getUser = () => {
const userStr = sessionStorage.getItem('user');
if (userStr) return JSON.parse(userStr);
else return null;
}
// return the token from the session storage
export const getToken = () => {
return sessionStorage.getItem('token') || null;
}
// remove the token and user from the session storage
export const removeUserSession = () => {
sessionStorage.removeItem('token');
sessionStorage.removeItem('user');
}
// set the token and user from the session storage
export const setUserSession = (token, user) => {
sessionStorage.setItem('token', token);
sessionStorage.setItem('user', JSON.stringify(user));
}
You need the leading slash in your axios call, Change
axios.post("data/api/v1/login.json", {
username: username.value,
password: password.value,
})
to
axios.post("/data/api/v1/login.json", {
username: username.value,
password: password.value,
})
This will fix the problem with it adding the sub-path to your api call.

Resources