diff --git a/.eslintrc.js b/.eslintrc.js index b5ff0bf..756f84b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,8 +15,14 @@ module.exports = { "plugin:react/recommended", "plugin:prettier/recommended", ], - plugins: ["@typescript-eslint", "react", "react-hooks", "prettier"], + plugins: ["@typescript-eslint", "react", "react-hooks", "prettier", "unused-imports"], rules: { + "no-unused-vars": "off", + "unused-imports/no-unused-imports": "error", + "unused-imports/no-unused-vars": [ + "error", + { "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" } + ], "prettier/prettier": ["error", { "endOfLine": "auto" }], "import/first": "error", "import/order": [ diff --git a/components/BottomNav.module.css b/components/BottomNav.module.css index be16f23..8a0bce9 100644 --- a/components/BottomNav.module.css +++ b/components/BottomNav.module.css @@ -63,7 +63,7 @@ transform: rotate(180deg); } -@media screen and (max-width: 768px) { +@media screen and (max-width: 1000px) { .subBox { flex-direction: column; align-items: flex-start; @@ -93,6 +93,14 @@ } .arrow { - width: calc(200rem / 16); + width: 100%; } +} + +.containerOnlyRightArrow { + justify-content: flex-end; +} + +.containerOnlyLeftArrow { + justify-content: flex-start; } \ No newline at end of file diff --git a/components/BottomNav.tsx b/components/BottomNav.tsx index 2829705..f31b9a0 100644 --- a/components/BottomNav.tsx +++ b/components/BottomNav.tsx @@ -4,35 +4,49 @@ import React from "react"; import styles from "./BottomNav.module.css"; interface PagesInfo { - leftPageLink: string; - leftPageName: string; - rightPageLink: string; - rightPageName: string; + leftPage?: { + url: string; + name: string; + }; + rightPage?: { + url: string; + name: string; + }; } export function BottomNav(props: PagesInfo) { + const onlyRightArrow = props.rightPage && !props.leftPage; + const onlyLeftArrow = !props.rightPage && props.leftPage; return ( -
-
- - - - - - - {props.leftPageName} - -
-
- - {props.rightPageName} - - - - - - -
+
+ {props.leftPage ? ( +
+ + + + + + + {props.leftPage.name} + +
+ ) : null} + {props.rightPage ? ( +
+ + {props.rightPage.name} + + + + + + +
+ ) : null}
); } diff --git a/components/ComponentWrapper.module.css b/components/ComponentWrapper.module.css index 4fad333..8cbdc3b 100644 --- a/components/ComponentWrapper.module.css +++ b/components/ComponentWrapper.module.css @@ -3,7 +3,7 @@ display: flex; padding: calc(40rem / 16) calc(50rem / 16); margin: calc(65rem / 16) 0; - width: 90%; + width: 88%; } .wrapperRight { @@ -43,7 +43,12 @@ padding: 0 15%; } -@media screen and (max-width: 768px) { +.wrapperNoBodyText { + flex-direction: column; + align-items: center; +} + +@media screen and (max-width: 900px) { .sideWrapperCommon { margin: auto; flex-direction: column; @@ -52,6 +57,10 @@ border-radius: 0; width: 100%; } + + .wrapperCenter { + padding: 0; + } } .internalWrapper { diff --git a/components/ComponentWrapper.tsx b/components/ComponentWrapper.tsx index 8893905..400b0c5 100644 --- a/components/ComponentWrapper.tsx +++ b/components/ComponentWrapper.tsx @@ -7,7 +7,7 @@ type AlignOption = "left" | "center" | "right"; type ComponentWrapperProps = { children: React.ReactNode; heading: string; - bodyText: string; + bodyText?: string; align?: AlignOption; noBackground?: boolean; }; @@ -30,11 +30,12 @@ export function ComponentWrapper({ className={` ${alignClasses[align]} ${noBackground ? styles.noBackground : ""} + ${bodyText ? "" : styles.wrapperNoBodyText} `} >

{heading}

-

{bodyText}

+ {bodyText ?

{bodyText}

: null}
{children}
diff --git a/components/Header.module.css b/components/Header.module.css new file mode 100644 index 0000000..5ec72d4 --- /dev/null +++ b/components/Header.module.css @@ -0,0 +1,137 @@ +.headerWrapper { + display: flex; + justify-content: space-between; + align-items: center; + position: sticky; + top: 0; + left: 0; + background: var(--dark--primary-background); + z-index: 98; + box-sizing: border-box; + padding: calc(10rem / 16) calc(100rem / 16) 0; +} + +.titleHeader { + margin: calc(16rem / 16) 0; +} + +.sideBarCommon { + position: fixed; + right: 0; + top: 0; + min-width: calc(400rem / 16); + height: 100vh; + background: var(--secondary-background); + padding: calc(100rem / 16); + margin: 0; + z-index: 100; + padding: 0; + padding-right: calc(20rem / 16); + transition: transform 0.8s; + overflow: auto; +} + +.sideBarShown { + composes: sideBarCommon; + /* -1% to hide slight line tip showing in some browsers */ + transform: translateX(-1%); +} + +.sideBarHidden { + composes: sideBarCommon; + transform: translateX(100%); +} + +.backgroundTintCommon { + background-color: var(--label); + animation: fadeIn 1s; + position: fixed; + z-index: 99; + left: 0; + top: 0; + width: 100vw; + height: 100vh; + transition: opacity 0.8s, visibility 0.8s; +} + +.backgroundTintShow { + composes: backgroundTintCommon; + visibility: visible; + opacity: 0.2; +} + +.backgroundTintHidden { + composes: backgroundTintCommon; + visibility: hidden; + opacity: 0; +} + + +.menuHeader { + margin-bottom: 0; + padding-left: calc(30rem / 16); + padding-bottom: 0; + color: var(--dark--secondary-heading); +} + +.sectionsWrapper { + padding-left: calc(30rem / 16); +} + +.menuIcon { + background: none; + border: none; +} + +.menuIcon:hover { + opacity: 0.8; + cursor: pointer; +} + + +@media screen and (max-width: 768px) { + .sideBarCommon { + min-width: calc(300rem / 16); + max-width: calc(500rem / 16); + } + + .menuHeader { + padding-left: calc(20rem / 16); + } + + .sectionsWrapper { + padding-left: calc(20rem / 16); + } + + .headerWrapper { + padding: calc(10rem / 16) calc(20rem / 16) 0; + } +} + +.closeMenuButton { + background: var(--primary-heading); + padding: 0 calc(20rem / 16); + border-radius: calc(50rem / 16); + display: flex; + flex-direction: row; + margin-left: calc(20rem / 16); + /* transparent border fixes weird coloring on the border in some browsers */ + border: calc(1rem / 16) solid transparent; +} + +.closeMenuButton:hover { + background-color: var(--secondary-accent-light); + cursor: pointer; +} + +.lineWrapper { + width: 100%; + display: flex; +} + +.lineWrapper:before { + content: ""; + flex: 1 1; + border-bottom: 3px solid white; + margin: auto; +} \ No newline at end of file diff --git a/components/Header.tsx b/components/Header.tsx new file mode 100644 index 0000000..c150c87 --- /dev/null +++ b/components/Header.tsx @@ -0,0 +1,69 @@ +import { pageRoutes } from "data/routes"; +import Link from "next/link"; +import React, { useState } from "react"; + +import { Sections } from "./Sections"; + +import styles from "./Header.module.css"; + +export function Header() { + const [isShowingMenu, setIsShowingMenu] = useState(false); + + return ( + <> +
{ + setIsShowingMenu(false); + }} + /> +
+

+ CS 2022 +

+ +
+ +
+

Sections

+
+ +
+
+ +
+
+ + ); +} diff --git a/components/LineGraph.tsx b/components/LineGraph.tsx index 673bd05..7e98241 100644 --- a/components/LineGraph.tsx +++ b/components/LineGraph.tsx @@ -83,6 +83,8 @@ interface LineGraphProps { const DEFAULT_LABEL_SIZE = 16; const DEFAULT_LEGEND_GAP = 16; +// TODO: Address unused props in this file +/* eslint-disable unused-imports/no-unused-vars*/ export function LineGraph(props: LineGraphProps) { const { width, diff --git a/components/SectionHeader.module.css b/components/SectionHeader.module.css new file mode 100644 index 0000000..a9faa52 --- /dev/null +++ b/components/SectionHeader.module.css @@ -0,0 +1,19 @@ +.header { + display: flex; + flex-direction: column; + justify-content: center; + padding: calc(40rem / 16) 0; + text-align: center; +} + +.title { + color: var(--primary-accent-light); + font-size: calc(70rem / 16); + margin: calc(40rem / 16) auto; +} + +.subTitle { + color: var(--primary-accent-lighter); + font-size: calc(26rem / 16); + margin: auto; +} \ No newline at end of file diff --git a/components/SectionHeader.tsx b/components/SectionHeader.tsx new file mode 100644 index 0000000..f8a9b46 --- /dev/null +++ b/components/SectionHeader.tsx @@ -0,0 +1,17 @@ +import React from "react"; + +import styles from "./SectionHeader.module.css"; + +interface SectionHeaderProps { + title: string; + subtitle?: string; +} + +export function SectionHeader({ title, subtitle }: SectionHeaderProps) { + return ( +
+

{title}

+ {subtitle &&
{subtitle}
} +
+ ); +} diff --git a/components/Sections.tsx b/components/Sections.tsx index 226d383..1d435c4 100644 --- a/components/Sections.tsx +++ b/components/Sections.tsx @@ -1,16 +1,12 @@ +import { PageRoutes } from "data/routes"; import React from "react"; import styles from "./Sections.module.css"; -interface SectionsData { - name: string; - url: string; -} - interface SectionsProps { /* Whether to display the "Sections" title and separator that appears on the left. */ showHeader?: boolean; - data: SectionsData[]; + data: PageRoutes; } export function Sections({ data, showHeader = true }: SectionsProps) { @@ -26,7 +22,7 @@ export function Sections({ data, showHeader = true }: SectionsProps) { )}