Skip to content

Commit 46567c7

Browse files
authored
Merge pull request #103 from pjuaristi-ikerlan/mui-sidebar-102
Sidebar, navigation bar and div usage changed to use Material UI
2 parents 94fb107 + 3f847ee commit 46567c7

File tree

16 files changed

+1084
-518
lines changed

16 files changed

+1084
-518
lines changed

ichub-frontend/src/App.css

Lines changed: 132 additions & 225 deletions
Large diffs are not rendered by default.

ichub-frontend/src/components/general/Header.tsx

Lines changed: 173 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -21,83 +21,189 @@
2121
********************************************************************************/
2222

2323
import { useState } from 'react';
24-
import { MainNavigation, IconButton } from '@catena-x/portal-shared-components';
25-
import PersonIcon from '@mui/icons-material/Person';
26-
import { Menu, MenuItem, Typography, Divider, ListItemIcon } from '@mui/material';
27-
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
28-
import SettingsIcon from '@mui/icons-material/Settings';
29-
import LogoutIcon from '@mui/icons-material/Logout';
24+
import AppBar from '@mui/material/AppBar';
25+
import Box from '@mui/material/Box';
26+
import Toolbar from '@mui/material/Toolbar';
27+
import IconButton from '@mui/material/IconButton';
28+
import Badge from '@mui/material/Badge';
29+
import MenuItem from '@mui/material/MenuItem';
30+
import Menu from '@mui/material/Menu';
31+
import AccountCircle from '@mui/icons-material/AccountCircle';
32+
import MailIcon from '@mui/icons-material/Mail';
33+
import NotificationsIcon from '@mui/icons-material/Notifications';
34+
import MoreIcon from '@mui/icons-material/MoreVert';
35+
import { Divider, ListItemIcon, Typography } from '@mui/material';
36+
import { Logout, Settings } from '@mui/icons-material';
3037

31-
const Header = () => {
32-
const [anchorEl, setAnchorEl] = useState(null);
33-
const open = Boolean(anchorEl);
38+
export default function PrimarySearchAppBar() {
39+
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
40+
const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = useState<null | HTMLElement>(null);
3441

35-
const handleMenuOpen = (event) => {
42+
const isMenuOpen = Boolean(anchorEl);
43+
const isMobileMenuOpen = Boolean(mobileMoreAnchorEl);
44+
45+
const handleProfileMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
3646
setAnchorEl(event.currentTarget);
3747
};
3848

49+
const handleMobileMenuClose = () => {
50+
setMobileMoreAnchorEl(null);
51+
};
52+
3953
const handleMenuClose = () => {
4054
setAnchorEl(null);
55+
handleMobileMenuClose();
4156
};
4257

43-
return (
44-
<MainNavigation
45-
items={[
46-
{ href: '/', title: 'Industry Core Hub' },
47-
]}
48-
>
49-
<div className='main-logo-wrapper'>
50-
<a href="/" className="main-logo-link">
51-
<img
52-
src="/241117_Tractus_X_Logo_RGB_Light_Version.png"
53-
alt="Eclipse Tractus-X logo"
54-
className='main-logo'
55-
/>
56-
</a>
57-
</div>
58-
<div>
59-
<IconButton aria-label="user-menu" onClick={handleMenuOpen}>
60-
<PersonIcon />
61-
</IconButton>
62-
<Menu
63-
anchorEl={anchorEl}
64-
open={open}
65-
onClose={handleMenuClose}
66-
className='navbar-user-dropdown'
67-
>
68-
{/* Encabezado con nombre y email */}
69-
<Typography variant="subtitle1" sx={{ padding: '8px 16px 0px 16px', fontWeight: 'bold' }}>
58+
const handleMobileMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
59+
setMobileMoreAnchorEl(event.currentTarget);
60+
};
61+
62+
const menuId = 'primary-search-account-menu';
63+
const renderMenu = (
64+
<Menu
65+
anchorEl={anchorEl}
66+
id={menuId}
67+
open={isMenuOpen}
68+
onClose={handleMenuClose}
69+
>
70+
<Typography variant="subtitle1" sx={{ padding: '8px 16px 0px 16px', fontWeight: 'bold' }}>
7071
Mathias Brunkow Moser
71-
</Typography>
72-
<Typography variant="body2" color="text.secondary" sx={{ padding: '0 16px 8px', fontStyle: 'italic' }}>
73-
CX-Operator
74-
</Typography>
75-
<Divider />
72+
</Typography>
73+
<Typography variant="body2" color="text.secondary" sx={{ padding: '0 16px 8px', fontStyle: 'italic' }}>
74+
CX-Operator
75+
</Typography>
76+
<Divider />
7677

77-
{/* Opciones del menú */}
78-
<MenuItem onClick={handleMenuClose}>
79-
<ListItemIcon>
80-
<AccountCircleIcon fontSize="small" />
81-
</ListItemIcon>
82-
Profile
83-
</MenuItem>
84-
<MenuItem onClick={handleMenuClose}>
85-
<ListItemIcon>
86-
<SettingsIcon fontSize="small" />
87-
</ListItemIcon>
88-
Settings
89-
</MenuItem>
90-
<Divider />
91-
<MenuItem onClick={handleMenuClose}>
92-
<ListItemIcon>
93-
<LogoutIcon fontSize="small" />
94-
</ListItemIcon>
95-
Logout
96-
</MenuItem>
97-
</Menu>
98-
</div>
99-
</MainNavigation>
78+
{/* Opciones del menú */}
79+
<MenuItem onClick={handleMenuClose}>
80+
<ListItemIcon>
81+
<AccountCircle fontSize="small" />
82+
</ListItemIcon>
83+
Profile
84+
</MenuItem>
85+
<MenuItem onClick={handleMenuClose}>
86+
<ListItemIcon>
87+
<Settings fontSize="small" />
88+
</ListItemIcon>
89+
Settings
90+
</MenuItem>
91+
<Divider />
92+
<MenuItem onClick={handleMenuClose}>
93+
<ListItemIcon>
94+
<Logout fontSize="small" />
95+
</ListItemIcon>
96+
Logout
97+
</MenuItem>
98+
</Menu>
10099
);
101-
};
102100

103-
export default Header;
101+
const mobileMenuId = 'primary-search-account-menu-mobile';
102+
const renderMobileMenu = (
103+
<Menu
104+
anchorEl={mobileMoreAnchorEl}
105+
anchorOrigin={{
106+
vertical: 'top',
107+
horizontal: 'right',
108+
}}
109+
id={mobileMenuId}
110+
keepMounted
111+
transformOrigin={{
112+
vertical: 'top',
113+
horizontal: 'right',
114+
}}
115+
open={isMobileMenuOpen}
116+
onClose={handleMobileMenuClose}
117+
>
118+
<MenuItem>
119+
<IconButton size="large" aria-label="show 4 new mails">
120+
<Badge badgeContent={4} color="error">
121+
<MailIcon />
122+
</Badge>
123+
</IconButton>
124+
<p>Messages</p>
125+
</MenuItem>
126+
<MenuItem>
127+
<IconButton
128+
size="large"
129+
aria-label="show 17 new notifications"
130+
>
131+
<Badge badgeContent={17} color="error">
132+
<NotificationsIcon />
133+
</Badge>
134+
</IconButton>
135+
<p>Notifications</p>
136+
</MenuItem>
137+
<MenuItem onClick={handleProfileMenuOpen}>
138+
<IconButton
139+
size="large"
140+
aria-label="account of current user"
141+
aria-controls="primary-search-account-menu"
142+
aria-haspopup="true"
143+
>
144+
<AccountCircle />
145+
</IconButton>
146+
<p>Profile</p>
147+
</MenuItem>
148+
</Menu>
149+
);
150+
151+
return (
152+
<Box sx={{ flexGrow: 1 }}>
153+
<AppBar position="static" className='ichub-header'>
154+
<Toolbar>
155+
<a href="/">
156+
<img
157+
src="/241117_Tractus_X_Logo_RGB_Light_Version.png"
158+
alt="Eclipse Tractus-X logo"
159+
className='main-logo'
160+
/>
161+
</a>
162+
<Box sx={{ flexGrow: 1, display: 'flex', justifyContent: 'center' }}>
163+
<h2>Industry Core Hub</h2>
164+
</Box>
165+
<Box sx={{ display: { xs: 'none', md: 'flex' } }}>
166+
<IconButton size="large" aria-label="show 4 new mails">
167+
<Badge badgeContent={4} color="error">
168+
<MailIcon />
169+
</Badge>
170+
</IconButton>
171+
<IconButton
172+
size="large"
173+
aria-label="show 17 new notifications"
174+
>
175+
<Badge badgeContent={17} color="error">
176+
<NotificationsIcon />
177+
</Badge>
178+
</IconButton>
179+
<IconButton
180+
size="large"
181+
edge="end"
182+
aria-label="account of current user"
183+
aria-controls={menuId}
184+
aria-haspopup="true"
185+
onClick={handleProfileMenuOpen}
186+
className='user-button'
187+
>
188+
<AccountCircle />
189+
</IconButton>
190+
</Box>
191+
<Box sx={{ display: { xs: 'flex', md: 'none' } }}>
192+
<IconButton
193+
size="large"
194+
aria-label="show more"
195+
aria-controls={mobileMenuId}
196+
aria-haspopup="true"
197+
onClick={handleMobileMenuOpen}
198+
color="inherit"
199+
>
200+
<MoreIcon />
201+
</IconButton>
202+
</Box>
203+
</Toolbar>
204+
</AppBar>
205+
{renderMobileMenu}
206+
{renderMenu}
207+
</Box>
208+
);
209+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/********************************************************************************
2+
* Eclipse Tractus-X - Industry Core Hub Frontend
3+
*
4+
* Copyright (c) 2025 Contributors to the Eclipse Foundation
5+
*
6+
* See the NOTICE file(s) distributed with this work for additional
7+
* information regarding copyright ownership.
8+
*
9+
* This program and the accompanying materials are made available under the
10+
* terms of the Apache License, Version 2.0 which is available at
11+
* https://www.apache.org/licenses/LICENSE-2.0.
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
16+
* either express or implied. See the
17+
* License for the specific language govern in permissions and limitations
18+
* under the License.
19+
*
20+
* SPDX-License-Identifier: Apache-2.0
21+
********************************************************************************/
22+
23+
24+
import { Grid2 } from '@mui/material';
25+
import { PageNotifications } from '@catena-x/portal-shared-components';
26+
27+
interface PageNotificationProps {
28+
notification: { open: boolean; severity: "success" | "error"; title: string } | null;
29+
}
30+
31+
const PageNotification = ({ notification }: PageNotificationProps) => {
32+
return (
33+
notification && (
34+
<Grid2 size={{xs: 12}}>
35+
<PageNotifications open severity={notification.severity} showIcon title={notification.title} />
36+
</Grid2>
37+
)
38+
);
39+
};
40+
41+
export default PageNotification;

ichub-frontend/src/components/general/ProductCard.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,9 @@ export const ProductCard = ({
177177
<Typography
178178
variant="h5"
179179
sx={{
180-
"-webkit-line-clamp": "2",
181-
display: "-webkit-box",
182-
"-webkit-box-orient": "vertical",
180+
WebkitLineClamp: 2,
181+
display: "WebkitBox",
182+
WebkitBoxOrient: "vertical",
183183
overflow: "hidden",
184184
fontWeight: "bold",
185185
fontSize: "18px",

ichub-frontend/src/components/general/Sidebar.tsx

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,50 @@
2020
* SPDX-License-Identifier: Apache-2.0
2121
********************************************************************************/
2222

23-
import { Menu } from '@catena-x/portal-shared-components';
23+
import { useState, JSX } from "react";
2424
import sidebarElements from '../../tests/payloads/sidebar-elements.json'
2525

26+
import { Box } from "@mui/material";
27+
28+
import { Storefront as StorefrontIcon, Category as CategoryIcon, People as PeopleIcon, Assignment as AssignmentIcon } from '@mui/icons-material';
29+
30+
const iconMap: { [key: string]: JSX.Element } = {
31+
Storefront: <StorefrontIcon />,
32+
Category: <CategoryIcon />,
33+
Shared: <PeopleIcon />,
34+
Status: <AssignmentIcon />
35+
};
36+
2637
const Sidebar = () => {
38+
const [activeIndex, setActiveIndex] = useState(0);
39+
2740
return (
28-
<Menu
29-
items={sidebarElements.map(({ title, subitems }) => ({
30-
title,
31-
href: '#',
32-
children: subitems.map(({ name, link }) => ({ title: name, href: link }))
33-
}))}
34-
/>
41+
<Box className="sidebarContainer">
42+
{/* Barra de Iconos */}
43+
<Box className="iconBar">
44+
{sidebarElements.map((item, index) => (
45+
<button
46+
key={index}
47+
className={`iconButton ${index === activeIndex ? "active" : ""}`}
48+
onClick={() => setActiveIndex(index)}
49+
>
50+
{iconMap[item.icon] || <StorefrontIcon />}
51+
</button>
52+
))}
53+
</Box>
54+
55+
{/* Contenido del Sidebar */}
56+
<Box className="sidebarContent">
57+
<h2>{sidebarElements[activeIndex].title}</h2>
58+
<ul>
59+
{sidebarElements[activeIndex].subitems.map((subitem, idx) => (
60+
<li key={idx}>
61+
<a href={subitem.link}>{subitem.name}</a>
62+
</li>
63+
))}
64+
</ul>
65+
</Box>
66+
</Box>
3567
);
3668
};
3769

0 commit comments

Comments
 (0)