Merge remote-tracking branch 'origin/main' into feat/organized-content
This commit is contained in:
commit
965093b6d0
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: node14
|
||||
|
||||
steps:
|
||||
- name: install-deps
|
||||
image: node:14
|
||||
commands:
|
||||
- npm install
|
||||
|
||||
- name: lint
|
||||
image: node:14
|
||||
depends_on:
|
||||
- install-deps
|
||||
commands:
|
||||
- npm run lint
|
||||
|
||||
- name: build
|
||||
image: node:14
|
||||
depends_on:
|
||||
- install-deps
|
||||
commands:
|
||||
- npm run build
|
||||
|
||||
- name: export
|
||||
image: node:14
|
||||
depends_on:
|
||||
- build
|
||||
commands:
|
||||
- npm run export
|
||||
|
||||
trigger:
|
||||
event:
|
||||
exclude:
|
||||
- pull_request #avoid double build on PRs
|
|
@ -1,49 +0,0 @@
|
|||
default:
|
||||
image: node:14
|
||||
|
||||
cache:
|
||||
paths:
|
||||
- node_modules/
|
||||
- .next
|
||||
|
||||
stages:
|
||||
- build
|
||||
- staging
|
||||
|
||||
variables:
|
||||
NEXT_PUBLIC_BASE_PATH: '/~a3thakra/csc'
|
||||
|
||||
install_deps:
|
||||
stage: .pre
|
||||
script:
|
||||
- npm install
|
||||
|
||||
lint:
|
||||
stage: build
|
||||
script:
|
||||
- npm run lint
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- npm run build
|
||||
|
||||
staging:
|
||||
stage: staging
|
||||
script:
|
||||
- npm run export
|
||||
artifacts:
|
||||
paths:
|
||||
- out
|
||||
only:
|
||||
refs:
|
||||
- main
|
||||
|
||||
deploy_staging:
|
||||
stage: .post
|
||||
needs: ["staging"]
|
||||
script:
|
||||
- 'curl -XPOST -H "Authorization: Basic $STAGING_SECRET" "https://csclub.uwaterloo.ca/~a3thakra/csc/"'
|
||||
only:
|
||||
refs:
|
||||
- main
|
|
@ -0,0 +1,7 @@
|
|||
.bubble {
|
||||
padding: calc(36rem / 16) 0;
|
||||
}
|
||||
|
||||
.bubble:nth-child(odd) {
|
||||
background-color: var(--blue-1-20);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import React from "react";
|
||||
import { DefaultLayout } from "./DefaultLayout";
|
||||
import styles from "./Bubble.module.css";
|
||||
|
||||
export default function Bubble(props: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className={styles.bubble}>
|
||||
<DefaultLayout>{props.children}</DefaultLayout>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
.header {
|
||||
color: var(--blue-2);
|
||||
font-weight: 600;
|
||||
font-size: calc(36rem / 16);
|
||||
margin-bottom: calc(12rem / 16);
|
||||
}
|
||||
|
||||
.socialLinks {
|
||||
margin: calc(36rem / 16) 0;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: calc(768rem / 16)) {
|
||||
.header {
|
||||
font-size: calc(24rem / 16);
|
||||
}
|
||||
|
||||
.socialLinks {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import React from "react";
|
||||
import styles from "./ConnectWithUs.module.css";
|
||||
import { SocialLinks } from "./SocialLinks";
|
||||
import { Link } from "./Link";
|
||||
|
||||
export function ConnectWithUs() {
|
||||
return (
|
||||
<section>
|
||||
<h1 className={styles.header}>Connect with us!</h1>
|
||||
<p>
|
||||
Drop by any of our social media outlets to learn more about us, keep
|
||||
up-to-date with our upcoming events, or to chat with our members!
|
||||
</p>
|
||||
|
||||
<div className={styles.socialLinks}>
|
||||
<SocialLinks color="gradient" size="big" />
|
||||
</div>
|
||||
|
||||
{/* TODO: fix feedback form link */}
|
||||
<p>
|
||||
Send feedback through our <Link href="#">Feedback Form</Link>
|
||||
</p>
|
||||
</section>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
.defaultLayout {
|
||||
margin: 0 auto;
|
||||
max-width: calc(800rem / 16);
|
||||
padding: 0 calc(20rem / 16);
|
||||
padding-bottom: calc(20rem / 16);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import React from "react";
|
||||
import styles from "./DefaultLayout.module.css";
|
||||
|
||||
export function DefaultLayout(props: { children: React.ReactNode }) {
|
||||
return <div className={styles.defaultLayout}>{props.children}</div>;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
.container form {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.header {
|
||||
color: var(--blue-2);
|
||||
font-weight: 600;
|
||||
font-size: calc(36rem / 16);
|
||||
margin-bottom: calc(12rem / 16);
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: calc(34rem / 16);
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: calc(768rem / 16)) {
|
||||
.header {
|
||||
font-size: calc(24rem / 16);
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: calc(20rem / 16);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import React from "react";
|
||||
import styles from "./EmailSignup.module.css";
|
||||
import { Button } from "./Button";
|
||||
import { Input } from "./Input";
|
||||
|
||||
export function EmailSignup() {
|
||||
return (
|
||||
<section className={styles.container}>
|
||||
<h1 className={styles.header}>Join Our Mailing List!</h1>
|
||||
<form className={styles.form} action="">
|
||||
<Input type="text" placeholder="Full Name*" required />
|
||||
<Input type="email" placeholder="Email*" required />
|
||||
<Button type="submit" className={styles.button}>
|
||||
Subscribe
|
||||
</Button>
|
||||
</form>
|
||||
</section>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
.input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: calc(21rem / 16) 0;
|
||||
padding: calc(10rem / 16) calc(32rem / 16);
|
||||
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
border-radius: calc(20rem / 16);
|
||||
|
||||
background-color: var(--grey-1-24);
|
||||
font-size: calc(18rem / 16);
|
||||
line-height: calc(30rem / 16);
|
||||
color: var(--grey-3);
|
||||
}
|
||||
|
||||
.input::placeholder {
|
||||
color: var(--grey-2);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.input:is(:active, :hover, :focus) {
|
||||
box-sizing: border-box;
|
||||
border: calc(3rem / 16) solid var(--blue-1);
|
||||
border-radius: calc(20rem / 16);
|
||||
outline: none;
|
||||
padding: calc(7rem / 16) calc(28rem / 16);
|
||||
}
|
||||
|
||||
/* TODO: make this only happen if the form is clicked on? */
|
||||
/* .form input:invalid {
|
||||
box-sizing: border-box;
|
||||
border: calc(3rem / 16) solid var(--red);
|
||||
border-radius: calc(20rem / 16);
|
||||
outline: none;
|
||||
padding: calc(7rem / 16) calc(28rem / 16);
|
||||
} */
|
|
@ -0,0 +1,8 @@
|
|||
import React, { InputHTMLAttributes } from "react";
|
||||
import styles from "./Input.module.css";
|
||||
|
||||
export function Input(props: InputHTMLAttributes<HTMLInputElement>) {
|
||||
return (
|
||||
<input {...props} className={`${styles.input} ${props.className ?? ""}`} />
|
||||
);
|
||||
}
|
|
@ -13,26 +13,36 @@
|
|||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
width: stretch;
|
||||
width: 100%;
|
||||
max-width: calc(1440rem / 16);
|
||||
height: auto;
|
||||
padding: calc(28rem / 16) calc(136rem / 16);
|
||||
}
|
||||
|
||||
.logo {
|
||||
.logo,
|
||||
.logoMobile {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
.logo:hover,
|
||||
.logoMobile:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.logoMobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.logo img {
|
||||
width: calc(96rem / 16);
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navMenu {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
|
@ -60,7 +70,7 @@
|
|||
color: var(--blue-2);
|
||||
}
|
||||
|
||||
.navMenu > li:hover > a {
|
||||
.navMenu > li > a:hover {
|
||||
color: var(--blue-2);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
@ -79,15 +89,19 @@
|
|||
padding: 1rem;
|
||||
}
|
||||
|
||||
.dropdownWrapper {
|
||||
.itemWrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dropdownIcon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
visibility: visible;
|
||||
visibility: hidden;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -107,37 +121,33 @@
|
|||
font-size: calc(14rem / 16);
|
||||
}
|
||||
|
||||
.dropdown > li {
|
||||
.dropdown li {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dropdown > li > a {
|
||||
.dropdown li a {
|
||||
padding: calc(8rem / 16);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.dropdown > li:hover > a,
|
||||
.dropdown > li > a:focus {
|
||||
.dropdown li:hover a,
|
||||
.dropdown li a:focus {
|
||||
background-color: var(--blue-1-20);
|
||||
}
|
||||
|
||||
.dropdown > li:first-child > a {
|
||||
.dropdown li:first-child a {
|
||||
padding-top: 1rem;
|
||||
border-radius: calc(8rem / 16) calc(8rem / 16) 0 0;
|
||||
}
|
||||
|
||||
.dropdown > li:last-child > a {
|
||||
.dropdown li:last-child a {
|
||||
padding-bottom: 1rem;
|
||||
border-radius: 0 0 calc(8rem / 16) calc(8rem / 16);
|
||||
}
|
||||
|
||||
.navMenu > li .dropdown {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.navMenu > li:hover .dropdown,
|
||||
.navMenu > li:focus-within .dropdown {
|
||||
.navMenu li:hover .dropdown,
|
||||
.navMenu li:focus-within .dropdown {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
|
@ -149,3 +159,214 @@
|
|||
padding: calc(28rem / 16) calc(64rem / 16);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: calc(768rem / 16)) {
|
||||
.navContent {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-areas: ". logo hamburger";
|
||||
column-gap: 0;
|
||||
justify-items: end;
|
||||
align-items: center;
|
||||
|
||||
padding: calc(20rem / 16);
|
||||
}
|
||||
|
||||
.logo {
|
||||
grid-area: logo;
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.logoMobile {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
margin-bottom: calc(20rem / 16);
|
||||
}
|
||||
|
||||
.logo img,
|
||||
.logoMobile img {
|
||||
width: calc(80rem / 16);
|
||||
}
|
||||
|
||||
.logoMobile img {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
grid-area: hamburger;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
padding: calc(12rem / 16);
|
||||
width: calc(36rem / 16);
|
||||
box-sizing: content-box;
|
||||
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.hamburger:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.navMobileBackground {
|
||||
position: fixed;
|
||||
visibility: hidden;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 20;
|
||||
|
||||
background-color: var(--navbar-gray);
|
||||
opacity: 0;
|
||||
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.navMenuWrapper {
|
||||
position: fixed;
|
||||
|
||||
width: calc(288rem / 16);
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
right: 0;
|
||||
overflow: auto;
|
||||
z-index: 30;
|
||||
|
||||
padding: calc(calc(64rem / 16) - 1rem);
|
||||
padding-left: calc(calc(78rem / 16) - 1rem);
|
||||
|
||||
background-color: var(--off-white);
|
||||
|
||||
transform: translateX(100vw);
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.navMenu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: calc(4rem / 16);
|
||||
|
||||
width: auto;
|
||||
|
||||
font-size: calc(18rem / 16);
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.navMenu > .itemWrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-areas:
|
||||
"link button"
|
||||
"dropdown dropdown";
|
||||
column-gap: 0;
|
||||
row-gap: 0;
|
||||
justify-items: start;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.navMenu > .itemWrapper > a {
|
||||
grid-area: link;
|
||||
}
|
||||
|
||||
.dropdownIcon {
|
||||
grid-area: button;
|
||||
justify-self: end;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
padding: 1rem;
|
||||
box-sizing: content-box;
|
||||
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.dropdownIcon:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
grid-area: dropdown;
|
||||
|
||||
display: none;
|
||||
visibility: visible;
|
||||
|
||||
justify-content: space-between;
|
||||
align-items: start;
|
||||
|
||||
position: static;
|
||||
|
||||
margin: 0;
|
||||
margin-left: calc(18rem / 16);
|
||||
margin-bottom: calc(18rem / 16);
|
||||
|
||||
border-radius: 0;
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.dropdown > .itemWrapper {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.dropdown li {
|
||||
width: auto;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dropdown li a {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.dropdown li:hover a,
|
||||
.dropdown li a:focus {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.dropdown li:hover a {
|
||||
color: default;
|
||||
font-weight: default;
|
||||
}
|
||||
|
||||
.dropdown li:first-child a {
|
||||
padding-top: calc(8rem / 16);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.dropdown li:last-child a {
|
||||
padding-bottom: calc(8rem / 16);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.show.navMobileBackground {
|
||||
visibility: visible;
|
||||
opacity: 100%;
|
||||
}
|
||||
|
||||
.show.navMobileBackground + .navMenuWrapper {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.rotate {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import React from "react";
|
||||
import React, { useReducer } from "react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { Image } from "./Image";
|
||||
import styles from "./Navbar.module.css";
|
||||
|
||||
interface NavLink {
|
||||
type Menu = {
|
||||
name: string;
|
||||
route: string;
|
||||
submenu?: {
|
||||
name: string;
|
||||
route: string;
|
||||
}[];
|
||||
}
|
||||
}[];
|
||||
|
||||
const menu: NavLink[] = [
|
||||
const menu: Menu = [
|
||||
{
|
||||
name: "Home",
|
||||
route: "/",
|
||||
|
@ -66,28 +66,146 @@ const menu: NavLink[] = [
|
|||
},
|
||||
{
|
||||
name: "CS Club Wiki",
|
||||
route: "https://wiki.csclub.uwaterloo.ca/",
|
||||
route: "https://wiki.csclub.uwaterloo.ca",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
function NavItem(props: NavLink) {
|
||||
export function Navbar() {
|
||||
const router = useRouter();
|
||||
const externalLink =
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
return (
|
||||
<nav className={styles.navbar}>
|
||||
<div className={styles.navContent}>
|
||||
<Link href="/">
|
||||
<a className={styles.logo}>
|
||||
<Image src="/images/logo-icon.svg" alt="CSC Logo" />
|
||||
</a>
|
||||
</Link>
|
||||
<button
|
||||
className={styles.hamburger}
|
||||
onClick={() => dispatch({ type: "open", route: router.pathname })}
|
||||
>
|
||||
<Image src="/images/hamburger.svg" alt="Menu" />
|
||||
</button>
|
||||
<div
|
||||
className={
|
||||
state.isNavOpen
|
||||
? `${styles.navMobileBackground} ${styles.show}`
|
||||
: styles.navMobileBackground
|
||||
}
|
||||
onClick={() => dispatch({ type: "close" })}
|
||||
/>
|
||||
<div className={styles.navMenuWrapper}>
|
||||
<Link href="/">
|
||||
<a
|
||||
className={styles.logoMobile}
|
||||
onClick={() => dispatch({ type: "close" })}
|
||||
>
|
||||
<Image src="/images/logo-icon.svg" alt="CSC Logo" />
|
||||
</a>
|
||||
</Link>
|
||||
<ul className={styles.navMenu}>
|
||||
{menu.map((item) => {
|
||||
return (
|
||||
<li className={styles.itemWrapper} key={item.name}>
|
||||
<NavItem
|
||||
name={item.name}
|
||||
route={item.route}
|
||||
submenu={item.submenu}
|
||||
mainRouteActive={state.activeSubmenus.has(
|
||||
getMainRoute(item.route)
|
||||
)}
|
||||
onClose={() => dispatch({ type: "close" })}
|
||||
onToggle={(route) => dispatch({ type: "toggle", route })}
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
interface MobileState {
|
||||
isNavOpen: boolean;
|
||||
activeSubmenus: Set<string>; // strings are NavLink routes
|
||||
}
|
||||
|
||||
type MobileAction =
|
||||
| { type: "open"; route: string }
|
||||
| { type: "toggle"; route: string }
|
||||
| { type: "close" };
|
||||
|
||||
const initialState: MobileState = {
|
||||
isNavOpen: false,
|
||||
activeSubmenus: new Set(),
|
||||
};
|
||||
|
||||
function reducer(state: MobileState, action: MobileAction): MobileState {
|
||||
switch (action.type) {
|
||||
case "open":
|
||||
return {
|
||||
isNavOpen: true,
|
||||
activeSubmenus: new Set([getMainRoute(action.route)]),
|
||||
};
|
||||
case "toggle": {
|
||||
const newSet = new Set(state.activeSubmenus);
|
||||
if (state.activeSubmenus.has(getMainRoute(action.route))) {
|
||||
newSet.delete(getMainRoute(action.route));
|
||||
} else {
|
||||
newSet.add(getMainRoute(action.route));
|
||||
}
|
||||
return {
|
||||
isNavOpen: state.isNavOpen,
|
||||
activeSubmenus: newSet,
|
||||
};
|
||||
}
|
||||
case "close":
|
||||
return initialState;
|
||||
}
|
||||
}
|
||||
|
||||
interface NavItemProps {
|
||||
name: string;
|
||||
route: string;
|
||||
submenu?: {
|
||||
name: string;
|
||||
route: string;
|
||||
}[];
|
||||
mainRouteActive: boolean;
|
||||
onToggle(route: string): void;
|
||||
onClose(): void;
|
||||
}
|
||||
|
||||
function NavItem(props: NavItemProps) {
|
||||
const router = useRouter();
|
||||
const isCurrentPage =
|
||||
router.pathname === props.route ||
|
||||
(props.submenu != null &&
|
||||
router.pathname.startsWith(getMainRoute(props.route)));
|
||||
const isExternalLink =
|
||||
props.route.includes("http://") || props.route.includes("https://");
|
||||
|
||||
function handleClick() {
|
||||
if (document.activeElement instanceof HTMLElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
props.onClose();
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{externalLink ? (
|
||||
{isExternalLink ? (
|
||||
<a
|
||||
href={props.route}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={() => {
|
||||
if (document.activeElement instanceof HTMLElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
}}
|
||||
onClick={handleClick}
|
||||
>
|
||||
{props.name}
|
||||
</a>
|
||||
|
@ -95,61 +213,57 @@ function NavItem(props: NavLink) {
|
|||
<Link href={props.route}>
|
||||
<a
|
||||
title={props.name}
|
||||
className={
|
||||
router.pathname === props.route ||
|
||||
((props.submenu?.length ?? 0) > 0 &&
|
||||
router.pathname.startsWith(props.route))
|
||||
? styles.currentPage
|
||||
: ""
|
||||
}
|
||||
onClick={() => {
|
||||
if (document.activeElement instanceof HTMLElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
}}
|
||||
className={isCurrentPage ? styles.currentPage : ""}
|
||||
onClick={handleClick}
|
||||
>
|
||||
{props.name}
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
{(props.submenu?.length ?? 0) > 0 ? (
|
||||
<ul className={styles.dropdown}>
|
||||
{props.submenu?.map((item) => {
|
||||
return (
|
||||
<li className={styles.dropdownWrapper} key={item.name}>
|
||||
<NavItem name={item.name} route={item.route} />
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
<>
|
||||
<button
|
||||
className={
|
||||
props.mainRouteActive
|
||||
? `${styles.dropdownIcon} ${styles.rotate}`
|
||||
: styles.dropdownIcon
|
||||
}
|
||||
onClick={() => props.onToggle(props.route)}
|
||||
>
|
||||
<Image src="/images/dropdown-icon.svg" alt="Dropdown Icon" />
|
||||
</button>
|
||||
<ul
|
||||
className={
|
||||
props.mainRouteActive
|
||||
? `${styles.dropdown} ${styles.show}`
|
||||
: styles.dropdown
|
||||
}
|
||||
>
|
||||
{props.submenu?.map((item) => {
|
||||
return (
|
||||
<li className={styles.itemWrapper} key={item.name}>
|
||||
<NavItem
|
||||
name={item.name}
|
||||
route={item.route}
|
||||
mainRouteActive={props.mainRouteActive}
|
||||
onClose={() => props.onClose()}
|
||||
onToggle={(route) => props.onToggle(route)}
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function Navbar() {
|
||||
return (
|
||||
<nav className={styles.navbar}>
|
||||
<div className={styles.navContent}>
|
||||
<Link href="/">
|
||||
<a className={styles.logo}>
|
||||
<Image src="/images/logo-icon.png" alt="CSC Logo" />
|
||||
</a>
|
||||
</Link>
|
||||
<ul className={styles.navMenu}>
|
||||
{menu.map((item) => {
|
||||
return (
|
||||
<li className={styles.dropdownWrapper} key={item.name}>
|
||||
<NavItem
|
||||
name={item.name}
|
||||
route={item.route}
|
||||
submenu={item.submenu}
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
function getMainRoute(route: string) {
|
||||
if (route === "/") {
|
||||
return "/";
|
||||
} else if (route.startsWith("http://") || route.startsWith("https://")) {
|
||||
return route;
|
||||
}
|
||||
return "/" + route.split("/")[1];
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
.link,
|
||||
.links {
|
||||
display: flex;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.links > * {
|
||||
margin: 0 calc(10rem / 16);
|
||||
.link {
|
||||
margin-left: calc(20rem / 16);
|
||||
}
|
||||
|
||||
.link:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.big > * {
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import Bubble from "./../../components/Bubble";
|
||||
|
||||
<Bubble>
|
||||
|
||||
CS Club is working towards bridging the gap between each and every CS student,
|
||||
to support their undergraduate experience and to provide a community that
|
||||
students can belong to and identify with. With hundreds of CS students joining
|
||||
Waterloo every year, CS Club aims to run events that encourage students to
|
||||
connect and socialize, to increase technical and academic interest with
|
||||
workshops and talks, and to provide a safe environment for academic learning and
|
||||
growth.
|
||||
|
||||
</Bubble>
|
||||
|
||||
<Bubble>
|
||||
|
||||
## Our <span>Vision</span>
|
||||
|
||||
1. Academic: Promoting the knowledge and interest of Computer Science, as well
|
||||
as supporting students throughout their academic experiences.
|
||||
|
||||
2. Career: Providing career guidance and resources to help students gain
|
||||
experience and knowledge for their own job search.
|
||||
|
||||
3. Community: Encouraging interpersonal relationships through community building
|
||||
and social events for all computing students.
|
||||
|
||||
</Bubble>
|
||||
|
||||
<Bubble>
|
||||
|
||||
## Our <span>Story</span>
|
||||
|
||||
We are students ourselves, coming from all computing backgrounds —
|
||||
Computer Science, Software Engineering, CFM, Mechatronics Engineering, and more.
|
||||
CS Club was born from an unfulfilled need; we felt that although there are so
|
||||
many students at UW that are interested in CS, there wasn't a proper support
|
||||
network in place. We lacked the cohorts provided to engineers, and we felt
|
||||
disconnected from one another.
|
||||
|
||||
By recreating what CS Club means for our community, we're passionate about
|
||||
helping students redefine their university experience here at Waterloo.
|
||||
|
||||
</Bubble>
|
||||
|
||||
<Bubble>
|
||||
|
||||
## Our <span>Mission</span>
|
||||
|
||||
The CS Club team is devoted to providing you with all the resources you could
|
||||
need as a student. We want to create a community that members can call home, to
|
||||
make it a place where you can reach out for career advice, for academic help, or
|
||||
even just to socialize. To fulfil this mission, we'll be running events and
|
||||
initiatives throughout the term, so please check out our [Events](/events/current)
|
||||
page to stay updated!
|
||||
|
||||
</Bubble>
|
||||
|
||||
<Bubble>
|
||||
|
||||
## Our <span>Office</span>
|
||||
|
||||
The CS Club office is located at room **MC 3036/3037**, in the Math & Computer
|
||||
Building of the University of Waterloo.
|
||||
|
||||
- An office favorite is our $0.50 pop for members. We have a fridge in the
|
||||
office which is stocked with many different kinds of pop.
|
||||
- We have lots of informative books, 5 computer terminals, and an array of
|
||||
knowledgeable people to talk to.
|
||||
|
||||
Come visit us on campus in our office! Meet new members and find out what's new
|
||||
in the club.
|
||||
|
||||
<address>
|
||||
|
||||
Computer Science Club <br />
|
||||
Math & Computer 3036/3037 <br />
|
||||
University of Waterloo <br />
|
||||
200 University Avenue West <br />
|
||||
Waterloo, ON N2L 3G1 <br />
|
||||
Canada
|
||||
|
||||
Our office phone number is [(519) 888-4567 x33870](tel:+15198884567,33870)
|
||||
|
||||
</address>
|
||||
|
||||
</Bubble>
|
||||
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
**Everyone at the University of Waterloo is welcome to come to our events and to
|
||||
use our resources!** Feel free to join our communities and chat with our
|
||||
members. However, if you wanted to officially become a member or support our
|
||||
vision of creating a supportive environment for all computing students, there's
|
||||
a bunch of ways you can join and help out.
|
||||
|
||||
## How to Join
|
||||
|
||||
### General Membership
|
||||
|
||||
<details>
|
||||
<summary>In-person Term</summary>
|
||||
|
||||
1. Drop by our office in **MC 3036/3037** with
|
||||
- your WatCard, and
|
||||
- $2 for term that you would like to pay for
|
||||
2. Sign our [Machine Usage Agreement](https://csclub.uwaterloo.ca/services/machine_usage)
|
||||
|
||||
That's all! After your account created, you'll have access to all the
|
||||
[services](https://csclub.uwaterloo.ca/services/) available to members.
|
||||
|
||||
#### Membership Renewal
|
||||
|
||||
If you are already a member of the CSC and want to renew your membership, you
|
||||
can do so by coming in person to our office.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Online Term</summary>
|
||||
|
||||
Email the CSC Systems Committee at
|
||||
[syscom@csclub.uwaterloo.ca](mailto:syscom@csclub.uwaterloo.ca) from your
|
||||
University of Waterloo email address with the following:
|
||||
|
||||
1. a scan or photograph copy of your **WatCard**,
|
||||
2. your **WatIAM userid**, and
|
||||
3. your acknowledgement of having read, understood, and agreeing with our
|
||||
[Machine Usage Agreement](https://csclub.uwaterloo.ca/services/machine_usage).
|
||||
|
||||
#### Membership Renewal
|
||||
|
||||
For this online term, you do not need to pay the $2 fee to renew your
|
||||
membership. We have extended the memberships of all members who had already
|
||||
previously paid for membership or have joined CS Club during an online term.
|
||||
|
||||
</details>
|
||||
|
||||
### Executive Committees
|
||||
|
||||
Are you interested in using your skills to get involved with CSC? We have
|
||||
committees covering everything from design to development, so no matter your
|
||||
interests, we’ve got a place for you.
|
||||
|
||||
**CSC hires at the end of every term**, so make sure to stay connected through
|
||||
social media to keep up to date on when applications open!
|
||||
|
||||
#### Programme Committee
|
||||
|
||||
- In charge of planning, advertising, and running all events hosted by CSC.
|
||||
- Voices concerns/ideas on behalf of the CS community.
|
||||
|
||||
#### Website Committee
|
||||
|
||||
- Creates functional and modern design for the CSC website.
|
||||
- Builds and maintains the static website, updating content for events and news.
|
||||
|
||||
#### Systems Committee
|
||||
|
||||
- Maintaining all services that CSC provides which includes file share, DNS,
|
||||
mail, configuration for IRC, Mattermost, Git hosting.
|
||||
- Managing mirrors used by large public organizations and 1000s of people
|
||||
internationally.
|
||||
|
||||
### Elected Roles
|
||||
Each term the CSC holds elections to determine the executive council.
|
||||
|
||||
- President
|
||||
- Vice-President
|
||||
- Assistant Vice-President
|
||||
- Treasurer
|
||||
|
||||
To find out when and where the next elections will be held, keep an eye on on the [News](/).
|
||||
|
||||
For details on the elections, see the [Constitution](https://csclub.uwaterloo.ca/about/constitution).
|
|
@ -11,8 +11,8 @@
|
|||
"@mdx-js/react": "^1.6.22",
|
||||
"@next/mdx": "^10.1.3",
|
||||
"date-fns": "^2.11.1",
|
||||
"gray-matter": "^4.0.2",
|
||||
"next": "^10.0.0",
|
||||
"next-mdx-remote": "^3.0.2",
|
||||
"prettier": "^2.3.0",
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1",
|
||||
|
@ -30,6 +30,7 @@
|
|||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-react": "^7.23.2",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"gray-matter": "^4.0.3",
|
||||
"postcss": "^8.3.0",
|
||||
"postcss-calc": "^8.0.0",
|
||||
"postcss-flexbugs-fixes": "^5.0.2",
|
||||
|
@ -1371,6 +1372,7 @@
|
|||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
|
@ -2574,6 +2576,15 @@
|
|||
"resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
|
||||
"integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw="
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.11.23",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.23.tgz",
|
||||
"integrity": "sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
|
@ -2908,6 +2919,7 @@
|
|||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"esparse": "bin/esparse.js",
|
||||
"esvalidate": "bin/esvalidate.js"
|
||||
|
@ -3009,6 +3021,7 @@
|
|||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-extendable": "^0.1.0"
|
||||
},
|
||||
|
@ -3307,6 +3320,7 @@
|
|||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz",
|
||||
"integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"js-yaml": "^3.13.1",
|
||||
"kind-of": "^6.0.2",
|
||||
|
@ -3821,6 +3835,7 @@
|
|||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
|
||||
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -4068,6 +4083,7 @@
|
|||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
|
@ -4127,6 +4143,7 @@
|
|||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -4529,6 +4546,75 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/next-mdx-remote": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/next-mdx-remote/-/next-mdx-remote-3.0.2.tgz",
|
||||
"integrity": "sha512-imLrrw6c/Hi1BKRyJE9yLhk45N5zzw+/CxSQRHOAByYUSOhd+DNjUaqm2jtd+/GgxJeYB1d3fJPXmvUZTez1MQ==",
|
||||
"dependencies": {
|
||||
"@mdx-js/mdx": "^1.6.22",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"esbuild": "^0.11.12",
|
||||
"pkg-dir": "^5.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.x <=17.x",
|
||||
"react-dom": ">=16.x <=17.x"
|
||||
}
|
||||
},
|
||||
"node_modules/next-mdx-remote/node_modules/find-up": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
||||
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
|
||||
"dependencies": {
|
||||
"locate-path": "^6.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/next-mdx-remote/node_modules/locate-path": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
|
||||
"dependencies": {
|
||||
"p-locate": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/next-mdx-remote/node_modules/p-locate": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
|
||||
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
|
||||
"dependencies": {
|
||||
"p-limit": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/next-mdx-remote/node_modules/pkg-dir": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz",
|
||||
"integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==",
|
||||
"dependencies": {
|
||||
"find-up": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/next/node_modules/postcss": {
|
||||
"version": "8.1.7",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.1.7.tgz",
|
||||
|
@ -7312,6 +7398,7 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
||||
"integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"kind-of": "^6.0.0"
|
||||
|
@ -7481,7 +7568,8 @@
|
|||
"node_modules/sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/stacktrace-parser": {
|
||||
"version": "0.1.10",
|
||||
|
@ -7637,6 +7725,7 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
|
||||
"integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -9386,6 +9475,7 @@
|
|||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
|
@ -10327,6 +10417,11 @@
|
|||
"resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
|
||||
"integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw="
|
||||
},
|
||||
"esbuild": {
|
||||
"version": "0.11.23",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.23.tgz",
|
||||
"integrity": "sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q=="
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
|
@ -10566,7 +10661,8 @@
|
|||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
||||
"dev": true
|
||||
},
|
||||
"esquery": {
|
||||
"version": "1.4.0",
|
||||
|
@ -10641,6 +10737,7 @@
|
|||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
|
@ -10876,6 +10973,7 @@
|
|||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz",
|
||||
"integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"js-yaml": "^3.13.1",
|
||||
"kind-of": "^6.0.2",
|
||||
|
@ -11221,7 +11319,8 @@
|
|||
"is-extendable": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
|
||||
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
|
||||
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
|
||||
"dev": true
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
|
@ -11378,6 +11477,7 @@
|
|||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
|
@ -11421,7 +11521,8 @@
|
|||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"dev": true
|
||||
},
|
||||
"levn": {
|
||||
"version": "0.4.1",
|
||||
|
@ -11750,6 +11851,52 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"next-mdx-remote": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/next-mdx-remote/-/next-mdx-remote-3.0.2.tgz",
|
||||
"integrity": "sha512-imLrrw6c/Hi1BKRyJE9yLhk45N5zzw+/CxSQRHOAByYUSOhd+DNjUaqm2jtd+/GgxJeYB1d3fJPXmvUZTez1MQ==",
|
||||
"requires": {
|
||||
"@mdx-js/mdx": "^1.6.22",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"esbuild": "^0.11.12",
|
||||
"pkg-dir": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"find-up": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
||||
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
|
||||
"requires": {
|
||||
"locate-path": "^6.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
|
||||
"requires": {
|
||||
"p-locate": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
|
||||
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
|
||||
"requires": {
|
||||
"p-limit": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"pkg-dir": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz",
|
||||
"integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==",
|
||||
"requires": {
|
||||
"find-up": "^5.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||
|
@ -13825,6 +13972,7 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
||||
"integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"kind-of": "^6.0.0"
|
||||
|
@ -13950,7 +14098,8 @@
|
|||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||
"dev": true
|
||||
},
|
||||
"stacktrace-parser": {
|
||||
"version": "0.1.10",
|
||||
|
@ -14076,7 +14225,8 @@
|
|||
"strip-bom-string": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
|
||||
"integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI="
|
||||
"integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=",
|
||||
"dev": true
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "3.1.1",
|
||||
|
|
|
@ -6,16 +6,16 @@
|
|||
"build": "next build",
|
||||
"start": "next start",
|
||||
"export": "next export",
|
||||
"lint": "eslint \"{pages,components}/**/*.{js,ts,tsx,jsx}\" --quiet",
|
||||
"lint:fix": "eslint \"{pages,components}/**/*.{js,ts,tsx,jsx}\" --quiet --fix"
|
||||
"lint": "eslint \"{pages,components,lib}/**/*.{js,ts,tsx,jsx}\" --quiet",
|
||||
"lint:fix": "eslint \"{pages,components,lib}/**/*.{js,ts,tsx,jsx}\" --quiet --fix"
|
||||
},
|
||||