Home page and navigate to login/register page if not logged in
This commit is contained in:
@@ -19,3 +19,4 @@ Table:
|
|||||||
| 14.07.2023 | Navbar | 10 |
|
| 14.07.2023 | Navbar | 10 |
|
||||||
| 16.07.2023 | Login and register page | 20 |
|
| 16.07.2023 | Login and register page | 20 |
|
||||||
| 16.07.2023 | Fix mock schema and move mock injections out of index.js | 1 |
|
| 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 |
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { themeSettings } from "theme";
|
|||||||
function App() {
|
function App() {
|
||||||
const mode = useSelector((state) => state.mode);
|
const mode = useSelector((state) => state.mode);
|
||||||
const theme = useMemo(() => createTheme(themeSettings(mode)), [mode]);
|
const theme = useMemo(() => createTheme(themeSettings(mode)), [mode]);
|
||||||
|
const isLogged = Boolean(useSelector((state) => state.token));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
@@ -19,8 +20,14 @@ function App() {
|
|||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<LoginPage />} />
|
<Route path="/" element={<LoginPage />} />
|
||||||
<Route path="/home" element={<HomePage />} />
|
<Route
|
||||||
<Route path="/profile/:userId" element={<ProfilePage />} />
|
path="/home"
|
||||||
|
element={isLogged ? <HomePage /> : <Navigate to="/" />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/profile/:userId"
|
||||||
|
element={isLogged ? <ProfilePage /> : <Navigate to="/" />}
|
||||||
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
|||||||
20
client/src/components/ProfilePhoto.jsx
Normal file
20
client/src/components/ProfilePhoto.jsx
Normal 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;
|
||||||
10
client/src/components/WidgetWrapper.jsx
Normal file
10
client/src/components/WidgetWrapper.jsx
Normal 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;
|
||||||
@@ -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 = () => {
|
const HomePage = () => {
|
||||||
|
const isNotMobile = useMediaQuery("(min-width: 1000px)");
|
||||||
|
const { _id, profilePicturePath } = useSelector((state) => state.user);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>homepage</div>
|
<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;
|
export default HomePage;
|
||||||
|
|||||||
132
client/src/scenes/widgets/UserWidget.jsx
Normal file
132
client/src/scenes/widgets/UserWidget.jsx
Normal 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(s)
|
||||||
|
</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;
|
||||||
Reference in New Issue
Block a user