refactor: replace socket prop usage with window.socketManager for consistent socket handling across components

This commit is contained in:
sebseb7
2025-07-23 08:08:58 +02:00
parent 9982527f35
commit 4e6b63a6a4
10 changed files with 56 additions and 145 deletions

View File

@@ -62,11 +62,10 @@ class ArticleAvailabilityForm extends Component {
// Emit data via socket
console.log('Availability Inquiry Data to emit:', availabilityData);
if (this.props.socket) {
this.props.socket.emit('availability_inquiry_submit', availabilityData);
window.socketManager.emit('availability_inquiry_submit', availabilityData);
// Set up response handler
this.props.socket.once('availability_inquiry_response', (response) => {
window.socketManager.once('availability_inquiry_response', (response) => {
if (response.success) {
this.setState({
loading: false,
@@ -89,7 +88,6 @@ class ArticleAvailabilityForm extends Component {
this.setState({ success: false, error: null });
}, 3000);
});
}
this.setState({ loading: true });

View File

@@ -77,11 +77,11 @@ class ArticleQuestionForm extends Component {
// Emit data via socket
console.log('Article Question Data to emit:', questionData);
if (this.props.socket) {
this.props.socket.emit('article_question_submit', questionData);
window.socketManager.emit('article_question_submit', questionData);
// Set up response handler
this.props.socket.once('article_question_response', (response) => {
window.socketManager.once('article_question_response', (response) => {
if (response.success) {
this.setState({
loading: false,
@@ -107,7 +107,6 @@ class ArticleQuestionForm extends Component {
this.setState({ success: false, error: null });
}, 3000);
});
}
} catch {
this.setState({
loading: false,

View File

@@ -85,11 +85,10 @@ class ArticleRatingForm extends Component {
// Emit data via socket
console.log('Article Rating Data to emit:', ratingData);
if (this.props.socket) {
this.props.socket.emit('article_rating_submit', ratingData);
window.socketManager.emit('article_rating_submit', ratingData);
// Set up response handler
this.props.socket.once('article_rating_response', (response) => {
window.socketManager.once('article_rating_response', (response) => {
if (response.success) {
this.setState({
loading: false,
@@ -116,7 +115,6 @@ class ArticleRatingForm extends Component {
this.setState({ success: false, error: null });
}, 3000);
});
}
} catch {
this.setState({
loading: false,

View File

@@ -20,14 +20,13 @@ class CartItem extends Component {
this.setState({image:window.tinyPicCache[picid],loading:false, error: false})
}else{
this.setState({image: null, loading: true, error: false});
//if(this.props.socket && this.props.socket.connected){
this.props.socket.emit('getPic', { bildId:picid, size:'tiny' }, (res) => {
window.socketManager.emit('getPic', { bildId:picid, size:'tiny' }, (res) => {
if(res.success){
window.tinyPicCache[picid] = URL.createObjectURL(new Blob([res.imageBuffer], { type: 'image/jpeg' }));
this.setState({image: window.tinyPicCache[picid], loading: false});
}
})
// }
}
}
}

View File

@@ -81,18 +81,6 @@ class ChatAssistant extends Component {
if (prevState.messages !== this.state.messages || prevState.isTyping !== this.state.isTyping) {
this.scrollToBottom();
}
// Handle socket connection changes
const wasConnected = prevProps.socket && prevProps.socket.connected;
const isNowConnected = this.props.socket && this.props.socket.connected;
if (!wasConnected && isNowConnected) {
// Socket just connected, add listeners
this.addSocketListeners();
} else if (wasConnected && !isNowConnected) {
// Socket just disconnected, remove listeners
this.removeSocketListeners();
}
}
componentWillUnmount() {
@@ -104,19 +92,18 @@ class ChatAssistant extends Component {
}
addSocketListeners = () => {
if (this.props.socket && this.props.socket.connected) {
// Remove existing listeners first to avoid duplicates
this.removeSocketListeners();
this.props.socket.on('aiassyResponse', this.handleBotResponse);
this.props.socket.on('aiassyStatus', this.handleStateResponse);
}
window.socketManager.on('aiassyResponse', this.handleBotResponse);
window.socketManager.on('aiassyStatus', this.handleStateResponse);
}
removeSocketListeners = () => {
if (this.props.socket) {
this.props.socket.off('aiassyResponse', this.handleBotResponse);
this.props.socket.off('aiassyStatus', this.handleStateResponse);
}
window.socketManager.off('aiassyResponse', this.handleBotResponse);
window.socketManager.off('aiassyStatus', this.handleStateResponse);
}
handleBotResponse = (msgId,response) => {
@@ -194,8 +181,8 @@ class ChatAssistant extends Component {
};
}, () => {
// Emit message to socket server after state is updated
if (userMessage.trim() && this.props.socket && this.props.socket.connected) {
this.props.socket.emit('aiassyMessage', userMessage);
if (userMessage.trim()) {
window.socketManager.emit('aiassyMessage', userMessage);
}
});
}
@@ -300,12 +287,10 @@ class ChatAssistant extends Component {
reader.onloadend = () => {
const base64Audio = reader.result.split(',')[1];
// Send audio data to server
if (this.props.socket && this.props.socket.connected) {
this.props.socket.emit('aiassyAudioMessage', {
window.socketManager.emit('aiassyAudioMessage', {
audio: base64Audio,
format: 'wav'
});
}
};
};
@@ -389,12 +374,12 @@ class ChatAssistant extends Component {
reader.onloadend = () => {
const base64Image = reader.result.split(',')[1];
// Send image data to server
if (this.props.socket && this.props.socket.connected) {
this.props.socket.emit('aiassyPicMessage', {
window.socketManager.emit('aiassyPicMessage', {
image: base64Image,
format: 'jpeg'
});
}
};
};

View File

@@ -171,7 +171,7 @@ export class LoginComponent extends Component {
handleLogin = () => {
const { email, password } = this.state;
const { socket, location, navigate } = this.props;
const { location, navigate } = this.props;
if (!email || !password) {
this.setState({ error: 'Bitte füllen Sie alle Felder aus' });
@@ -185,16 +185,8 @@ export class LoginComponent extends Component {
this.setState({ loading: true, error: '' });
// Call verifyUser socket endpoint
if (!socket || !socket.connected) {
this.setState({
loading: false,
error: 'Verbindung zum Server verloren. Bitte versuchen Sie es erneut.'
});
return;
}
socket.emit('verifyUser', { email, password }, (response) => {
window.socketManager.emit('verifyUser', { email, password }, (response) => {
console.log('LoginComponent: verifyUser', response);
if (response.success) {
sessionStorage.setItem('user', JSON.stringify(response.user));
@@ -216,9 +208,9 @@ export class LoginComponent extends Component {
const serverCartArr = newCart ? Object.values(newCart) : [];
if (serverCartArr.length === 0) {
if (socket && socket.connected) {
socket.emit('updateCart', window.cart);
}
window.socketManager.emit('updateCart', window.cart);
this.handleClose();
dispatchLoginEvent();
} else if (localCartArr.length === 0 && serverCartArr.length > 0) {
@@ -253,7 +245,6 @@ export class LoginComponent extends Component {
handleRegister = () => {
const { email, password, confirmPassword } = this.state;
const { socket } = this.props;
if (!email || !password || !confirmPassword) {
this.setState({ error: 'Bitte füllen Sie alle Felder aus' });
@@ -276,17 +267,9 @@ export class LoginComponent extends Component {
}
this.setState({ loading: true, error: '' });
// Call createUser socket endpoint
if (!socket || !socket.connected) {
this.setState({
loading: false,
error: 'Verbindung zum Server verloren. Bitte versuchen Sie es erneut.'
});
return;
}
socket.emit('createUser', { email, password }, (response) => {
window.socketManager.emit('createUser', { email, password }, (response) => {
if (response.success) {
this.setState({
loading: false,
@@ -311,22 +294,7 @@ export class LoginComponent extends Component {
};
handleLogout = () => {
if (!this.props.socket || !this.props.socket.connected) {
// If socket is not connected, just clear local storage
sessionStorage.removeItem('user');
window.cart = [];
window.dispatchEvent(new CustomEvent('cart'));
window.dispatchEvent(new CustomEvent('userLoggedOut'));
this.setState({
isLoggedIn: false,
user: null,
isAdmin: false,
anchorEl: null
});
return;
}
this.props.socket.emit('logout', (response) => {
window.socketManager.emit('logout', (response) => {
if(response.success){
sessionStorage.removeItem('user');
window.dispatchEvent(new CustomEvent('userLoggedIn'));
@@ -343,7 +311,6 @@ export class LoginComponent extends Component {
handleForgotPassword = () => {
const { email } = this.state;
const { socket } = this.props;
if (!email) {
this.setState({ error: 'Bitte geben Sie Ihre E-Mail-Adresse ein' });
@@ -357,8 +324,8 @@ export class LoginComponent extends Component {
this.setState({ loading: true, error: '' });
// Call resetPassword socket endpoint
socket.emit('resetPassword', {
window.socketManager.emit('resetPassword', {
email,
domain: window.location.origin
}, (response) => {
@@ -379,13 +346,11 @@ export class LoginComponent extends Component {
// Google login functionality
handleGoogleLoginSuccess = (credentialResponse) => {
const { socket, location, navigate } = this.props;
const { location, navigate } = this.props;
this.setState({ loading: true, error: '' });
console.log('beforeG',credentialResponse)
socket.emit('verifyGoogleUser', { credential: credentialResponse.credential }, (response) => {
window.socketManager.emit('verifyGoogleUser', { credential: credentialResponse.credential }, (response) => {
console.log('google respo',response);
if (response.success) {
sessionStorage.setItem('user', JSON.stringify(response.user));
@@ -407,7 +372,7 @@ export class LoginComponent extends Component {
const serverCartArr = newCart ? Object.values(newCart) : [];
if (serverCartArr.length === 0) {
socket.emit('updateCart', window.cart);
window.socketManager.emit('updateCart', window.cart);
this.handleClose();
dispatchLoginEvent();
} else if (localCartArr.length === 0 && serverCartArr.length > 0) {
@@ -457,7 +422,7 @@ export class LoginComponent extends Component {
localAndArchiveServer(localCartSync, serverCartSync);
break;
case 'deleteServer':
this.props.socket.emit('updateCart', window.cart)
window.socketManager.emit('updateCart', window.cart)
break;
case 'useServer':
window.cart = serverCartSync;

View File

@@ -1,10 +1,9 @@
import React, { Component } from 'react';
import { Navigate } from 'react-router-dom';
import { Box, CircularProgress, Typography } from '@mui/material';
import SocketContext from '../contexts/SocketContext.js';
class PaymentSuccess extends Component {
static contextType = SocketContext;
constructor(props) {
super(props);
@@ -73,19 +72,10 @@ class PaymentSuccess extends Component {
};
checkMolliePaymentStatus = (paymentId) => {
const { socket } = this.context;
if (!socket || !socket.connected) {
console.error('Socket not connected');
this.setState({
redirectUrl: '/profile#cart',
processing: false,
error: 'Connection error'
});
return;
}
socket.emit('checkMollieIntent', { paymentId }, (response) => {
window.socketManager.emit('checkMollieIntent', { paymentId }, (response) => {
if (response.success) {
console.log('Payment Status:', response.payment.status);
console.log('Is Paid:', response.payment.isPaid);

View File

@@ -34,9 +34,8 @@ class ButtonGroup extends Component {
componentDidMount() {
this.cart = () => {
// @note Only emit if socket exists, is connected, AND the update didn't come from socket
if (this.props.socket && this.props.socket.connected && !this.isUpdatingFromSocket) {
this.props.socket.emit('updateCart', window.cart);
if (!this.isUpdatingFromSocket) {
window.socketManager.emit('updateCart', window.cart);
}
this.setState({
@@ -53,19 +52,6 @@ class ButtonGroup extends Component {
this.addSocketListeners();
}
componentDidUpdate(prevProps) {
// Handle socket connection changes
const wasConnected = prevProps.socket && prevProps.socket.connected;
const isNowConnected = this.props.socket && this.props.socket.connected;
if (!wasConnected && isNowConnected) {
// Socket just connected, add listeners
this.addSocketListeners();
} else if (wasConnected && !isNowConnected) {
// Socket just disconnected, remove listeners
this.removeSocketListeners();
}
}
componentWillUnmount() {
window.removeEventListener('cart', this.cart);
@@ -74,17 +60,17 @@ class ButtonGroup extends Component {
}
addSocketListeners = () => {
if (this.props.socket && this.props.socket.connected) {
// Remove existing listeners first to avoid duplicates
this.removeSocketListeners();
this.props.socket.on('cartUpdated', this.handleCartUpdated);
}
window.socketManager.on('cartUpdated', this.handleCartUpdated);
}
removeSocketListeners = () => {
if (this.props.socket) {
this.props.socket.off('cartUpdated', this.handleCartUpdated);
}
window.socketManager.off('cartUpdated', this.handleCartUpdated);
}
handleCartUpdated = (id,user,cart) => {
@@ -118,7 +104,7 @@ class ButtonGroup extends Component {
}
render() {
const { socket, navigate, t } = this.props;
const { navigate, t } = this.props;
const { isCartOpen } = this.state;
const cartItems = Array.isArray(window.cart) ? window.cart : [];
@@ -126,7 +112,7 @@ class ButtonGroup extends Component {
<Box sx={{ display: 'flex', gap: { xs: 0.5, sm: 1 } }}>
<LanguageSwitcher />
<LoginComponent socket={socket} />
<LoginComponent/>
<IconButton
color="inherit"
@@ -172,7 +158,7 @@ class ButtonGroup extends Component {
</Box>
<Divider sx={{ mb: 2 }} />
<CartDropdown cartItems={cartItems} socket={socket} onClose={this.toggleCart} onCheckout={()=>{
<CartDropdown cartItems={cartItems} onClose={this.toggleCart} onCheckout={()=>{
/*open the Drawer inside <LoginComponent */
if (isUserLoggedIn().isLoggedIn) {

View File

@@ -12,12 +12,10 @@ import IconButton from "@mui/material/IconButton";
import SearchIcon from "@mui/icons-material/Search";
import KeyboardReturnIcon from "@mui/icons-material/KeyboardReturn";
import { useNavigate, useLocation } from "react-router-dom";
import SocketContext from "../../contexts/SocketContext.js";
const SearchBar = () => {
const navigate = useNavigate();
const location = useLocation();
const context = React.useContext(SocketContext);
const searchParams = new URLSearchParams(location.search);
// State management
@@ -60,7 +58,7 @@ const SearchBar = () => {
// @note Autocomplete function using getSearchProducts Socket.io API - returns objects with name and seoName
const fetchAutocomplete = React.useCallback(
(query) => {
if (!context || !context.socket || !context.socket.connected || !query || query.length < 2) {
if (!query || query.length < 2) {
setSuggestions([]);
setShowSuggestions(false);
setLoadingSuggestions(false);
@@ -69,7 +67,7 @@ const SearchBar = () => {
setLoadingSuggestions(true);
context.socket.emit(
window.socketManager.emit(
"getSearchProducts",
{
query: query.trim(),
@@ -92,7 +90,7 @@ const SearchBar = () => {
}
);
},
[context]
[]
);
const handleSearchChange = (e) => {

View File

@@ -5,7 +5,6 @@ import CheckoutForm from "./CheckoutForm.js";
import PaymentConfirmationDialog from "./PaymentConfirmationDialog.js";
import OrderProcessingService from "./OrderProcessingService.js";
import CheckoutValidation from "./CheckoutValidation.js";
import SocketContext from "../../contexts/SocketContext.js";
import { withI18n } from "../../i18n/index.js";
class CartTab extends Component {
@@ -68,8 +67,7 @@ class CartTab extends Component {
// @note Add method to fetch and apply order template prefill data
fetchOrderTemplate = () => {
if (this.context && this.context.socket && this.context.socket.connected) {
this.context.socket.emit('getOrderTemplate', (response) => {
window.socketManager.emit('getOrderTemplate', (response) => {
if (response.success && response.orderTemplate) {
const template = response.orderTemplate;
@@ -147,7 +145,6 @@ class CartTab extends Component {
console.log("No order template available or failed to fetch");
}
});
}
};
componentDidMount() {
@@ -468,7 +465,6 @@ class CartTab extends Component {
{!showPaymentConfirmation && (
<CartDropdown
cartItems={cartItems}
socket={this.context.socket}
showDetailedSummary={showStripePayment}
deliveryMethod={deliveryMethod}
deliveryCost={deliveryCost}
@@ -539,7 +535,4 @@ class CartTab extends Component {
}
}
// Set static contextType to access the socket
CartTab.contextType = SocketContext;
export default withI18n()(CartTab);