Compare commits
5 Commits
177744db9c
...
017812443b
Author | SHA1 | Date |
---|---|---|
b38peng | 017812443b | |
Amy Wang | 8bb5f160f0 | |
Jared He | 966129adf8 | |
Aditya Thakral | a0d0b8e843 | |
Amy Wang | 0bb8049db3 |
|
@ -9,16 +9,15 @@ import styles from "./Navbar.module.css";
|
|||
type Menu = {
|
||||
name: string;
|
||||
route: string;
|
||||
submenu?: {
|
||||
name: string;
|
||||
route: string;
|
||||
}[];
|
||||
exact?: boolean;
|
||||
submenu?: Menu;
|
||||
}[];
|
||||
|
||||
const menu: Menu = [
|
||||
{
|
||||
name: "Home",
|
||||
route: "/",
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
name: "About",
|
||||
|
@ -27,6 +26,7 @@ const menu: Menu = [
|
|||
{
|
||||
name: "About Us",
|
||||
route: "/about",
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
name: "Meet the Team",
|
||||
|
@ -76,7 +76,21 @@ const menu: Menu = [
|
|||
},
|
||||
{
|
||||
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",
|
||||
|
@ -198,10 +212,11 @@ interface NavItemProps {
|
|||
|
||||
function NavItem(props: NavItemProps) {
|
||||
const router = useRouter();
|
||||
const isCurrentPage =
|
||||
router.pathname === props.route ||
|
||||
(props.submenu != null &&
|
||||
router.pathname.startsWith(getMainRoute(props.route)));
|
||||
const isCurrentPage = shouldHighlight(
|
||||
router.pathname,
|
||||
props.name,
|
||||
props.route
|
||||
);
|
||||
const isExternalLink =
|
||||
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) {
|
||||
if (route === "/") {
|
||||
return "/";
|
||||
|
|
|
@ -45,7 +45,11 @@ export function ShapesBackground({ getConfig }: Props) {
|
|||
}, [getConfig, width, height, prevWidth, prevRoute, router.asPath]);
|
||||
|
||||
return (
|
||||
<div className={styles.shapesContainer} ref={shapesContainerRef}>
|
||||
<div
|
||||
className={styles.shapesContainer}
|
||||
ref={shapesContainerRef}
|
||||
aria-hidden
|
||||
>
|
||||
{Object.entries(config).map(([type, instances]) =>
|
||||
instances.map((attributes, idx) => (
|
||||
<Shape
|
||||
|
|
|
@ -3,4 +3,4 @@ title: License Information and Attribution
|
|||
index: 11
|
||||
---
|
||||
|
||||
- The Code of Conduct is distributed under a [Creative Commons Attribution-ShareAlike License](http://creativecommons.org/licenses/by-sa/3.0/) , derived from the [Women in Computer Science Code of Conduct](http://wics.uwaterloo.ca/code-of-conduct/) , the [UW Amateur Radio Club Code of Conduct](http://uwarc.uwaterloo.ca/policies-procedures/code-of-conduct/) , and the [FASS Code of Conduct (Article 2, Section 16)](http://fass.uwaterloo.ca/wp-content/uploads/2015/03/constitution.pdf) .
|
||||
- The Code of Conduct is distributed under a [Creative Commons Attribution-ShareAlike License](http://creativecommons.org/licenses/by-sa/3.0/), derived from the [Women in Computer Science Code of Conduct](http://wics.uwaterloo.ca/deprecated/code-of-conduct/), the [UW Amateur Radio Club Code of Conduct](http://uwarc.uwaterloo.ca/policies-procedures/code-of-conduct/), and the [FASS Code of Conduct](http://fass.uwaterloo.ca/fassconstitution).
|
||||
|
|
|
@ -4,5 +4,5 @@ index: 12
|
|||
---
|
||||
|
||||
1. The Club has a [Code of Conduct](/about/code-of-conduct).
|
||||
2. The [scope of the Code of Conduct](/about/code-of-conduct/scopes-and-spaces) is specified by the Code of Conduct.
|
||||
2. The [scope of the Code of Conduct](/about/code-of-conduct/scope-and-spaces) is specified by the Code of Conduct.
|
||||
3. Changes to the Code of Conduct are governed by the same rules as changes to the Constitution.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## Coop Advice
|
||||
## Co-op Advice
|
||||
|
||||
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
|
|
@ -80,6 +80,6 @@ Each term, the CSC holds elections to determine the executive council:
|
|||
- Assistant Vice-President
|
||||
- Treasurer
|
||||
|
||||
To find out when and where the next elections will be held, keep an eye on on the [News](/).
|
||||
To find out when and where the next elections will be held, keep an eye on on the [News](/#news).
|
||||
|
||||
For details on the elections, see the [Constitution](/about/constitution).
|
|
@ -3,7 +3,7 @@ title: CS Club Email
|
|||
index: 2
|
||||
---
|
||||
|
||||
Members also receive a **username@csclub.uwaterloo.ca** email address.
|
||||
Members also receive a **[username@csclub.uwaterloo.ca](#)** email address.
|
||||
|
||||
- Mailboxes are considered as part of your disk quota, so your mailbox may grow up to the amount of disk quota you have.
|
||||
- Attachments of any file size or type may be sent.
|
||||
|
|
|
@ -3,8 +3,8 @@ title: Mailing Lists
|
|||
index: 10
|
||||
---
|
||||
|
||||
Our [csc-general mailing list](http://mailman.csclub.uwaterloo.ca/listinfo/csc-general) informs members about our current events.
|
||||
Our [csc-general mailing list](https://mailman.csclub.uwaterloo.ca/postorius/lists/csc-general.csclub.uwaterloo.ca/) informs members about our current events.
|
||||
|
||||
Our [csc-industry mailing list](http://mailman.csclub.uwaterloo.ca/listinfo/csc-industry) allows students to opt-in to receiving emails from industry representatives.
|
||||
Our [csc-industry mailing list](https://mailman.csclub.uwaterloo.ca/postorius/lists/csc-industry.csclub.uwaterloo.ca/) allows students to opt-in to receiving emails from industry representatives.
|
||||
|
||||
- Corporate events, job postings, info sessions, and related events may be posted here.
|
||||
|
|
|
@ -179,28 +179,34 @@ export async function getEventsPageProps({
|
|||
};
|
||||
}
|
||||
|
||||
export function getCurrentTerm(): { year: string; term: string } {
|
||||
const date = new Date();
|
||||
let term = "";
|
||||
const year = date.getUTCFullYear().toString();
|
||||
export function getCurrentTerm() {
|
||||
const today = new Date().toLocaleDateString("en-CA", {
|
||||
timeZone: "EST",
|
||||
year: "numeric",
|
||||
month: "numeric",
|
||||
day: "numeric",
|
||||
});
|
||||
|
||||
if (
|
||||
new Date(`${year}-01-01 EST`).getTime() <= date.getTime() &&
|
||||
date.getTime() <= new Date(`${year}-04-30 EST`).getTime()
|
||||
) {
|
||||
const [year] = today.split("-");
|
||||
|
||||
let term = "";
|
||||
|
||||
if (`${year}-01-01` <= today) {
|
||||
term = "winter";
|
||||
} else if (
|
||||
new Date(`${year}-05-01 EST`).getTime() <= date.getTime() &&
|
||||
date.getTime() <= new Date(`${year}-08-31 EST`).getTime()
|
||||
) {
|
||||
}
|
||||
|
||||
if (`${year}-05-01` <= today) {
|
||||
term = "spring";
|
||||
} else if (
|
||||
new Date(`${year}-09-01 EST`).getTime() <= date.getTime() &&
|
||||
date.getTime() <= new Date(`${year}-12-31 EST`).getTime()
|
||||
) {
|
||||
}
|
||||
|
||||
if (`${year}-09-01` <= today) {
|
||||
term = "fall";
|
||||
}
|
||||
|
||||
if (term === "") {
|
||||
throw new Error("Error setting the current term");
|
||||
}
|
||||
|
||||
return { year, term };
|
||||
}
|
||||
|
||||
|
@ -211,7 +217,7 @@ function getPastTerm(
|
|||
const index = TERMS.indexOf(term);
|
||||
|
||||
if (index === -1) {
|
||||
throw new Error("Not a valid term");
|
||||
throw new Error(`[getPastTerm] Not a valid term: "${term}" "${year}"`);
|
||||
}
|
||||
|
||||
return index === 0
|
||||
|
@ -232,7 +238,7 @@ function getFutureTerm(
|
|||
const index = TERMS.indexOf(term);
|
||||
|
||||
if (index === -1) {
|
||||
throw new Error("Not a valid term");
|
||||
throw new Error(`[getFutureTerm] Not a valid term: "${term}" "${year}"`);
|
||||
}
|
||||
|
||||
return index === TERMS.length - 1
|
||||
|
|
|
@ -83,9 +83,18 @@ export default function Term(props: Props) {
|
|||
</div>
|
||||
</section>
|
||||
)}
|
||||
{hasPastEvents && props.isCurrentTerm && (
|
||||
{hasPastEvents && (
|
||||
<section>
|
||||
<h1>Past Events</h1>
|
||||
{props.isCurrentTerm ? (
|
||||
<h1>Past Events</h1>
|
||||
) : (
|
||||
<h1>
|
||||
Events Archive:
|
||||
<span className={styles.blue}>
|
||||
{` ${capitalize(props.term)} ${props.year}`}
|
||||
</span>
|
||||
</h1>
|
||||
)}
|
||||
<div className={styles.miniEventCards}>
|
||||
{props.pastEvents.map(({ content, metadata }) => (
|
||||
<MiniEventCard
|
||||
|
@ -98,14 +107,6 @@ export default function Term(props: Props) {
|
|||
</div>
|
||||
</section>
|
||||
)}
|
||||
{hasPastEvents && !props.isCurrentTerm && (
|
||||
<h1>
|
||||
Events Archive:
|
||||
<span className={styles.blue}>
|
||||
{` ${capitalize(props.term)} ${props.year}`}
|
||||
</span>
|
||||
</h1>
|
||||
)}
|
||||
{!hasFutureEvents && !hasPastEvents && (
|
||||
<>
|
||||
<h1>Events</h1>
|
||||
|
@ -114,16 +115,6 @@ export default function Term(props: Props) {
|
|||
later!
|
||||
</>
|
||||
)}
|
||||
<div className={styles.miniEventCards}>
|
||||
{props.pastEvents.map(({ content, metadata }) => (
|
||||
<MiniEventCard
|
||||
{...metadata}
|
||||
date={new Date(metadata.date)}
|
||||
description={<MDXRemote {...content} />}
|
||||
key={metadata.name + metadata.date.toString()}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Title } from "@/components/Title";
|
|||
|
||||
import Content from "../../../content/advice/academic-advice.mdx";
|
||||
|
||||
import { Advice } from "./coop";
|
||||
import { Advice } from "./co-op";
|
||||
|
||||
export default function AcademicAdvice() {
|
||||
return (
|
||||
|
|
|
@ -5,9 +5,9 @@ import React, { ReactNode } from "react";
|
|||
import { Image } from "@/components/Image";
|
||||
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() {
|
||||
return (
|
||||
|
@ -30,13 +30,13 @@ export function Advice(props: { children: ReactNode }) {
|
|||
<Image src="/images/advice.svg" className={styles.codey} />
|
||||
</div>
|
||||
<div className={styles.adviceBarContainer}>
|
||||
<Link href="/resources/advice/coop">
|
||||
<Link href="/resources/advice/co-op">
|
||||
<a
|
||||
className={
|
||||
path == "/resources/advice/coop" ? styles.currentAdvice : ""
|
||||
path == "/resources/advice/co-op" ? styles.currentAdvice : ""
|
||||
}
|
||||
>
|
||||
Coop Advice
|
||||
Co-op Advice
|
||||
</a>
|
||||
</Link>
|
||||
<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 { Advice } from "./coop";
|
||||
import { Advice } from "./co-op";
|
||||
|
||||
export default function MiscAdvice() {
|
||||
return (
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Head from "next/head";
|
||||
import React from "react";
|
||||
|
||||
export default function Resources() {
|
||||
export default function ResourcesRedirect() {
|
||||
return (
|
||||
<Head>
|
||||
<meta httpEquiv="refresh" content="0;url=/resources/services" />
|
||||
|
|
Loading…
Reference in New Issue