adding chat features, admin features and bug fixes
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
ListItemIcon,
|
||||
Divider,
|
||||
Box,
|
||||
Tooltip,
|
||||
} from '@mui/material';
|
||||
import {
|
||||
LocalFireDepartment,
|
||||
@@ -17,10 +18,15 @@ import {
|
||||
Settings,
|
||||
Logout,
|
||||
Menu as MenuIcon,
|
||||
Launch,
|
||||
Chat,
|
||||
} from '@mui/icons-material';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useAuth } from '../../contexts/AuthContext';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import NotificationBell from './NotificationBell';
|
||||
import { configApi } from '../../services/config';
|
||||
import { useLayout } from '../../contexts/LayoutContext';
|
||||
|
||||
interface HeaderProps {
|
||||
onMenuClick: () => void;
|
||||
@@ -29,7 +35,16 @@ interface HeaderProps {
|
||||
function Header({ onMenuClick }: HeaderProps) {
|
||||
const { user, logout } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const { toggleChatPanel } = useLayout();
|
||||
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
||||
const [toolsAnchorEl, setToolsAnchorEl] = useState<null | HTMLElement>(null);
|
||||
|
||||
const { data: externalLinks } = useQuery({
|
||||
queryKey: ['external-links'],
|
||||
queryFn: () => configApi.getExternalLinks(),
|
||||
staleTime: 10 * 60 * 1000,
|
||||
enabled: !!user,
|
||||
});
|
||||
|
||||
const handleMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
@@ -39,6 +54,14 @@ function Header({ onMenuClick }: HeaderProps) {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const handleToolsOpen = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setToolsAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleToolsClose = () => {
|
||||
setToolsAnchorEl(null);
|
||||
};
|
||||
|
||||
const handleProfile = () => {
|
||||
handleMenuClose();
|
||||
navigate('/profile');
|
||||
@@ -54,6 +77,11 @@ function Header({ onMenuClick }: HeaderProps) {
|
||||
logout();
|
||||
};
|
||||
|
||||
const handleOpenExternal = (url: string) => {
|
||||
handleToolsClose();
|
||||
window.open(url, '_blank', 'noopener,noreferrer');
|
||||
};
|
||||
|
||||
// Get initials for avatar
|
||||
const getInitials = () => {
|
||||
if (!user) return '?';
|
||||
@@ -61,6 +89,16 @@ function Header({ onMenuClick }: HeaderProps) {
|
||||
return initials || user.name?.[0] || '?';
|
||||
};
|
||||
|
||||
const linkEntries = externalLinks
|
||||
? Object.entries(externalLinks).filter(([, url]) => !!url)
|
||||
: [];
|
||||
|
||||
const linkLabels: Record<string, string> = {
|
||||
nextcloud: 'Nextcloud',
|
||||
bookstack: 'BookStack',
|
||||
vikunja: 'Vikunja',
|
||||
};
|
||||
|
||||
return (
|
||||
<AppBar
|
||||
position="fixed"
|
||||
@@ -71,7 +109,7 @@ function Header({ onMenuClick }: HeaderProps) {
|
||||
<Toolbar>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
aria-label="Men� �ffnen"
|
||||
aria-label="Menü öffnen"
|
||||
edge="start"
|
||||
onClick={onMenuClick}
|
||||
sx={{ mr: 2, display: { sm: 'none' } }}
|
||||
@@ -86,6 +124,63 @@ function Header({ onMenuClick }: HeaderProps) {
|
||||
|
||||
{user && (
|
||||
<>
|
||||
{linkEntries.length > 0 && (
|
||||
<>
|
||||
<Tooltip title="Externe Tools">
|
||||
<IconButton
|
||||
color="inherit"
|
||||
onClick={handleToolsOpen}
|
||||
size="small"
|
||||
aria-label="Externe Tools"
|
||||
aria-controls="tools-menu"
|
||||
aria-haspopup="true"
|
||||
>
|
||||
<Launch />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
<Menu
|
||||
id="tools-menu"
|
||||
anchorEl={toolsAnchorEl}
|
||||
open={Boolean(toolsAnchorEl)}
|
||||
onClose={handleToolsClose}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
PaperProps={{
|
||||
elevation: 3,
|
||||
sx: { minWidth: 180, mt: 1 },
|
||||
}}
|
||||
>
|
||||
{linkEntries.map(([key, url]) => (
|
||||
<MenuItem key={key} onClick={() => handleOpenExternal(url)}>
|
||||
<ListItemIcon>
|
||||
<Launch fontSize="small" />
|
||||
</ListItemIcon>
|
||||
{linkLabels[key] || key}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Tooltip title="Chat">
|
||||
<IconButton
|
||||
color="inherit"
|
||||
onClick={toggleChatPanel}
|
||||
size="small"
|
||||
aria-label="Chat öffnen"
|
||||
sx={{ ml: 0.5 }}
|
||||
>
|
||||
<Chat />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
<NotificationBell />
|
||||
|
||||
<IconButton
|
||||
|
||||
Reference in New Issue
Block a user