Dealer_Onboard_Frontend/src/context/SocketContext.tsx

71 lines
2.1 KiB
TypeScript

import React, { createContext, useContext, useEffect, useState } from 'react';
import { io, Socket } from 'socket.io-client';
import { useSelector } from 'react-redux';
import { RootState } from '../store';
interface SocketContextType {
socket: Socket | null;
isConnected: boolean;
}
const SocketContext = createContext<SocketContextType>({
socket: null,
isConnected: false
});
export const useSocket = () => useContext(SocketContext);
export const SocketProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [socket, setSocket] = useState<Socket | null>(null);
const [isConnected, setIsConnected] = useState(false);
const { user: currentUser } = useSelector((state: RootState) => state.auth);
useEffect(() => {
let socketUrl = (import.meta as any).env.VITE_API_URL || 'http://localhost:5000';
// If URL ends with /api, strip it as Socket.io usually connects to the root
if (socketUrl.endsWith('/api')) {
socketUrl = socketUrl.replace(/\/api$/, '');
}
const newSocket = io(socketUrl, {
withCredentials: true
});
newSocket.on('connect', () => {
console.log('Socket connected:', newSocket.id);
setIsConnected(true);
});
newSocket.on('disconnect', () => {
console.log('Socket disconnected');
setIsConnected(false);
});
setSocket(newSocket);
return () => {
newSocket.close();
};
}, []);
// Join personal room for notifications
useEffect(() => {
if (socket && isConnected && currentUser?.id) {
socket.emit('join_room', `user_${currentUser.id}`);
console.log(`Joined private notification room: user_${currentUser.id}`);
return () => {
socket.emit('leave_room', `user_${currentUser.id}`);
};
}
}, [socket, isConnected, currentUser?.id]);
return (
<SocketContext.Provider value={{ socket, isConnected }}>
{children}
</SocketContext.Provider>
);
};