Enhance responsive design across components by adjusting padding, margins, and layout properties for better mobile usability. Updated styles in Content, Header, Product, ProductFilters, ProductList, and SearchBar components to improve visual consistency and user experience on various screen sizes.
This commit is contained in:
@@ -441,7 +441,7 @@ class Content extends Component {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container maxWidth="xl" sx={{ py: 2, flexGrow: 1, display: 'grid', gridTemplateRows: '1fr' }}>
|
<Container maxWidth="xl" sx={{ py: { xs: 0, sm: 2 }, px: { xs: 0, sm: 3 }, flexGrow: 1, display: 'grid', gridTemplateRows: '1fr' }}>
|
||||||
|
|
||||||
{showCategoryBoxes ? (
|
{showCategoryBoxes ? (
|
||||||
// Show category boxes layout when no products but have child categories
|
// Show category boxes layout when no products but have child categories
|
||||||
@@ -491,30 +491,20 @@ class Content extends Component {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Subcategories Grid */}
|
{/* Subcategories Grid */}
|
||||||
<Box sx={{ flex: 1, minWidth: 0 }}>
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
<CategoryBoxGrid
|
<CategoryBoxGrid categories={this.state.childCategories} />
|
||||||
categories={this.state.childCategories}
|
|
||||||
showTitle={false}
|
|
||||||
spacing={3}
|
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Just show subcategories without parent
|
// No parent category, just show subcategories
|
||||||
return (
|
return <CategoryBoxGrid categories={this.state.childCategories} />;
|
||||||
<CategoryBoxGrid
|
|
||||||
categories={this.state.childCategories}
|
|
||||||
showTitle={false}
|
|
||||||
spacing={3}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
})()}
|
})()}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Show parent category navigation when in 2nd or 3rd level but no subcategories */}
|
{/* Show standalone parent category navigation when there are only products */}
|
||||||
{this.state.loaded &&
|
{this.state.loaded &&
|
||||||
this.props.params.categoryId &&
|
this.props.params.categoryId &&
|
||||||
!(this.state.unfilteredProducts.length > 0 && this.state.childCategories.length > 0) && (() => {
|
!(this.state.unfilteredProducts.length > 0 && this.state.childCategories.length > 0) && (() => {
|
||||||
@@ -558,7 +548,7 @@ class Content extends Component {
|
|||||||
<Box sx={{
|
<Box sx={{
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
gridTemplateColumns: { xs: '1fr', sm: '1fr 2fr', md: '1fr 3fr', lg: '1fr 4fr', xl: '1fr 4fr' },
|
gridTemplateColumns: { xs: '1fr', sm: '1fr 2fr', md: '1fr 3fr', lg: '1fr 4fr', xl: '1fr 4fr' },
|
||||||
gap: 3
|
gap: { xs: 0, sm: 3 }
|
||||||
}}>
|
}}>
|
||||||
|
|
||||||
<Stack direction="row" spacing={0} sx={{
|
<Stack direction="row" spacing={0} sx={{
|
||||||
|
|||||||
@@ -42,8 +42,12 @@ class Header extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AppBar position="sticky" color="primary" elevation={0} sx={{ zIndex: 1100 }}>
|
<AppBar position="sticky" color="primary" elevation={0} sx={{ zIndex: 1100 }}>
|
||||||
<Toolbar sx={{ minHeight: 64 }}>
|
<Toolbar sx={{ minHeight: 64, py: { xs: 0.5, sm: 0 } }}>
|
||||||
<Container maxWidth="lg" sx={{ display: 'flex', alignItems: 'center' }}>
|
<Container maxWidth="lg" sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
px: { xs: 0, sm: 3 }
|
||||||
|
}}>
|
||||||
{/* First row: Logo and ButtonGroup on xs, all items on larger screens */}
|
{/* First row: Logo and ButtonGroup on xs, all items on larger screens */}
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -56,25 +60,38 @@ class Header extends Component {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
justifyContent: { xs: 'space-between', sm: 'flex-start' }
|
justifyContent: { xs: 'space-between', sm: 'flex-start' },
|
||||||
|
minHeight: { xs: 52, sm: 'auto' },
|
||||||
|
px: { xs: 0, sm: 0 }
|
||||||
}}>
|
}}>
|
||||||
<Logo />
|
<Logo />
|
||||||
{/* SearchBar visible on sm and up */}
|
{/* SearchBar visible on sm and up */}
|
||||||
<Box sx={{ display: { xs: 'none', sm: 'block' }, flexGrow: 1 }}>
|
<Box sx={{ display: { xs: 'none', sm: 'block' }, flexGrow: 1 }}>
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: { xs: 'flex-end', sm: 'center' },
|
||||||
|
transform: { xs: 'translateY(4px) translateX(9px)', sm: 'none' },
|
||||||
|
ml: { xs: 0, sm: 0 }
|
||||||
|
}}>
|
||||||
<ButtonGroupWithRouter socket={socket}/>
|
<ButtonGroupWithRouter socket={socket}/>
|
||||||
</Box>
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
{/* Second row: SearchBar only on xs */}
|
{/* Second row: SearchBar only on xs - make it wider */}
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
display: { xs: 'block', sm: 'none' },
|
display: { xs: 'block', sm: 'none' },
|
||||||
width: '100%',
|
width: '100%',
|
||||||
mt: 1,mb: 1
|
mt: { xs: 1, sm: 0 },
|
||||||
|
mb: { xs: 0.5, sm: 0 },
|
||||||
|
px: { xs: 0, sm: 0 }
|
||||||
}}>
|
}}>
|
||||||
|
<Box sx={{ width: '100%' }}>
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
</Box>
|
||||||
</Container>
|
</Container>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
{(isHomePage || this.props.categoryId || isProfilePage) && <CategoryList categoryId={209} activeCategoryId={this.props.categoryId} socket={socket} socketB={socketB} />}
|
{(isHomePage || this.props.categoryId || isProfilePage) && <CategoryList categoryId={209} activeCategoryId={this.props.categoryId} socket={socket} socketB={socketB} />}
|
||||||
|
|||||||
@@ -180,18 +180,21 @@ class Product extends Component {
|
|||||||
|
|
||||||
<Card
|
<Card
|
||||||
sx={{
|
sx={{
|
||||||
width: { xs: 'calc(100vw - 48px)', sm: '250px' },
|
width: { xs: '100vw', sm: '250px' },
|
||||||
minWidth: { xs: 'calc(100vw - 48px)', sm: '250px' },
|
minWidth: { xs: '100vw', sm: '250px' },
|
||||||
height: '100%',
|
height: '100%',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
transition: 'transform 0.3s ease, box-shadow 0.3s ease',
|
transition: 'transform 0.3s ease, box-shadow 0.3s ease',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
borderRadius: '8px',
|
borderRadius: { xs: 0, sm: '8px' },
|
||||||
|
border: { xs: 'none', sm: 'inherit' },
|
||||||
|
boxShadow: { xs: 'none', sm: 'inherit' },
|
||||||
|
mx: { xs: 0, sm: 'auto' },
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
transform: 'translateY(-5px)',
|
transform: { xs: 'none', sm: 'translateY(-5px)' },
|
||||||
boxShadow: '0px 10px 20px rgba(0,0,0,0.1)'
|
boxShadow: { xs: 'none', sm: '0px 10px 20px rgba(0,0,0,0.1)' }
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -162,13 +162,17 @@ class ProductFilters extends Component {
|
|||||||
return (
|
return (
|
||||||
<Paper
|
<Paper
|
||||||
id="filters-paper"
|
id="filters-paper"
|
||||||
elevation={1}
|
elevation={window.innerWidth < 600 ? 0 : 1}
|
||||||
sx={{
|
sx={{
|
||||||
p: 2,
|
p: { xs: 1, sm: 2 },
|
||||||
borderRadius: 2,
|
borderRadius: { xs: 0, sm: 2 },
|
||||||
bgcolor: 'background.paper',
|
bgcolor: 'background.paper',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column'
|
flexDirection: 'column',
|
||||||
|
border: { xs: 'none', sm: 'inherit' },
|
||||||
|
boxShadow: { xs: 'none', sm: 'inherit' },
|
||||||
|
mx: { xs: 0, sm: 'auto' },
|
||||||
|
width: { xs: '100%', sm: 'auto' }
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|||||||
@@ -123,8 +123,14 @@ class ProductList extends Component {
|
|||||||
|
|
||||||
renderPagination = (pages, page) => {
|
renderPagination = (pages, page) => {
|
||||||
return (
|
return (
|
||||||
<Box sx={{ height: 64, display: 'flex', alignItems: 'center', justifyContent: 'left' }}>
|
<Box sx={{
|
||||||
{((this.state.itemsPerPage==='all')||(this.props.products.length<this.state.itemsPerPage))?null:
|
height: 64,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'left',
|
||||||
|
width: '100%'
|
||||||
|
}}>
|
||||||
|
{(this.state.itemsPerPage==='all')?null:
|
||||||
<Pagination
|
<Pagination
|
||||||
count={pages}
|
count={pages}
|
||||||
page={page}
|
page={page}
|
||||||
@@ -164,15 +170,28 @@ class ProductList extends Component {
|
|||||||
const products = this.state.itemsPerPage==='all'?[...filteredProducts]:filteredProducts.slice((this.state.page - 1) * this.state.itemsPerPage , this.state.page * this.state.itemsPerPage);
|
const products = this.state.itemsPerPage==='all'?[...filteredProducts]:filteredProducts.slice((this.state.page - 1) * this.state.itemsPerPage , this.state.page * this.state.itemsPerPage);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ height: '100%' }}>
|
<Box sx={{ height: '100%', px: { xs: 0, sm: 0 } }}>
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
alignItems: 'center'
|
alignItems: 'center',
|
||||||
|
flexDirection: { xs: 'column', sm: 'row' },
|
||||||
|
gap: { xs: 1, sm: 0 },
|
||||||
|
px: { xs: 0, sm: 0 },
|
||||||
|
py: { xs: 1, sm: 0 },
|
||||||
|
bgcolor: { xs: '#e8f5e8', sm: 'transparent' },
|
||||||
|
mb: { xs: 0, sm: 0 }
|
||||||
}}>
|
}}>
|
||||||
|
|
||||||
|
|
||||||
<Box sx={{ display: 'flex', gap: 1, alignItems: 'center', flexWrap: 'wrap' }}>
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
gap: { xs: 0.5, sm: 1 },
|
||||||
|
alignItems: 'center',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
order: { xs: 2, sm: 1 },
|
||||||
|
px: { xs: 1, sm: 0 }
|
||||||
|
}}>
|
||||||
{this.props.activeAttributeFilters.map((filter,index) => (
|
{this.props.activeAttributeFilters.map((filter,index) => (
|
||||||
<Chip
|
<Chip
|
||||||
size="medium"
|
size="medium"
|
||||||
@@ -207,9 +226,23 @@ class ProductList extends Component {
|
|||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
gap: { xs: 1, sm: 2 },
|
||||||
|
alignItems: 'center',
|
||||||
|
order: { xs: 1, sm: 2 },
|
||||||
|
width: { xs: '100%', sm: 'auto' },
|
||||||
|
justifyContent: { xs: 'space-between', sm: 'flex-end' },
|
||||||
|
px: { xs: 1, sm: 0 }
|
||||||
|
}}>
|
||||||
{/* Sort Dropdown */}
|
{/* Sort Dropdown */}
|
||||||
<FormControl variant="outlined" size="small" sx={{ minWidth: 140 }}>
|
<FormControl
|
||||||
|
variant={window.innerWidth < 600 ? 'standard' : 'outlined'}
|
||||||
|
size="small"
|
||||||
|
sx={{
|
||||||
|
minWidth: { xs: 120, sm: 140 }
|
||||||
|
}}
|
||||||
|
>
|
||||||
<InputLabel id="sort-by-label">Sortierung</InputLabel>
|
<InputLabel id="sort-by-label">Sortierung</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
size="small"
|
size="small"
|
||||||
@@ -244,7 +277,13 @@ class ProductList extends Component {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
{/* Per Page Dropdown */}
|
{/* Per Page Dropdown */}
|
||||||
<FormControl variant="outlined" size="small" sx={{ minWidth: 100 }}>
|
<FormControl
|
||||||
|
variant={window.innerWidth < 600 ? 'standard' : 'outlined'}
|
||||||
|
size="small"
|
||||||
|
sx={{
|
||||||
|
minWidth: { xs: 80, sm: 100 }
|
||||||
|
}}
|
||||||
|
>
|
||||||
<InputLabel id="products-per-page-label">pro Seite</InputLabel>
|
<InputLabel id="products-per-page-label">pro Seite</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
labelId="products-per-page-label"
|
labelId="products-per-page-label"
|
||||||
@@ -278,16 +317,37 @@ class ProductList extends Component {
|
|||||||
<MenuItem value="all">Alle</MenuItem>
|
<MenuItem value="all">Alle</MenuItem>
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
|
{/* Product count info - mobile only */}
|
||||||
|
<Box sx={{
|
||||||
|
display: { xs: 'block', sm: 'none' },
|
||||||
|
ml: 1
|
||||||
|
}}>
|
||||||
|
<Typography variant="body2" color="text.secondary" sx={{ fontSize: '0.75rem' }}>
|
||||||
|
{
|
||||||
|
this.props.totalProductCount==this.props.products.length && this.props.totalProductCount>0 ?
|
||||||
|
`${this.props.totalProductCount} Produkte`
|
||||||
|
:
|
||||||
|
`${this.props.products.length} von ${this.props.totalProductCount} Produkte`
|
||||||
|
}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
alignItems: 'center'
|
alignItems: 'center',
|
||||||
|
px: { xs: 0, sm: 0 },
|
||||||
|
py: { xs: 1, sm: 0 },
|
||||||
|
bgcolor: { xs: '#e8f5e8', sm: 'transparent' },
|
||||||
|
mt: { xs: 0, sm: 0 }
|
||||||
}}>
|
}}>
|
||||||
|
<Box sx={{ px: { xs: 1, sm: 0 }, width: '100%' }}>
|
||||||
{ this.renderPagination(Math.ceil(filteredProducts.length / this.state.itemsPerPage), this.state.page) }
|
{ this.renderPagination(Math.ceil(filteredProducts.length / this.state.itemsPerPage), this.state.page) }
|
||||||
<Stack direction="row" spacing={2}>
|
</Box>
|
||||||
|
<Stack direction="row" spacing={2} sx={{ display: { xs: 'none', sm: 'flex' }, px: { xs: 1, sm: 0 } }}>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<Typography variant="body2" color="text.secondary">
|
||||||
{/*this.props.dataType == 'category' && (<>Kategorie: {this.props.dataParam}</>)}*/}
|
{/*this.props.dataType == 'category' && (<>Kategorie: {this.props.dataParam}</>)}*/}
|
||||||
{this.props.dataType == 'search' && (<>Suchergebnisse für: "{this.props.dataParam}"</>)}
|
{this.props.dataType == 'search' && (<>Suchergebnisse für: "{this.props.dataParam}"</>)}
|
||||||
@@ -303,14 +363,19 @@ class ProductList extends Component {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={{ xs: 0, sm: 2 }}>
|
||||||
{products.map((product) => (
|
{products.map((product, index) => (
|
||||||
<Grid
|
<Grid
|
||||||
key={product.id}
|
key={product.id}
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: { xs: 'stretch', sm: 'center' },
|
justifyContent: { xs: 'stretch', sm: 'center' },
|
||||||
mb: 1
|
mb: { xs: 0, sm: 1 },
|
||||||
|
width: { xs: '100%', sm: 'auto' },
|
||||||
|
borderBottom: {
|
||||||
|
xs: index < products.length - 1 ? '16px solid #e8f5e8' : 'none',
|
||||||
|
sm: 'none'
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Product
|
<Product
|
||||||
@@ -339,8 +404,18 @@ class ProductList extends Component {
|
|||||||
))}
|
))}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
{/* Bottom pagination */}
|
||||||
|
<Box sx={{
|
||||||
|
px: { xs: 0, sm: 0 },
|
||||||
|
py: { xs: 1, sm: 1 },
|
||||||
|
bgcolor: { xs: '#e8f5e8', sm: 'transparent' },
|
||||||
|
mt: { xs: 0, sm: 2 }
|
||||||
|
}}>
|
||||||
|
<Box sx={{ px: { xs: 1, sm: 0 } }}>
|
||||||
{this.renderPagination(Math.ceil(filteredProducts.length / this.state.itemsPerPage), this.state.page)}
|
{this.renderPagination(Math.ceil(filteredProducts.length / this.state.itemsPerPage), this.state.page)}
|
||||||
</Box>
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ const SearchBar = () => {
|
|||||||
onSubmit={handleSearch}
|
onSubmit={handleSearch}
|
||||||
sx={{
|
sx={{
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
mx: { xs: 1, sm: 2, md: 4 },
|
mx: { xs: 0, sm: 2, md: 4 },
|
||||||
position: "relative",
|
position: "relative",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user