Ignore:
Timestamp:
06/17/24 21:59:14 (2 weeks ago)
Author:
223021 <daniel.ilievski.2@…>
Branches:
main
Children:
08f82ec
Parents:
b248810
Message:

Added an edit profile page for both job seekers and recruiters, where they can upload profile pictures/company logos and edit their profile data. Added profile page specifically for recruiters. Refactored existing code.

Location:
jobvista-frontend/src/views/static
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • jobvista-frontend/src/views/static/Header.css

    rb248810 rbefb988  
    66    background-size: contain;
    77    margin-right: 0;
     8
    89}
    910
     
    1819
    1920.navbar {
     21    width: calc(100% - 17px);
    2022    height: 80px;
    21     background-color: #535C91;
     23    background-color: #f8f9fa;
    2224    font-family: Poppins, sans-serif;
     25    position: fixed;
     26    z-index: 10;
     27    box-sizing: border-box;
    2328}
    2429
    2530.navbar .nav-item {
    26 
    2731    color: rgba(1,38,90,0.9);
    2832    margin-right: 15px;
     
    3135    font-size: 20px;
    3236    font-weight: 600;
    33     //font-family: 'Ubuntu', sans-serif;
    3437    font-family: Poppins, sans-serif;
    3538}
     
    3740    color: white;
    3841    background-color: rgba(1,38,90,0.9);
    39     /*border-bottom: 3px solid rgba(1,38,90,0.9);*/
    4042}
    4143.active {
     
    4446}
    4547
    46 .user {
    47 
    48 }
    49 
    50 .auth-box {
    51     display: inline-block;
    52     margin-right: 35px;
    53     margin-left: 5px;
    54     //height: 50px;
    55 
    56 }
    57 
    58 .user {
     48/*NOVO*/
     49
     50:root {
     51    --gray: #555;
     52    --purple: #4e65ff;
     53    --green-blue: #92effd;
     54    --white: #fff;
     55}
     56
     57.navigation {
     58    position: fixed;
     59    top: 10px;
     60    right: 20px;
     61    width: 120px;
     62    height: 60px;
     63    display: flex;
     64    justify-content: space-between;
     65    border-radius: 5px;
     66    background: var(--white);
     67    box-shadow: 0 25px 35px rgba(0, 0, 0, 0.3);
     68    /*box-shadow: 0px 0px 18px 4px rgba(0,0,0,0.46);*/
     69    overflow: hidden;
     70    transition: height 0.5s, width 0.5s;
     71    transition-delay: 0s, 0.3s;
     72    z-index: 15;
     73    /*border: 2px solid var(--gray);*/
     74}
     75
     76.navigation .user-box {
     77    position: relative;
     78    width: 60px;
     79    height: 60px;
     80    display: flex;
     81    align-items: center;
     82    overflow: hidden;
     83    transition: 0.3s;
     84    transition-delay: 0.3s;
     85}
     86
     87.navigation .user-box .username {
     88    font-size: 1.2rem;
     89     font-weight: bold;
     90    white-space: nowrap;
     91    margin: 0;
    5992    color: black;
    6093    padding-top: 10px;
    61     margin-bottom: 0;
    62 
    63 }
    64 
    65 .role {
     94
     95}
     96
     97.navigation .user-box .role {
    6698    color: darkgray;
    6799    margin-bottom: 10px;
    68     font-size: 15px;
    69 
    70 }
    71 
    72 
     100    font-size: 1rem;
     101}
     102
     103.navigation .user-box .image-box {
     104    position: relative;
     105    min-width: 60px;
     106    height: 60px;
     107    background: var(--white);
     108    border-radius: 50%;
     109    overflow: hidden;
     110    border: 10px solid var(--white);
     111
     112}
     113
     114.navigation .user-box .image-box img {
     115    position: absolute;
     116    top: 0;
     117    left: 0;
     118    width: 100%;
     119    height: 100%;
     120    object-fit: cover;
     121    /*border: 1px solid black*/
     122}
     123
     124.navigation .menu-toggle {
     125    position: relative;
     126    width: 60px;
     127    height: 60px;
     128    display: flex;
     129    justify-content: center;
     130    align-items: center;
     131    cursor: pointer;
     132}
     133
     134.navigation .menu-toggle::before {
     135    content: "";
     136    position: absolute;
     137    width: 32px;
     138    height: 2px;
     139    background: var(--gray);
     140    transform: translateY(-10px);
     141    box-shadow: 0 10px var(--gray);
     142    transition: 0.5s;
     143}
     144
     145.navigation .menu-toggle::after {
     146    content: "";
     147    position: absolute;
     148    width: 32px;
     149    height: 2px;
     150    background: var(--gray);
     151    transform: translateY(10px);
     152    transition: 0.5s;
     153}
     154
     155.menu {
     156    position: absolute;
     157    width: 100%;
     158    /*height: calc(100% - 60px);*/
     159    margin-top: 60px;
     160    padding: 0;
     161    border-top: 1px solid rgba(0, 0, 0, 0.1);
     162}
     163
     164.menu .menu-link {
     165    text-decoration: none;
     166    color: black;
     167    display: flex;
     168    align-items: center;
     169    gap: 10px;
     170    font-size: 1.1rem;
     171    padding: 15px 30px;
     172}
     173.menu .menu-link:hover {
     174    background-color: #EEEEEE;
     175}
     176
     177
     178.navigation.active .menu-toggle::before {
     179    transform: translateY(0px) rotate(45deg);
     180    box-shadow: none;
     181}
     182
     183.navigation.active .menu-toggle::after {
     184    transform: translateY(0px) rotate(-45deg);
     185}
     186
     187.navigation.active {
     188    width: 300px;
     189    height: 175px;
     190    transition: width 0.3s, height 0.3s;
     191    transition-delay: 0s, 0.3s;
     192}
     193
     194.navigation.active .user-box {
     195    width: calc(100% - 60px);
     196    transition-delay: 0s;
     197}
     198
     199
     200
     201
     202
  • jobvista-frontend/src/views/static/Header.js

    rb248810 rbefb988  
    11import {Link, NavLink} from "react-router-dom";
    22import "./Header.css"
    3 import { jwtDecode } from "jwt-decode";
     3import {jwtDecode} from "jwt-decode";
    44import {useDispatch, useSelector} from 'react-redux';
    55import {useEffect, useState} from "react";
     
    88import {useNavigate} from "react-router";
    99import {AUTH_TOKEN} from "../../axios/axiosInstance";
     10import {JobSeekerActions} from "../../redux/actions/JobSeekerActions";
     11import {RecruiterActions} from "../../redux/actions/recruiterActions";
    1012
    1113export const Header = (props) => {
     
    1719    const [role, setRole] = useState("");
    1820    const [username, setUsername] = useState("");
     21    const [user, setUser] = useState("");
    1922
    20     const [user, setUser] = useState("");
     23    const [profilePics, setProfilePics] = useState({});
     24    let profilePicState = useSelector(state => state.images.profilePictures);
     25    const [profilePicDispatched, setProfilePicDispatched] = useState(false);
     26
     27    const [logos, setLogos] = useState({});
     28    let logoState = useSelector(state => state.images.logos);
     29    const [logoDispatched, setLogoDispatched] = useState(false);
    2130
    2231    const signOut = () => {
    2332        dispatch(AuthActions.signOut());
    2433        window.location = "/";
     34        //navigator("/")
    2535    }
     36    const [isActive, setIsActive] = useState(false);
     37
     38    const toggleMenu = () => {
     39        setIsActive(!isActive);
     40    };
    2641
    2742    useEffect(() => {
    2843        const token = localStorage.getItem(AUTH_TOKEN);
    29         if (token!=null) {
     44        if (token != null) {
    3045            try {
    3146                const decodedToken = jwtDecode(token);
     
    3449                    role: decodedToken.role,
    3550                    hasAccess: decodedToken.hasAccess,
     51                    id: decodedToken.id
    3652                });
    3753            } catch (error) {
     
    4561            setRole(auth.role);
    4662            setUsername(auth.name);
     63
     64            console.log("ROLE: " + auth.role)
     65
     66            if (auth.role === Roles.JOBSEEKER) {
     67                dispatch(JobSeekerActions.downloadProfilePic(auth.id, (success, reponse) => {
     68                    if (success) {
     69                        setProfilePics(prevState => ({...prevState, [auth.id]: reponse}))
     70                        console.log(reponse)
     71                    }
     72                }))
     73            } else if (auth.role === Roles.RECRUITER) {
     74                dispatch(RecruiterActions.downloadLogo(auth.id, (success, reponse) => {
     75                    if (success) {
     76                        setLogos(prevState => ({...prevState, [auth.id]: reponse}))
     77                        console.log(reponse)
     78                    }
     79                }))
     80            }
    4781        }
    4882    }, [auth]);
     
    5185        <nav className="navbar navbar-expand-lg bg-light">
    5286            <div className="container-fluid">
    53                 <Link to="/" className="logo navbar-brand" />
    54                 <Link to="/" className="brand-name navbar-brand" />
    55                 <div className="collapse navbar-collapse" id="navbarSupportedContent">
     87                <Link to="/" className="logo"/>
     88                <Link to="/" className="brand-name"/>
     89                <div className="navbar-collapse">
    5690                    <ul className="navbar-nav me-auto mb-2 mb-lg-0">
    5791                        <NavLink to="/" className="nav-item nav-link">Home</NavLink>
    58                         {role==Roles.JOBSEEKER &&
     92                        {role == Roles.JOBSEEKER &&
    5993                            <>
    60                                 <NavLink to="/my-applications" className="nav-item nav-link" >My Applications</NavLink>
    61                                 {/*<NavLink to="/favoritejobs" className="nav-item nav-link" >Saved</NavLink>*/}
    62                             </>
    63 
    64                         }
    65                         {role==Roles.RECRUITER &&
    66                             <>
    67                                 <NavLink to="/my-job-advertisements" className="nav-item nav-link" >My Advertisements</NavLink>
    68                                 {/*<NavLink to="/favoritejobs" className="nav-item nav-link" >Saved</NavLink>*/}
     94                                <NavLink to="/my-applications" className="nav-item nav-link">My Applications</NavLink>
    6995                            </>
    7096                        }
    71                         {role===Roles.ADMIN &&
     97                        {role == Roles.RECRUITER &&
     98                            <>
     99                                <NavLink to="/job-management-hub" className="nav-item nav-link">Job Management Hub</NavLink>
     100                            </>
     101                        }
     102                        {role === Roles.ADMIN &&
    72103                            <>
    73104                                <NavLink to="/admin-panel" className="nav-item nav-link">Admin Panel</NavLink>
    74105                            </>
     106                        }
     107                        <NavLink to="/about" className="nav-item nav-link">About Us</NavLink>
     108                        {/*<NavLink to="/contact" className="nav-item nav-link">Support</NavLink>*/}
     109                    </ul>
     110                </div>
     111                {(auth.role === Roles.RECRUITER || auth.role === Roles.ADMIN || auth.role === Roles.JOBSEEKER) ?
     112                    <>
     113                        <div className={`navigation ${isActive ? 'active' : ''}`}>
     114                            <div className="user-box">
     115                                <div className="image-box">
     116                                    {user.role === Roles.JOBSEEKER && <img src={profilePicState[auth.id]} /> }
     117                                    {user.role === Roles.RECRUITER && <img src={logoState[auth.id]} /> }
     118                                    {user.role === Roles.ADMIN && <img src="/images/admin.jpg"/> }
     119                                </div>
     120                                <div className="auth-box">
     121                                    <p className="username">{user.name}</p>
     122                                    {user.role === Roles.RECRUITER && <p className="role">Recruiter</p>}
     123                                    {user.role === Roles.JOBSEEKER && <p className="role">Job Seeker</p>}
     124                                    {user.role === Roles.ADMIN && <p className="role">Admin</p>}
     125                                </div>
    75126
    76                         }
    77                         <NavLink to="/about" className="nav-item nav-link">About</NavLink>
    78                         <NavLink to="/contact" className="nav-item nav-link">Support</NavLink>
    79                     </ul>
     127                            </div>
     128                            <div className="menu-toggle" onClick={toggleMenu}></div>
     129                            <ul className="menu">
     130                                {user.role == Roles.JOBSEEKER &&
     131                                    <>
     132                                        <Link to="/job-seeker/edit-profile" onClick={toggleMenu} className="menu-link">
     133                                            <i className="fa-solid fa-pen-to-square"></i> Edit profile
     134                                        </Link>
     135                                    </>
     136                                }
     137                                {user.role == Roles.RECRUITER &&
     138                                    <>
     139                                        <Link to="/recruiter/edit-profile" onClick={toggleMenu} className="menu-link">
     140                                            <i className="fa-solid fa-pen-to-square"></i> Edit profile
     141                                        </Link>
     142                                    </>
     143                                }
    80144
    81                     {auth ?
    82                         <>
    83                             <img src="/images/user.png" width="45" height="45"/>
    84                             <div className="auth-box">
    85                                 <p className="user"><b>{user.name}</b></p>
    86                                 {user.role==Roles.RECRUITER && <p className="role">Recruiter</p>}
    87                                 {user.role==Roles.JOBSEEKER && <p className="role">Job Seeker</p>}
    88                                 {user.role==Roles.ADMIN && <p className="role">Admin</p>}
    89                                 {/*<p className="role">{user.role==Roles.RECRUITER ? "Recruiter" : "Job Seeker"}</p>*/}
    90                             </div>
    91 
    92 
    93                             <Link onClick={signOut} className="btn auth-secondary-btn">Log out</Link>
    94                         </> :
    95                         <>
    96                             <Link to="/signin" className="btn auth-secondary-btn">Sign in</Link>
    97                         </>
    98                     }
    99 
    100                 </div>
     145                                <Link onClick={signOut} className="menu-link">
     146                                    <i className="fa-solid fa-right-from-bracket"></i> Log out
     147                                </Link>
     148                            </ul>
     149                        </div>
     150                    </> :
     151                    <>
     152                        <Link to="/signin" className="btn auth-secondary-btn">Sign in</Link>
     153                    </>
     154                }
    101155            </div>
    102156        </nav>
Note: See TracChangeset for help on using the changeset viewer.