- 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.
293 lines
9.1 KiB
JavaScript
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;
|