From 4e6b63a6a4df6720799617fd7246af29b33b63e2 Mon Sep 17 00:00:00 2001 From: sebseb7 Date: Wed, 23 Jul 2025 08:08:58 +0200 Subject: [PATCH] refactor: replace socket prop usage with window.socketManager for consistent socket handling across components --- src/components/ArticleAvailabilityForm.js | 6 +-- src/components/ArticleQuestionForm.js | 7 ++- src/components/ArticleRatingForm.js | 6 +-- src/components/CartItem.js | 5 +- src/components/ChatAssistant.js | 43 +++++----------- src/components/LoginComponent.js | 63 +++++------------------ src/components/PaymentSuccess.js | 18 ++----- src/components/header/ButtonGroup.js | 36 ++++--------- src/components/header/SearchBar.js | 8 ++- src/components/profile/CartTab.js | 9 +--- 10 files changed, 56 insertions(+), 145 deletions(-) diff --git a/src/components/ArticleAvailabilityForm.js b/src/components/ArticleAvailabilityForm.js index 62596ec..93e6d4a 100644 --- a/src/components/ArticleAvailabilityForm.js +++ b/src/components/ArticleAvailabilityForm.js @@ -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 }); diff --git a/src/components/ArticleQuestionForm.js b/src/components/ArticleQuestionForm.js index cd291dc..aa34ef9 100644 --- a/src/components/ArticleQuestionForm.js +++ b/src/components/ArticleQuestionForm.js @@ -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, diff --git a/src/components/ArticleRatingForm.js b/src/components/ArticleRatingForm.js index da314df..ed8789c 100644 --- a/src/components/ArticleRatingForm.js +++ b/src/components/ArticleRatingForm.js @@ -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, diff --git a/src/components/CartItem.js b/src/components/CartItem.js index f6c8bce..e00e90b 100644 --- a/src/components/CartItem.js +++ b/src/components/CartItem.js @@ -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}); } }) - // } } } } diff --git a/src/components/ChatAssistant.js b/src/components/ChatAssistant.js index ee611c5..b9076f4 100644 --- a/src/components/ChatAssistant.js +++ b/src/components/ChatAssistant.js @@ -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' }); - } + }; }; diff --git a/src/components/LoginComponent.js b/src/components/LoginComponent.js index 7fa779a..0921be8 100644 --- a/src/components/LoginComponent.js +++ b/src/components/LoginComponent.js @@ -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; diff --git a/src/components/PaymentSuccess.js b/src/components/PaymentSuccess.js index c9899d5..436c527 100644 --- a/src/components/PaymentSuccess.js +++ b/src/components/PaymentSuccess.js @@ -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); diff --git a/src/components/header/ButtonGroup.js b/src/components/header/ButtonGroup.js index e437c7b..60b75b4 100644 --- a/src/components/header/ButtonGroup.js +++ b/src/components/header/ButtonGroup.js @@ -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 { - + - { + { /*open the Drawer inside { 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) => { diff --git a/src/components/profile/CartTab.js b/src/components/profile/CartTab.js index e748d47..ab19306 100644 --- a/src/components/profile/CartTab.js +++ b/src/components/profile/CartTab.js @@ -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 && (