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();
}
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