Refactor LoginComponent button text from 'Anmelden' to 'Login' and enhance CategoryList with mobile menu functionality, including collapsible categories and improved layout for mobile screens. Adjust Home component card heights for better responsiveness across devices.

This commit is contained in:
seb
2025-07-04 01:56:10 +02:00
parent 6afe2ca90f
commit 9fc4286b8e
3 changed files with 94 additions and 16 deletions

View File

@@ -543,7 +543,7 @@ export class LoginComponent extends Component {
onClick={this.handleOpen} onClick={this.handleOpen}
sx={{ my: 1, mx: 1.5 }} sx={{ my: 1, mx: 1.5 }}
> >
Anmelden Login
</Button> </Button>
) )
)} )}

View File

@@ -3,8 +3,11 @@ import Box from "@mui/material/Box";
import Container from "@mui/material/Container"; import Container from "@mui/material/Container";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Collapse from "@mui/material/Collapse";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import HomeIcon from "@mui/icons-material/Home"; import HomeIcon from "@mui/icons-material/Home";
import MenuIcon from "@mui/icons-material/Menu";
import CloseIcon from "@mui/icons-material/Close";
class CategoryList extends Component { class CategoryList extends Component {
findCategoryById = (category, targetId) => { findCategoryById = (category, targetId) => {
@@ -54,6 +57,7 @@ class CategoryList extends Component {
level3Categories: [], // Children of active level 2 category level3Categories: [], // Children of active level 2 category
activePath: [], // Array of active category objects for each level activePath: [], // Array of active category objects for each level
fetchedCategories: false, fetchedCategories: false,
mobileMenuOpen: false, // State for mobile collapsible menu
}; };
// Try to get cached data for SSR // Try to get cached data for SSR
@@ -313,18 +317,32 @@ class CategoryList extends Component {
}); });
}; };
handleMobileMenuToggle = () => {
this.setState(prevState => ({
mobileMenuOpen: !prevState.mobileMenuOpen
}));
};
handleMobileCategoryClick = () => {
// Close the mobile menu when a category is selected
this.setState({
mobileMenuOpen: false
});
};
render() { render() {
const { level1Categories, level2Categories, level3Categories, activePath } = const { level1Categories, activePath, mobileMenuOpen } =
this.state; this.state;
const renderCategoryRow = (categories, level = 1) => ( const renderCategoryRow = (categories, level = 1, isMobile = false) => (
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
justifyContent: "flex-start", justifyContent: "flex-start",
alignItems: "center", alignItems: "center",
flexWrap: "nowrap", flexWrap: isMobile ? "wrap" : "nowrap",
overflowX: "auto", overflowX: isMobile ? "visible" : "auto",
flexDirection: isMobile ? "column" : "row",
py: 0.5, // Add vertical padding to prevent border clipping py: 0.5, // Add vertical padding to prevent border clipping
"&::-webkit-scrollbar": { "&::-webkit-scrollbar": {
display: "none", display: "none",
@@ -340,17 +358,19 @@ class CategoryList extends Component {
color="inherit" color="inherit"
size="small" size="small"
aria-label="Zur Startseite" aria-label="Zur Startseite"
onClick={isMobile ? this.handleMobileCategoryClick : undefined}
sx={{ sx={{
fontSize: "0.75rem", fontSize: "0.75rem",
fontWeight: "normal", fontWeight: "normal",
textTransform: "none", textTransform: "none",
whiteSpace: "nowrap", whiteSpace: "nowrap",
opacity: 0.9, opacity: 0.9,
mx: 0.5, mx: isMobile ? 0 : 0.5,
my: 0.25, // Add consistent vertical margin to account for borders my: 0.25, // Add consistent vertical margin to account for borders
minWidth: "auto", minWidth: isMobile ? "100%" : "auto",
border: "2px solid transparent", // Always have border space border: "2px solid transparent", // Always have border space
borderRadius: 1, // Always have border radius borderRadius: 1, // Always have border radius
justifyContent: isMobile ? "flex-start" : "center",
...(this.props.activeCategoryId === null && { ...(this.props.activeCategoryId === null && {
boxShadow: "0 4px 12px rgba(0,0,0,0.5)", boxShadow: "0 4px 12px rgba(0,0,0,0.5)",
transform: "translateY(-2px)", transform: "translateY(-2px)",
@@ -367,7 +387,8 @@ class CategoryList extends Component {
}, },
}} }}
> >
<HomeIcon sx={{ fontSize: "1rem" }} /> <HomeIcon sx={{ fontSize: "1rem", mr: isMobile ? 1 : 0 }} />
{isMobile && "Startseite"}
</Button> </Button>
)} )}
{this.state.fetchedCategories && categories.length > 0 ? ( {this.state.fetchedCategories && categories.length > 0 ? (
@@ -385,16 +406,19 @@ class CategoryList extends Component {
to={`/Kategorie/${category.seoName}`} to={`/Kategorie/${category.seoName}`}
color="inherit" color="inherit"
size="small" size="small"
onClick={isMobile ? this.handleMobileCategoryClick : undefined}
sx={{ sx={{
fontSize: "0.75rem", fontSize: "0.75rem",
fontWeight: "normal", fontWeight: "normal",
textTransform: "none", textTransform: "none",
whiteSpace: "nowrap", whiteSpace: "nowrap",
opacity: 0.9, opacity: 0.9,
mx: 0.5, mx: isMobile ? 0 : 0.5,
my: 0.25, // Add consistent vertical margin to account for borders my: 0.25, // Add consistent vertical margin to account for borders
minWidth: isMobile ? "100%" : "auto",
border: "2px solid transparent", // Always have border space border: "2px solid transparent", // Always have border space
borderRadius: 1, // Always have border radius borderRadius: 1, // Always have border radius
justifyContent: isMobile ? "flex-start" : "center",
...(isActiveAtThisLevel && { ...(isActiveAtThisLevel && {
boxShadow: "0 4px 12px rgba(0,0,0,0.5)", boxShadow: "0 4px 12px rgba(0,0,0,0.5)",
transform: "translateY(-2px)", transform: "translateY(-2px)",
@@ -417,7 +441,7 @@ class CategoryList extends Component {
})} })}
</> </>
) : ( ) : (
level === 1 && ( level === 1 && !isMobile && (
<Typography <Typography
variant="caption" variant="caption"
color="inherit" color="inherit"
@@ -447,30 +471,84 @@ class CategoryList extends Component {
return ( return (
<Profiler id="CategoryList" onRender={onRenderCallback}> <Profiler id="CategoryList" onRender={onRenderCallback}>
{/* Desktop Menu - Hidden on xs, shown on sm and up */}
<Box <Box
sx={{ sx={{
width: "100%", width: "100%",
bgcolor: "primary.dark", bgcolor: "primary.dark",
display: { xs: "none", md: "block" }, display: { xs: "none", sm: "block" },
}} }}
> >
<Container maxWidth="lg" sx={{ px: 2 }}> <Container maxWidth="lg" sx={{ px: 2 }}>
{/* Level 1 Categories Row - Always shown */} {/* Level 1 Categories Row - Always shown */}
{renderCategoryRow(level1Categories, 1)} {renderCategoryRow(level1Categories, 1, false)}
{/* Level 2 Categories Row - Show when level 1 is selected */} {/* Level 2 Categories Row - Show when level 1 is selected */}
{/* DISABLED FOR NOW
{level2Categories.length > 0 && ( {level2Categories.length > 0 && (
<Box sx={{ mt: 0.5 }}> <Box sx={{ mt: 0.5 }}>
{renderCategoryRow(level2Categories, 2)} {renderCategoryRow(level2Categories, 2, false)}
</Box> </Box>
)} )}
{/* Level 3 Categories Row - Show when level 2 is selected */} {/* Level 3 Categories Row - Show when level 2 is selected */}
{/* DISABLED FOR NOW
{level3Categories.length > 0 && ( {level3Categories.length > 0 && (
<Box sx={{ mt: 0.5 }}> <Box sx={{ mt: 0.5 }}>
{renderCategoryRow(level3Categories, 3)} {renderCategoryRow(level3Categories, 3, false)}
</Box> </Box>
)} )}
*/}
</Container>
</Box>
{/* Mobile Menu - Shown only on xs screens */}
<Box
sx={{
width: "100%",
bgcolor: "primary.dark",
display: { xs: "block", sm: "none" },
}}
>
<Container maxWidth="lg" sx={{ px: 2 }}>
{/* Toggle Button */}
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
py: 1,
cursor: "pointer",
"&:hover": {
bgcolor: "rgba(255,255,255,0.1)"
}
}}
onClick={this.handleMobileMenuToggle}
role="button"
tabIndex={0}
aria-label={mobileMenuOpen ? "Kategorien schließen" : "Kategorien öffnen"}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
this.handleMobileMenuToggle();
}
}}
>
<Typography variant="subtitle2" color="inherit" sx={{ fontWeight: "bold" }}>
Kategorien
</Typography>
<Box sx={{ display: "flex", alignItems: "center" }}>
{mobileMenuOpen ? <CloseIcon /> : <MenuIcon />}
</Box>
</Box>
{/* Collapsible Menu Content */}
<Collapse in={mobileMenuOpen}>
<Box sx={{ pb: 2 }}>
{/* Level 1 Categories - Only level shown in mobile menu */}
{renderCategoryRow(level1Categories, 1, true)}
</Box>
</Collapse>
</Container> </Container>
</Box> </Box>
</Profiler> </Profiler>

View File

@@ -407,7 +407,7 @@ const Home = () => {
color: "text.primary", color: "text.primary",
borderRadius: 2, borderRadius: 2,
overflow: "hidden", overflow: "hidden",
height: { xs: 250, sm: 300 }, height: { xs: 150, sm: 200, md: 300 },
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
transition: "all 0.3s ease", transition: "all 0.3s ease",
@@ -468,7 +468,7 @@ const Home = () => {
color: "text.primary", color: "text.primary",
borderRadius: 2, borderRadius: 2,
overflow: "hidden", overflow: "hidden",
height: { xs: 250, sm: 300 }, height: { xs: 150, sm: 200, md: 300 },
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
boxShadow: 10, boxShadow: 10,