Skip to content

Commit

Permalink
Feat: navbar functionality and visuals (#75)
Browse files Browse the repository at this point in the history
Co-authored-by: Ryan Chang <[email protected]>
Co-authored-by: Amanda Misjuwar <[email protected]>
  • Loading branch information
3 people authored Jul 6, 2022
1 parent 9b6972d commit d2b2ebc
Show file tree
Hide file tree
Showing 18 changed files with 367 additions and 27 deletions.
4 changes: 4 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
"private": true,
"dependencies": {
"@apollo/client": "^3.3.16",
"@chakra-ui/icons": "^1.1.7",
"@chakra-ui/react": "^2.1.2",
"@emotion/react": "^11",
"@emotion/styled": "^11",
"@fontsource/noto-sans": "^4.5.10",
"@fortawesome/fontawesome-svg-core": "^6.1.1",
"@fortawesome/free-solid-svg-icons": "^6.1.1",
"@fortawesome/react-fontawesome": "^0.1.18",
"@rjsf/bootstrap-4": "^2.5.1",
"@rjsf/core": "^2.5.1",
"@testing-library/jest-dom": "^5.11.4",
Expand Down
22 changes: 19 additions & 3 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import Login from "./components/auth/Login";
import Signup from "./components/auth/Signup";
import PrivateRoute from "./components/auth/PrivateRoute";
import CreatePage from "./components/pages/CreatePage";
import Default from "./components/pages/Default";
import DisplayPage from "./components/pages/DisplayPage";
import NotFound from "./components/pages/NotFound";
import UpdatePage from "./components/pages/UpdatePage";
import CampsPage from "./components/pages/CampsPage";
import GlobalFormsPage from "./components/pages/GlobalFormsPage";
import AccessControlPage from "./components/pages/AccessControlPage";
import * as Routes from "./constants/Routes";
import AUTHENTICATED_USER_KEY from "./constants/AuthConstants";
import AuthContext from "./contexts/AuthContext";
Expand All @@ -25,6 +27,8 @@ import EditTeamInfoPage from "./components/pages/EditTeamPage";
import HooksDemo from "./components/pages/HooksDemo";

import { AuthenticatedUser } from "./types/AuthTypes";
import LandingPage from "./components/pages/LandingPage";
import NavBar from "./components/common/NavBar";

const App = (): React.ReactElement => {
const currentUser: AuthenticatedUser = getLocalStorageObj<AuthenticatedUser>(
Expand Down Expand Up @@ -53,13 +57,25 @@ const App = (): React.ReactElement => {
value={{ authenticatedUser, setAuthenticatedUser }}
>
<Router>
<NavBar />
<Switch>
<Route exact path={Routes.LOGIN_PAGE} component={Login} />
<Route exact path={Routes.SIGNUP_PAGE} component={Signup} />
<Route exact path={Routes.HOME_PAGE} component={LandingPage} />
<PrivateRoute
exact
path={Routes.HOME_PAGE}
component={Default}
path={Routes.CAMPS_PAGE}
component={CampsPage}
/>
<PrivateRoute
exact
path={Routes.GLOBAL_FORMS_PAGE}
component={GlobalFormsPage}
/>
<PrivateRoute
exact
path={Routes.ACCESS_CONTROL_PAGE}
component={AccessControlPage}
/>
<PrivateRoute
exact
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/assets/fon_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions frontend/src/components/auth/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { Button, Center, Image, Text, VStack } from "@chakra-ui/react";
import { FcGoogle } from "react-icons/fc";
import authAPIClient from "../../APIClients/AuthAPIClient";
import { HOME_PAGE } from "../../constants/Routes";
import { CAMPS_PAGE } from "../../constants/Routes";
import AuthContext from "../../contexts/AuthContext";
import { AuthenticatedUser } from "../../types/AuthTypes";

Expand Down Expand Up @@ -64,7 +64,7 @@ const Login = (): React.ReactElement => {
};

if (authenticatedUser) {
return <Redirect to={HOME_PAGE} />;
return <Redirect to={CAMPS_PAGE} />;
}

return (
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/auth/PrivateRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useContext } from "react";
import { Route, Redirect } from "react-router-dom";

import AuthContext from "../../contexts/AuthContext";
import { LOGIN_PAGE } from "../../constants/Routes";
import { CAMPS_PAGE, LOGIN_PAGE } from "../../constants/Routes";

type PrivateRouteProps = {
component: React.FC;
Expand Down
176 changes: 176 additions & 0 deletions frontend/src/components/common/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import {
Container,
Flex,
Image,
Button,
Tabs,
Tab,
TabList,
PopoverContent,
PopoverTrigger,
Popover,
PopoverBody,
} from "@chakra-ui/react";
import { LockIcon, ChevronDownIcon, ChevronUpIcon } from "@chakra-ui/icons";

import React, { useContext } from "react";
import { useHistory } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCampground, faPenToSquare } from "@fortawesome/free-solid-svg-icons";

import authAPIClient from "../../APIClients/AuthAPIClient";
import FONIcon from "../../assets/fon_icon.svg";
import * as Routes from "../../constants/Routes";
import AuthContext from "../../contexts/AuthContext";
import { Role } from "../../types/AuthTypes";

import { FontWeights } from "../../theme/textStyles";

const NavBar = (): JSX.Element => {
const { authenticatedUser, setAuthenticatedUser } = useContext(AuthContext);
const history = useHistory();

const onLogOutClick = async () => {
const success = await authAPIClient.logout(authenticatedUser?.id);
if (success) {
history.push(Routes.LOGIN_PAGE);
setAuthenticatedUser(null);
}
};

const navigate = (index: number) => {
switch (index) {
case 0:
history.push(Routes.CAMPS_PAGE);
break;
case 1:
history.push(Routes.GLOBAL_FORMS_PAGE);
break;
case 2:
history.push(Routes.ACCESS_CONTROL_PAGE);
break;
default:
history.push(Routes.CAMPS_PAGE);
break;
}
};

const getIndex = () => {
switch (window.location.pathname) {
case Routes.CAMPS_PAGE:
return 0;
case Routes.GLOBAL_FORMS_PAGE:
return 1;
case Routes.ACCESS_CONTROL_PAGE:
return 2;
default:
return 0;
}
};

return (
<Container maxWidth="100vw">
<Flex
direction="row"
justifyContent="space-between"
marginLeft="80px"
marginRight="80px"
marginTop="14px"
marginBottom="14px"
>
{authenticatedUser ? (
<>
<Image
src={FONIcon}
alt="FON icon"
display="inline"
width="40px"
height="40px"
/>
<Tabs
variant="unstyled"
onChange={navigate}
defaultIndex={getIndex as any}
width="750px"
alignContent="center"
>
<TabList justifyContent="space-evenly">
<Tab
id="Camps"
_selected={{
color: "primary.green.100",
fontWeight: FontWeights.SEMIBOLD,
}}
>
<FontAwesomeIcon icon={faCampground} />
&nbsp; Camps
</Tab>
{authenticatedUser.role === Role.ADMIN && (
<>
<Tab
id="Global Forms"
_selected={{
color: "primary.green.100",
fontWeight: FontWeights.SEMIBOLD,
}}
>
<FontAwesomeIcon icon={faPenToSquare} />
&nbsp; Global Forms
</Tab>
<Tab
id="Access Control"
_selected={{
color: "primary.green.100",
fontWeight: FontWeights.SEMIBOLD,
}}
>
<LockIcon />
&nbsp; Access Control
</Tab>
</>
)}
</TabList>
</Tabs>
<Popover placement="bottom-start" matchWidth>
{({ isOpen }) => (
<>
<PopoverTrigger>
<Button
rightIcon={
isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />
}
bg="background.white.100"
_hover={{
color: "none",
}}
_active={{
color: "none",
}}
_focus={{
color: "none",
}}
>
{authenticatedUser?.firstName}{" "}
{authenticatedUser?.lastName}
</Button>
</PopoverTrigger>
<PopoverContent width="inherit">
<PopoverBody
as={Button}
bg="background.white.100"
onClick={onLogOutClick}
>
Logout
</PopoverBody>
</PopoverContent>
</>
)}
</Popover>
</>
) : null}
</Flex>
</Container>
);
};

export default NavBar;
11 changes: 11 additions & 0 deletions frontend/src/components/pages/AccessControlPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React, { useContext } from "react";

const AccessControlPage = (): React.ReactElement => {
return (
<div>
<h2>Access Control Page</h2>
</div>
);
};

export default AccessControlPage;
11 changes: 11 additions & 0 deletions frontend/src/components/pages/CampsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React, { useContext } from "react";

const CampsPage = (): React.ReactElement => {
return (
<div>
<h2>Camps Page</h2>
</div>
);
};

export default CampsPage;
32 changes: 18 additions & 14 deletions frontend/src/components/pages/Default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import SampleContext from "../../contexts/SampleContext";
import Logout from "../auth/Logout";
import RefreshCredentials from "../auth/RefreshCredentials";
import ResetPassword from "../auth/ResetPassword";
import NavBar from "../common/NavBar";

type ButtonProps = { text: string; path: string };

Expand Down Expand Up @@ -39,22 +40,25 @@ const TeamInfoDisplay = () => {

const Default = (): React.ReactElement => {
return (
<div style={{ textAlign: "center", paddingTop: "20px" }}>
<h1>Default Page</h1>
<div className="btn-group" style={{ paddingRight: "10px" }}>
<Logout />
<RefreshCredentials />
<ResetPassword />
<Button text="Create Entity" path={Routes.CREATE_ENTITY_PAGE} />
<Button text="Update Entity" path={Routes.UPDATE_ENTITY_PAGE} />
<Button text="Display Entities" path={Routes.DISPLAY_ENTITY_PAGE} />
<Button text="Edit Team" path={Routes.EDIT_TEAM_PAGE} />
<Button text="Hooks Demo" path={Routes.HOOKS_PAGE} />
</div>
<div>
<NavBar />
<div style={{ textAlign: "center", paddingTop: "20px" }}>
<h1>Default Page</h1>
<div className="btn-group" style={{ paddingRight: "10px" }}>
<Logout />
<RefreshCredentials />
<ResetPassword />
<Button text="Create Entity" path={Routes.CREATE_ENTITY_PAGE} />
<Button text="Update Entity" path={Routes.UPDATE_ENTITY_PAGE} />
<Button text="Display Entities" path={Routes.DISPLAY_ENTITY_PAGE} />
<Button text="Edit Team" path={Routes.EDIT_TEAM_PAGE} />
<Button text="Hooks Demo" path={Routes.HOOKS_PAGE} />
</div>

<div style={{ height: "2rem" }} />
<div style={{ height: "2rem" }} />

<TeamInfoDisplay />
<TeamInfoDisplay />
</div>
</div>
);
};
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/components/pages/GlobalFormsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React, { useContext } from "react";

const GlobalFormsPage = (): React.ReactElement => {
return (
<div>
<h2>Global Forms Page</h2>
</div>
);
};

export default GlobalFormsPage;
11 changes: 11 additions & 0 deletions frontend/src/components/pages/LandingPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React, { useContext } from "react";

const LandingPage = (): React.ReactElement => {
return (
<div>
<h2>Placeholder Landing Page</h2>
</div>
);
};

export default LandingPage;
6 changes: 6 additions & 0 deletions frontend/src/constants/Routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ export const CREATE_ENTITY_PAGE = "/entity/create";
export const UPDATE_ENTITY_PAGE = "/entity/update";

export const HOOKS_PAGE = "/hooks";

export const CAMPS_PAGE = "/admin";

export const GLOBAL_FORMS_PAGE = "/admin/global-forms";

export const ACCESS_CONTROL_PAGE = "/admin/access-control";
4 changes: 4 additions & 0 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

*:focus{
box-shadow: none !important;
}
2 changes: 1 addition & 1 deletion frontend/src/theme/textStyles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
enum FontWeights {
export enum FontWeights {
REGULAR = 400,
MEDIUM = 500,
SEMIBOLD = 600,
Expand Down
Loading

0 comments on commit d2b2ebc

Please sign in to comment.