Files
reactShop/src/pages/PrerenderTestPage.js
sebseb7 6a144f7441 feat: add prerendering support and improve component imports
- Introduced a new PrerenderHome component for development testing.
- Updated App.js to conditionally render the PrerenderHome based on the route.
- Refactored several components to use ES6 import/export syntax for consistency.
- Enhanced AppContent to manage dynamic theming and added a development-only FAB for prerender testing.
- Minor adjustments to props in PrerenderCategory for clarity.
2025-08-31 06:04:55 +02:00

293 lines
9.1 KiB
JavaScript

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 (
<Suspense fallback={
<Box sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
minHeight: '200px'
}}>
<CircularProgress />
</Box>
}>
<Component {...componentProps} />
</Suspense>
);
};
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 (
<Container maxWidth="xl" sx={{ py: 4 }}>
<Typography variant="h3" component="h1" gutterBottom align="center">
Prerender Preview Environment
</Typography>
<Typography variant="body1" align="center" sx={{ mb: 4, color: 'text.secondary' }}>
Preview prerender components dynamically during development
</Typography>
<Alert severity="info" sx={{ mb: 3 }}>
This page allows you to preview prerender components in a development environment.
The actual prerender components remain unchanged and are used for static generation.
</Alert>
{/* Component Selection */}
<StyledPaper elevation={2}>
<Typography variant="h5" gutterBottom>
Select Component to Preview
</Typography>
<Grid container spacing={2} sx={{ mb: 3 }}>
{Object.keys(categories).map(category => (
<Grid item xs={12} key={category}>
<Typography variant="h6" sx={{ mb: 2, mt: 2 }}>
{category} Components
</Typography>
<Grid container spacing={2}>
{categories[category].map(componentKey => {
const config = availableComponents[componentKey];
return (
<Grid item xs={12} sm={6} md={4} lg={3} key={componentKey}>
<ComponentCard
onClick={() => handleComponentChange(componentKey)}
sx={{
cursor: 'pointer',
border: selectedComponent === componentKey ? '2px solid' : '1px solid',
borderColor: selectedComponent === componentKey ? 'primary.main' : 'divider'
}}
>
<CardContent sx={{ flexGrow: 1 }}>
<Typography variant="h6" component="div" gutterBottom>
{config.name}
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
{config.description}
</Typography>
<Chip
label={category}
size="small"
color={category === 'Prerender' ? 'primary' : 'secondary'}
variant="outlined"
/>
</CardContent>
<CardActions>
<Button
size="small"
variant={selectedComponent === componentKey ? 'contained' : 'outlined'}
fullWidth
startIcon={<ScienceIcon />}
>
{selectedComponent === componentKey ? 'Previewing' : 'Preview'}
</Button>
</CardActions>
</ComponentCard>
</Grid>
);
})}
</Grid>
</Grid>
))}
</Grid>
{/* Current Selection Info */}
<Box sx={{ mb: 3 }}>
<Typography variant="h6" gutterBottom>
Currently Previewing: {availableComponents[selectedComponent]?.name}
</Typography>
<Typography variant="body2" color="text.secondary">
Component: {selectedComponent} | Category: {availableComponents[selectedComponent]?.category}
</Typography>
</Box>
</StyledPaper>
{/* Component Preview Area */}
<StyledPaper elevation={1}>
<Typography variant="h5" gutterBottom>
Component Preview
</Typography>
<Alert severity="warning" sx={{ mb: 3 }}>
The component below is rendered dynamically for development preview.
In production, this would be prerendered as static HTML.
</Alert>
<Box sx={{
border: '1px solid',
borderColor: 'divider',
borderRadius: 1,
minHeight: '400px',
backgroundColor: 'background.default',
p: 2,
overflow: 'auto'
}}>
{renderComponent()}
</Box>
</StyledPaper>
{/* Navigation */}
<Box sx={{ mt: 4, textAlign: 'center' }}>
<Button
variant="outlined"
onClick={() => navigate('/')}
sx={{ mr: 2 }}
>
Back to Home
</Button>
<Button
variant="contained"
onClick={() => window.location.reload()}
>
Refresh Preview
</Button>
</Box>
</Container>
);
};
export default PrerenderTestPage;