Search code examples
javareactjsreact-router-dom

Page does not load correctly unless I refresh


I have a Jewlery Store app using React and there are two types of users: admin and customer. The admin has the possibility to see a table with all the users and whether the user is online or offline. I did this by putting an active attribute to each customer and when someone logs in successfully, the active attribute turns to 1 (Online), otherwise it is 0 (Offline). The opposite happens when a user logs off.

The problem is that the change in active column does not load correctly unless I refresh the page with the table. It stays at the last status that it had so the problem is at the frontend and I don't know exactly where.

This is the Login page:

import axios from "axios";
import React, { useState, useEffect } from "react";
import { Link, useNavigate } from "react-router-dom";

export default function Login() {
  const navigate = useNavigate();
  const [customer, setCustomer] = useState({
    email: "",
    password: "",
  });



  const [onlineusers, setOnline] = useState([]); // State to track online/offline status

  useEffect(() => {
    // Load online/offline status when component mounts
    loadOnlineStatus();
  }, []);



  const { email, password } = customer;

  const onInputChange = (e) => {
    setCustomer({ ...customer, [e.target.name]: e.target.value });
  };

  const loadOnlineStatus = async () => {
    // try {
      const response = await axios.get("http://localhost:8080/customers");
      setOnline(response.data);
    // } catch (error) {
    //   console.error("Error loading online status:", error);
    // }
  };

  const onSubmit = async (e) => {
    e.preventDefault();
  
    try {
      const response = await axios.get(
        `http://localhost:8080/customerEmail?email=${email}&password=${password}`
      );
  
      const loggedInCustomer = response.data;
  
      if (loggedInCustomer) {
        console.log("Login successful:", loggedInCustomer);

        await axios.put(`http://localhost:8080/customeron/${email}`);
        loadOnlineStatus();

        //stocare email
        localStorage.setItem('loggedInEmail', email);
        const role = await axios.get(
            `http://localhost:8080/role?email=${email}&password=${password}`
        );

        

        if (role.data==="ADMIN") {
          navigate("/admin");
        } else {
          navigate("/customer");
        }
      } else {
        console.error("Login failed");
      }
    } catch (error) {
      console.error("Error during login:", error);
    }
  };
  

  return (
    <div className="container">
      <div className="row">
        <div className="col-md-6 offset-md-3 border rounded p-4 mt-2 shadow">
          <h2 className="text-center m-4">Log In</h2>

          <form onSubmit={(e) => onSubmit(e)}>
            <div className="mb-3">
              <label htmlFor="Email" className="form-label">
                E-mail
              </label>
              <input
                type="text"
                className="form-control"
                placeholder="Enter your e-mail address"
                name="email"
                value={email}
                onChange={(e) => onInputChange(e)}
              />
            </div>
            <div className="mb-3">
              <label htmlFor="Password" className="form-label">
                Password
              </label>
              <input
                type="password" 
                className="form-control"
                placeholder="Enter your password"
                name="password"
                value={password}
                onChange={(e) => onInputChange(e)}
              />
            </div>

            <button type="submit" className="btn btn-outline-danger mx-2">
              Log In
            </button>
            <Link className="btn btn-outline-danger mx-2" to="/register">
              Sign Up
            </Link>
          </form>
        </div>
      </div>
    </div>
  );
}

This is my OnlineUsers page:

import React, { useEffect, useState } from "react";
import axios from "axios";
import { Link } from "react-router-dom";

export default function OnlineUsers() {
  const [users, setUsers] = useState([]);


  useEffect(() => {
    loadUsers();
  }, []);

  const loadUsers = async () => {
    const result = await axios.get("http://localhost:8080/customers");
    setUsers(result.data);
  };

  return (
    <div className="container">
      <div className="py-4">
        <table className="table border shadow">
          <thead>
            <tr>
              <th scope="col">ID</th>
              <th scope="col">Name</th>
              <th scope="col">Username</th>
              <th scope="col">Email</th>
              <th scope="col">Online Activity</th>
            </tr>
          </thead>
          <tbody>
            {users.map((user, index) => (
              <tr>
                <th scope="row" key={index}>
                  {index + 1}
                </th>
                <td>{user.name}</td>
                <td>{user.username}</td>
                <td>{user.email}</td>
                <td>{user.activ===0 ? "Offline" : "Online"}</td>
              </tr>
            ))}
          </tbody>
        </table>
        <Link
          className="btn btn-outline-primary mx-2"
          to={`/admin`}
        >
          Back
        </Link>
      </div>
    </div>
  );
}

This is the controller function that gets all the customers:

@GetMapping("/customers")
List<Customer> getAllCustomers() {
    return customerService.findAll();
}

Solution

  • A straightforward solution would be to use setInterval to periodically fetch user data:

      useEffect(() => {
        loadUsers();
    
        const interval = setInterval(() => {
          loadUsers();
        }, 5000); // 5s
    
        return () => clearInterval(interval);
      }, []);
    

    If you want to achieve real-time updates, you may need to use WebSockets, but it requires changes to both the backend and frontend