Skip to content

Commit

Permalink
Merge pull request #44 from Real-Dev-Squad/feat/navbar
Browse files Browse the repository at this point in the history
feat: add navbar component
  • Loading branch information
bhtibrewal authored Mar 2, 2024
2 parents 712faf3 + 15e032f commit ca993ef
Show file tree
Hide file tree
Showing 15 changed files with 182 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
NEXT_PUBLIC_BACKEND_BASE_URL = 'https://staging-skilltree-api.realdevsquad.com/v1'
NEXT_PUBLIC_RDS_BACKEND_URL='https://staging-api.realdevsquad.com'
NEXT_PUBLIC_SKILL_TREE_SITE='https://staging-skilltree.realdevsquad.com'
NEXT_PUBLIC_STATUS_SITE='https://staging-status.realdevsquad.com'
NEXT_PUBLIC_MEMBERS_SITE='https://staging-members.realdevsquad.com'
NEXT_PUBLIC_WELCOME_SITE='https://welcome.realdevsquad.com'
Expand Down
54 changes: 54 additions & 0 deletions __tests__/components/common/navbar/Navbar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from "react";
import { fireEvent, render, screen } from "@testing-library/react";

import { NavbarLink } from "@/components/common/Navbar/navbar.types";
import { NAVBAR_LINKS, SIGNIN_URL } from "@/components/common/Navbar/navbar.constants";

import Navbar from "@/components/common/Navbar/Navbar";

describe("Navbar Component", () => {
it("should render the Navbar", () => {
render(<Navbar />);
const nav = screen.getByRole("banner");

expect(nav).toBeInTheDocument();

// nav links assertions - desktop
NAVBAR_LINKS.forEach((link: NavbarLink) => {
const navLink = screen.getAllByText(link.name)[0];
expect(navLink).toHaveTextContent(link.name);
});

// signin button assertions
const signinButton = screen.getByTestId("signin-button");
const signInText = screen.getByText("Sign in with Github");

expect(signInText).toBeInTheDocument();
expect(signinButton).toBeInTheDocument();
expect(signinButton).toHaveAttribute("href", SIGNIN_URL);
});

it("should render the mobile navbar when hamburger button is clicked", () => {
render(<Navbar />);

const mobileNav = screen.queryByTestId("mobile-nav");
const hamburgerButton = screen.queryByRole("button");

// hamburgerButton assertions
expect(hamburgerButton).toBeInTheDocument();
expect(hamburgerButton).toHaveClass("hamburger");

// toggle navlinks assertions
expect(mobileNav).toHaveClass("hidden");

fireEvent.click(hamburgerButton!);

expect(mobileNav).toHaveClass("visible");

// nav links assertions - mobile
NAVBAR_LINKS.forEach((link: NavbarLink) => {
const navLink = screen.queryAllByText(link.name)[1];
expect(navLink).toHaveTextContent(link.name);
});
});
});
2 changes: 2 additions & 0 deletions env/.env.development
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
NEXT_PUBLIC_BACKEND_BASE_URL = 'https://staging-skilltree-api.realdevsquad.com/v1'
NEXT_PUBLIC_RDS_BACKEND_URL='https://staging-api.realdevsquad.com'
NEXT_PUBLIC_SKILL_TREE_SITE='https://staging-skilltree.realdevsquad.com'
NEXT_PUBLIC_STATUS_SITE='https://staging-status.realdevsquad.com'
NEXT_PUBLIC_MEMBERS_SITE='https://staging-members.realdevsquad.com'
NEXT_PUBLIC_WELCOME_SITE='https://welcome.realdevsquad.com'
Expand Down
6 changes: 5 additions & 1 deletion env/.env.production
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
NEXT_PUBLIC_BACKEND_BASE_URL = 'https://skilltree-api.realdevsquad.com/v1'
NEXT_PUBLIC_RDS_BACKEND_URL='https://api.realdevsquad.com'
NEXT_PUBLIC_SKILL_TREE_SITE='https:/skilltree.realdevsquad.com'
NEXT_PUBLIC_STATUS_SITE='https://status.realdevsquad.com'
NEXT_PUBLIC_MEMBERS_SITE='https://members.realdevsquad.com'
NEXT_PUBLIC_WELCOME_SITE='https://welcome.realdevsquad.com'
NEXT_PUBLIC_WWW_SITE='https://www.realdevsquad.com'
NEXT_PUBLIC_MY_SITE='https://my.realdevsquad.com'
NEXT_PUBLIC_MY_SITE='https://my.realdevsquad.com'


2 changes: 2 additions & 0 deletions env/.env.staging
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
NEXT_PUBLIC_BACKEND_BASE_URL = 'https://staging-skilltree-api.realdevsquad.com/v1'
NEXT_PUBLIC_RDS_BACKEND_URL='https://staging-api.realdevsquad.com'
NEXT_PUBLIC_SKILL_TREE_SITE='https:/staging-skilltree.realdevsquad.com'
NEXT_PUBLIC_STATUS_SITE='https://staging-status.realdevsquad.com'
NEXT_PUBLIC_MEMBERS_SITE='https://staging-members.realdevsquad.com'
NEXT_PUBLIC_WELCOME_SITE='https://welcome.realdevsquad.com'
Expand Down
2 changes: 2 additions & 0 deletions env/.env.test
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
NEXT_PUBLIC_BACKEND_BASE_URL = 'https://staging-skilltree-api.realdevsquad.com/v1'
NEXT_PUBLIC_RDS_BACKEND_URL='https://staging-api.realdevsquad.com'
NEXT_PUBLIC_SKILL_TREE_SITE='https:/staging-skilltree.realdevsquad.com'
NEXT_PUBLIC_STATUS_SITE='https://staging-status.realdevsquad.com'
NEXT_PUBLIC_MEMBERS_SITE='https://staging-members.realdevsquad.com'
NEXT_PUBLIC_WELCOME_SITE='https://welcome.realdevsquad.com'
Expand Down
10 changes: 10 additions & 0 deletions process-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
declare namespace NodeJS {
interface ProcessEnv {
NEXT_PUBLIC_BACKEND_BASE_URL: string;
NEXT_PUBLIC_STATUS_SITE: string;
NEXT_PUBLIC_MEMBERS_SITE: string;
NEXT_PUBLIC_WELCOME_SITE: string;
NEXT_PUBLIC_WWW_SITE: string;
NEXT_PUBLIC_MY_SITE: string;
}
}
9 changes: 9 additions & 0 deletions public/rds-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ReactNode } from "react";
import Head from "next/head";
import Navbar from "./common/Navbar/Navbar";

type LayoutProps = {
title: string;
Expand All @@ -11,6 +12,7 @@ export default function Layout({ title, children }: LayoutProps) {
<Head>
<title>{title}</title>
</Head>
<Navbar />
{children}
</div>
);
Expand Down
56 changes: 56 additions & 0 deletions src/components/common/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Image from "next/image";
import React, { useState } from "react";
import { GiHamburgerMenu } from "react-icons/gi";
import { IoLogoGithub } from "react-icons/io5";

import { NAVBAR_LINKS, SIGNIN_URL } from "./navbar.constants";
import { NavbarLink } from "./navbar.types";

function Navbar() {
const [isNavbarLinksVisible, setIsNavbarLinksVisible] = useState<boolean>(false);

function toggleNavbarLinksVisibility() {
setIsNavbarLinksVisible((prevState) => !prevState);
}

const navbarItemsMapping = NAVBAR_LINKS.map((item: NavbarLink) => (
<li
key={item.id}
className="text-base font-bold max-lg:w-full max-lg:text-primary text-white hover:text-contrast "
>
<a className="decoration-none max-lg:p-3 max-lg:w-full max-lg:inline-block max-lg:pl-10" href={item.link}>
{item.name}
</a>
</li>
));

return (
<header className="navbar bg-primary w-full flex items-center max-lg:flex-col">
<div className="bg-primary w-full p-5 pl-10 max-sm:pl-6 flex gap-10 items-center justify-between">
<Image className="max-lg:hidden" src="/rds-logo.svg" alt="Real Dev Squad" height={45} width={45} />
<button onClick={toggleNavbarLinksVisibility} className="hamburger lg:hidden">
<GiHamburgerMenu className="text-white font-bold" size={30} />
</button>
<nav className="navbar__desktop max-lg:hidden visible">
<ul className="flex gap-10 items-center max-lg:flex-col">{navbarItemsMapping}</ul>
</nav>
<a data-testid="signin-button" className="ml-auto decoration-none" href={SIGNIN_URL}>
<span className="flex gap-2 items-center text-base max-sm:text-sm max-sm:font-bold font-semibold w-fit border text-white rounded-md py-2 p-2">
<span>Sign in with Github</span>
<IoLogoGithub size={25} />
</span>
</a>
</div>
<nav
data-testid="mobile-nav"
className={`navbar__mobile ${isNavbarLinksVisible ? "visible" : "hidden"} max-lg:w-full`}
>
<ul className="bg-white shadow-md flex lg:hidden items-center max-lg:flex-col max-lg:py-3">
{navbarItemsMapping}
</ul>
</nav>
</header>
);
}

export default Navbar;
28 changes: 28 additions & 0 deletions src/components/common/Navbar/navbar.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { RDS_BACKEND_URL } from "@/constants/urls";
import { NavbarLink } from "./navbar.types";

// ?v2=true so that we get rds-session-v2 cookie from RDS backend
export const SIGNIN_URL = `${RDS_BACKEND_URL}/auth/github/login?redirectURL=${process.env.NEXT_PUBLIC_SKILL_TREE_SITE}?v2=true`;

export const NAVBAR_LINKS: NavbarLink[] = [
{
id: "welcome-site",
name: "Welcome",
link: process.env.NEXT_PUBLIC_WELCOME_SITE,
},
{
id: "events-site",
name: "Events",
link: `${process.env.NEXT_PUBLIC_WWW_SITE}/events`,
},
{
id: "members-site",
name: "Members",
link: process.env.NEXT_PUBLIC_MEMBERS_SITE,
},
{
id: "status-site",
name: "Status",
link: process.env.NEXT_PUBLIC_STATUS_SITE,
},
];
5 changes: 5 additions & 0 deletions src/components/common/Navbar/navbar.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type NavbarLink = {
id: string;
name: string;
link: string;
};
1 change: 1 addition & 0 deletions src/constants/urls.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export const BASE_URL = process.env.NEXT_PUBLIC_BACKEND_BASE_URL;
export const RDS_BACKEND_URL = process.env.NEXT_PUBLIC_RDS_BACKEND_URL;
3 changes: 3 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ module.exports = {
},
},
colors: {
primary: "#041187",
secondary: "#E30062",
contrast: "#85DA6B",
green: "#059669",
red: {
100: "#FEF2F2",
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
}
},
"include": [
"process-env.d.ts",
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
Expand Down

0 comments on commit ca993ef

Please sign in to comment.