diff --git a/.env b/.env index e26a791..75b3434 100644 --- a/.env +++ b/.env @@ -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' diff --git a/__tests__/components/common/navbar/Navbar.test.tsx b/__tests__/components/common/navbar/Navbar.test.tsx new file mode 100644 index 0000000..bdfcbd1 --- /dev/null +++ b/__tests__/components/common/navbar/Navbar.test.tsx @@ -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(); + 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(); + + 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); + }); + }); +}); diff --git a/env/.env.development b/env/.env.development index e26a791..75b3434 100644 --- a/env/.env.development +++ b/env/.env.development @@ -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' diff --git a/env/.env.production b/env/.env.production index e431ded..20e752e 100644 --- a/env/.env.production +++ b/env/.env.production @@ -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' \ No newline at end of file +NEXT_PUBLIC_MY_SITE='https://my.realdevsquad.com' + + diff --git a/env/.env.staging b/env/.env.staging index e26a791..cd2c360 100644 --- a/env/.env.staging +++ b/env/.env.staging @@ -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' diff --git a/env/.env.test b/env/.env.test index e26a791..cd2c360 100644 --- a/env/.env.test +++ b/env/.env.test @@ -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' diff --git a/process-env.d.ts b/process-env.d.ts new file mode 100644 index 0000000..8ed51b1 --- /dev/null +++ b/process-env.d.ts @@ -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; + } +} diff --git a/public/rds-logo.svg b/public/rds-logo.svg new file mode 100644 index 0000000..b484842 --- /dev/null +++ b/public/rds-logo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 11df706..6f0d9dc 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -1,5 +1,6 @@ import { ReactNode } from "react"; import Head from "next/head"; +import Navbar from "./common/Navbar/Navbar"; type LayoutProps = { title: string; @@ -11,6 +12,7 @@ export default function Layout({ title, children }: LayoutProps) { {title} + {children} ); diff --git a/src/components/common/Navbar/Navbar.tsx b/src/components/common/Navbar/Navbar.tsx new file mode 100644 index 0000000..1e74fc0 --- /dev/null +++ b/src/components/common/Navbar/Navbar.tsx @@ -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(false); + + function toggleNavbarLinksVisibility() { + setIsNavbarLinksVisible((prevState) => !prevState); + } + + const navbarItemsMapping = NAVBAR_LINKS.map((item: NavbarLink) => ( +
  • + + {item.name} + +
  • + )); + + return ( +
    +
    + Real Dev Squad + + + + + Sign in with Github + + + +
    + +
    + ); +} + +export default Navbar; diff --git a/src/components/common/Navbar/navbar.constants.ts b/src/components/common/Navbar/navbar.constants.ts new file mode 100644 index 0000000..70ebaf6 --- /dev/null +++ b/src/components/common/Navbar/navbar.constants.ts @@ -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, + }, +]; diff --git a/src/components/common/Navbar/navbar.types.ts b/src/components/common/Navbar/navbar.types.ts new file mode 100644 index 0000000..2527636 --- /dev/null +++ b/src/components/common/Navbar/navbar.types.ts @@ -0,0 +1,5 @@ +export type NavbarLink = { + id: string; + name: string; + link: string; +}; diff --git a/src/constants/urls.ts b/src/constants/urls.ts index ccaa369..5a7ddf6 100644 --- a/src/constants/urls.ts +++ b/src/constants/urls.ts @@ -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; diff --git a/tailwind.config.js b/tailwind.config.js index 4040b80..14373a2 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -23,6 +23,9 @@ module.exports = { }, }, colors: { + primary: "#041187", + secondary: "#E30062", + contrast: "#85DA6B", green: "#059669", red: { 100: "#FEF2F2", diff --git a/tsconfig.json b/tsconfig.json index 101ccd7..0c6727b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,6 +24,7 @@ } }, "include": [ + "process-env.d.ts", "next-env.d.ts", "**/*.ts", "**/*.tsx",