Fix navbar highlight for Organized Content sections (#182)
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
Also fixes the navbar highlight for the different Advice sections. Closes #181 Co-authored-by: Amy <a258wang@uwaterloo.ca> Reviewed-on: #182 Reviewed-by: Aditya Thakral <a3thakra@csclub.uwaterloo.ca> Co-authored-by: Amy <a258wang@csclub.uwaterloo.ca> Co-committed-by: Amy <a258wang@csclub.uwaterloo.ca>
This commit is contained in:
parent
485230c95a
commit
0bb8049db3
|
@ -9,16 +9,15 @@ import styles from "./Navbar.module.css";
|
||||||
type Menu = {
|
type Menu = {
|
||||||
name: string;
|
name: string;
|
||||||
route: string;
|
route: string;
|
||||||
submenu?: {
|
exact?: boolean;
|
||||||
name: string;
|
submenu?: Menu;
|
||||||
route: string;
|
|
||||||
}[];
|
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
const menu: Menu = [
|
const menu: Menu = [
|
||||||
{
|
{
|
||||||
name: "Home",
|
name: "Home",
|
||||||
route: "/",
|
route: "/",
|
||||||
|
exact: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "About",
|
name: "About",
|
||||||
|
@ -27,6 +26,7 @@ const menu: Menu = [
|
||||||
{
|
{
|
||||||
name: "About Us",
|
name: "About Us",
|
||||||
route: "/about",
|
route: "/about",
|
||||||
|
exact: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Meet the Team",
|
name: "Meet the Team",
|
||||||
|
@ -76,7 +76,21 @@ const menu: Menu = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Advice",
|
name: "Advice",
|
||||||
route: "/resources/advice/coop",
|
route: "/resources/advice/co-op",
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
name: "Co-op Advice",
|
||||||
|
route: "/resources/advice/co-op",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Academic Advice",
|
||||||
|
route: "/resources/advice/academic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Additional Resources",
|
||||||
|
route: "/resources/advice/misc",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Internships",
|
name: "Internships",
|
||||||
|
@ -198,10 +212,11 @@ interface NavItemProps {
|
||||||
|
|
||||||
function NavItem(props: NavItemProps) {
|
function NavItem(props: NavItemProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const isCurrentPage =
|
const isCurrentPage = shouldHighlight(
|
||||||
router.pathname === props.route ||
|
router.pathname,
|
||||||
(props.submenu != null &&
|
props.name,
|
||||||
router.pathname.startsWith(getMainRoute(props.route)));
|
props.route
|
||||||
|
);
|
||||||
const isExternalLink =
|
const isExternalLink =
|
||||||
props.route.includes("http://") || props.route.includes("https://");
|
props.route.includes("http://") || props.route.includes("https://");
|
||||||
|
|
||||||
|
@ -273,6 +288,54 @@ function NavItem(props: NavItemProps) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Leaf {
|
||||||
|
name: string;
|
||||||
|
route: string;
|
||||||
|
exact?: boolean;
|
||||||
|
ancestors: { name: string; route: string }[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectLeaves(
|
||||||
|
accumulator: Leaf[],
|
||||||
|
entry: {
|
||||||
|
name: string;
|
||||||
|
route: string;
|
||||||
|
exact?: boolean;
|
||||||
|
submenu?: Menu;
|
||||||
|
}
|
||||||
|
): Leaf[] {
|
||||||
|
if (entry.submenu == null) {
|
||||||
|
return [...accumulator, { ...entry, ancestors: [] }];
|
||||||
|
}
|
||||||
|
|
||||||
|
const subleaves = entry.submenu.reduce(collectLeaves, [] as Leaf[]);
|
||||||
|
return [
|
||||||
|
...accumulator,
|
||||||
|
...subleaves.map((leaf) => ({
|
||||||
|
...leaf,
|
||||||
|
ancestors: [...leaf.ancestors, { name: entry.name, route: entry.route }],
|
||||||
|
})),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const leaves: Leaf[] = menu.reduce(collectLeaves, [] as Leaf[]);
|
||||||
|
|
||||||
|
function shouldHighlight(
|
||||||
|
pathname: string,
|
||||||
|
name: string,
|
||||||
|
route: string
|
||||||
|
): boolean {
|
||||||
|
const match = leaves.find((leaf) =>
|
||||||
|
leaf.exact ? leaf.route === pathname : pathname.startsWith(leaf.route)
|
||||||
|
);
|
||||||
|
return match
|
||||||
|
? (match.name === name && match.route === route) ||
|
||||||
|
match.ancestors.find(
|
||||||
|
(ancestor) => ancestor.name === name && ancestor.route === route
|
||||||
|
) != null
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
function getMainRoute(route: string) {
|
function getMainRoute(route: string) {
|
||||||
if (route === "/") {
|
if (route === "/") {
|
||||||
return "/";
|
return "/";
|
||||||
|
|
|
@ -45,7 +45,11 @@ export function ShapesBackground({ getConfig }: Props) {
|
||||||
}, [getConfig, width, height, prevWidth, prevRoute, router.asPath]);
|
}, [getConfig, width, height, prevWidth, prevRoute, router.asPath]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.shapesContainer} ref={shapesContainerRef}>
|
<div
|
||||||
|
className={styles.shapesContainer}
|
||||||
|
ref={shapesContainerRef}
|
||||||
|
aria-hidden
|
||||||
|
>
|
||||||
{Object.entries(config).map(([type, instances]) =>
|
{Object.entries(config).map(([type, instances]) =>
|
||||||
instances.map((attributes, idx) => (
|
instances.map((attributes, idx) => (
|
||||||
<Shape
|
<Shape
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## Coop Advice
|
## Co-op Advice
|
||||||
|
|
||||||
Although WaterlooWorks is quite reliable, there are many more opportunities outside of the job board.
|
Although WaterlooWorks is quite reliable, there are many more opportunities outside of the job board.
|
||||||
Being able to apply for jobs externally not only prepares you to look for jobs full time but it also
|
Being able to apply for jobs externally not only prepares you to look for jobs full time but it also
|
|
@ -4,7 +4,7 @@ import { Title } from "@/components/Title";
|
||||||
|
|
||||||
import Content from "../../../content/advice/academic-advice.mdx";
|
import Content from "../../../content/advice/academic-advice.mdx";
|
||||||
|
|
||||||
import { Advice } from "./coop";
|
import { Advice } from "./co-op";
|
||||||
|
|
||||||
export default function AcademicAdvice() {
|
export default function AcademicAdvice() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -5,9 +5,9 @@ import React, { ReactNode } from "react";
|
||||||
import { Image } from "@/components/Image";
|
import { Image } from "@/components/Image";
|
||||||
import { Title } from "@/components/Title";
|
import { Title } from "@/components/Title";
|
||||||
|
|
||||||
import Content from "../../../content/advice/coop-advice.mdx";
|
import Content from "../../../content/advice/co-op-advice.mdx";
|
||||||
|
|
||||||
import styles from "./coop.module.css";
|
import styles from "./co-op.module.css";
|
||||||
|
|
||||||
export default function CoopAdvice() {
|
export default function CoopAdvice() {
|
||||||
return (
|
return (
|
||||||
|
@ -30,13 +30,13 @@ export function Advice(props: { children: ReactNode }) {
|
||||||
<Image src="/images/advice.svg" className={styles.codey} />
|
<Image src="/images/advice.svg" className={styles.codey} />
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.adviceBarContainer}>
|
<div className={styles.adviceBarContainer}>
|
||||||
<Link href="/resources/advice/coop">
|
<Link href="/resources/advice/co-op">
|
||||||
<a
|
<a
|
||||||
className={
|
className={
|
||||||
path == "/resources/advice/coop" ? styles.currentAdvice : ""
|
path == "/resources/advice/co-op" ? styles.currentAdvice : ""
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Coop Advice
|
Co-op Advice
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/resources/advice/academic">
|
<Link href="/resources/advice/academic">
|
|
@ -0,0 +1,10 @@
|
||||||
|
import Head from "next/head";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function AdviceRedirect() {
|
||||||
|
return (
|
||||||
|
<Head>
|
||||||
|
<meta httpEquiv="refresh" content="0;url=/resources/advice/co-op" />
|
||||||
|
</Head>
|
||||||
|
);
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ import { Title } from "@/components/Title";
|
||||||
|
|
||||||
import Content from "../../../content/advice/misc-advice.mdx";
|
import Content from "../../../content/advice/misc-advice.mdx";
|
||||||
|
|
||||||
import { Advice } from "./coop";
|
import { Advice } from "./co-op";
|
||||||
|
|
||||||
export default function MiscAdvice() {
|
export default function MiscAdvice() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
export default function Resources() {
|
export default function ResourcesRedirect() {
|
||||||
return (
|
return (
|
||||||
<Head>
|
<Head>
|
||||||
<meta httpEquiv="refresh" content="0;url=/resources/services" />
|
<meta httpEquiv="refresh" content="0;url=/resources/services" />
|
||||||
|
|
Loading…
Reference in New Issue