-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from UniversityWeb/feature/user-profile
Feature/user profile
- Loading branch information
Showing
21 changed files
with
1,140 additions
and
242 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import React from 'react'; | ||
import { | ||
Box, | ||
VStack, | ||
Text, | ||
Image, | ||
Avatar, | ||
Drawer, | ||
DrawerBody, | ||
DrawerFooter, | ||
DrawerHeader, | ||
DrawerOverlay, | ||
DrawerContent, | ||
Skeleton, | ||
} from '@chakra-ui/react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import styles from './Drawer.module.scss'; | ||
|
||
import { useNavigate } from 'react-router-dom'; | ||
import { | ||
MdOutlineAssignment, | ||
MdOutlineShoppingBag, | ||
MdNotificationsNone, | ||
MdLogout | ||
} from 'react-icons/md'; | ||
import { PiCertificate } from "react-icons/pi"; | ||
import { IoBookOutline } from "react-icons/io5"; | ||
import MenuBookOutlinedIcon from '@mui/icons-material/MenuBookOutlined'; | ||
import AssignmentOutlinedIcon from '@mui/icons-material/AssignmentOutlined'; | ||
import ShoppingBagOutlinedIcon from '@mui/icons-material/ShoppingBagOutlined'; | ||
import WorkspacePremiumOutlinedIcon from '@mui/icons-material/WorkspacePremiumOutlined'; | ||
import NotificationsNoneOutlinedIcon from '@mui/icons-material/NotificationsNoneOutlined'; | ||
import LogoutIcon from '@mui/icons-material/Logout'; | ||
import config from '~/config'; | ||
import { isLoggedIn, removeLoginResponse } from '~/utils/authUtils'; | ||
import SidebarItem from '~/components/Drawers/SidebarItem'; | ||
|
||
DrawerRightDefault.propTypes = { | ||
isOpen: PropTypes.bool, | ||
onClose: PropTypes.func, | ||
user: PropTypes.object, | ||
isUserLoading: PropTypes.bool, | ||
}; | ||
|
||
DrawerRightDefault.defaultProps = { | ||
user: { | ||
username: 'john', | ||
fullName: 'john', | ||
email: '[email protected]', | ||
phoneNumber: '+84972640891', | ||
bio: 'A student.', | ||
gender: 'MALE', | ||
dob: '2024-08-05', | ||
role: 'ADMIN', | ||
createdAt: '2024-08-05T13:47:06.794Z', | ||
avatarSrc: '', | ||
}, | ||
}; | ||
|
||
function DrawerRightDefault(props) { | ||
const user = props.user; | ||
const navigate = useNavigate(); | ||
|
||
const handleLogout = () => { | ||
removeLoginResponse(); | ||
navigate(config.routes.login); | ||
}; | ||
|
||
return ( | ||
<Drawer | ||
isOpen={props?.isOpen} | ||
placement="right" | ||
onClose={props.onClose} | ||
size={'sm'} | ||
> | ||
<DrawerOverlay /> | ||
<DrawerContent backgroundColor={'var(--white)'}> | ||
<DrawerHeader borderBottomWidth="1px"> | ||
<Box | ||
display="flex" | ||
alignItems="center" | ||
gap="4%" | ||
justifyContent="start" | ||
onClick={() => navigate(config.routes.user_profile_edit)} | ||
_hover={{ | ||
transform: 'scale(1.05)', | ||
transition: 'transform 0.2s ease', | ||
backgroundColor: '#f8f8f8', | ||
cursor: 'pointer', | ||
}} | ||
> | ||
<Avatar size="xl" name={user?.fullName} src={user?.urlImage} /> | ||
{!isLoggedIn() || props?.isUserLoading ? ( | ||
<Skeleton height="20px" width="100vh" /> | ||
) : ( | ||
<Text className={styles.drawer__heading}>{user?.fullName}</Text> | ||
)} | ||
</Box> | ||
</DrawerHeader> | ||
|
||
<DrawerBody padding={0}> | ||
<VStack ps="10px"> | ||
<SidebarItem | ||
icon={IoBookOutline} | ||
text="Enrolled Courses" | ||
handleClick={() => navigate(config.routes.course_management_for_student)} | ||
/> | ||
|
||
<SidebarItem | ||
icon={MdOutlineAssignment} | ||
text="My Assignments" | ||
handleClick={() => navigate('')} | ||
/> | ||
|
||
<SidebarItem | ||
icon={MdOutlineShoppingBag} | ||
text="My Orders" | ||
handleClick={() => navigate('')} | ||
/> | ||
|
||
<SidebarItem | ||
icon={PiCertificate} | ||
text="My Certificates" | ||
handleClick={() => navigate('')} | ||
/> | ||
|
||
<SidebarItem | ||
icon={MdNotificationsNone} | ||
text="Notifications" | ||
handleClick={() => navigate(config.routes.notifications_for_student)} | ||
/> | ||
|
||
<SidebarItem | ||
icon={MdLogout} | ||
text="Logout" | ||
handleClick={handleLogout} | ||
/>> | ||
</VStack> | ||
</DrawerBody> | ||
|
||
<DrawerFooter padding={0}> | ||
<VStack> | ||
<Image width={'100%'} objectFit="cover" alt="" /> | ||
<Image width={'100%'} objectFit="cover" alt="" /> | ||
</VStack> | ||
</DrawerFooter> | ||
</DrawerContent> | ||
</Drawer> | ||
); | ||
} | ||
|
||
export default DrawerRightDefault; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import React from 'react'; | ||
import { Box } from '@chakra-ui/react'; | ||
|
||
const SidebarItem = ({ icon: Icon, text, isActive, handleClick, size = 22 }) => { | ||
return ( | ||
<Box | ||
w="100%" | ||
onClick={handleClick} | ||
className="drawer__item" | ||
style={{ textDecoration: 'none', border: 'none', cursor: 'pointer' }} | ||
display="flex" | ||
alignItems="center" | ||
justifyContent="flex-start" | ||
padding="10px" | ||
_hover={{ | ||
transform: 'scale(1.05)', | ||
transition: 'transform 0.2s ease', | ||
backgroundColor: isActive ? '#e2e2e2' : '#f8f8f8', | ||
cursor: 'pointer', | ||
}} | ||
> | ||
{Icon && <Icon style={{ fontSize: size }} />} | ||
<p style={{ marginLeft: '10px' }}>{text}</p> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default SidebarItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import React, { useState, useEffect } from 'react'; | ||
import './Navbar.scss'; | ||
import TransientAppLogo from '~/assets/images/TransientAppLogo.svg'; | ||
import Button from '~/components/Buttons/Button'; | ||
import { useDisclosure, Avatar, Spacer } from '@chakra-ui/react'; | ||
import AuthService from '~/services/authService'; | ||
import { isLoggedIn } from '~/utils/authUtils'; | ||
import useCustomToast from '~/hooks/useCustomToast'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import config from '~/config'; | ||
import RightSidebarForStudent from '~/components/Drawers/RightSidebarForStudent'; | ||
|
||
function HomeNavbar(props) { | ||
const navigate = useNavigate(); | ||
const { errorToast } = useCustomToast(); | ||
const { isOpen, onOpen, onClose } = useDisclosure(); | ||
const [user, setUser] = useState(null); | ||
const [isUserLoading, setIsUserLoading] = useState(true); | ||
|
||
useEffect(() => { | ||
const fetchUser = async () => { | ||
setIsUserLoading(true); | ||
AuthService.getCurUser() | ||
.then((user) => { | ||
setUser(user); | ||
}) | ||
.catch((e) => { | ||
errorToast(e?.message); | ||
}) | ||
.finally(() => { | ||
setIsUserLoading(false); | ||
}); | ||
}; | ||
|
||
fetchUser(); | ||
}, []); | ||
|
||
return ( | ||
<div className="navbar"> | ||
<img | ||
className="navbar--logo" | ||
src={TransientAppLogo} | ||
alt="Logo" | ||
style={{ width: '100px', height: '100px' }} | ||
/> | ||
<div className="navbar--list"> | ||
<div className="navbar--list__gap20"> | ||
<Button | ||
id="courses" | ||
light | ||
onClick={() => | ||
navigate(config.routes.course_management_for_student) | ||
} | ||
> | ||
Courses | ||
</Button> | ||
<Button id="assignment" light onClick={() => navigate('')}> | ||
Assignments | ||
</Button> | ||
|
||
<Spacer /> | ||
|
||
{isLoggedIn() ? ( | ||
<> | ||
<div className="navbar__group"> | ||
<Avatar | ||
size="lg" | ||
cursor="pointer" | ||
name={user?.fullName} | ||
onClick={onOpen} | ||
src={user?.urlImage} | ||
/> | ||
</div> | ||
<RightSidebarForStudent | ||
user={user} | ||
isUserLoading={isUserLoading} | ||
isOpen={isOpen} | ||
onClose={onClose} | ||
></RightSidebarForStudent> | ||
</> | ||
) : ( | ||
<Button | ||
id="login" | ||
light | ||
onClick={() => navigate(config.routes.login)} | ||
> | ||
Login | ||
</Button> | ||
)} | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
export default React.memo(HomeNavbar); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.