diff --git a/src/App.js b/src/App.js index b7c2aca..5b6db1a 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,5 @@ import React, { useState, useEffect, lazy, Suspense } from "react"; +import { createTheme } from "@mui/material/styles"; import { Routes, Route, @@ -14,6 +15,7 @@ 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 config from "./config.js"; @@ -60,11 +62,13 @@ const ThcTestPage = lazy(() => import(/* webpackChunkName: "thc-test" */ "./page // 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")); -import { createTheme } from "@mui/material/styles"; const deleteMessages = () => { console.log("Deleting messages"); @@ -72,13 +76,16 @@ const deleteMessages = () => { }; -const AppContent = ({ currentTheme, onThemeChange }) => { +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); + // 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(); @@ -138,6 +145,35 @@ const AppContent = ({ currentTheme, onThemeChange }) => { // 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 ( { {/* Admin page */} } /> - + {/* Admin Users page */} } /> - + {/* Admin Server Logs page */} } /> @@ -312,6 +348,25 @@ const AppContent = ({ currentTheme, onThemeChange }) => { )} + {/* Development-only Prerender Test FAB */} + {isDevelopment && ( + + navigate('/prerenderTest/home')} + > + + + + )} + {/* Development-only Theme Customizer Dialog */} {isDevelopment && isThemeCustomizerOpen && ( { diff --git a/src/PrerenderCategory.js b/src/PrerenderCategory.js index 066273c..0e3fdb5 100644 --- a/src/PrerenderCategory.js +++ b/src/PrerenderCategory.js @@ -3,7 +3,7 @@ import { Box, AppBar, Toolbar, Container, Typography, Grid, Card, CardMedia, Car import Footer from './components/Footer.js'; import { Logo, SearchBar, CategoryList } from './components/header/index.js'; -const PrerenderCategory = ({ categoryId, categoryName, categorySeoName, productData }) => { +const PrerenderCategory = ({ categoryId, categoryName, categorySeoName: _categorySeoName, productData }) => { const products = productData?.products || []; return ( diff --git a/src/PrerenderHome.js b/src/PrerenderHome.js index cfc2693..4aa1de4 100644 --- a/src/PrerenderHome.js +++ b/src/PrerenderHome.js @@ -1,13 +1,12 @@ -const React = require('react'); -const { - Box, - AppBar, - Toolbar, - Container -} = require('@mui/material'); -const Footer = require('./components/Footer.js').default; -const { Logo, CategoryList } = require('./components/header/index.js'); -const MainPageLayout = require('./components/MainPageLayout.js').default; +import React from 'react'; +import { + Box, + AppBar, + Toolbar, + Container +} from '@mui/material'; +import Footer from './components/Footer.js'; +import { Logo, CategoryList } from './components/header/index.js'; class PrerenderHome extends React.Component { @@ -65,4 +64,4 @@ class PrerenderHome extends React.Component { } } -module.exports = { default: PrerenderHome }; \ No newline at end of file +export default PrerenderHome; \ No newline at end of file diff --git a/src/PrerenderNotFound.js b/src/PrerenderNotFound.js index 835be4f..f8c7382 100644 --- a/src/PrerenderNotFound.js +++ b/src/PrerenderNotFound.js @@ -1,13 +1,13 @@ -const React = require('react'); -const { - Box, - AppBar, - Toolbar, - Container -} = require('@mui/material'); -const Footer = require('./components/Footer.js').default; -const { Logo } = require('./components/header/index.js'); -const NotFound404 = require('./pages/NotFound404.js').default; +import React from 'react'; +import { + Box, + AppBar, + Toolbar, + Container +} from '@mui/material'; +import Footer from './components/Footer.js'; +import { Logo } from './components/header/index.js'; +import NotFound404 from './pages/NotFound404.js'; class PrerenderNotFound extends React.Component { render() { @@ -89,4 +89,4 @@ class PrerenderNotFound extends React.Component { } } -module.exports = { default: PrerenderNotFound }; \ No newline at end of file +export default PrerenderNotFound; \ No newline at end of file diff --git a/src/PrerenderProduct.js b/src/PrerenderProduct.js index 64ada6d..4221a26 100644 --- a/src/PrerenderProduct.js +++ b/src/PrerenderProduct.js @@ -1,20 +1,17 @@ -const React = require('react'); -const { - Container, - Typography, - Card, - CardMedia, - Grid, +import React from 'react'; +import { + Container, + Typography, Box, Chip, Stack, AppBar, Toolbar, Button -} = require('@mui/material'); -const Footer = require('./components/Footer.js').default; -const { Logo } = require('./components/header/index.js'); -const ProductImage = require('./components/ProductImage.js').default; +} from '@mui/material'; +import Footer from './components/Footer.js'; +import { Logo } from './components/header/index.js'; +import ProductImage from './components/ProductImage.js'; // Utility function to clean product names by removing trailing number in parentheses const cleanProductName = (name) => { @@ -46,9 +43,6 @@ class PrerenderProduct extends React.Component { const product = productData.product; const attributes = productData.attributes || []; - const mainImage = product.pictureList && product.pictureList.trim() - ? `/assets/images/prod${product.pictureList.split(',')[0].trim()}.jpg` - : '/assets/images/nopicture.jpg'; // Format price with tax const priceWithTax = new Intl.NumberFormat("de-DE", { @@ -563,4 +557,4 @@ class PrerenderProduct extends React.Component { } } -module.exports = { default: PrerenderProduct }; \ No newline at end of file +export default PrerenderProduct; \ No newline at end of file diff --git a/src/PrerenderSitemap.js b/src/PrerenderSitemap.js index f640788..71fb246 100644 --- a/src/PrerenderSitemap.js +++ b/src/PrerenderSitemap.js @@ -1,17 +1,11 @@ -const React = require('react'); -const { - Box, - AppBar, - Toolbar, - Container, +import React from 'react'; +import { Typography, List, ListItem, ListItemText -} = require('@mui/material'); -const Footer = require('./components/Footer.js').default; -const { Logo, CategoryList } = require('./components/header/index.js'); -const LegalPage = require('./pages/LegalPage.js').default; +} from '@mui/material'; +import LegalPage from './pages/LegalPage.js'; const PrerenderSitemap = ({ categoryData }) => { // Process category data to flatten the hierarchy @@ -134,4 +128,4 @@ const PrerenderSitemap = ({ categoryData }) => { return React.createElement(LegalPage, { title: 'Sitemap', content: content }); }; -module.exports = { default: PrerenderSitemap }; \ No newline at end of file +export default PrerenderSitemap; \ No newline at end of file diff --git a/src/pages/PrerenderTestPage.js b/src/pages/PrerenderTestPage.js new file mode 100644 index 0000000..96739e2 --- /dev/null +++ b/src/pages/PrerenderTestPage.js @@ -0,0 +1,292 @@ +import React, { useState, lazy, Suspense } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import { + Box, + Container, + Typography, + Paper, + Button, + Grid, + Card, + CardContent, + CardActions, + Chip, + Alert, + CircularProgress +} from '@mui/material'; +import { styled } from '@mui/material/styles'; +import ScienceIcon from '@mui/icons-material/Science'; + +// Lazy load prerender components for testing +const PrerenderHome = lazy(() => import('../PrerenderHome.js')); +const PrerenderCategory = lazy(() => import('../PrerenderCategory.js')); +const PrerenderProduct = lazy(() => import('../PrerenderProduct.js')); +const PrerenderKonfigurator = lazy(() => import('../PrerenderKonfigurator.js')); +const PrerenderProfile = lazy(() => import('../PrerenderProfile.js')); +const PrerenderSitemap = lazy(() => import('../PrerenderSitemap.js')); + +const StyledPaper = styled(Paper)(({ theme }) => ({ + padding: theme.spacing(3), + margin: theme.spacing(2, 0), + backgroundColor: theme.palette.background.paper, +})); + +const ComponentCard = styled(Card)(({ theme }) => ({ + height: '100%', + display: 'flex', + flexDirection: 'column', + transition: 'transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out', + '&:hover': { + transform: 'translateY(-2px)', + boxShadow: theme.shadows[4], + }, +})); + +const PrerenderTestPage = () => { + const { componentName } = useParams(); + const navigate = useNavigate(); + const [selectedComponent, setSelectedComponent] = useState(componentName || 'home'); + const [componentProps, setComponentProps] = useState({}); + + // Available components for testing - memoized to prevent re-renders + const availableComponents = React.useMemo(() => ({ + // Prerender components + home: { + component: PrerenderHome, + name: 'Home Page', + description: 'Main homepage component', + category: 'Prerender', + props: {} + }, + category: { + component: PrerenderCategory, + name: 'Category Page', + description: 'Category listing with products', + category: 'Prerender', + props: { + categoryId: 209, + categoryName: 'Test Category', + categorySeoName: 'test-category', + productData: null + } + }, + product: { + component: PrerenderProduct, + name: 'Product Page', + description: 'Individual product detail page', + category: 'Prerender', + props: { + productData: { + product: { + id: 1, + name: 'Test Product', + seoName: 'test-product', + description: 'This is a test product for prerender testing', + price: 99.99 + } + } + } + }, + konfigurator: { + component: PrerenderKonfigurator, + name: 'Konfigurator', + description: 'Grow tent configurator', + category: 'Prerender', + props: {} + }, + profile: { + component: PrerenderProfile, + name: 'Profile Page', + description: 'User profile page', + category: 'Prerender', + props: {} + }, + sitemap: { + component: PrerenderSitemap, + name: 'Sitemap', + description: 'Site navigation map', + category: 'Prerender', + props: { + categoryData: null + } + } + }), []); + + React.useEffect(() => { + if (componentName && availableComponents[componentName]) { + setSelectedComponent(componentName); + setComponentProps(availableComponents[componentName].props); + } + }, [componentName, availableComponents]); + + const handleComponentChange = (componentKey) => { + setSelectedComponent(componentKey); + setComponentProps(availableComponents[componentKey].props); + navigate(`/prerenderTest/${componentKey}`); + }; + + const renderComponent = () => { + const componentConfig = availableComponents[selectedComponent]; + if (!componentConfig) return null; + + const Component = componentConfig.component; + + return ( + + + + }> + + + ); + }; + + const getCategories = () => { + const categories = {}; + Object.keys(availableComponents).forEach(key => { + const category = availableComponents[key].category; + if (!categories[category]) { + categories[category] = []; + } + categories[category].push(key); + }); + return categories; + }; + + const categories = getCategories(); + + return ( + + + Prerender Preview Environment + + + + Preview prerender components dynamically during development + + + + This page allows you to preview prerender components in a development environment. + The actual prerender components remain unchanged and are used for static generation. + + + {/* Component Selection */} + + + Select Component to Preview + + + + {Object.keys(categories).map(category => ( + + + {category} Components + + + {categories[category].map(componentKey => { + const config = availableComponents[componentKey]; + return ( + + handleComponentChange(componentKey)} + sx={{ + cursor: 'pointer', + border: selectedComponent === componentKey ? '2px solid' : '1px solid', + borderColor: selectedComponent === componentKey ? 'primary.main' : 'divider' + }} + > + + + {config.name} + + + {config.description} + + + + + + + + + ); + })} + + + ))} + + + {/* Current Selection Info */} + + + Currently Previewing: {availableComponents[selectedComponent]?.name} + + + Component: {selectedComponent} | Category: {availableComponents[selectedComponent]?.category} + + + + + {/* Component Preview Area */} + + + Component Preview + + + + The component below is rendered dynamically for development preview. + In production, this would be prerendered as static HTML. + + + + {renderComponent()} + + + + {/* Navigation */} + + + + + + ); +}; + +export default PrerenderTestPage;