简体   繁体   English

React MongoDB 电子商务网站。 如果用户已经登录,如何从“帐户”按钮重定向到用户信息而不是登录页面?

[英]React MongoDB E-Commerce website. If user is already logged in, how to redirect from "Account" button to User info instead of Login page?

I am creating an E-Commerce website with React and MongoDB. So far I have a JSON that plugs in a list of products that someone can select and add to there cart for purchase.我正在使用 React 和 MongoDB 创建一个电子商务网站。到目前为止,我有一个 JSON,它插入了一个产品列表,有人可以 select 并将其添加到购物车中进行购买。 The design aspect is nearly finished and now I am working on the functionally.设计方面即将完成,现在我正在处理功能方面的工作。

The Navbar that appears on every screen has an option for an "Account" button that redirects someone to the login page.每个屏幕上出现的导航栏都有一个“帐户”按钮选项,可以将某人重定向到登录页面。 Either they sign up for an account or if they already have an account then they enter there info and log in and are redirected to "Home2" account information page.他们要么注册一个帐户,要么如果他们已经有一个帐户,那么他们会在那里输入信息并登录,然后被重定向到“Home2”帐户信息页面。

The issue I am facing is that if they are already logged in and they click "Account" button in the navbar then they are redirected back to the Log in page.我面临的问题是,如果他们已经登录并单击导航栏中的“帐户”按钮,那么他们将被重定向回登录页面。 I want to set it so if they click the "Account" button in the navbar after they are signed in then they are redirected to the "Home2" account info page.我想设置它,如果他们在登录后单击导航栏中的“帐户”按钮,那么他们将被重定向到“Home2”帐户信息页面。 Id imagine it is some type of if else statement?我想这是某种类型的 if else 语句?

The Index.JS page Index.JS 页面

import React from 'react';
import ReactDOM from 'react-dom/client';
import '../node_modules/font-awesome/css/font-awesome.min.css';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './redux/store';

import Signup from "./pages/Signup.page";
import { UserProvider } from "./contexts/user.context";
import PrivateRoute from "./pages/PrivateRoute.page";
import Home2 from "./pages/Home2";

import { Home, Product, Products, AboutPage, ContactPage, Cart, Login, Register, Checkout, PageNotFound } from "./pages"

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    {/* We are wrapping our whole app with UserProvider so that */}
    {/* our user is accessible through out the app from any page*/}
    <UserProvider>
      <Provider store={store}>
        <UserProvider>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/product" element={<Products />} />
          <Route path="/product/:id" element={<Product />} />
          <Route path="/about" element={<AboutPage />} />
          <Route path="/contact" element={<ContactPage />} />
          <Route path="/cart" element={<Cart />} />
          <Route exact path="/login" element={<Login />} />
          <Route exact path="/signup" element={<Signup />} />
          {/* We are protecting our Home Page from unauthenticated */}
          {/* users by wrapping it with PrivateRoute here. */}
          <Route element={<PrivateRoute />}>
            <Route exact path="/Home2" element={<Home2 />} />
          </Route>
          <Route path="/register" element={<Register />} />
          <Route path="/checkout" element={<Checkout />} />
          <Route path="*" element={<PageNotFound />} />
          <Route path="/product/*" element={<PageNotFound />} />
        </Routes>
        </UserProvider>
      </Provider>
    </UserProvider>
  </BrowserRouter>
);

The Navbar.Jsx page where the account button is账号按钮所在的Navbar.Jsx页面

import React from 'react'
import { NavLink } from 'react-router-dom'
import { useSelector } from 'react-redux'

const Navbar = () => {
    const state = useSelector(state => state.handleCart)
    
    return (
        // Navbar 
        <nav className="navbar navbar-expand-lg navbar-light bg-light py-2 sticky-top">
            <div className="container">

                {/* Company Name/Logo */}
                <NavLink className="navbar-brand fw-bold fs-4 px-2" to="/" ><img
                className="card-img"
                src="./assets/Logo2.jpg"
                alt="Card"
                height={100}/>
                </NavLink>

                {/* Nav Collapse */}
                <button className="navbar-toggler mx-2" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                    <span className="navbar-toggler-icon"></span>
                </button>

                {/* Navigation Options */}
                <div className="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul className="navbar-nav m-auto my-2 text-center">
                        <li>
                            <button className="nav-item graphic2 btn-8 m-2" >
                                <NavLink className="nav-link" to="/">Home </NavLink>
                            </button>
                        </li>
                        <li>  
                            <button className="nav-item graphic2 btn-8 m-2" >
                                <NavLink className="nav-link" to="/product">Products</NavLink>
                            </button>
                        </li>
                        <li>
                            <button className="nav-item graphic2 btn-8 m-2" >
                                <NavLink className="nav-link" to="/about">About</NavLink>
                            </button>
                        </li>
                        <li >
                            <button className="nav-item graphic2 btn-8 m-2" >
                                <NavLink className="nav-link light" to="/contact">Contact</NavLink>
                            </button>
                        </li>
                    </ul>
                    
                    {/* Account Info */}
                    <div className="buttons text-center">
                        <NavLink to="/login" className="btn btn-outline-dark m-2 graphic2 btn-8"style={{color: 'black', padding:'0.3rem'}}><i className="fa fa-user-plus mr-1"></i> Account</NavLink>
                        {/* <NavLink to="/register" className="btn btn-outline-dark m-2"><i className="fa fa-user-plus mr-1"></i> Register</NavLink> */}
                        <NavLink to="/cart" className="btn btn-outline-dark m-2 graphic2 btn-8"style={{color: 'black', padding:'0.3rem'}}><i className="fa fa-cart-shopping mr-1"></i> Cart ({state.length}) </NavLink>
                    </div>
                </div>


            </div>
        </nav>
    )
}

export default Navbar

The login page登录页面

import { Button, TextField } from "@mui/material";
import { useContext, useEffect, useState } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom";
import { UserContext } from "../contexts/user.context";
import { Navbar, Footer } from "../components";

import Card from '@mui/material/Card';

const Login = () => {
const navigate = useNavigate();
const location = useLocation();

// We are consuming our user-management context to
// get & set the user details here
const { user, fetchUser, emailPasswordLogin } = useContext(UserContext);

// We are using React's "useState" hook to keep track
//  of the form values.
const [form, setForm] = useState({
  email: "",
  password: ""
});

// This function will be called whenever the user edits the form.
const onFormInputChange = (event) => {
  const { name, value } = event.target;
  setForm({ ...form, [name]: value });
};

// This function will redirect the user to the
// appropriate page once the authentication is done.
const redirectNow = () => {
  const redirectTo = location.search.replace("?redirectTo=", "");
  navigate(redirectTo ? redirectTo : "/Home2");
}

// Once a user logs in to our app, we don’t want to ask them for their
// credentials again every time the user refreshes or revisits our app, 
// so we are checking if the user is already logged in and
// if so we are redirecting the user to the home page.
// Otherwise we will do nothing and let the user to login.
const loadUser = async () => {
  if (!user) {
    const fetchedUser = await fetchUser();
    if (fetchedUser) {
      // Redirecting them once fetched.
      redirectNow();
    }
  }
}

// This useEffect will run only once when the component is mounted.
// Hence this is helping us in verifying whether the user is already logged in
// or not.
useEffect(() => {
  loadUser(); // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

// This function gets fired when the user clicks on the "Login" button.
const onSubmit = async (event) => {
  try {
    // Here we are passing user details to our emailPasswordLogin
    // function that we imported from our realm/authentication.js
    // to validate the user credentials and log in the user into our App.
    const user = await emailPasswordLogin(form.email, form.password);
    if (user) {
      redirectNow();
    }
  } catch (error) {
      if (error.statusCode === 401) {
        alert("Invalid username/password. Try again!");
    } else {
        alert(error);
    }

  }
};

return <>
    <Navbar />
    <Card sx={{ maxWidth: 600 }} style={{display: 'block', margin: 'auto', marginBottom: '5rem', marginTop: '5rem' }}>
      <form style={{ display: "flex", flexDirection: "column", maxWidth: "300px", margin: "auto", marginTop: '3rem', marginBottom: '3rem' }}>
        <h3 className="text-center">Login Page</h3>
        <TextField
          label="Email"
          type="email"
          variant="outlined"
          name="email"
          value={form.email}
          onChange={onFormInputChange}
          style={{ marginBottom: "1rem" }}
        />
        <TextField
          label="Password"
          type="password"
          variant="outlined"
          name="password"
          value={form.password}
          onChange={onFormInputChange}
          style={{ marginBottom: "1rem" }}
        />
        <Button className="graphic2 btn-8 m-2" onClick={onSubmit}>
          Login
        </Button>
        <p>Don't have an account? <Link to="/signup">Signup</Link></p>
      </form>
    </Card>


    <Footer />
  </>
}

export default Login;

The Home2 page主页2

import { Button, CardActionArea } from '@mui/material'
import { useContext } from 'react';
import { UserContext } from '../contexts/user.context';
import { Footer, Navbar } from "../components";

import Card from '@mui/material/Card';
import Typography from '@mui/material/Typography';
import CardContent from '@mui/material/CardContent';

import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';

import BadgeIcon from '@mui/icons-material/Badge';
import EmailIcon from '@mui/icons-material/Email';

import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Paper from '@mui/material/Paper';


export default function Home2() {
const { logOutUser } = useContext(UserContext);

// This function is called when the user clicks the "Logout" button.
const logOut = async () => {
try {
    // Calling the logOutUser function from the user context.
    const loggedOut = await logOutUser();
    // Now we will refresh the page, and the user will be logged out and
    // redirected to the login page because of the <PrivateRoute /> component.
    if (loggedOut) {
    window.location.reload(true);
    }
} catch (error) {
    alert(error)
}
}

return (
<>
    <Navbar />
        <h1 className="text-center mt-5 improv m-3" >Welcome back Name</h1>
        <Card sx={{ maxWidth: 600 }} style={{display: 'block', margin: 'auto', marginBottom: '3rem' }}>
            <CardActionArea>
                <CardContent>
                <Typography gutterBottom variant="h5" component="div">
                    Account Information
                </Typography>
                <Typography variant="body2" color="text.secondary">


                <List>
                    <ListItem disablePadding>
                        <ListItemButton>
                        <ListItemIcon>
                            <BadgeIcon />
                        </ListItemIcon>
                        <ListItemText primary="Name" />
                        </ListItemButton>
                    </ListItem>
                    <ListItem disablePadding>
                        <ListItemButton>
                        <ListItemIcon>
                            <EmailIcon />
                        </ListItemIcon>
                        <ListItemText primary="Email" />
                        </ListItemButton>
                    </ListItem>
                </List>
                <Typography gutterBottom variant="h6" component="div">
                    Purchase History
                </Typography>
                <TableContainer component={Paper}>
                    <Table sx={{ minWidth: 650 }} aria-label="simple table">
                        <TableHead>
                        <TableRow>
                            <TableCell>Product</TableCell>
                            <TableCell align="right">Quantity</TableCell>
                            <TableCell align="right">Price</TableCell>
                            <TableCell align="right">Date Sold</TableCell>
                            <TableCell align="right">Protein&nbsp;(g)</TableCell>
                        </TableRow>
                        </TableHead>
                        <TableBody>
                            <TableRow>
                            <TableCell component="th" scope="row">Mats
                            </TableCell>
                            <TableCell align="right">2</TableCell>
                            <TableCell align="right">$500</TableCell>
                            <TableCell align="right">1/12/23</TableCell>
                            <TableCell align="right">More</TableCell>
                            </TableRow>

                        </TableBody>
                    </Table>
                </TableContainer>


                </Typography>
                </CardContent>
            </CardActionArea>
        </Card>
        <Button className="graphic2 btn-8 " style={{display: 'block', margin: 'auto', marginBottom: '3rem' }} onClick={logOut}>Logout</Button>
    <Footer />
</>
)
}

For this to work you have to save the user logged in state in the redux(because you are using redux in your project) or local storage at the time of user login.为此,您必须在用户登录时将登录 state 的用户保存在 redux 中(因为您在项目中使用 redux)或本地存储。

  let res = await login({ email, password });
  if (res.data) {
    console.log(
      "SAVE USER RES IN REDUX AND LOCAL STORAGE AND THEN REDIRECT"
    );
    // console.log(res.data);
    //save user and token to local storage
    window.localStorage.setItem("auth", JSON.stringify(res.data));
    //save user and token to redux
    dispatch({
      type: "LOGGED_IN_USER",
      payload: res.data,
    });
    history.push("/Home2");
  }

Afterwards you can apply the if/else condition on you button by checking if the user is available in logged in or not with the help of redux.之后,您可以在 redux 的帮助下检查用户是否可以登录,从而在您的按钮上应用 if/else 条件。

const { auth } = useSelector((state) => ({ ...state }));

 if(auth != null){
 <NavLink to="/Home2" className="btn btn-outline-dark m-2 graphic2 btn-8"style={{color: 'black', padding:'0.3rem'}}><i className="fa fa-user-plus mr-1"></i> Home</NavLink>
}
else{
 
 <NavLink to="/login" className="btn btn-outline-dark m-2 graphic2        btn-8"style={{color: 'black', padding:'0.3rem'}}><i className="fa fa-user-plus mr-1"></i> Account</NavLink>
 }

I hope this resolves your problem at hand.我希望这可以解决您手头的问题。

At the top in your Navbar.jsx file you add a constant for getting the logged in user在 Navbar.jsx 文件的顶部,添加一个常量以获取登录用户

Assuming we get the user from context假设我们从上下文中获取用户

const { user } = useContext(UserContext);

...

// next at the bottom for the {/* Account Info */} part convert the second line to


{user ? (<NavLink to="/login" className="btn btn-outline-dark m-2 graphic2 btn-8"style={{color: 'black', padding:'0.3rem'}}><i className="fa fa-user-plus mr-1"></i> Account</NavLink>) : (<NavLink to="/Home2" className="btn btn-outline-dark m-2 graphic2 btn-8"style={{color: 'black', padding:'0.3rem'}}><i className="fa fa-user-plus mr-1"></i> Account</NavLink>)

We use conditional rendering to render different nav links depending on wheather the user is logged in or not我们使用条件渲染根据用户是否登录来渲染不同的导航链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用php将登录用户从登录页面重定向到用户仪表板 - Redirect a logged in user from login page to user dashboard with php 如果用户尚未登录Java servlet,如何重定向到jsp登录页面? - How to redirect to jsp login page, if user does not logged in already, Java servlet? 如果用户已经登录,则隐藏“ FB登录”按钮 - Hide the FB Login button if user already logged in 如果已经使用 Reactjs 登录,如何限制用户显示登录页面 - How to restrict user to display login page if already logged in using Reactjs 如果未登录,则将用户从 JQuery 自动完成重定向到登录页面 - Redirect user to login page from JQuery autocomplete if not logged in 电商网站购物车页面计算及HTMl更新 - E-commerce website cart page calculation and HTMl updation 单击电子商务网站中的搜索按钮后,如何阻止页面重新加载? - How can I stop the page from reloading after I click on search button in my E-commerce site? 我应该如何为电子商务网站的结帐页面创建逻辑? - How should i create logic for checkout page for an e-commerce website? 如何计算电子商务网站上产品的排名/位置? - How to count rank/position of products on e-commerce website? 如果登录成功,如何将用户从登录页面重定向到另一个反应页面? - How to redirect user from login page to another react page if the login was successful?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM