Merge remote-tracking branch 'origin/main' into support-multiple-news-homepage
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
commit
9ea1cc9456
|
@ -34,6 +34,8 @@ export const PALETTE_NAMES = [
|
||||||
"--text",
|
"--text",
|
||||||
|
|
||||||
"--form-invalid",
|
"--form-invalid",
|
||||||
|
"--warning-background",
|
||||||
|
"--warning-text",
|
||||||
|
|
||||||
"--input-background",
|
"--input-background",
|
||||||
"--input-placeholder-text",
|
"--input-placeholder-text",
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
.warning{
|
||||||
|
background-color: var(--warning-background);
|
||||||
|
padding: calc(6rem / 16);
|
||||||
|
color: var(--warning-text);
|
||||||
|
font-size: calc(16rem / 16);
|
||||||
|
text-align: center;
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
/* The following are for a smooth fade in if there ever is a loading required for the warning, is not needed currently */
|
||||||
|
/* max-height: 500px;
|
||||||
|
/* transition: max-height 1000ms ease-in, padding 100ms ease-in; */
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { parse } from "date-fns";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import warnings from "../content/warnings/warnings.json";
|
||||||
|
import { DATE_FORMAT, getLocalDateFromEST } from "../utils";
|
||||||
|
|
||||||
|
import styles from "./WarningHeader.module.css";
|
||||||
|
|
||||||
|
interface Warning {
|
||||||
|
message: string;
|
||||||
|
startDate: string;
|
||||||
|
endDate: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentWarning(): Warning | null {
|
||||||
|
const today = new Date();
|
||||||
|
const currentWarnings: Warning[] = warnings.filter((warning) => {
|
||||||
|
// convert dates to date objects in EST time zone
|
||||||
|
let startDate = parse(warning.startDate, DATE_FORMAT, new Date());
|
||||||
|
let endDate = parse(warning.endDate, DATE_FORMAT, new Date());
|
||||||
|
|
||||||
|
if (
|
||||||
|
!startDate ||
|
||||||
|
!endDate ||
|
||||||
|
isNaN(startDate.getTime()) || // this checks if the parsed date is not valid (eg. wrong format), since getLocalDateFromEST fails with invalid dates
|
||||||
|
isNaN(endDate.getTime())
|
||||||
|
) {
|
||||||
|
throw new Error('WARNING WITH INVALID DATES: "' + warning.message + '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
startDate = getLocalDateFromEST(startDate);
|
||||||
|
endDate = getLocalDateFromEST(endDate);
|
||||||
|
|
||||||
|
return (
|
||||||
|
startDate.getTime() <= today.getTime() &&
|
||||||
|
endDate.getTime() >= today.getTime()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (currentWarnings.length > 1) {
|
||||||
|
// If more than one warning is scheduled, log an error to the console. We cannot throw an error, since the site would go down on the live
|
||||||
|
// website, on the day when more than one warning is scheduled.
|
||||||
|
console.error(
|
||||||
|
"ERROR: MORE THAN ONE WARNING SCHEDULED CURRENTLY! ",
|
||||||
|
currentWarnings
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentWarnings.length === 0 ? null : currentWarnings[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function WarningHeader() {
|
||||||
|
const warning = getCurrentWarning();
|
||||||
|
|
||||||
|
if (warning == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className={styles.warning}>{warning.message}</div>;
|
||||||
|
}
|
|
@ -38,20 +38,28 @@ University of Waterloo email address with the following:
|
||||||
3. your acknowledgement of having read, understood, and agreeing with our
|
3. your acknowledgement of having read, understood, and agreeing with our
|
||||||
[Machine Usage Agreement](/resources/machine-usage-agreement).
|
[Machine Usage Agreement](/resources/machine-usage-agreement).
|
||||||
|
|
||||||
You will need to pay the membership fee of $2 through PayPal.
|
<!--~~You will need to pay the membership fee of $2 through WUSA store.~~-->
|
||||||
A one-term payment via PayPal comes out to $2.37 (due to PayPal fees).
|
|
||||||
|
|
||||||
<p>
|
MathSoc has waived membership fees for the Winter 2022 term, so just send syscom
|
||||||
|
an email and we'll be happy to register your CSC account for free this term.
|
||||||
|
|
||||||
|
#### Membership Renewal
|
||||||
|
|
||||||
|
**Membership renewals for the Winter 2022 term are free.**
|
||||||
|
|
||||||
|
**Note: we no longer use Paypal to process memberships.**
|
||||||
|
|
||||||
|
For all other terms...
|
||||||
|
|
||||||
|
<!--<p>
|
||||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||||
<input type="hidden" name="cmd" value="_s-xclick"/>
|
<input type="hidden" name="cmd" value="_s-xclick"/>
|
||||||
<input type="hidden" name="hosted_button_id" value="9065852"/>
|
<input type="hidden" name="hosted_button_id" value="9065852"/>
|
||||||
<button size="small" name="submit">Renew by PayPal</button>
|
<button size="small" name="submit">Renew by PayPal</button>
|
||||||
</form>
|
</form>
|
||||||
</p>
|
</p>-->
|
||||||
|
|
||||||
#### Membership Renewal
|
Contact syscom to renew your membership for as many terms
|
||||||
|
|
||||||
Use the PayPal link above to renew your membership for as many terms
|
|
||||||
as you wish. You do not need to send us your WatCard or sign the usage
|
as you wish. You do not need to send us your WatCard or sign the usage
|
||||||
agreement again.
|
agreement again.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
author: 'b72zhou'
|
||||||
|
date: 'January 13 2022 00:00'
|
||||||
|
---
|
||||||
|
|
||||||
|
Winter 2022 elections have concluded. Here are your executives for the term:
|
||||||
|
|
||||||
|
- President: Juthika Hoque (j3hoque)
|
||||||
|
- Vice President (Head of Events): Eric Huang (e48huang)
|
||||||
|
- Assistant Vice President (Lead of Marketing): Dina Orucevic (dmorucev)
|
||||||
|
- Treasurer: Eden Chan (e223chan)
|
||||||
|
- Sysadmin: Raymond Li (r389li)
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
Additionally, the following postions were appointed:
|
||||||
|
|
||||||
|
- Head of Discord: Andy Wang (a284wang)
|
||||||
|
- Heads of Design: Vivian Guo (v6guo) and Jenny Zhang (j2447zha)
|
||||||
|
- Head of Reps: Amy Luo (a27luo)
|
||||||
|
|
||||||
|
<!-- -->
|
|
@ -0,0 +1,12 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"startDate": "February 15 2022 00:00",
|
||||||
|
"endDate": "February 20 2022 18:00",
|
||||||
|
"message": "Warning: There will be a scheduled system maintenance on February 17 from 9pm to 12pm EST"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startDate": "January 29 2022 21:00",
|
||||||
|
"endDate": "January 30 2022 18:00",
|
||||||
|
"message": "This is a sample warning"
|
||||||
|
}
|
||||||
|
]
|
Binary file not shown.
After Width: | Height: | Size: 515 KiB |
|
@ -2,14 +2,19 @@ import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
import { parse } from "date-fns";
|
import { parse } from "date-fns";
|
||||||
import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";
|
|
||||||
import matter from "gray-matter";
|
import matter from "gray-matter";
|
||||||
import { MDXRemoteSerializeResult } from "next-mdx-remote";
|
import { MDXRemoteSerializeResult } from "next-mdx-remote";
|
||||||
import { serialize } from "next-mdx-remote/serialize";
|
import { serialize } from "next-mdx-remote/serialize";
|
||||||
|
|
||||||
import type { Props } from "../pages/events/[year]/[term]/index";
|
import type { Props } from "../pages/events/[year]/[term]/index";
|
||||||
// do not use alias "@/utils" as generate-calendar imports a function from this file and ts-node is not compatible
|
// do not use alias "@/utils" as generate-calendar imports a function from this file and ts-node is not compatible
|
||||||
import { Term, TERMS, isTerm } from "../utils";
|
import {
|
||||||
|
Term,
|
||||||
|
TERMS,
|
||||||
|
isTerm,
|
||||||
|
DATE_FORMAT,
|
||||||
|
getLocalDateFromEST,
|
||||||
|
} from "../utils";
|
||||||
|
|
||||||
const EVENTS_PATH = path.join("content", "events");
|
const EVENTS_PATH = path.join("content", "events");
|
||||||
|
|
||||||
|
@ -55,8 +60,6 @@ export interface Event {
|
||||||
metadata: Metadata;
|
metadata: Metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DATE_FORMAT = "MMMM dd yyyy HH:mm";
|
|
||||||
|
|
||||||
export async function getEventBySlug(
|
export async function getEventBySlug(
|
||||||
year: string,
|
year: string,
|
||||||
term: Term,
|
term: Term,
|
||||||
|
@ -284,12 +287,3 @@ function getFutureTerm(year: string, term: Term): { year: string; term: Term } {
|
||||||
term: TERMS[index + 1],
|
term: TERMS[index + 1],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// The date that's returned should be in local time
|
|
||||||
export function getLocalDateFromEST(date: Date) {
|
|
||||||
return utcToZonedTime(
|
|
||||||
// The parsed date is in EST
|
|
||||||
zonedTimeToUtc(date, "America/Toronto"),
|
|
||||||
Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { serialize } from "next-mdx-remote/serialize";
|
||||||
|
|
||||||
import { isTerm, Term, TERMS } from "@/utils";
|
import { isTerm, Term, TERMS } from "@/utils";
|
||||||
|
|
||||||
import { DATE_FORMAT, getLocalDateFromEST } from "./events";
|
import { DATE_FORMAT, getLocalDateFromEST } from "../utils";
|
||||||
|
|
||||||
export const NEWS_PATH = path.join("content", "news");
|
export const NEWS_PATH = path.join("content", "news");
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ body {
|
||||||
--text: #000000;
|
--text: #000000;
|
||||||
|
|
||||||
--form-invalid: #9f616a;
|
--form-invalid: #9f616a;
|
||||||
|
--warning-background: #dd0014;
|
||||||
|
--warning-text: #ffffff;
|
||||||
|
|
||||||
--input-background: #f0f0f0;
|
--input-background: #f0f0f0;
|
||||||
--input-placeholder-text: #bbbbbb;
|
--input-placeholder-text: #bbbbbb;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {
|
||||||
} from "@/components/ShapesBackground";
|
} from "@/components/ShapesBackground";
|
||||||
import { Table } from "@/components/Table";
|
import { Table } from "@/components/Table";
|
||||||
import { ThemeProvider } from "@/components/Theme";
|
import { ThemeProvider } from "@/components/Theme";
|
||||||
|
import { WarningHeader } from "@/components/WarningHeader";
|
||||||
|
|
||||||
import styles from "./_app.module.css";
|
import styles from "./_app.module.css";
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ export default function App({ Component, pageProps }: AppProps): JSX.Element {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={styles.appContainer}>
|
<div className={styles.appContainer}>
|
||||||
|
<WarningHeader />
|
||||||
<Navbar />
|
<Navbar />
|
||||||
{/* Wrapping content with a div to allow for a display: block parent */}
|
{/* Wrapping content with a div to allow for a display: block parent */}
|
||||||
<div className={styles.contentContainer}>
|
<div className={styles.contentContainer}>
|
||||||
|
|
|
@ -3,8 +3,9 @@ import path from "path";
|
||||||
|
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
|
|
||||||
|
import { DATE_FORMAT } from "@/utils";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DATE_FORMAT,
|
|
||||||
getEventsByTerm,
|
getEventsByTerm,
|
||||||
getEventTermsByYear,
|
getEventTermsByYear,
|
||||||
getEventYears,
|
getEventYears,
|
||||||
|
|
12
utils.ts
12
utils.ts
|
@ -1,5 +1,8 @@
|
||||||
|
import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";
|
||||||
|
|
||||||
export const TERMS = ["winter", "spring", "fall"] as const;
|
export const TERMS = ["winter", "spring", "fall"] as const;
|
||||||
export type Term = typeof TERMS[number];
|
export type Term = typeof TERMS[number];
|
||||||
|
export const DATE_FORMAT = "MMMM dd yyyy HH:mm";
|
||||||
|
|
||||||
// https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates
|
// https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates
|
||||||
export function isTerm(x: string): x is Term {
|
export function isTerm(x: string): x is Term {
|
||||||
|
@ -9,3 +12,12 @@ export function isTerm(x: string): x is Term {
|
||||||
export function capitalize(str: string) {
|
export function capitalize(str: string) {
|
||||||
return str.slice(0, 1).toUpperCase() + str.slice(1);
|
return str.slice(0, 1).toUpperCase() + str.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Converts a date to local time
|
||||||
|
export function getLocalDateFromEST(date: Date): Date {
|
||||||
|
return utcToZonedTime(
|
||||||
|
// The date parameter is in EST
|
||||||
|
zonedTimeToUtc(date, "America/Toronto"),
|
||||||
|
Intl.DateTimeFormat().resolvedOptions().timeZone
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue