import { useRef, forwardRef, useImperativeHandle } from "react"; import io from "socket.io-client"; import PropTypes from "prop-types"; let socket = null; if (socket === null) { socket = io( window.location.hostname === "localhost" ? "http://localhost:8082" : "/", { path: "/database-socket.io", transports: ["websocket", "polling"], } ); } export const User = forwardRef(({ onLoginSuccess, onCreateSuccess, onDeleteSuccess, onFailure }, ref) => { const socketRef = useRef(socket); const currentUser = useRef(null); const createUser = (userConfig) => { if (socketRef.current) { socketRef.current.emit("createUser", { username: userConfig.username, password: userConfig.password, }); socketRef.current.once("userCreated", (data) => { currentUser.current = { id: data.user._id, username: data.user.username, sessionToken: data.user.sessionToken, }; localStorage.setItem('sessionToken', data.user.sessionToken); onCreateSuccess(data); }); socketRef.current.once("error", (error) => { console.error(error); const errorMsg = (error && typeof error === 'object' && error !== null) ? error.error || error.message || 'An error occurred' : String(error); onFailure(errorMsg); }); } }; const loginUser = (userConfig) => { if (socketRef.current) { setTimeout(() => { socketRef.current.emit("loginUser", { username: userConfig.username, password: userConfig.password, sessionToken: userConfig.sessionToken, }); socketRef.current.once("userFound", (data) => { currentUser.current = { id: data._id, username: data.username, sessionToken: data.sessionToken, }; localStorage.setItem('sessionToken', data.sessionToken); onLoginSuccess(data); }); socketRef.current.once("error", (error) => { console.error(error); const errorMsg = (error && typeof error === 'object' && error !== null) ? error.error || error.message || 'An error occurred' : String(error); onFailure(errorMsg); }); }, 500); } }; const logoutUser = () => { localStorage.removeItem('sessionToken'); currentUser.current = null; }; const deleteUser = () => { if (currentUser.current?.id && socketRef.current) { socketRef.current.emit("deleteUser", { userId: currentUser.current.id, }); socketRef.current.once("userDeleted", (data) => { onDeleteSuccess(data); currentUser.current = null; localStorage.removeItem('sessionToken'); }); socketRef.current.once("error", (error) => { console.error(error); const errorMsg = (error && typeof error === 'object' && error !== null) ? error.error || error.message || 'An error occurred' : String(error); onFailure(errorMsg); }); } else { onFailure("No user is currently logged in."); } }; const getUser = () => { return currentUser.current; } useImperativeHandle(ref, () => ({ createUser, loginUser, logoutUser, deleteUser, getUser, })); return
; }); User.displayName = "User"; User.propTypes = { onLoginSuccess: PropTypes.func.isRequired, onCreateSuccess: PropTypes.func.isRequired, onDeleteSuccess: PropTypes.func.isRequired, onFailure: PropTypes.func.isRequired, };