Home page and navigate to login/register page if not logged in

This commit is contained in:
Andrew Trieu
2023-07-18 21:43:53 +03:00
parent bab2bfad0b
commit 94232b24d9
6 changed files with 201 additions and 5 deletions

View File

@@ -19,3 +19,4 @@ Table:
| 14.07.2023 | Navbar | 10 |
| 16.07.2023 | Login and register page | 20 |
| 16.07.2023 | Fix mock schema and move mock injections out of index.js | 1 |
| 18.07.2023 | Home page and navigate to login/register page if not logged in | 20 |

View File

@@ -11,6 +11,7 @@ import { themeSettings } from "theme";
function App() {
const mode = useSelector((state) => state.mode);
const theme = useMemo(() => createTheme(themeSettings(mode)), [mode]);
const isLogged = Boolean(useSelector((state) => state.token));
return (
<div className="App">
@@ -19,8 +20,14 @@ function App() {
<CssBaseline />
<Routes>
<Route path="/" element={<LoginPage />} />
<Route path="/home" element={<HomePage />} />
<Route path="/profile/:userId" element={<ProfilePage />} />
<Route
path="/home"
element={isLogged ? <HomePage /> : <Navigate to="/" />}
/>
<Route
path="/profile/:userId"
element={isLogged ? <ProfilePage /> : <Navigate to="/" />}
/>
</Routes>
</ThemeProvider>
</BrowserRouter>

View File

@@ -0,0 +1,20 @@
import { Box } from "@mui/material";
const ProfilePhoto = ({ image, size = "60px" }) => {
return (
<Box width={size} height={size}>
<img
style={{
objectFit: "cover",
borderRadius: "50%",
}}
width={size}
height={size}
alt="profile"
src={`http://localhost:3001/assets/${image}`}
/>
</Box>
);
};
export default ProfilePhoto;

View File

@@ -0,0 +1,10 @@
import { Box } from "@mui/material";
import { styled } from "@mui/system";
const WidgetWrapper = styled(Box)(({ theme }) => ({
padding: " 1.5 rem 1.5 rem 0.75rem 1.5rem",
backgroundColor: theme.palette.background.alt,
borderRadius: "0.75rem",
}));
export default WidgetWrapper;

View File

@@ -1,7 +1,33 @@
import { Box, useMediaQuery } from "@mui/material";
import { useSelector } from "react-redux";
import Navbar from "scenes/navbar";
import UserWidget from "scenes/widgets/UserWidget";
const HomePage = () => {
return (
<div>homepage</div>
)
const isNotMobile = useMediaQuery("(min-width: 1000px)");
const { _id, profilePicturePath } = useSelector((state) => state.user);
return (
<Box>
<Navbar />
<Box
width="100%"
padding="2rem 6%"
display={isNotMobile ? "flex" : "block"}
gap="0.5rem"
justifyContent="space-between"
>
<Box flexBasis={isNotMobile ? "26%" : undefined}>
<UserWidget userId={_id} profilePicturePath={profilePicturePath} />
</Box>
<Box
flexBasis={isNotMobile ? "42%" : undefined}
mt={isNotMobile ? undefined : "2rem"}
></Box>
{isNotMobile && <Box flexBasis="26%"></Box>}
</Box>
</Box>
);
};
export default HomePage;

View File

@@ -0,0 +1,132 @@
import {
ManageAccountsOutlined,
EditOutlined,
LocationOnOutlined,
FavoriteOutlined,
} from "@mui/icons-material";
import { Box, Typography, Divider, useTheme } from "@mui/material";
import ProfilePhoto from "components/ProfilePhoto";
import WidgetWrapper from "components/WidgetWrapper";
import FlexBetween from "components/FlexBetween";
import { useSelector } from "react-redux";
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
const UserWidget = ({ userId, profilePicturePath }) => {
const [user, setUser] = useState(null);
const { palette } = useTheme();
const navigate = useNavigate();
const token = useSelector((state) => state.token);
const dark = palette.neutral.dark;
const medium = palette.neutral.medium;
const main = palette.neutral.main;
const getUser = async () => {
const response = await fetch(`http://localhost:3001/users/${userId}`, {
method: "GET",
headers: { Authorization: `Bearer ${token}` },
});
const data = await response.json();
setUser(data);
};
useEffect(() => {
getUser();
}, []); // eslint-disable-line react-hooks/exhaustive-deps
if (!user) return null;
const { firstName, lastName, location, description, friends } = user;
return (
<WidgetWrapper>
<FlexBetween
gap="0.5rem"
pb="1.1rem"
onClick={() => navigate(`/profile/${userId}`)}
>
<FlexBetween gap="1rem">
<ProfilePhoto image={profilePicturePath} />
<Box>
<Typography
variant="h4"
color={dark}
fontWeight="500"
sx={{
"&:hover": {
color: palette.primary.main,
cursor: "pointer",
},
}}
>
{firstName} {lastName}
</Typography>
<Typography color={medium}>
{friends.length} friend&#40;s&#41;
</Typography>
</Box>
</FlexBetween>
<ManageAccountsOutlined />
</FlexBetween>
<Divider />
<Box p="1rem 0">
<Box display="flex" alignItems="center" gap="1rem" mb="0.5rem">
<LocationOnOutlined fontSize="large" sx={{ color: main }} />
<Typography color={medium}>{location}</Typography>
</Box>
<Box display="flex" alignItems="center" gap="1rem">
<FavoriteOutlined fontSize="large" sx={{ color: main }} />
<Typography color={medium}>{description}</Typography>
</Box>
</Box>
<Divider />
<Box p="1rem 0">
<Typography fontSize="1rem" fontWeight="500" color={main} mb="1rem">
Other platforms
</Typography>
<FlexBetween gap="1rem" mb="0.5rem">
<FlexBetween gap="1rem">
<img src="../../public/assets/icons/facebook.svg" alt="facebook" />
<Box>
<Typography color={main} fontWeight="500">
Facebook
</Typography>
<Typography color={medium}>Social media</Typography>
</Box>
</FlexBetween>
<EditOutlined sx={{ color: main }} />
</FlexBetween>
<FlexBetween gap="1rem">
<FlexBetween gap="1rem">
<img
src="../../public/assets/icons/instagram.svg"
alt="instagram"
/>
<Box>
<Typography color={main} fontWeight="500">
Instagram
</Typography>
<Typography color={medium}>Social media</Typography>
</Box>
</FlexBetween>
<EditOutlined sx={{ color: main }} />
</FlexBetween>
<FlexBetween gap="1rem">
<FlexBetween gap="1rem">
<img src="../../public/assets/icons/linkedin.svg" alt="linkedin" />
<Box>
<Typography color={main} fontWeight="500">
LinkedIn
</Typography>
<Typography color={medium}>Network platform</Typography>
</Box>
</FlexBetween>
<EditOutlined sx={{ color: main }} />
</FlexBetween>
</Box>
</WidgetWrapper>
);
};
export default UserWidget;