parent
c71bac5bd2
commit
31ba7bead1
File diff suppressed because it is too large
Load Diff
|
|
@ -6,7 +6,7 @@
|
|||
"@emotion/react": "^11.11.3",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@fontsource/roboto": "^5.0.8",
|
||||
"@mui/icons-material": "^5.15.7",
|
||||
"@mui/icons-material": "^5.15.8",
|
||||
"@mui/material": "^5.15.7",
|
||||
"@reduxjs/toolkit": "^2.1.0",
|
||||
"axios": "^1.6.7",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
import { useEffect, useState } from "react";
|
||||
|
||||
function getWindowDimensions() {
|
||||
const { innerWidth: width, innerHeight: height } = window;
|
||||
return { width, height };
|
||||
}
|
||||
|
||||
export default function useWindowDimensions() {
|
||||
const [windowDimensions, setWindowDimensions] = useState(
|
||||
getWindowDimensions()
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
function handleResize() {
|
||||
setWindowDimensions(getWindowDimensions());
|
||||
}
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
return () => window.removeEventListener("resize", handleResize);
|
||||
}, []);
|
||||
|
||||
return windowDimensions;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import { BottomNavigation, BottomNavigationAction, Paper } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import FeedIcon from "@mui/icons-material/Feed";
|
||||
import GlobalIcon from "@mui/icons-material/Public";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import SearchIcon from "@mui/icons-material/Search";
|
||||
|
||||
export default function BottomAppBar() {
|
||||
const [value, setValue] = useState(0);
|
||||
|
||||
return (
|
||||
<Paper
|
||||
sx={{ position: "fixed", bottom: 0, left: 0, right: 0 }}
|
||||
elevation={8}
|
||||
>
|
||||
<BottomNavigation
|
||||
showLabels
|
||||
value={value}
|
||||
onChange={(event, newValue) => {
|
||||
setValue(newValue);
|
||||
}}
|
||||
>
|
||||
<BottomNavigationAction label="My Feed" icon={<FeedIcon />} />
|
||||
<BottomNavigationAction label="Global Feed" icon={<GlobalIcon />} />
|
||||
<BottomNavigationAction label="New Post" icon={<AddIcon />} />
|
||||
<BottomNavigationAction label="Search" icon={<SearchIcon />} />
|
||||
</BottomNavigation>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import NotificationsIcon from "@mui/icons-material/Notifications";
|
||||
import { Badge, Tooltip } from "@mui/material";
|
||||
|
||||
export default function NotificationBell() {
|
||||
return (
|
||||
<Badge badgeContent={4} color="secondary">
|
||||
<Tooltip title="Notifications">
|
||||
<NotificationsIcon />
|
||||
</Tooltip>
|
||||
</Badge>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
import {
|
||||
Divider,
|
||||
Drawer,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemButton,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
Toolbar,
|
||||
} from "@mui/material";
|
||||
|
||||
import FeedIcon from "@mui/icons-material/Feed";
|
||||
import GlobalIcon from "@mui/icons-material/Public";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import SearchIcon from "@mui/icons-material/Search";
|
||||
|
||||
export interface SideAppBarProps {
|
||||
drawerWidth: number;
|
||||
}
|
||||
|
||||
export default function SideAppBar(props: SideAppBarProps) {
|
||||
const { drawerWidth } = props;
|
||||
return (
|
||||
<Drawer
|
||||
sx={{
|
||||
width: drawerWidth,
|
||||
flexShrink: 0,
|
||||
"& .MuiDrawer-paper": {
|
||||
width: drawerWidth,
|
||||
boxSizing: "border-box",
|
||||
},
|
||||
}}
|
||||
variant="permanent"
|
||||
anchor="left"
|
||||
>
|
||||
<Toolbar />
|
||||
|
||||
<Divider />
|
||||
<List>
|
||||
<ListItem key={"myfeed"} disablePadding>
|
||||
<ListItemButton>
|
||||
<ListItemIcon>
|
||||
<FeedIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={"My feed"} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
|
||||
<ListItem key={"globalfeed"} disablePadding>
|
||||
<ListItemButton>
|
||||
<ListItemIcon>
|
||||
<GlobalIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={"Global feed"} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
|
||||
<ListItem key={"newpost"} disablePadding>
|
||||
<ListItemButton>
|
||||
<ListItemIcon>
|
||||
<AddIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={"New Post"} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
|
||||
<ListItem key={"search"} disablePadding>
|
||||
<ListItemButton>
|
||||
<ListItemIcon>
|
||||
<SearchIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={"Search"} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
|
||||
</List>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
import * as React from "react";
|
||||
import AppBar from "@mui/material/AppBar";
|
||||
import Box from "@mui/material/Box";
|
||||
import Toolbar from "@mui/material/Toolbar";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Menu from "@mui/material/Menu";
|
||||
import Container from "@mui/material/Container";
|
||||
import Avatar from "@mui/material/Avatar";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import NotificationBell from "./notificationBell";
|
||||
import {useSelector} from "react-redux";
|
||||
import {selectUserInfo} from "../app/loginSlice";
|
||||
|
||||
const settings = ["Profile", "Account", "Dashboard", "Logout"];
|
||||
|
||||
function TopAppBar() {
|
||||
|
||||
const userInfo = useSelector(selectUserInfo);
|
||||
const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(
|
||||
null
|
||||
);
|
||||
|
||||
console.log(userInfo)
|
||||
|
||||
const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setAnchorElUser(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleCloseUserMenu = () => {
|
||||
setAnchorElUser(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<AppBar position="static">
|
||||
<Container maxWidth="xl" sx={{ zIndex: 2500 }}>
|
||||
<Toolbar disableGutters>
|
||||
<Typography
|
||||
variant="h6"
|
||||
noWrap
|
||||
component="a"
|
||||
href="#app-bar-with-responsive-menu"
|
||||
sx={{
|
||||
mr: 2,
|
||||
display: "flex",
|
||||
fontFamily: "monospace",
|
||||
fontWeight: 700,
|
||||
letterSpacing: ".3rem",
|
||||
color: "inherit",
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
DevSpace
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
display: "flex",
|
||||
justifyContent: "right",
|
||||
padding: "1rem",
|
||||
}}
|
||||
>
|
||||
<NotificationBell />
|
||||
</Box>
|
||||
|
||||
<Box sx={{ flexGrow: 0 }}>
|
||||
<Tooltip title="Open settings">
|
||||
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
|
||||
<Avatar alt={userInfo.firstName} src="/static/images/avatar/2.jpg" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Menu
|
||||
sx={{ mt: "45px" }}
|
||||
id="menu-appbar"
|
||||
anchorEl={anchorElUser}
|
||||
anchorOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "right",
|
||||
}}
|
||||
keepMounted
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "right",
|
||||
}}
|
||||
open={Boolean(anchorElUser)}
|
||||
onClose={handleCloseUserMenu}
|
||||
>
|
||||
{settings.map((setting) => (
|
||||
<MenuItem key={setting} onClick={handleCloseUserMenu}>
|
||||
<Typography textAlign="center">{setting}</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
</Box>
|
||||
</Toolbar>
|
||||
</Container>
|
||||
</AppBar>
|
||||
);
|
||||
}
|
||||
export default TopAppBar;
|
||||
|
|
@ -1,16 +1,21 @@
|
|||
import ResponsiveDrawer from "../components/Drawer";
|
||||
import { Outlet, useActionData, useNavigate } from "react-router-dom";
|
||||
import { Button, Grid } from "@mui/material";
|
||||
import { Outlet, useNavigate } from "react-router-dom";
|
||||
import { Box } from "@mui/material";
|
||||
import { postLogout, selectLoggedIn, selectUserInfo } from "../app/loginSlice";
|
||||
import { useAppDispatch } from "../app/store";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useEffect } from "react";
|
||||
import useWindowDimensions from "../app/hooks/useWindowDimensions";
|
||||
import SideAppBar from "../components/sideAppBar";
|
||||
import BottomAppBar from "../components/bottomAppBar";
|
||||
import TopAppBar from "../components/topAppBar";
|
||||
|
||||
const drawerWidth = 240;
|
||||
|
||||
export default function Root() {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useAppDispatch();
|
||||
const loggedIn = useSelector(selectLoggedIn);
|
||||
const userInfo = useSelector(selectUserInfo);
|
||||
const { width } = useWindowDimensions();
|
||||
|
||||
useEffect(() => {
|
||||
if (!loggedIn) {
|
||||
|
|
@ -24,9 +29,39 @@ export default function Root() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Button color="primary" variant="contained" onClick={handleClick}>
|
||||
Log Off
|
||||
</Button>
|
||||
<Box>
|
||||
<TopAppBar />
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
flexDirection: { xs: "column", sm: "row" },
|
||||
}}
|
||||
>
|
||||
{width > 600 && (
|
||||
<Box sx={{ flexBasis: { sm: "auto" } }}>
|
||||
<SideAppBar drawerWidth={drawerWidth} />
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Box
|
||||
component="main"
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
p: 3,
|
||||
width: { sm: `calc(100% - ${width > 600 ? drawerWidth : 0}px)` },
|
||||
}}
|
||||
>
|
||||
<Outlet />
|
||||
</Box>
|
||||
|
||||
{width <= 600 && (
|
||||
<Box sx={{ flexBasis: "100%" }}>
|
||||
<BottomAppBar />
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue