import React, { useState, useEffect, lazy, Suspense } from "react";
import { createTheme } from "@mui/material/styles";
import {
Routes,
Route,
Navigate,
useLocation,
useNavigate
} from "react-router-dom";
import { ThemeProvider } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import Box from "@mui/material/Box";
import CircularProgress from "@mui/material/CircularProgress";
import Fab from "@mui/material/Fab";
import Tooltip from "@mui/material/Tooltip";
import SmartToyIcon from "@mui/icons-material/SmartToy";
import PaletteIcon from "@mui/icons-material/Palette";
import ScienceIcon from "@mui/icons-material/Science";
import { CarouselProvider } from "./contexts/CarouselContext.js";
import { ProductContextProvider } from "./context/ProductContext.js";
import { CategoryContextProvider } from "./context/CategoryContext.js";
import TitleUpdater from "./components/TitleUpdater.js";
import config from "./config.js";
import ScrollToTop from "./components/ScrollToTop.js";
// Import i18n
import './i18n/index.js';
import { LanguageProvider } from './i18n/withTranslation.js';
import i18n from './i18n/index.js';
//import TelemetryService from './services/telemetryService.js';
import Header from "./components/Header.js";
import Footer from "./components/Footer.js";
import MainPageLayout from "./components/MainPageLayout.js";
// TEMPORARILY DISABLE ALL LAZY LOADING TO ELIMINATE CircularProgress
import Content from "./components/Content.js";
import ProductDetail from "./components/ProductDetail.js";
import ProfilePage from "./pages/ProfilePage.js";
import ResetPassword from "./pages/ResetPassword.js";
// Lazy load admin pages - only loaded when admin users access them
const AdminPage = lazy(() => import(/* webpackChunkName: "admin" */ "./pages/AdminPage.js"));
const UsersPage = lazy(() => import(/* webpackChunkName: "admin-users" */ "./pages/UsersPage.js"));
const ServerLogsPage = lazy(() => import(/* webpackChunkName: "admin-logs" */ "./pages/ServerLogsPage.js"));
// Lazy load legal pages - rarely accessed
const Datenschutz = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/Datenschutz.js"));
const AGB = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/AGB.js"));
//const NotFound404 = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/NotFound404.js")); } />
const Sitemap = lazy(() => import(/* webpackChunkName: "sitemap" */ "./pages/Sitemap.js"));
const Impressum = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/Impressum.js"));
const Batteriegesetzhinweise = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/Batteriegesetzhinweise.js"));
const Widerrufsrecht = lazy(() => import(/* webpackChunkName: "legal" */ "./pages/Widerrufsrecht.js"));
// Lazy load special features
const GrowTentKonfigurator = lazy(() => import(/* webpackChunkName: "konfigurator" */ "./pages/GrowTentKonfigurator.js"));
const ChatAssistant = lazy(() => import(/* webpackChunkName: "chat" */ "./components/ChatAssistant.js"));
// Lazy load separate pages that are truly different
const PresseverleihPage = lazy(() => import(/* webpackChunkName: "presseverleih" */ "./pages/PresseverleihPage.js"));
const ThcTestPage = lazy(() => import(/* webpackChunkName: "thc-test" */ "./pages/ThcTestPage.js"));
// Lazy load payment success page
const PaymentSuccess = lazy(() => import(/* webpackChunkName: "payment" */ "./components/PaymentSuccess.js"));
// Lazy load prerender component (development testing only)
const PrerenderHome = lazy(() => import(/* webpackChunkName: "prerender-home" */ "./PrerenderHome.js"));
// Import theme from separate file to reduce main bundle size
import defaultTheme from "./theme.js";
// Lazy load theme customizer for development only
const ThemeCustomizerDialog = lazy(() => import(/* webpackChunkName: "theme-customizer" */ "./components/ThemeCustomizerDialog.js"));
const deleteMessages = () => {
console.log("Deleting messages");
window.chatMessages = [];
};
const AppContent = ({ currentTheme, dynamicTheme, onThemeChange }) => {
// State to manage chat visibility
const [isChatOpen, setChatOpen] = useState(false);
const [authVersion, setAuthVersion] = useState(0);
// @note Theme customizer state for development mode
const [isThemeCustomizerOpen, setThemeCustomizerOpen] = useState(false);
// State to track active category for article pages
const [articleCategoryId, setArticleCategoryId] = useState(null);
// Remove duplicate theme state since it's passed as prop
// const [dynamicTheme, setDynamicTheme] = useState(createTheme(defaultTheme));
// Get current location
const location = useLocation();
const navigate = useNavigate();
useEffect(() => {
if (location.hash && location.hash.length > 1) {
// Check if it's a potential order ID (starts with # and has alphanumeric characters with dashes)
const potentialOrderId = location.hash.substring(1);
if (/^[A-Z0-9]+-[A-Z0-9]+$/i.test(potentialOrderId)) {
if (location.pathname !== "/profile") {
navigate(`/profile${location.hash}`, { replace: true });
}
}
}
}, [location, navigate]);
useEffect(() => {
const handleLogin = () => {
setAuthVersion((v) => v + 1);
};
window.addEventListener("userLoggedIn", handleLogin);
return () => {
window.removeEventListener("userLoggedIn", handleLogin);
};
}, []);
// Clear article category when navigating away from article pages
useEffect(() => {
const isArticlePage = location.pathname.startsWith('/Artikel/');
const isCategoryPage = location.pathname.startsWith('/Kategorie/');
const isHomePage = location.pathname === '/';
// Only clear article category when navigating to non-article pages
// (but keep it when going from category to article)
if (!isArticlePage && !isCategoryPage && !isHomePage) {
setArticleCategoryId(null);
}
}, [location.pathname]);
// Read article category from navigation state (when coming from product click)
useEffect(() => {
if (location.state && location.state.articleCategoryId !== undefined) {
if (location.state.articleCategoryId !== null) {
setArticleCategoryId(location.state.articleCategoryId);
}
// Clear the state so it doesn't persist on page refresh
navigate(location.pathname, { replace: true, state: {} });
}
}, [location.state, navigate, location.pathname]);
// Extract categoryId from pathname if on category route, or use article category
const getCategoryId = () => {
const match = location.pathname.match(/^\/Kategorie\/(.+)$/);
if (match) {
return match[1];
}
// For article pages, use the article category if available
const isArticlePage = location.pathname.startsWith('/Artikel/');
if (isArticlePage && articleCategoryId) {
return articleCategoryId;
}
return null;
};
const categoryId = getCategoryId();
// Handler to toggle chat visibility
const handleChatToggle = () => {
if (isChatOpen)
window.messageDeletionTimeout = setTimeout(deleteMessages, 1000 * 60);
if (!isChatOpen && window.messageDeletionTimeout)
clearTimeout(window.messageDeletionTimeout);
setChatOpen(!isChatOpen);
};
// Handler to close the chat
const handleChatClose = () => {
window.messageDeletionTimeout = setTimeout(deleteMessages, 1000 * 60);
setChatOpen(false);
};
// @note Theme customizer handlers for development mode
const handleThemeCustomizerToggle = () => {
setThemeCustomizerOpen(!isThemeCustomizerOpen);
};
// Check if we're in development mode
const isDevelopment = process.env.NODE_ENV === "development";
// Check if current route is a prerender test route
const isPrerenderTestRoute = isDevelopment && location.pathname === "/prerenderTest/home";
// If it's a prerender test route, render it standalone without app layout
if (isPrerenderTestRoute) {
return (
}>
);
}
// Regular app layout for all other routes
return (
) : (
)
}>
{/* Main pages using unified component */}
} />
} />
} />
{/* Category page - Render Content in parallel */}
}
/>
{/* Single product page */}
}
/>
{/* Search page - Render Content in parallel */}
} />
{/* Profile page */}
} />
{/* Payment success page for Mollie redirects */}
} />
{/* Reset password page */}
}
/>
{/* Admin page */}
} />
{/* Admin Users page */}
} />
{/* Admin Server Logs page */}
} />
{/* Legal pages */}
} />
} />
} />
} />
}
/>
} />
{/* Grow Tent Configurator */}
} />
{/* Separate pages that are truly different */}
} />
} />
{/* Fallback for undefined routes */}
} />
{/* Conditionally render the Chat Assistant */}
{isChatOpen && (
) : (
)
}>
)}
{/* Chat AI Assistant FAB */}
{/* GitHub Issue Reporter FAB
*/}
{/* Development-only Theme Customizer FAB */}
{isDevelopment && (
)}
{/* Development-only Prerender Test FAB */}
{isDevelopment && (
navigate('/prerenderTest/home')}
>
)}
{/* Development-only Theme Customizer Dialog */}
{isDevelopment && isThemeCustomizerOpen && (
) : (
)
}>
setThemeCustomizerOpen(false)}
theme={currentTheme}
onThemeChange={onThemeChange}
/>
)}
);
};
// Convert App to a functional component to use hooks
const App = () => {
// @note Theme state moved to App level to provide dynamic theming
const [currentTheme, setCurrentTheme] = useState(defaultTheme);
const [dynamicTheme, setDynamicTheme] = useState(createTheme(defaultTheme));
const handleThemeChange = (newTheme) => {
setCurrentTheme(newTheme);
setDynamicTheme(createTheme(newTheme));
};
// Make config globally available for language switching
useEffect(() => {
window.shopConfig = config;
}, []);
return (
);
};
export default App;
export { AppContent };