Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Granthamblin0/tces 9 urd navbar #23

Merged
merged 12 commits into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion client/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ node_modules
README.md
.eslintrc.json
package-lock.json
package.json
package.json


Binary file added client/public/img/tces-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 79 additions & 0 deletions client/src/components/navbar-component/Dropdown.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
.dropdown-container {
margin-top: 10px;
border-radius: 8px;
background: var(--light-background-paper, #fff);
box-shadow:
0px 1px 5px 0px rgba(0, 0, 0, 0.12),
0px 2px 2px 0px rgba(0, 0, 0, 0.14),
0px 3px 1px -2px rgba(0, 0, 0, 0.2);
width: 600px;
position: fixed;
top: 56px;
right: 25px;
z-index: 1000;
}

.dropdown-title {
color: var(--light-text-primary, rgba(0, 0, 0, 0.87));
font-feature-settings:
"clig" off,
"liga" off;
font-size: 24px;
font-style: normal;
font-weight: 400;
line-height: 133.4%;
/* 32.016px */
height: 32px;
padding: 16px;
display: flex;
align-items: center;
align-self: stretch;
border-bottom: 1px solid #0000008a;
}

.dropdown-item-container {
display: flex;
padding: 8px 16px;
align-items: center;
align-self: stretch;
justify-content: space-between;
height: 48px;
background: none;
border: none;
width: 100%;
}

.dropdown-item-button {
text-decoration: none;
display: block;
width: 100%;
}

.dropdown-item-container:not(:last-child) {
border-bottom: 1px solid #0000008a;
}

.dropdown-items {
display: flex;
padding: 16px;
flex-direction: column;
align-items: flex-start;
align-self: stretch;
}

.dropdown-item-text {
color: var(--light-text-primary, rgba(0, 0, 0, 0.87));
font-feature-settings:
"clig" off,
"liga" off;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 150%;
letter-spacing: 0.15px;
}

.dropdown-item-left-content {
display: flex;
gap: 22px;
}
46 changes: 46 additions & 0 deletions client/src/components/navbar-component/Dropdown.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import PropTypes from "prop-types";
import { useEffect, useRef } from "react";
import "./Dropdown.css";
import DropdownItem from "./DropdownItem";

function Dropdown({ isAdmin, setIsDropdownVisible }) {
function useOutsideAlerter(ref) {
useEffect(() => {
/**
* Alert if clicked on outside of element
*/
function handleClickOutside(event) {
if (ref.current && !ref.current.contains(event.target)) {
setIsDropdownVisible(false);
}
}
// Bind the event listener
document.addEventListener("mousedown", handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.removeEventListener("mousedown", handleClickOutside);
};
}, [ref]);
}

const wrapperRef = useRef(null);
useOutsideAlerter(wrapperRef);

return (
<div className="dropdown-container" ref={wrapperRef}>
<div className="dropdown-title">Profile</div>
<div className="dropdown-items">
jordanjanakievski marked this conversation as resolved.
Show resolved Hide resolved
{isAdmin && <DropdownItem keyword="admin" />}
<DropdownItem keyword="settings" />
<DropdownItem keyword="logout" />
Comment on lines +33 to +35
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally these are clickable rather than just the arrow contained within them

</div>
</div>
);
}

Dropdown.propTypes = {
isAdmin: PropTypes.bool.isRequired,
setIsDropdownVisible: PropTypes.func.isRequired,
};

export default Dropdown;
54 changes: 54 additions & 0 deletions client/src/components/navbar-component/DropdownItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import PropTypes from "prop-types";
import "./Navbar.css";
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
import SettingsIcon from "@mui/icons-material/Settings";
import LogoutIcon from "@mui/icons-material/Logout";
import AdminIcon from "@mui/icons-material/Group";
import Button from "@mui/material/Button";

function DropdownItem({ keyword }) {
const icons = {
settings: <SettingsIcon color="action" />,
logout: <LogoutIcon color="action" />,
admin: <AdminIcon color="action" />,
};

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also recommend retrieving label from a dictionary that matches keyword to label as you have done with icons.

const labels = {
settings: "Settings",
logout: "Log Out",
admin: "Admin Dashboard",
};

const routes = {
settings: "#",
logout: "#",
admin: "#",
};

const icon = icons[keyword];
const label = labels[keyword];
const route = routes[keyword];

return (
<Button
variant="text"
className="dropdown-item-button"
style={{ color: "rgba(0, 0, 0, 0.6)" }}
href={route}
>
<div className="dropdown-item-container">
<div className="dropdown-item-left-content">
{icon}
<div className="dropdown-item-text">{label}</div>
</div>
<ArrowForwardIcon color="action" />
</div>
</Button>
);
}

DropdownItem.propTypes = {
keyword: PropTypes.string.isRequired,
};

export default DropdownItem;
46 changes: 46 additions & 0 deletions client/src/components/navbar-component/Navbar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.nav-container {
display: flex;
justify-content: space-between;
flex: 1;
padding: 8px 16px;
border-bottom: 1px solid #0000008a;
background: var(--light-primary-contrast, #fff);
box-shadow:
0px 1px 5px 0px rgba(0, 0, 0, 0.12),
0px 2px 2px 0px rgba(0, 0, 0, 0.14),
0px 3px 1px -2px rgba(0, 0, 0, 0.2);
}

.left-content {
display: flex;
align-items: center;
justify-content: space-between;
}

.right-content {
display: flex;
align-items: center;
}

.right-content-image {
padding: 12px;
background: none;
border: none;
}
.left-content-buttons {
display: flex;
justify-content: space-between;
width: 342px;
margin-left: 50px;
}

.nav-left-button {
color: rgba(0, 0, 0, 0.6);
background: none;
border: none;
font-size: 15px;
font-weight: 500;
line-height: 26px;
letter-spacing: 0.46000000834465027px;
text-align: left;
}
35 changes: 35 additions & 0 deletions client/src/components/navbar-component/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useState } from "react";
import Dropdown from "./Dropdown";
import NavbarProfile from "./NavbarProfile";
import NavbarButton from "./NavbarButton";

function Navbar() {
const [isDropdownVisible, setIsDropdownVisible] = useState(false);

const toggleDropdown = () => {
setIsDropdownVisible(!isDropdownVisible);
};

return (
<div className="nav-container">
<div className="left-content">
<div className="image">
<img src="./img/tcesLogo.svg" alt="logo" width="46" height="50" />
</div>
<div className="left-content-buttons">
<NavbarButton keyword="clients" />
<NavbarButton keyword="jobleads" />
<NavbarButton keyword="employers" />
</div>
</div>
<div className="right-content">
<NavbarProfile toggleDropdown={toggleDropdown} />
</div>
{isDropdownVisible && (
<Dropdown isAdmin setIsDropdownVisible={setIsDropdownVisible} />
)}
</div>
);
}

export default Navbar;
36 changes: 36 additions & 0 deletions client/src/components/navbar-component/NavbarButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import PropTypes from "prop-types";
import Button from "@mui/material/Button";
import "./Navbar.css";

function NavbarButton({ keyword }) {
const titles = {
clients: "CLIENTS",
jobleads: "JOB LEADS",
employers: "EMPLOYERS",
};

const routes = {
clients: "#",
jobleads: "#",
employers: "#",
};

const title = titles[keyword];
const route = routes[keyword];
return (
<Button
variant="text"
className="nav-left-button"
style={{ color: "rgba(0, 0, 0, 0.6)" }}
href={route}
>
{title}
</Button>
);
}

NavbarButton.propTypes = {
keyword: PropTypes.string.isRequired,
};

export default NavbarButton;
18 changes: 18 additions & 0 deletions client/src/components/navbar-component/NavbarProfile.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import PropTypes from "prop-types";
import "./Navbar.css";
import IconButton from "@mui/material/IconButton";
import AccountCircleIcon from "@mui/icons-material/AccountCircle";

function NavbarProfile({ toggleDropdown }) {
return (
<IconButton className="right-content-image" onClick={toggleDropdown}>
<AccountCircleIcon />
</IconButton>
);
}

NavbarProfile.propTypes = {
toggleDropdown: PropTypes.func.isRequired,
};

export default NavbarProfile;
1 change: 0 additions & 1 deletion client/src/logo.svg

This file was deleted.

Loading