This commit is contained in:
seb
2026-07-31 07:02:51 +02:00
parent 9dac151854
commit a95b7f4b1e
14 changed files with 1064 additions and 831 deletions

View File

@@ -1,4 +1,5 @@
import { useState } from 'react';
import { Component } from 'react';
import { connect } from 'react-redux';
import Avatar from '@mui/material/Avatar';
import Box from '@mui/material/Box';
import IconButton from '@mui/material/IconButton';
@@ -8,62 +9,95 @@ import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import LogoutIcon from '@mui/icons-material/Logout';
import BusinessIcon from '@mui/icons-material/Business';
import { useAuth } from '../auth/useAuth';
import { logout, selectAuthUser } from '../store/authSlice';
import CompanySettingsDialog from './CompanySettingsDialog';
// Menu open/close state is local; toggling it only re-renders this component.
export default function UserMenu() {
const { user, logout } = useAuth();
const [anchorEl, setAnchorEl] = useState(null);
const [settingsOpen, setSettingsOpen] = useState(false);
const open = Boolean(anchorEl);
class UserMenu extends Component {
constructor(props) {
super(props);
this.state = {
anchorEl: null,
settingsOpen: false,
};
this.handleOpenMenu = this.handleOpenMenu.bind(this);
this.handleCloseMenu = this.handleCloseMenu.bind(this);
this.handleOpenSettings = this.handleOpenSettings.bind(this);
this.handleCloseSettings = this.handleCloseSettings.bind(this);
this.handleLogout = this.handleLogout.bind(this);
}
return (
<>
<Box sx={{ px: 1.5, py: 1.5, alignSelf: 'flex-start' }}>
<IconButton
onClick={(e) => setAnchorEl(e.currentTarget)}
onMouseDown={(e) => e.preventDefault()}
sx={{ p: 0, width: 32, height: 32, borderRadius: '50%' }}
handleOpenMenu(event) {
this.setState({ anchorEl: event.currentTarget });
}
handleCloseMenu() {
this.setState({ anchorEl: null });
}
handleOpenSettings() {
this.setState({ anchorEl: null, settingsOpen: true });
}
handleCloseSettings() {
this.setState({ settingsOpen: false });
}
handleLogout() {
this.setState({ anchorEl: null });
void this.props.logout();
}
render() {
const { user } = this.props;
const { anchorEl, settingsOpen } = this.state;
const open = Boolean(anchorEl);
return (
<>
<Box sx={{ px: 1.5, py: 1.5, alignSelf: 'flex-start' }}>
<IconButton
onClick={this.handleOpenMenu}
onMouseDown={(e) => e.preventDefault()}
sx={{ p: 0, width: 32, height: 32, borderRadius: '50%' }}
>
<Avatar src={user?.picture} alt={user?.email} sx={{ width: 32, height: 32 }}>
{user?.email?.[0]?.toUpperCase()}
</Avatar>
</IconButton>
</Box>
<Menu
anchorEl={anchorEl}
open={open}
onClose={this.handleCloseMenu}
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'bottom', horizontal: 'left' }}
>
<Avatar src={user?.picture} alt={user?.email} sx={{ width: 32, height: 32 }}>
{user?.email?.[0]?.toUpperCase()}
</Avatar>
</IconButton>
</Box>
<Menu
anchorEl={anchorEl}
open={open}
onClose={() => setAnchorEl(null)}
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'bottom', horizontal: 'left' }}
>
<MenuItem disabled>{user?.email}</MenuItem>
<MenuItem
disabled={!user?.selectedCompanyId}
onClick={() => {
setAnchorEl(null);
setSettingsOpen(true);
}}
>
<ListItemIcon>
<BusinessIcon fontSize="small" />
</ListItemIcon>
<ListItemText>Unternehmen</ListItemText>
</MenuItem>
<MenuItem
onClick={() => {
setAnchorEl(null);
logout();
}}
>
<ListItemIcon>
<LogoutIcon fontSize="small" />
</ListItemIcon>
<ListItemText>Sign out</ListItemText>
</MenuItem>
</Menu>
<CompanySettingsDialog open={settingsOpen} onClose={() => setSettingsOpen(false)} />
</>
);
<MenuItem disabled>{user?.email}</MenuItem>
<MenuItem disabled={!user?.selectedCompanyId} onClick={this.handleOpenSettings}>
<ListItemIcon>
<BusinessIcon fontSize="small" />
</ListItemIcon>
<ListItemText>Unternehmen</ListItemText>
</MenuItem>
<MenuItem onClick={this.handleLogout}>
<ListItemIcon>
<LogoutIcon fontSize="small" />
</ListItemIcon>
<ListItemText>Sign out</ListItemText>
</MenuItem>
</Menu>
<CompanySettingsDialog open={settingsOpen} onClose={this.handleCloseSettings} />
</>
);
}
}
const mapStateToProps = (state) => ({
user: selectAuthUser(state),
});
const mapDispatchToProps = (dispatch) => ({
logout: () => dispatch(logout()),
});
export default connect(mapStateToProps, mapDispatchToProps)(UserMenu);