Compare commits

...

9 Commits

Author SHA1 Message Date
b38peng 977d226b70 Merge branch 'main' of https://git.csclub.uwaterloo.ca/www/www-new into feat/meet-the-team-page 1 year ago
Jared He 485230c95a Fix title inconsistencies (#229) 1 year ago
Jared He c0c2420ee6 Fix mobile header (#231) 1 year ago
Aditya Thakral 30102822da Add title to all pages (#222) 1 year ago
Aditya Thakral 298e3c6efb Fix constitution formatting (#216) 1 year ago
Aditya Thakral 8375bce092 Add old .ics file and .atom files (#223) 1 year ago
Aditya Thakral a8337cbe5e Add a minimal README (#218) 1 year ago
Amy Wang bb4219a02b Show pointer cursor when hovering over dropdowns on Get Involved page (#228) 1 year ago
Aditya Thakral 9c6d5ccf16 Remove Bill from Syscom + Fix Andrew's picture (#226) 1 year ago
  1. 3
      .vscode/settings.json
  2. 21
      README.md
  3. 39
      components/ArchivePage.tsx
  4. 2
      components/ConnectWithUs.tsx
  5. 11
      components/OrganizedContent.module.css
  6. 32
      components/OrganizedContent.tsx
  7. 44
      components/OrganizedContent/ReadAll.tsx
  8. 35
      components/OrganizedContent/Section.tsx
  9. 19
      components/Title.tsx
  10. 7
      components/playground.tsx
  11. 2
      content/about/constitution/amendments-and-procedures.md
  12. 2
      content/about/constitution/code-of-conduct.md
  13. 8
      content/about/constitution/committees.md
  14. 2
      content/about/constitution/dissolution.md
  15. 36
      content/about/constitution/duties-of-officers.md
  16. 2
      content/about/constitution/executive-council.md
  17. 2
      content/about/constitution/finances.md
  18. 2
      content/about/constitution/meetings.md
  19. 2
      content/about/constitution/membership.md
  20. 2
      content/about/constitution/name.md
  21. 34
      content/about/constitution/officers.md
  22. 10
      content/about/constitution/purpose.md
  23. 2
      content/about/constitution/use-of-club-resources.md
  24. 2
      content/about/index.mdx
  25. 12
      content/get-involved.mdx
  26. 7
      content/meet-the-team/systems-committee.json
  27. 4
      lib/team.ts
  28. 2
      pages/about/code-of-conduct/[section].tsx
  29. 7
      pages/about/code-of-conduct/index.tsx
  30. 2
      pages/about/constitution/[section].tsx
  31. 8
      pages/about/constitution/index.tsx
  32. 2
      pages/about/index.tsx
  33. 2
      pages/about/our-supporters.tsx
  34. 10
      pages/about/team.tsx
  35. 27
      pages/events/[year]/[term]/[event].tsx
  36. 13
      pages/events/[year]/[term]/index.module.css
  37. 30
      pages/events/[year]/[term]/index.tsx
  38. 6
      pages/events/[year]/index.module.css
  39. 2
      pages/events/[year]/index.tsx
  40. 2
      pages/events/index.tsx
  41. 4
      pages/get-involved.module.css
  42. 2
      pages/get-involved.tsx
  43. 2
      pages/index.tsx
  44. 5
      pages/news/[year]/[term].module.css
  45. 2
      pages/news/[year]/[term].tsx
  46. 11
      pages/resources/advice/academic.tsx
  47. 10
      pages/resources/advice/coop.tsx
  48. 11
      pages/resources/advice/misc.tsx
  49. 2
      pages/resources/machine-usage-agreement/[section].tsx
  50. 0
      pages/resources/machine-usage-agreement/index.tsx
  51. 2
      pages/resources/services/[section].tsx
  52. 0
      pages/resources/services/index.tsx
  53. 7
      pages/resources/tech-talks/[slug].tsx
  54. 0
      pages/resources/tech-talks/index.module.css
  55. 4
      pages/resources/tech-talks/index.tsx
  56. 4
      pages/themer.tsx
  57. 8178
      public/events.atom
  58. 5696
      public/events.ics
  59. BIN
      public/images/team/AndrewWang-Syscom.jpg
  60. 2850
      public/news.atom

@ -40,6 +40,7 @@
"files.eol": "\n",
"[markdown]": {
"editor.wordWrap": "on",
"editor.quickSuggestions": false
"editor.quickSuggestions": false,
"editor.tabSize": 4
}
}

@ -0,0 +1,21 @@
# Development
## Dependencies
Make sure that you have `node` >= 14 and `npm` >= 7. Node 14 ships with npm v6,
so if you're using node 14, you would need to upgrade npm. Alternatively you
could also upgrade to node 16, which ships with npm 7.
How to upgrade npm: `npm i -g npm`
## Local
- `npm install` to install project dependencies
- `npm run dev` to run the dev server (http://localhost:3000)
## Production
- `npm install` to install project dependencies
- `npm run build` to generate html/css/js
- `npm run export` to move the built files (along with assets in the public directory) to the `/out` directory
- Use your favourite web server to host the files in the `/out` directory. (A very simple one would be `python -m http.server` - not sure if it should actually be used for production :P)

@ -1,12 +1,14 @@
import React from "react";
import { Link } from "@/components/Link";
import { capitalize } from "@/utils";
import { Link } from "./Link";
import {
ShapesConfig,
GetShapesConfig,
defaultGetShapesConfig,
} from "@/components/ShapesBackground";
import { capitalize } from "@/utils";
} from "./ShapesBackground";
import { Title } from "./Title";
import styles from "./ArchivePage.module.css";
@ -20,20 +22,23 @@ export interface Props {
export function ArchivePage({ items, type }: Props) {
return (
<div className={styles.page}>
<h1>{capitalize(type)} Archive</h1>
<ul className={styles.list}>
{items.map(({ year, terms }) =>
terms.map((term) => (
<li key={`/${type}/${year}/${term}`}>
<Link href={`/${type}/${year}/${term}`}>
{capitalize(term)} {year}
</Link>
</li>
))
)}
</ul>
</div>
<>
<Title>{[capitalize(type), "Archive"]}</Title>
<div className={styles.page}>
<h1>{capitalize(type)} Archive</h1>
<ul className={styles.list}>
{items.map(({ year, terms }) =>
terms.map((term) => (
<li key={`/${type}/${year}/${term}`}>
<Link href={`/${type}/${year}/${term}`}>
{capitalize(term)} {year}
</Link>
</li>
))
)}
</ul>
</div>
</>
);
}

@ -20,7 +20,7 @@ export function ConnectWithUs() {
<p>
Send feedback through our{" "}
<Link href="https://bit.ly/uwcsclub-feedback-form">Feedback Form</Link>
<Link href="https://bit.ly/uwcsclub-feedback-form">Feedback Form</Link>.
</p>
</section>
);

@ -133,7 +133,6 @@
}
@media only screen and (max-width: calc(768rem / 16)) {
.burger {
display: flex;
position: fixed;
@ -178,6 +177,11 @@
margin-bottom: calc(8rem / 16);
}
.content ul,
.content ol {
padding-left: 1rem;
}
.nav {
position: fixed;
@ -209,11 +213,11 @@
transition: 0.5s;
}
.mobileNavOpen {
transform: translateX(0);
}
.mobileNavTitle {
display: flex;
font-size: calc(24rem / 16);
@ -227,4 +231,3 @@
opacity: 100%;
}
}

@ -26,6 +26,7 @@ interface Props {
children: ReactNode;
pageTitle: string;
link: Link;
numberedSections?: boolean;
}
export function OrganizedContent({
@ -34,6 +35,7 @@ export function OrganizedContent({
children,
pageTitle,
link: Link,
numberedSections = false,
}: Props) {
const [mobileNavOpen, setMobileNavOpen] = useState(false);
const currentIndex = sections.findIndex(
@ -71,6 +73,7 @@ export function OrganizedContent({
currentIndex={currentIndex}
link={Link}
pageTitle={pageTitle}
numberedSections={numberedSections}
mobileNavOpen={mobileNavOpen}
setMobileNavOpen={setMobileNavOpen}
/>
@ -80,7 +83,11 @@ export function OrganizedContent({
) : (
<>
<section>
<h1>{section.title}</h1>
<h1>
{numberedSections
? `${currentIndex}. ${section.title}`
: section.title}
</h1>
{children}
</section>
<Footer
@ -108,6 +115,7 @@ interface NavProps {
currentIndex: number;
link: Link;
pageTitle: string;
numberedSections: boolean;
mobileNavOpen: boolean;
setMobileNavOpen: (mobileNavOpen: boolean) => void;
}
@ -117,6 +125,7 @@ function Nav({
currentIndex,
link: Link,
pageTitle,
numberedSections,
mobileNavOpen,
setMobileNavOpen,
}: NavProps) {
@ -150,7 +159,11 @@ function Nav({
>
<Link className={classNames.join(" ")} id={section.id}>
<span className={styles.marker} />
<div>{section.title}</div>
<div>
{numberedSections && section.id !== READ_ALL_ID
? `${index}. ${section.title}`
: section.title}
</div>
</Link>
</div>
);
@ -221,15 +234,18 @@ export interface SectionWithContent {
export function createReadAllSection(
sections: Section[],
content: false
content: false,
numberedSections?: undefined
): Section;
export function createReadAllSection(
sections: SectionWithContent[],
content: true
content: true,
numberedSections: boolean
): SectionWithContent;
export function createReadAllSection(
sections: SectionWithContent[] | Section[],
content = true
content = true,
numberedSections?: boolean
): SectionWithContent | Section {
const readAllSection = {
id: READ_ALL_ID,
@ -243,9 +259,11 @@ export function createReadAllSection(
return (
<>
{(sections as SectionWithContent[]).map(
({ section: { id, title }, Content }) => (
({ section: { id, title }, Content }, index) => (
<section key={id}>
<h1>{title}</h1>
<h1>
{numberedSections ? `${index + 1}. ${title}` : title}
</h1>
<Content />
</section>
)

@ -9,6 +9,7 @@ import {
} from "@/components/OrganizedContent";
import { GetShapesConfig } from "../ShapesBackground";
import { Title } from "../Title";
import { Header } from "./Header";
@ -32,6 +33,7 @@ export interface Options {
imagePosition?: "left" | "right";
link?: ComponentType<LinkProps>;
description?: string;
numberedSections?: boolean;
}
export function createReadAllPage({
@ -42,6 +44,7 @@ export function createReadAllPage({
link,
description,
imagePosition,
numberedSections = false,
}: Options) {
const Link = link ?? createLink(pagePath);
@ -53,28 +56,33 @@ export function createReadAllPage({
return <MDXRemote {...content} />;
},
})),
true
true,
numberedSections
);
return (
<Header
title={title}
image={image}
description={description}
imagePosition={imagePosition}
>
<OrganizedContent
id={readAllSection.section.id}
sections={[
readAllSection.section,
...sections.map(({ section }) => section),
]}
pageTitle={title}
link={Link}
<>
<Title>{title}</Title>
<Header
title={title}
image={image}
description={description}
imagePosition={imagePosition}
>
<readAllSection.Content />
</OrganizedContent>
</Header>
<OrganizedContent
id={readAllSection.section.id}
sections={[
readAllSection.section,
...sections.map(({ section }) => section),
]}
numberedSections={numberedSections}
pageTitle={title}
link={Link}
>
<readAllSection.Content />
</OrganizedContent>
</Header>
</>
);
}

@ -3,6 +3,8 @@ import React from "react";
import { createLink, OrganizedContent } from "@/components/OrganizedContent";
import { Title } from "../Title";
import { Header } from "./Header";
import { Options } from "./ReadAll";
@ -25,26 +27,31 @@ export function createSectionPage({
link,
description,
imagePosition,
numberedSections,
}: Options) {
const Link = link ?? createLink(pagePath);
function Page(this: void, { content, sections, current }: Props) {
return (
<Header
title={title}
image={image}
description={description}
imagePosition={imagePosition}
>
<OrganizedContent
sections={sections}
id={sections[current].id}
pageTitle={title}
link={Link}
<>
<Title>{[sections[current].title, title]}</Title>
<Header
title={title}
image={image}
description={description}
imagePosition={imagePosition}
>
<MDXRemote {...content} />
</OrganizedContent>
</Header>
<OrganizedContent
sections={sections}
id={sections[current].id}
pageTitle={title}
link={Link}
numberedSections={numberedSections}
>
<MDXRemote {...content} />
</OrganizedContent>
</Header>
</>
);
}

@ -0,0 +1,19 @@
import Head from "next/head";
import React from "react";
interface Props {
children: string | string[];
}
export function Title(props: Props) {
const children =
typeof props.children === "string" ? [props.children] : props.children;
children.push("CSC", "University of Waterloo");
return (
<Head>
<title>{children.join(" - ")}</title>
</Head>
);
}

@ -146,7 +146,7 @@ export function EventDescriptionCardDemo() {
export function EventCardDemo() {
return (
<>
{events.map(({ Content, metadata }, idx) => (
{events.map(({ Content, metadata }) => (
<>
<EventCard
{...metadata}
@ -220,12 +220,14 @@ export function LinkDemo() {
export function OrganizedContentDemo() {
const sections = [...constitution];
const numberedSections = false;
const readAllSection = createReadAllSection(
constitution.map(({ id, title, Content }) => ({
Content,
section: { id, title },
})),
true
true,
numberedSections
);
sections.unshift({
...readAllSection.section,
@ -253,6 +255,7 @@ export function OrganizedContentDemo() {
id={id}
link={FakeLink}
pageTitle="Playground"
numberedSections={numberedSections}
>
<Content />
</OrganizedContent>

@ -1,5 +1,5 @@
---
title: 10. Amendments and Procedures
title: Amendments and Procedures
index: 10
---

@ -1,5 +1,5 @@
---
title: 12. Code of Conduct
title: Code of Conduct
index: 12
---

@ -1,5 +1,5 @@
---
title: 7. Committees
title: Committees
index: 7
---
@ -17,9 +17,9 @@ index: 7
3. Members should only be appointed to the Systems Committee if they show interest and some existing ability in systems administration.
4. Members should only be removed from the Systems Committee with cause, or when they no longer show interest in systems administration.
5. The Systems Committee will collectively, under the leadership of the Systems Administrator,
a. operate any and all equipment in the possession of the Club.
a. maintain and upgrade the software on equipment that is operated by the Club.
a. facilitate the use of equipment that is operated by the Club.
1. operate any and all equipment in the possession of the Club.
1. maintain and upgrade the software on equipment that is operated by the Club.
1. facilitate the use of equipment that is operated by the Club.
6. Members of the Systems Committee shall have root access to the machines operated by the Club.
## Other Committees

@ -1,5 +1,5 @@
---
title: 11. Dissolution
title: Dissolution
index: 11
---

@ -1,27 +1,27 @@
---
title: 5. Duties of Officers
title: Duties of Officers
index: 5
---
1. The duties of the President shall be:
a. to call and preside at all general, special, and executive meetings of the Club, except during the election of officers;
a. to appoint special committees of the Club and the membership and chairs of such committees, with the approval of the Executive Council; and
a. to audit, or to appoint a representative to audit, the financial records of the club at the end of each academic term.
a. with the approval of the Faculty Advisor, rule on any point of procedure under the constitution that arises outside of a meeting.
1. to call and preside at all general, special, and executive meetings of the Club, except during the election of officers;
1. to appoint special committees of the Club and the membership and chairs of such committees, with the approval of the Executive Council; and
1. to audit, or to appoint a representative to audit, the financial records of the club at the end of each academic term.
1. with the approval of the Faculty Advisor, rule on any point of procedure under the constitution that arises outside of a meeting.
1. The duties of the Vice-President shall be:
a. to assume the duties of the President in the event of the President's absence;
a. to chair the Programme Committee;
a. to appoint members to and remove members from the Programme Committee;
a. to ensure that Club events are held regularly; and
a. to assume those duties of the President that are delegated to them by the President.
1. to assume the duties of the President in the event of the President's absence;
1. to chair the Programme Committee;
1. to appoint members to and remove members from the Programme Committee;
1. to ensure that Club events are held regularly; and
1. to assume those duties of the President that are delegated to them by the President.
1. The duties of the Secretary shall be:
a. to keep minutes of all Club meetings;
a. to care for all Club correspondence; and
a. manage any persons appointed to internal positions by the Executive.
1. to keep minutes of all Club meetings;
1. to care for all Club correspondence; and
1. manage any persons appointed to internal positions by the Executive.
1. The duties of the Treasurer shall be:
a. to collect dues and maintain all financial and membership records;
a. to produce a financial or membership statement when requested.
1. to collect dues and maintain all financial and membership records;
1. to produce a financial or membership statement when requested.
1. The duties of the System Administrator shall be:
a. to chair the Systems Committee;
a. to appoint members to and remove members from the Systems Committee.
a. to ensure that the duties of the Systems Committee are performed.
1. to chair the Systems Committee;
1. to appoint members to and remove members from the Systems Committee.
1. to ensure that the duties of the Systems Committee are performed.

@ -1,5 +1,5 @@
---
title: 6. Executive Council
title: Executive Council
index: 6
---

@ -1,5 +1,5 @@
---
title: 9. Finances
title: Finances
index: 9
---

@ -1,5 +1,5 @@
---
title: 8. Meetings
title: Meetings
index: 8
---

@ -1,5 +1,5 @@
---
title: 3. Membership
title: Membership
index: 3
---

@ -1,5 +1,5 @@
---
title: 1. Name
title: Name
index: 1
---

@ -1,29 +1,29 @@
---
title: 4. Officers
title: Officers
index: 4
---
1. The officers of the Club shall be:
a. President
a. Vice-President
a. Secretary
a. Treasurer
a. System Administrator
1. President
1. Vice-President
1. Secretary
1. Treasurer
1. System Administrator
1. There shall additionally be a Faculty Advisor, selected by the Executive from time to time from among the faculty of the School of Computer Science. The Faculty Advisor shall be an ex-officio affiliate member of the Club.
1. The choice of officers shall be limited to full members of the Club.
1. All officers, other than the System Administrator, shall be elected at a meeting to be held no later than two weeks after the start of lectures in each term.
1. The election of officers shall be accomplished by the following procedure:
a. Before the end of the prior term, the then-Executive shall choose a willing Chief Returning Officer, who is responsible for carrying out elections according to this procedure.
a. The CRO shall set the date and time of the election meeting, and set the nomination period. The nomination shall be at least one week long and shall end at least 24 hours before the start of the election meeting.
a. Announcements of the election and the nomination procedure must be distributed to all members by the members' mailing list, and should also be advertised by posters in the MC building.
a. During the nomination period, the Chief Returning Officer (CRO) shall be available to receive nominations for the posts of officers of the club, either in person, by email, by depositing nomination forms in the CSC's mailbox in the MathSoc office, or by writing the nomination in a place in the CSC office to be specified by the CRO.
a. A nomination shall consist of the nominee's userid, and post(s) nominated for. Nominees must be full members of the Computer Science Club. A member may decline a nomination at any point prior to the taking of the vote.
a. The election shall commence with the offering of memberships for sale. After a reasonable time, control of the meeting is given to the CRO who will preside over the election of the President, Vice-President, Treasurer, and Secretary, in that order.
a. During each election, if the position has no nominees, the CRO will take nominations from the floor. Any present, eligible member can be nominated.
a. Each election shall be carried out by secret vote, in a manner to be decided on by the CRO, with the approval of the members at the meeting. A simple heads-down-hands-up method is considered acceptable.
a. The CRO shall not vote except to break a tie.
a. The CRO may, if feasible, accept absentee ballots from full members. No absentee vote from a member shall be counted if the member is present at the time the vote is taken. The CRO shall make a best effort to ensure that absentee ballots are compatible with the method of voting chosen; if this is not possible (for instance, if the CRO is overruled by the membership), then the absentee votes shall not be counted.
a. Immediately after the vote is taken, the CRO will announce the results of the election and the winner will be removed from subsequent contests. If, due to lack of candidates (because there were no nominations, or candidates withdrew or were eliminated), there is no one elected to an office, then the members at the meeting will decide whether or not to hold extra elections in accordance with the procedure for vacancies. If they choose not to, this does not prevent the Executive or a group of members from calling extra elections later in the term in accordance with the usual vacancy provisions.
1. Before the end of the prior term, the then-Executive shall choose a willing Chief Returning Officer, who is responsible for carrying out elections according to this procedure.
1. The CRO shall set the date and time of the election meeting, and set the nomination period. The nomination shall be at least one week long and shall end at least 24 hours before the start of the election meeting.
1. Announcements of the election and the nomination procedure must be distributed to all members by the members' mailing list, and should also be advertised by posters in the MC building.
1. During the nomination period, the Chief Returning Officer (CRO) shall be available to receive nominations for the posts of officers of the club, either in person, by email, by depositing nomination forms in the CSC's mailbox in the MathSoc office, or by writing the nomination in a place in the CSC office to be specified by the CRO.
1. A nomination shall consist of the nominee's userid, and post(s) nominated for. Nominees must be full members of the Computer Science Club. A member may decline a nomination at any point prior to the taking of the vote.
1. The election shall commence with the offering of memberships for sale. After a reasonable time, control of the meeting is given to the CRO who will preside over the election of the President, Vice-President, Treasurer, and Secretary, in that order.
1. During each election, if the position has no nominees, the CRO will take nominations from the floor. Any present, eligible member can be nominated.
1. Each election shall be carried out by secret vote, in a manner to be decided on by the CRO, with the approval of the members at the meeting. A simple heads-down-hands-up method is considered acceptable.
1. The CRO shall not vote except to break a tie.
1. The CRO may, if feasible, accept absentee ballots from full members. No absentee vote from a member shall be counted if the member is present at the time the vote is taken. The CRO shall make a best effort to ensure that absentee ballots are compatible with the method of voting chosen; if this is not possible (for instance, if the CRO is overruled by the membership), then the absentee votes shall not be counted.
1. Immediately after the vote is taken, the CRO will announce the results of the election and the winner will be removed from subsequent contests. If, due to lack of candidates (because there were no nominations, or candidates withdrew or were eliminated), there is no one elected to an office, then the members at the meeting will decide whether or not to hold extra elections in accordance with the procedure for vacancies. If they choose not to, this does not prevent the Executive or a group of members from calling extra elections later in the term in accordance with the usual vacancy provisions.
1. Following the elections, it is the responsibility of the new executive to select a System Administrator. The selection of System Administrator must then be ratified by the members at the meeting. If a suitable System Administrator is not available, then the executive may delay their selection until one becomes available. In this case the selection of System Administrator must be ratified at the next meeting of the Club.
1. Any two offices may be held by a single person with the approval of the President (if any), and the explicit approval of the members.
1. In the case of a resignation of an officer or officers, including the President, or if a vacancy occurs for any other reason, the Executive, members at a meeting, or any ten (10) members may call extra elections to replace such officer(s). If extra elections are held, they are held for all vacant offices.

@ -1,10 +1,10 @@
---
title: 2. Purpose
title: Purpose
index: 2
---
1. The Club is organized and will be operated exclusively for educational and scientific purposes in furtherance of:
a. promoting an increased knowledge of computer science and its applications;
a. providing a means of communication between persons having interest in computer science.
a. promoting a greater interest in computer science and its applications; and
1. The above purposes will be fulfilled by the organization of discussions and lectures with professionals and academics in the field of computer science and related fields, the maintenance of a library of materials related to computer science, the maintenance of an office containing the library as an aid to aim (1.c) above, and such other means as decided by the club membership.
1. promoting an increased knowledge of computer science and its applications;
1. providing a means of communication between persons having interest in computer science.
1. promoting a greater interest in computer science and its applications; and
1. The above purposes will be fulfilled by the organization of discussions and lectures with professionals and academics in the field of computer science and related fields, the maintenance of a library of materials related to computer science, the maintenance of an office containing the library as an aid to aim (1.3) above, and such other means as decided by the club membership.

@ -1,5 +1,5 @@
---
title: 13. Use of Club Resources
title: Use of Club Resources
index: 13
---

@ -80,7 +80,7 @@ University of Waterloo <br />
Waterloo, ON N2L 3G1 <br />
Canada
Our office phone number is [(519) 888-4567 x33870](tel:+15198884567,33870)
Our office phone number is [(519) 888-4567 x33870](tel:+15198884567,33870).
</address>

@ -1,6 +1,6 @@
**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
members. However, if you want 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.
@ -35,12 +35,12 @@ 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 
3. your acknowledgement of having read, understood, and agreeing with our
[Machine Usage Agreement](/resources/machine-usage-agreement).
#### Membership Renewal
For this online term, you do not need to pay the $2 fee to renew your
For this online term (Spring 2021), 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.
@ -62,18 +62,18 @@ social media to keep up to date on when applications open!
#### Website Committee
- Creates functional and modern design for the CSC website.
- Creates functional and modern designs 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
- Managing mirrors used by large public organizations and thousands of people
internationally.
### Elected Roles
Each term the CSC holds elections to determine the executive council.
Each term, the CSC holds elections to determine the executive council:
- President
- Vice-President

@ -5,11 +5,8 @@
},
{
"name": "Andrew Wang",
"role": "Member"
},
{
"name": "Bill Xiang",
"role": "Member"
"role": "Member",
"image": "/images/team/AndrewWang-Syscom.jpg"
},
{
"name": "Raymond Li",

@ -22,7 +22,9 @@ export async function getExecNames() {
export async function getExec(fileName: string, convert = true) {
const raw = await readFile(path.join(EXECS_PATH, `${fileName}${fileType}`));
const { content, data: metadata } = matter(raw);
const image = await getMemberImagePath(metadata.name);
const image =
(metadata.image as string | undefined) ??
(await getMemberImagePath(metadata.name));
return {
content: convert ? await serialize(content) : content,

@ -4,7 +4,7 @@ import {
createSectionGetStaticProps,
} from "@/components/OrganizedContent/static";
import { options } from "../code-of-conduct";
import { options } from "./";
export default createSectionPage(options);

@ -1,9 +1,12 @@
import path from "path";
import { createReadAllPage } from "@/components/OrganizedContent/ReadAll";
import {
createReadAllPage,
Options,
} from "@/components/OrganizedContent/ReadAll";
import { createReadAllGetStaticProps } from "@/components/OrganizedContent/static";
export const options = {
export const options: Options = {
title: "Code of Conduct",
image: "images/code-of-conduct.svg",
pagePath: path.join("about", "code-of-conduct"),

@ -4,7 +4,7 @@ import {
createSectionGetStaticProps,
} from "@/components/OrganizedContent/static";
import { options } from "../constitution";
import { options } from "./";
export default createSectionPage(options);

@ -1,12 +1,16 @@
import path from "path";
import { createReadAllPage } from "@/components/OrganizedContent/ReadAll";
import {
createReadAllPage,
Options,
} from "@/components/OrganizedContent/ReadAll";
import { createReadAllGetStaticProps } from "@/components/OrganizedContent/static";
export const options = {
export const options: Options = {
title: "Constitution",
image: "images/constitution.svg",
pagePath: path.join("about", "constitution"),
numberedSections: true,
};
export default createReadAllPage(options);

@ -8,6 +8,7 @@ import {
GetShapesConfig,
mobileShapesConfig,
} from "@/components/ShapesBackground";
import { Title } from "@/components/Title";
import Content from "../../content/about/index.mdx";
@ -16,6 +17,7 @@ import styles from "./index.module.css";
export default function AboutUs() {
return (
<>
<Title>About</Title>
<div className={styles.titleContainer}>
<h1 className={styles.title}>About Us!</h1>
<Image src="/images/about-us.svg" className={styles.codey} />

@ -1,6 +1,7 @@
import React from "react";
import { Image } from "@/components/Image";
import { Title } from "@/components/Title";
import Content from "../../content/about/our-supporters.mdx";
@ -9,6 +10,7 @@ import styles from "./our-supporters.module.css";
export default function OurSupporters() {
return (
<>
<Title>Our Supporters</Title>
<div className={styles.headerContainer}>
<h1 className={styles.header}>Our Supporters</h1>
<Image src="images/our-supporters/codey.svg" className={styles.codey} />

@ -8,6 +8,7 @@ import { Image } from "@/components/Image";
import { Link } from "@/components/Link";
import { TeamMember } from "@/components/TeamMember";
import { TeamMemberCard } from "@/components/TeamMemberCard";
import { Title } from "@/components/Title";
import {
getExec,
getExecNames,
@ -36,6 +37,7 @@ interface Props {
export default function Team({ execs, programme, website, systems }: Props) {
return (
<>
<Title>Team</Title>
<DefaultLayout>
<div className={styles.headerContainer}>
<div className={styles.headerTextContainer}>
@ -85,7 +87,7 @@ export default function Team({ execs, programme, website, systems }: Props) {
To find out when and where the next elections will be held, keep an
eye on on the <Link href="/#news">News</Link>. <br />
For details on the elections, read our
<Link href="/about/constitution"> Constitution</Link>
<Link href="/about/constitution"> Constitution</Link>.
</Bubble>
</div>
</>
@ -110,10 +112,12 @@ function MembersList(props: MembersProps) {
);
}
async function getTeamWithImages(team: Omit<Metadata, "image">[]) {
type TeamMember = Omit<Metadata, "image"> & { image?: string };
async function getTeamWithImages(team: TeamMember[]) {
return await Promise.all(
team.map(async (member) => {
const image = await getMemberImagePath(member.name);
const image = member.image ?? (await getMemberImagePath(member.name));
return {
...member,
image,

@ -5,6 +5,7 @@ import { MDXRemote } from "next-mdx-remote";
import React from "react";
import { EventCard } from "@/components/EventCard";
import { Title } from "@/components/Title";
import {
Event,
getEventYears,
@ -12,20 +13,26 @@ import {
getEventsByTerm,
getEventBySlug,
} from "@/lib/events";
import { capitalize } from "@/utils";
export default function EventInfoPage(props: Props) {
export default function EventInfoPage({ year, term, event }: Props) {
return (
<EventCard
{...props.event.metadata}
date={new Date(props.event.metadata.date)}
showDescription
>
<MDXRemote {...props.event.content} />
</EventCard>
<>
<Title>{[event.metadata.name, `${capitalize(term)} ${year}`]}</Title>
<EventCard
{...event.metadata}
date={new Date(event.metadata.date)}
showDescription
>
<MDXRemote {...event.content} />
</EventCard>
</>
);
}
interface Props {
year: string;
term: string;
event: Event;
}
@ -40,7 +47,9 @@ export const getStaticProps: GetStaticProps<Props, Params> = async (
) => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const { year, term, event } = context.params!;
return { props: { event: await getEventBySlug(year, term, event) } };
return {
props: { year, term, event: await getEventBySlug(year, term, event) },
};
};
export const getStaticPaths: GetStaticPaths<Params> = async () => {

@ -3,15 +3,20 @@
margin-bottom: calc(60rem / 16);
}
.main > h2 {
padding-bottom: 1rem;
border-bottom: 1px solid var(--primary-heading);
.main > h1, .main > section > h1 {
padding-bottom: calc(16rem / 16);
border-bottom: calc(1rem / 16) solid var(--primary-heading);
}
.header {
display: flex;
flex-wrap: wrap;
}
.header a {
color: var(--text);
font-size: calc(18rem / 16);
margin-right: calc(30rem / 16);
margin-right: 1rem;
}
.header a .curTerm {

@ -7,6 +7,7 @@ import React from "react";
import { EventCard } from "@/components/EventCard";
import { Link } from "@/components/Link";
import { MiniEventCard } from "@/components/MiniEventCard";
import { Title } from "@/components/Title";
import {
Event,
getEventsPageProps,
@ -54,6 +55,7 @@ export default function Term(props: Props) {
return (
<div className={styles.main}>
<Title>{["Events", `${capitalize(props.term)} ${props.year}`]}</Title>
<div className={styles.header}>
{headerTerms.map((link) => (
<HeaderLink
@ -65,8 +67,8 @@ export default function Term(props: Props) {
<Link href="/events/archive">Archive</Link>
</div>
{hasFutureEvents && (
<>
<h2>Upcoming Events</h2>
<section>
<h1>Upcoming Events</h1>
<div className={styles.miniEventCards}>
{props.futureEvents.map(({ content, metadata }) => (
<EventCard
@ -79,20 +81,34 @@ export default function Term(props: Props) {
</EventCard>
))}
</div>
</>
</section>
)}
{hasPastEvents && props.isCurrentTerm && (
<section>
<h1>Past Events</h1>
<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>
</section>
)}
{hasPastEvents && props.isCurrentTerm && <h2>Past Events</h2>}
{hasPastEvents && !props.isCurrentTerm && (
<h2>
<h1>
Events Archive:
<span className={styles.blue}>
{` ${capitalize(props.term)} ${props.year}`}
</span>
</h2>
</h1>
)}
{!hasFutureEvents && !hasPastEvents && (
<>
<h2>Events</h2>
<h1>Events</h1>
There are no upcoming or past events for the{" "}
{`${capitalize(props.term)} ${props.year}`} term. Please check back
later!

@ -2,9 +2,9 @@
margin-top: calc(60rem / 16);
}
.main > h2 {
padding-bottom: calc(1rem / 16);
border-bottom: 1px solid var(--primary-heading);
.main > h1 {
padding-bottom: calc(16rem / 16);
border-bottom: calc(1rem / 16) solid var(--primary-heading);
}
.blue {

@ -4,6 +4,7 @@ import { GetStaticPaths, GetStaticProps } from "next";
import React from "react";
import { Link } from "@/components/Link";
import { Title } from "@/components/Title";
import { getEventYears, getEventTermsByYear } from "@/lib/events";
import styles from "./index.module.css";
@ -16,6 +17,7 @@ interface Props {
export default function Year(props: Props) {
return (
<div className={styles.main}>
<Title>{["Events", props.year]}</Title>
<h2>
Events Archive:<span className={styles.blue}>{` ${props.year}`}</span>
</h2>

@ -2,7 +2,7 @@ import { GetStaticProps } from "next";
import { getCurrentTerm, getEventsPageProps } from "@/lib/events";
import Term, { Props } from "./[year]/[term]/index";
import Term, { Props } from "./[year]/[term]";
export default Term;

@ -34,6 +34,10 @@
font-weight: 600;
}
.content summary {
cursor: pointer;
}
.content details > * {
padding-left: 1rem;
}

@ -3,6 +3,7 @@ import React from "react";
import { ConnectWithUs } from "@/components/ConnectWithUs";
import { EmailSignup } from "@/components/EmailSignup";
import { Image } from "@/components/Image";
import { Title } from "@/components/Title";
import Content from "../content/get-involved.mdx";
@ -11,6 +12,7 @@ import styles from "./get-involved.module.css";
export default function GetInvolved() {
return (
<div className={styles.page}>
<Title>Get Involved</Title>
<header>
<div className={styles.headerText}>
<h1>Get Involved!</h1>

@ -11,6 +11,7 @@ import { Link } from "@/components/Link";
import { NewsCard } from "@/components/NewsCard";
import { GetShapesConfig } from "@/components/ShapesBackground";
import { SocialLinks } from "@/components/SocialLinks";
import { Title } from "@/components/Title";
import { Event, getUpcomingEvents } from "@/lib/events";
import { News, getRecentNews } from "@/lib/news";
@ -25,6 +26,7 @@ interface Props {
export default function Home(props: Props) {
return (
<>
<Title>{[]}</Title>
<DefaultLayout>
<header className={styles.intro}>
<div className={styles.introTop} />

<
@ -2,6 +2,11 @@
padding-bottom: calc(30rem / 16);
}