This commit is contained in:
seb
2025-07-02 12:49:06 +02:00
commit edbd56f6a9
123 changed files with 32598 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
import React, { Component } from 'react';
import GoogleAuthContext from '../contexts/GoogleAuthContext.js';
class GoogleAuthProvider extends Component {
constructor(props) {
super(props);
this.state = {
isLoaded: false,
error: null,
loadingStarted: false
};
// Initialize Google API client ID
this.clientId = props.clientId;
}
componentDidMount() {
// Load the Google Sign-In API script
this.loadGoogleScript();
}
loadGoogleScript = () => {
// Prevent multiple load attempts
if (this.state.loadingStarted) {
return;
}
this.setState({ loadingStarted: true });
// Check if the script is already loaded
if (window.google && window.google.accounts && window.google.accounts.id) {
this.setState({ isLoaded: true });
return;
}
if (document.getElementById('google-auth-script')) {
// Script tag exists but may not be fully loaded yet
const checkGoogleLoaded = setInterval(() => {
if (window.google && window.google.accounts && window.google.accounts.id) {
this.setState({ isLoaded: true });
clearInterval(checkGoogleLoaded);
}
}, 100);
// Set a timeout to stop checking after a reasonable time
setTimeout(() => {
clearInterval(checkGoogleLoaded);
if (!this.state.isLoaded) {
this.setState({
error: new Error('Timeout waiting for Google Sign-In API to load'),
isLoaded: false
});
}
}, 10000); // 10 second timeout
return;
}
// Create and add the script tag
const script = document.createElement('script');
script.src = 'https://accounts.google.com/gsi/client';
script.id = 'google-auth-script';
script.async = true;
script.defer = true;
script.onload = () => {
// Give a small delay to ensure the API is fully initialized
setTimeout(() => {
if (window.google && window.google.accounts && window.google.accounts.id) {
this.setState({ isLoaded: true });
} else {
this.setState({
error: new Error('Google Sign-In API loaded but not initialized properly'),
isLoaded: false
});
}
}, 100);
};
script.onerror = () => {
this.setState({
error: new Error('Failed to load Google Sign-In API script'),
isLoaded: false
});
};
document.body.appendChild(script);
};
render() {
const { children } = this.props;
const { isLoaded, error } = this.state;
// Context value includes loading state, clientId and any errors
const contextValue = {
clientId: this.clientId,
isLoaded,
error
};
return (
<GoogleAuthContext.Provider value={contextValue}>
{children}
</GoogleAuthContext.Provider>
);
}
}
export default GoogleAuthProvider;

View File

@@ -0,0 +1,129 @@
import React, { Component } from "react";
import io from "socket.io-client";
import SocketContext from "../contexts/SocketContext.js";
import { isUserLoggedIn } from "../components/LoginComponent.js";
class SocketProvider extends Component {
constructor(props) {
super(props);
this.socket = null;
this.state = {
connected: false,
showPrerenderFallback: true,
};
}
connectToSocket(url) {
if (this.socket) {
this.socket.disconnect();
}
console.log(`SocketProvider: Connecting to socket server... ${url}`);
this.socket = io(url, {
transports: ["websocket"],
});
this.socket.on("connect", () => {
const user = isUserLoggedIn();
console.log("SocketProvider: connected", user);
// Check for ID parameter in URL and emit setId if present
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get("id");
if (id) {
console.log("SocketProvider: Emitting setId with ID:", id);
this.socket.emit("setId", { id });
}
if (user && user.isLoggedIn && user.user.token)
this.socket.emit(
"verifyToken",
{ token: user.user.token },
(response) => {
console.log("SocketProvider: verifyToken", response);
if (response.success) {
try {
window.cart = JSON.parse(response.user.cart);
window.dispatchEvent(new CustomEvent("cart"));
} catch (error) {
console.error("Error parsing cart :", response.user, error);
}
} else {
sessionStorage.removeItem("user");
window.location.reload();
}
}
);
this.setState({ connected: true, showPrerenderFallback: false });
console.log("SocketProvider: Socket connected successfully");
});
this.socket.on("disconnect", () => {
this.setState({ connected: false });
console.log("SocketProvider: Socket disconnected");
});
this.socket.on("connect_error", (error) => {
console.error("SocketProvider: Connection error:", error);
this.handleConnectionFailure();
});
this.socket.on("reconnect_attempt", (attemptNumber) => {
console.log(`SocketProvider: Reconnection attempt ${attemptNumber}`);
});
this.socket.on("reconnect_failed", () => {
console.error("SocketProvider: Failed to reconnect");
this.handleConnectionFailure();
});
}
handleConnectionFailure() {
// Check if prerendered fallback content is available
if (typeof window !== "undefined" && window.__PRERENDER_FALLBACK__) {
console.log("SocketProvider: Using prerendered fallback content");
this.setState({ showPrerenderFallback: true });
}
}
componentDidMount() {
this.connectToSocket(this.props.url);
}
componentWillUnmount() {
if (this.socket) {
console.log("SocketProvider: Disconnecting socket");
this.socket.disconnect();
}
}
render() {
const showPrerenderFallback = this.state.showPrerenderFallback &&
typeof window !== "undefined" &&
window.__PRERENDER_FALLBACK__;
return (
<SocketContext.Provider value={this.socket}>
{/* Always render children but control visibility */}
<div style={{ display: this.state.connected ? 'block' : 'none' }}>
{this.props.children}
</div>
{/* Show prerendered fallback when appropriate */}
{showPrerenderFallback && (
<div
dangerouslySetInnerHTML={{
__html: window.__PRERENDER_FALLBACK__.content,
}}
/>
)}
{/* Show default fallback when not connected and no prerendered content */}
{!this.state.connected && !showPrerenderFallback && this.props.fallback}
</SocketContext.Provider>
);
}
}
export default SocketProvider;