Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/logout header #25

Merged
merged 2 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions frontend/src/components/Header/AuthenticatedIcons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { IconButton, Badge, Box, useTheme } from "@mui/material";
import ChatBubbleOutlineIcon from "@mui/icons-material/ChatBubbleOutline";
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
import { Link } from "react-router-dom";

interface AuthenticatedIconsProps {
isMobile: boolean;
}

export default function AuthenticatedIcons({ isMobile }: AuthenticatedIconsProps) {
const theme = useTheme();

return (
<>
<IconButton component={Link} to="/chat">
<ChatBubbleOutlineIcon
fontSize="large"
style={{
color: theme.palette.common.black,
marginRight: isMobile ? 0 : 2,
}}
/>
</IconButton>
<IconButton>
<HelpOutlineIcon
fontSize="large"
style={{
color: theme.palette.common.black,
marginRight: isMobile ? 0 : 2,
}}
/>
</IconButton>
<IconButton sx={{ position: "relative", marginRight: isMobile ? 0 : 2 }}>
<Box
component="img"
src="/images/mango.png"
alt="Mango notification"
sx={{
width: 40,
height: 40,
position: "relative",
}}
/>
<Badge
badgeContent={4}
sx={{
position: "absolute",
bottom: 20,
right: 24,
}}
/>
</IconButton>
</>
);
}
36 changes: 36 additions & 0 deletions frontend/src/components/Header/DesktopMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Button, Avatar } from "@mui/material";
import ProfileMenu from "./ProfileMenu";
import { useState } from "react";

interface DesktopMenuProps {
onLogout: () => void;
}

export default function DesktopMenu({ onLogout }: DesktopMenuProps) {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);

const handleProfileClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
};

const handleMenuClose = () => {
setAnchorEl(null);
};

return (
<>
<Button
color="primary"
startIcon={<Avatar sx={{ width: 24, height: 24 }} />}
onClick={handleProfileClick}
>
Célia K.
</Button>
<ProfileMenu
anchorEl={anchorEl}
onClose={handleMenuClose}
onLogout={onLogout}
/>
</>
);
}
206 changes: 51 additions & 155 deletions frontend/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,175 +1,71 @@
import {
AppBar,
Toolbar,
IconButton,
Badge,
Box,
Avatar,
Button,
useTheme,
useMediaQuery,
Drawer,
List,
ListItemButton,
ListItemText,
} from "@mui/material";
import { Menu as MenuIcon } from "@mui/icons-material";
import ChatBubbleOutlineIcon from "@mui/icons-material/ChatBubbleOutline";
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
import Logo from "./Logo";
import HeaderButton from "../Header/HeaderButton";
import { AppBar, Toolbar, Box, useTheme, useMediaQuery } from "@mui/material";
import { useState } from "react";
import { useAuth } from "../../contexts/AuthContext";
import { Link } from "react-router-dom";
import { Dispatch, SetStateAction } from "react";
import Logo from "./Logo";
import HeaderButton from "../Header/HeaderButton";
import DesktopMenu from "./DesktopMenu";
import MobileMenu from "./MobileMenu";
import AuthenticatedIcons from "./AuthenticatedIcons";

interface HeaderProps {
setAuthModalIsOpen: Dispatch<SetStateAction<boolean>>;
setAuthModalIsOpen: (isOpen: boolean) => void;
}

export default function Header({ setAuthModalIsOpen }: HeaderProps) {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const { isAuthenticated } = useAuth();

const { isAuthenticated, logout } = useAuth();
const [drawerOpen, setDrawerOpen] = useState(false);

const handleDrawerToggle = () => {
setDrawerOpen(!drawerOpen);
};
const handleDrawerToggle = () => setDrawerOpen(!drawerOpen);

return (
<>
<AppBar position="static" sx={{ bgcolor: "transparent", border: 0 }}>
<Toolbar sx={{ justifyContent: "space-between" }}>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent:
!isAuthenticated && isMobile ? "center" : "flex-start",
gap: !isAuthenticated || isMobile ? 0 : 2,
...(isMobile && { width: "100%" }),
}}
>
<Logo />
{isAuthenticated && !isMobile && (
<>
<HeaderButton
color="secondary"
text="Créer une annonce"
icon="/images/mango.png"
/>
<HeaderButton color="primary" text="Explorer" paddingX={4} />
</>
)}
</Box>

<Box sx={{ display: "flex", alignItems: "center" }}>
{isAuthenticated ? (
<>
<IconButton component={Link} to="/chat">
<ChatBubbleOutlineIcon
fontSize="large"
style={{
color: theme.palette.common.black,
marginRight: isMobile ? 0 : 2,
}}
/>
</IconButton>
<IconButton>
<HelpOutlineIcon
fontSize="large"
style={{
color: theme.palette.common.black,
marginRight: isMobile ? 0 : 2,
}}
/>
</IconButton>
<IconButton
sx={{ position: "relative", marginRight: isMobile ? 0 : 2 }}
>
<Box
component="img"
src="/images/mango.png"
alt="Mango notification"
sx={{
width: 40,
height: 40,
position: "relative",
}}
/>
<Badge
badgeContent={4}
sx={{
position: "absolute",
bottom: 20,
right: 24,
}}
/>
</IconButton>
<Box
sx={{
display: isMobile ? "none" : "flex",
alignItems: "center",
gap: 1,
}}
>
<Button
color="primary"
startIcon={<Avatar sx={{ width: 24, height: 24 }} />}
>
Célia K.
</Button>
</Box>
</>
) : (
<>
{!isAuthenticated && !isMobile && (
<Button
variant="contained"
sx={{
bgcolor: theme.palette.primary.main,
"&:hover": { bgcolor: theme.palette.primary.dark },
}}
onClick={() => setAuthModalIsOpen(true)}
>
S’inscrire / Se connecter
</Button>
)}
</>
)}
{isMobile && isAuthenticated && (
<IconButton onClick={handleDrawerToggle}>
<MenuIcon />
</IconButton>
)}
</Box>
</Toolbar>
</AppBar>
<AppBar position="static" sx={{ bgcolor: "transparent", border: 0 }}>
<Toolbar sx={{ justifyContent: "space-between" }}>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: !isAuthenticated && isMobile ? "center" : "flex-start",
gap: !isAuthenticated || isMobile ? 0 : 2,
...(isMobile && { width: "100%" }),
}}
>
<Logo />
{isAuthenticated && !isMobile && (
<>
<HeaderButton color="secondary" text="Créer une annonce" icon="/images/mango.png" />
<HeaderButton color="primary" text="Explorer" paddingX={4} />
</>
)}
</Box>

<Drawer anchor="right" open={drawerOpen} onClose={handleDrawerToggle}>
<List sx={{ width: 250 }}>
{isAuthenticated && (
<Box sx={{ display: "flex", alignItems: "center" }}>
{isAuthenticated ? (
<>
<ListItemButton onClick={handleDrawerToggle}>
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Avatar sx={{ width: 24, height: 24 }} />
<ListItemText primary="Célia K." />
</Box>
</ListItemButton>
<ListItemButton onClick={handleDrawerToggle} sx={{ display: "flex", flexDirection: "column", alignItems: "flex-start", gap: 2 }}>
<HeaderButton
color="secondary"
text="Créer une annonce"
icon="/images/mango.png"
<AuthenticatedIcons isMobile={isMobile} />
{isMobile ? (
<MobileMenu
isOpen={drawerOpen}
onClose={handleDrawerToggle}
onToggle={handleDrawerToggle}
onLogout={logout}
/>
<HeaderButton color="primary" text="Explorer" paddingX={4} />
</ListItemButton>
) : (
<DesktopMenu onLogout={logout} />
)}
</>
) : (
!isMobile && (
<HeaderButton
color="primary"
text="S'inscrire / Se connecter"
onClick={() => setAuthModalIsOpen(true)}
/>
)
)}
</List>
</Drawer>
</>
</Box>
</Toolbar>
</AppBar>
);
}
37 changes: 37 additions & 0 deletions frontend/src/components/Header/MobileMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Drawer, List, ListItemButton, IconButton } from "@mui/material";
import { Menu as MenuIcon } from "@mui/icons-material";
import HeaderButton from "../Header/HeaderButton";

interface MobileMenuProps {
isOpen: boolean;
onClose: () => void;
onToggle: () => void;
onLogout: () => void;
}

export default function MobileMenu({ isOpen, onClose, onToggle, onLogout }: MobileMenuProps) {
return (
<>
<IconButton onClick={onToggle}>
<MenuIcon />
</IconButton>
<Drawer anchor="right" open={isOpen} onClose={onClose}>
<List sx={{ width: 250 }}>
<ListItemButton
onClick={onClose}
sx={{
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
gap: 2,
}}
>
<HeaderButton color="secondary" text="Créer une annonce" icon="/images/mango.png" />
<HeaderButton color="primary" text="Explorer" paddingX={4} />
<HeaderButton color="error" text="Déconnexion" paddingX={4} onClick={onLogout} />
</ListItemButton>
</List>
</Drawer>
</>
);
}
Loading
Loading