Merge branch 'main' into feat/events-year
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
commit
a13f48edfe
12
.drone.yml
12
.drone.yml
|
@ -4,8 +4,15 @@ type: docker
|
|||
name: node16
|
||||
|
||||
steps:
|
||||
- name: check-lockfile
|
||||
image: node:16
|
||||
commands:
|
||||
- node ./check-lockfile.js
|
||||
|
||||
- name: install-deps
|
||||
image: node:16
|
||||
depends_on:
|
||||
- check-lockfile
|
||||
commands:
|
||||
- npm install
|
||||
|
||||
|
@ -38,10 +45,7 @@ steps:
|
|||
TOKEN:
|
||||
from_secret: STAGING_TOKEN
|
||||
commands:
|
||||
- 'curl -XPOST -H "Authorization: $TOKEN" "https://csclub.uwaterloo.ca/~a3thakra/update-csc/"'
|
||||
when:
|
||||
branch:
|
||||
- main
|
||||
- 'curl -XPOST -H "Authorization: $TOKEN" -H "X-Branch: $DRONE_BRANCH" "https://csclub.uwaterloo.ca/~a3thakra/update-csc/"'
|
||||
|
||||
trigger:
|
||||
event:
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
const lockfile = require('./package-lock.json')
|
||||
|
||||
if (lockfile.lockfileVersion !== 2) {
|
||||
console.error(`
|
||||
Please upgrade to npm v7 and revert changes to the lockfile.
|
||||
|
||||
- \`npm i -g npm\` to upgrade.
|
||||
`.trim())
|
||||
process.exit(1)
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
.code {
|
||||
padding: 0 calc(4rem / 16);
|
||||
background: var(--code-background);
|
||||
border-radius: calc(5rem / 16);
|
||||
word-wrap: break-word;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import React, { HTMLAttributes } from "react";
|
||||
|
||||
import styles from "./Code.module.css";
|
||||
|
||||
export function Code(props: HTMLAttributes<HTMLElement>) {
|
||||
const classes = [styles.code, props.className ?? ""];
|
||||
|
||||
return <code {...props} className={classes.join(" ")} />;
|
||||
}
|
|
@ -18,9 +18,9 @@ export function ConnectWithUs() {
|
|||
<SocialLinks color="gradient" size="big" />
|
||||
</div>
|
||||
|
||||
{/* TODO: fix feedback form link */}
|
||||
<p>
|
||||
Send feedback through our <Link href="#">Feedback Form</Link>
|
||||
Send feedback through our{" "}
|
||||
<Link href="https://bit.ly/uwcsclub-feedback-form">Feedback Form</Link>
|
||||
</p>
|
||||
</section>
|
||||
);
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
.container form {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.header {
|
||||
color: var(--primary-accent);
|
||||
font-weight: 600;
|
||||
|
@ -9,8 +5,9 @@
|
|||
}
|
||||
|
||||
.button {
|
||||
margin-top: calc(34rem / 16);
|
||||
margin-top: calc(26rem / 16);
|
||||
display: block;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: calc(768rem / 16)) {
|
||||
|
|
|
@ -1,21 +1,24 @@
|
|||
import React from "react";
|
||||
|
||||
import { Button } from "./Button";
|
||||
import { Input } from "./Input";
|
||||
|
||||
import styles from "./EmailSignup.module.css";
|
||||
|
||||
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}>
|
||||
<h1 className={styles.header}>Join our mailing list!</h1>
|
||||
<p>
|
||||
Join our mailing list to receive email notifications about important
|
||||
news and upcoming events!
|
||||
</p>
|
||||
<Button
|
||||
isLink={true}
|
||||
href="https://mailman.csclub.uwaterloo.ca/postorius/lists/csc-general.csclub.uwaterloo.ca/"
|
||||
className={styles.button}
|
||||
>
|
||||
Subscribe
|
||||
</Button>
|
||||
</form>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.email {
|
||||
color: unset;
|
||||
text-decoration: unset;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: calc(768rem / 16)) {
|
||||
.footer {
|
||||
height: calc(120rem / 16);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import Link from "next/link";
|
||||
import React from "react";
|
||||
|
||||
import { SocialLinks } from "./SocialLinks";
|
||||
|
@ -9,7 +10,10 @@ export function Footer() {
|
|||
<footer className={styles.footer}>
|
||||
<div className={styles.container}>
|
||||
<div className={styles.text}>
|
||||
Have questions? Email us at XX@XXX.COM
|
||||
Have questions? Email us at{" "}
|
||||
<Link href="mailto:exec@csclub.uwaterloo.ca">
|
||||
<a className={styles.email}>exec@csclub.uwaterloo.ca</a>
|
||||
</Link>
|
||||
</div>
|
||||
<SocialLinks color="white" size="small" />
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.line {
|
||||
display: block;
|
||||
margin: calc(1rem / 16) 0 calc(34rem / 16);
|
||||
margin: calc(34rem / 16) 0;
|
||||
height: calc(1rem / 16);
|
||||
border: none;
|
||||
background-color: var(--primary-heading);
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import React, { ImgHTMLAttributes } from "react";
|
||||
|
||||
export function Image(props: ImgHTMLAttributes<HTMLImageElement>) {
|
||||
if (props.src?.startsWith("http://") || props.src?.startsWith("https://")) {
|
||||
return <img {...props} />;
|
||||
}
|
||||
|
||||
const { src: relativeSrc = "" } = props;
|
||||
|
||||
let absoluteSrc = process.env.NEXT_PUBLIC_BASE_PATH ?? "/";
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
.card {
|
||||
.card > a {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
box-sizing: border-box;
|
||||
padding: calc(16rem / 16);
|
||||
color: var(--purple-2);
|
||||
font-size: 1rem;
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
.card aside {
|
||||
max-width: calc(142rem / 16);
|
||||
margin-right: calc(45rem / 16);
|
||||
margin-right: 1rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
@ -29,6 +30,7 @@
|
|||
margin: 0;
|
||||
margin-top: calc(4rem / 16);
|
||||
font-size: calc(18rem / 16);
|
||||
color: var(--primary-heading);
|
||||
}
|
||||
|
||||
.card section {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import Link from "next/link";
|
||||
import React from "react";
|
||||
|
||||
import { Image } from "./Image";
|
||||
|
@ -5,19 +6,36 @@ import { Image } from "./Image";
|
|||
import styles from "./MiniTechTalkCard.module.css";
|
||||
|
||||
interface MiniTechTalkProps {
|
||||
name: string;
|
||||
short: string;
|
||||
poster?: string;
|
||||
slug: string;
|
||||
title: string;
|
||||
presentors: string[];
|
||||
poster: string;
|
||||
}
|
||||
|
||||
export function MiniTechTalkCard({ name, poster, short }: MiniTechTalkProps) {
|
||||
export function MiniTechTalkCard({
|
||||
slug,
|
||||
title,
|
||||
presentors,
|
||||
poster,
|
||||
}: MiniTechTalkProps) {
|
||||
const presentorsStr = presentors.join(", ");
|
||||
|
||||
return (
|
||||
<article className={styles.card}>
|
||||
<aside>{poster && <Image alt={name} src={poster} />}</aside>
|
||||
<Link href={`/resources/tech-talks/${slug}`}>
|
||||
<a>
|
||||
<aside>
|
||||
<Image
|
||||
alt={`Thumbnail of tech talk by ${presentorsStr}: ${title}`}
|
||||
src={poster}
|
||||
/>
|
||||
</aside>
|
||||
<div className={styles.content}>
|
||||
<h1>{name}</h1>
|
||||
<p>{short}</p>
|
||||
<h1>{title}</h1>
|
||||
<p>{presentorsStr}</p>
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ const menu: Menu = [
|
|||
name: "Services",
|
||||
route: "/resources/services",
|
||||
},
|
||||
{
|
||||
name: "Machine Usage",
|
||||
route: "/resources/machine-usage-agreement",
|
||||
},
|
||||
{
|
||||
name: "Tech Talks",
|
||||
route: "/resources/tech-talks",
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
}
|
||||
|
||||
.selected {
|
||||
background-color: var(--primary-accent-dim);
|
||||
background-color: var(--primary-accent-lightest);
|
||||
color: var(--primary-accent);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
@ -124,7 +124,48 @@
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
.burger {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobileNavTitle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: calc(768rem / 16)) {
|
||||
|
||||
.burger {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
border: none;
|
||||
bottom: calc(32rem / 16);
|
||||
left: calc(16rem / 16);
|
||||
width: calc(62rem / 16);
|
||||
height: calc(57rem / 16);
|
||||
cursor: pointer;
|
||||
z-index: 9;
|
||||
background: var(--primary-accent-light);
|
||||
border-radius: calc(5rem / 16);
|
||||
transition: transform 0.3s ease-in-out;
|
||||
transform: translateY(calc(94rem / 16));
|
||||
padding: calc(11rem / 16) calc(9rem / 16);
|
||||
}
|
||||
|
||||
.burgerVisible {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.burger > svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
stroke: var(--primary-accent);
|
||||
}
|
||||
|
||||
.navItem {
|
||||
width: auto;
|
||||
padding: 0 calc(16rem / 16);
|
||||
}
|
||||
|
||||
.content h1 {
|
||||
font-size: calc(18rem / 16);
|
||||
}
|
||||
|
@ -138,6 +179,52 @@
|
|||
}
|
||||
|
||||
.nav {
|
||||
display: none;
|
||||
position: fixed;
|
||||
|
||||
top: 0;
|
||||
left: 0;
|
||||
overflow-y: auto;
|
||||
z-index: 30;
|
||||
|
||||
margin: 0;
|
||||
background: var(--primary-accent-lighter);
|
||||
width: calc(288rem / 16);
|
||||
|
||||
transform: translateX(-100vw);
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.navMobileBackground {
|
||||
position: fixed;
|
||||
visibility: hidden;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 20;
|
||||
|
||||
background-color: var(--navbar-page-overlay);
|
||||
opacity: 0;
|
||||
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.mobileNavOpen {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.mobileNavTitle {
|
||||
display: flex;
|
||||
font-size: calc(24rem / 16);
|
||||
font-weight: 700;
|
||||
margin: calc(14rem / 16);
|
||||
margin-top: calc(39rem / 16);
|
||||
}
|
||||
|
||||
.show.navMobileBackground {
|
||||
visibility: visible;
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
import NextLink from "next/link";
|
||||
import React, { ReactNode, ComponentType } from "react";
|
||||
import React, {
|
||||
ReactNode,
|
||||
ComponentType,
|
||||
useState,
|
||||
useRef,
|
||||
useEffect,
|
||||
useCallback,
|
||||
} from "react";
|
||||
|
||||
import styles from "./OrganizedContent.module.css";
|
||||
|
||||
|
@ -17,6 +24,7 @@ interface Props {
|
|||
sections: Section[];
|
||||
id: string;
|
||||
children: ReactNode;
|
||||
pageTitle: string;
|
||||
link: Link;
|
||||
}
|
||||
|
||||
|
@ -24,8 +32,10 @@ export function OrganizedContent({
|
|||
sections,
|
||||
id,
|
||||
children,
|
||||
pageTitle,
|
||||
link: Link,
|
||||
}: Props) {
|
||||
const [mobileNavOpen, setMobileNavOpen] = useState(false);
|
||||
const currentIndex = sections.findIndex(
|
||||
({ id: sectionId }) => sectionId === id
|
||||
);
|
||||
|
@ -36,10 +46,34 @@ export function OrganizedContent({
|
|||
|
||||
const section = sections[currentIndex];
|
||||
const isReadAll = section.id === READ_ALL_ID;
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const isVisible = useOnScreen(ref.current);
|
||||
const burgerVisible = useBurger(isVisible);
|
||||
|
||||
useEffect(() => {
|
||||
mobileNavOpen
|
||||
? (document.body.style.overflow = "hidden")
|
||||
: (document.body.style.overflow = "visible");
|
||||
}, [mobileNavOpen]);
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<Nav sections={sections} currentIndex={currentIndex} link={Link} />
|
||||
<div className={styles.wrapper} ref={ref}>
|
||||
<div
|
||||
className={
|
||||
mobileNavOpen
|
||||
? `${styles.navMobileBackground} ${styles.show}`
|
||||
: styles.navMobileBackground
|
||||
}
|
||||
onClick={() => setMobileNavOpen(false)}
|
||||
/>
|
||||
<Nav
|
||||
sections={sections}
|
||||
currentIndex={currentIndex}
|
||||
link={Link}
|
||||
pageTitle={pageTitle}
|
||||
mobileNavOpen={mobileNavOpen}
|
||||
setMobileNavOpen={setMobileNavOpen}
|
||||
/>
|
||||
<div className={styles.content}>
|
||||
{isReadAll ? (
|
||||
children
|
||||
|
@ -57,6 +91,14 @@ export function OrganizedContent({
|
|||
</>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
className={`${styles.burger} ${
|
||||
burgerVisible ? styles.burgerVisible : ""
|
||||
}`}
|
||||
onClick={() => setMobileNavOpen(!mobileNavOpen)}
|
||||
>
|
||||
<Burger />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -65,11 +107,29 @@ interface NavProps {
|
|||
sections: Section[];
|
||||
currentIndex: number;
|
||||
link: Link;
|
||||
pageTitle: string;
|
||||
mobileNavOpen: boolean;
|
||||
setMobileNavOpen: (mobileNavOpen: boolean) => void;
|
||||
}
|
||||
|
||||
function Nav({ sections, currentIndex, link: Link }: NavProps) {
|
||||
function Nav({
|
||||
sections,
|
||||
currentIndex,
|
||||
link: Link,
|
||||
pageTitle,
|
||||
mobileNavOpen,
|
||||
setMobileNavOpen,
|
||||
}: NavProps) {
|
||||
const navStyles = mobileNavOpen
|
||||
? [styles.nav, styles.mobileNavOpen]
|
||||
: [styles.nav];
|
||||
|
||||
return (
|
||||
<nav className={styles.nav}>
|
||||
<nav
|
||||
className={navStyles.join(" ")}
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
>
|
||||
<h1 className={styles.mobileNavTitle}>{pageTitle}</h1>
|
||||
{sections.map((section, index) => {
|
||||
const classNames = [styles.navItem];
|
||||
|
||||
|
@ -82,14 +142,17 @@ function Nav({ sections, currentIndex, link: Link }: NavProps) {
|
|||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
className={classNames.join(" ")}
|
||||
id={section.id}
|
||||
<div
|
||||
onClick={() => {
|
||||
setMobileNavOpen(false);
|
||||
}}
|
||||
key={section.id}
|
||||
>
|
||||
<Link className={classNames.join(" ")} id={section.id}>
|
||||
<span className={styles.marker} />
|
||||
<div>{section.title}</div>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
|
@ -137,6 +200,20 @@ function Footer({ sections, currentIndex, link: Link }: FooterProps) {
|
|||
);
|
||||
}
|
||||
|
||||
function useDebounce(func: () => void, delay = 300) {
|
||||
const timerRef = useRef<number | undefined>(undefined);
|
||||
return useCallback(() => {
|
||||
if (timerRef.current != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
timerRef.current = window.setTimeout(() => {
|
||||
func();
|
||||
timerRef.current = undefined;
|
||||
}, delay);
|
||||
}, [func, delay]);
|
||||
}
|
||||
|
||||
export interface SectionWithContent {
|
||||
section: Section;
|
||||
Content: ComponentType;
|
||||
|
@ -216,3 +293,91 @@ function Arrow({ direction }: { direction: "left" | "right" }) {
|
|||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function useOnScreen(element: HTMLDivElement | null) {
|
||||
const [isIntersecting, setIntersecting] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(([entry]) =>
|
||||
setIntersecting(entry.isIntersecting)
|
||||
);
|
||||
|
||||
if (element) {
|
||||
observer.observe(element);
|
||||
}
|
||||
// Remove the observer as soon as the component is unmounted
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [element]);
|
||||
|
||||
return isIntersecting;
|
||||
}
|
||||
|
||||
function useBurger(componentIsVisible: boolean): boolean {
|
||||
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
||||
const [burgerVisible, setBurgerVisible] = useState(true);
|
||||
|
||||
const handleScroll = useDebounce(() => {
|
||||
// find current scroll position
|
||||
const currentScrollPos = window.pageYOffset;
|
||||
setBurgerVisible(
|
||||
componentIsVisible &&
|
||||
((prevScrollPos > currentScrollPos &&
|
||||
prevScrollPos - currentScrollPos > 70) ||
|
||||
currentScrollPos < 10)
|
||||
);
|
||||
|
||||
// set state to new scroll position
|
||||
setPrevScrollPos(currentScrollPos);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, [handleScroll]);
|
||||
|
||||
return burgerVisible;
|
||||
}
|
||||
|
||||
// Inlining this svg because we want to fill in colors using css variables
|
||||
function Burger() {
|
||||
return (
|
||||
<svg
|
||||
width="30"
|
||||
height="23"
|
||||
viewBox="0 0 30 23"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<line
|
||||
x1="28"
|
||||
y1="2"
|
||||
x2="2"
|
||||
y2="2"
|
||||
strokeWidth="4"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<line
|
||||
x1="28"
|
||||
y1="11.375"
|
||||
x2="2"
|
||||
y2="11.375"
|
||||
strokeWidth="4"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<line
|
||||
x1="28"
|
||||
y1="20.75"
|
||||
x2="2"
|
||||
y2="20.75"
|
||||
strokeWidth="4"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,15 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.imageRight {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.imageRight .header {
|
||||
text-align: left;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: calc(768rem / 16)) {
|
||||
.headerContainer {
|
||||
flex-direction: column;
|
||||
|
@ -34,4 +43,8 @@
|
|||
.headerImage {
|
||||
width: calc(100rem / 16);
|
||||
}
|
||||
|
||||
.description {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,29 @@ export interface Props {
|
|||
title: string;
|
||||
image: string;
|
||||
children: ReactNode;
|
||||
description?: string;
|
||||
imagePosition?: "left" | "right";
|
||||
}
|
||||
|
||||
export function Header({ title, image, children }: Props) {
|
||||
export function Header({
|
||||
title,
|
||||
image,
|
||||
children,
|
||||
description,
|
||||
imagePosition,
|
||||
}: Props) {
|
||||
return (
|
||||
<main className={styles.page}>
|
||||
<header className={styles.headerContainer}>
|
||||
<header
|
||||
className={`${styles.headerContainer} ${
|
||||
imagePosition === "right" ? styles.imageRight : ""
|
||||
}`}
|
||||
>
|
||||
<Image src={image} className={styles.headerImage} />
|
||||
<div>
|
||||
<h1 className={styles.header}>{title}</h1>
|
||||
{description && <p className={styles.description}>{description}</p>}
|
||||
</div>
|
||||
</header>
|
||||
{children}
|
||||
</main>
|
||||
|
|
|
@ -8,6 +8,8 @@ import {
|
|||
OrganizedContent,
|
||||
} from "@/components/OrganizedContent";
|
||||
|
||||
import { GetShapesConfig } from "../ShapesBackground";
|
||||
|
||||
import { Header } from "./Header";
|
||||
|
||||
export interface SerializedSection {
|
||||
|
@ -26,13 +28,24 @@ export interface Options {
|
|||
pagePath: string;
|
||||
title: string;
|
||||
image: string;
|
||||
getShapesConfig?: GetShapesConfig;
|
||||
imagePosition?: "left" | "right";
|
||||
link?: ComponentType<LinkProps>;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export function createReadAllPage({ title, image, pagePath, link }: Options) {
|
||||
export function createReadAllPage({
|
||||
title,
|
||||
image,
|
||||
pagePath,
|
||||
getShapesConfig,
|
||||
link,
|
||||
description,
|
||||
imagePosition,
|
||||
}: Options) {
|
||||
const Link = link ?? createLink(pagePath);
|
||||
|
||||
return function Page({ sections }: Props) {
|
||||
function Page({ sections }: Props) {
|
||||
const readAllSection = createReadAllSection(
|
||||
sections.map(({ section, content }) => ({
|
||||
section,
|
||||
|
@ -44,18 +57,28 @@ export function createReadAllPage({ title, image, pagePath, link }: Options) {
|
|||
);
|
||||
|
||||
return (
|
||||
<Header title={title} image={image}>
|
||||
<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}
|
||||
>
|
||||
<readAllSection.Content />
|
||||
</OrganizedContent>
|
||||
</Header>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Page.getShapesConfig = getShapesConfig;
|
||||
|
||||
return Page;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
import { MDXRemote, MDXRemoteSerializeResult } from "next-mdx-remote";
|
||||
import React, { ComponentType } from "react";
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
createLink,
|
||||
LinkProps,
|
||||
OrganizedContent,
|
||||
} from "@/components/OrganizedContent";
|
||||
import { createLink, OrganizedContent } from "@/components/OrganizedContent";
|
||||
|
||||
import { Header } from "./Header";
|
||||
import { Options } from "./ReadAll";
|
||||
|
||||
interface Section {
|
||||
id: string;
|
||||
|
@ -20,27 +17,38 @@ export interface Props {
|
|||
current: number;
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
title: string;
|
||||
pagePath: string;
|
||||
image: string;
|
||||
link?: ComponentType<LinkProps>;
|
||||
}
|
||||
|
||||
export function createSectionPage({ title, image, pagePath, link }: Options) {
|
||||
export function createSectionPage({
|
||||
title,
|
||||
image,
|
||||
pagePath,
|
||||
getShapesConfig,
|
||||
link,
|
||||
description,
|
||||
imagePosition,
|
||||
}: Options) {
|
||||
const Link = link ?? createLink(pagePath);
|
||||
|
||||
return function Page(this: void, { content, sections, current }: Props) {
|
||||
function Page(this: void, { content, sections, current }: Props) {
|
||||
return (
|
||||
<Header title={title} image={image}>
|
||||
<Header
|
||||
title={title}
|
||||
image={image}
|
||||
description={description}
|
||||
imagePosition={imagePosition}
|
||||
>
|
||||
<OrganizedContent
|
||||
sections={sections}
|
||||
id={sections[current].id}
|
||||
pageTitle={title}
|
||||
link={Link}
|
||||
>
|
||||
<MDXRemote {...content} />
|
||||
</OrganizedContent>
|
||||
</Header>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Page.getShapesConfig = getShapesConfig;
|
||||
|
||||
return Page;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
.pre {
|
||||
padding: calc(10rem / 16);
|
||||
background: var(--code-background);
|
||||
overflow-x: auto;
|
||||
border-radius: calc(5rem / 16);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import React, { HTMLAttributes } from "react";
|
||||
|
||||
import styles from "./Pre.module.css";
|
||||
|
||||
export function Pre(props: HTMLAttributes<HTMLPreElement>) {
|
||||
const classes = [styles.pre, props.className ?? ""];
|
||||
|
||||
return <pre {...props} className={classes.join(" ")} />;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
.shapesContainer {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -10;
|
||||
}
|
||||
|
||||
.shape {
|
||||
--blue: invert(53%) sepia(80%) saturate(4689%) hue-rotate(189deg)
|
||||
brightness(92%) contrast(93%);
|
||||
--teal: invert(76%) sepia(39%) saturate(578%) hue-rotate(110deg)
|
||||
brightness(91%) contrast(88%);
|
||||
|
||||
position: absolute;
|
||||
filter: var(--blue);
|
||||
opacity: 20%;
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
import { useWindowDimension } from "hooks/useWindowDimension";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { CSSProperties, useEffect, useRef, useState } from "react";
|
||||
|
||||
import { Image } from "./Image";
|
||||
|
||||
import styles from "./ShapesBackground.module.css";
|
||||
|
||||
const MOBILE_WIDTH = 768;
|
||||
|
||||
interface Props {
|
||||
getConfig?: GetShapesConfig;
|
||||
}
|
||||
|
||||
export function ShapesBackground({ getConfig }: Props) {
|
||||
const [config, setConfig] = useState<ShapesConfig>({});
|
||||
const [prevWidth, setPrevWidth] = useState<number>(-1);
|
||||
const [prevRoute, setPrevRoute] = useState<string>("");
|
||||
const { width, height } = useWindowDimension();
|
||||
const shapesContainerRef = useRef<HTMLDivElement>(null);
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
const containerWidth = shapesContainerRef.current?.offsetWidth;
|
||||
const containerHeight = shapesContainerRef.current?.offsetHeight;
|
||||
|
||||
// In general, rerun getShapesConfig() if the screen size changes from desktop to mobile (or vice versa)
|
||||
if (
|
||||
containerWidth == null ||
|
||||
containerHeight == null ||
|
||||
!(
|
||||
router.asPath === "/" ||
|
||||
router.asPath !== prevRoute ||
|
||||
prevWidth < 0 ||
|
||||
(prevWidth <= MOBILE_WIDTH && MOBILE_WIDTH < width) ||
|
||||
(prevWidth > MOBILE_WIDTH && MOBILE_WIDTH >= width)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
setPrevWidth(width);
|
||||
setPrevRoute(router.asPath);
|
||||
setConfig(getConfig?.(containerWidth, containerHeight) ?? {});
|
||||
}, [getConfig, width, height, prevWidth, prevRoute, router.asPath]);
|
||||
|
||||
return (
|
||||
<div className={styles.shapesContainer} ref={shapesContainerRef}>
|
||||
{Object.entries(config).map(([type, instances]) =>
|
||||
instances.map((attributes, idx) => (
|
||||
<Shape
|
||||
key={idx.toString() + type}
|
||||
type={type as ShapeType}
|
||||
style={attributes}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Shape(props: { type: ShapeType; style: CSSProperties }) {
|
||||
return (
|
||||
<Image
|
||||
src={`/images/shapes/${props.type}.svg`}
|
||||
className={styles.shape}
|
||||
style={props.style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export type ShapeType =
|
||||
| "asterisk"
|
||||
| "circle"
|
||||
| "cross"
|
||||
| "dots"
|
||||
| "hash"
|
||||
| "plus"
|
||||
| "ring"
|
||||
| "triangle"
|
||||
| "triangleBig"
|
||||
| "waves"
|
||||
| "wavesBig";
|
||||
|
||||
export type ShapesConfig = {
|
||||
[key in ShapeType]?: CSSProperties[];
|
||||
};
|
||||
|
||||
export type GetShapesConfig = (width: number, height: number) => ShapesConfig;
|
||||
|
||||
type ShapeSize = {
|
||||
[key in ShapeType]: {
|
||||
size: "big" | "small";
|
||||
width: number;
|
||||
height: number;
|
||||
// 0 <= minAngle, maxAngle <= 180
|
||||
minAngle?: number;
|
||||
maxAngle?: number;
|
||||
};
|
||||
};
|
||||
|
||||
const shapeTypes: ShapeType[] = [
|
||||
"asterisk",
|
||||
"circle",
|
||||
"cross",
|
||||
"dots",
|
||||
"hash",
|
||||
"plus",
|
||||
"ring",
|
||||
"triangle",
|
||||
"triangleBig",
|
||||
"waves",
|
||||
"wavesBig",
|
||||
];
|
||||
|
||||
const shapesSizes: ShapeSize = {
|
||||
asterisk: {
|
||||
size: "big",
|
||||
width: 168,
|
||||
height: 168,
|
||||
},
|
||||
circle: {
|
||||
size: "big",
|
||||
width: 132,
|
||||
height: 132,
|
||||
},
|
||||
cross: {
|
||||
size: "big",
|
||||
width: 150,
|
||||
height: 150,
|
||||
},
|
||||
dots: {
|
||||
size: "big",
|
||||
width: 232,
|
||||
height: 250,
|
||||
},
|
||||
hash: {
|
||||
size: "small",
|
||||
width: 60,
|
||||
height: 60,
|
||||
},
|
||||
plus: {
|
||||
size: "small",
|
||||
width: 48,
|
||||
height: 48,
|
||||
},
|
||||
ring: {
|
||||
size: "small",
|
||||
width: 70,
|
||||
height: 70,
|
||||
},
|
||||
triangle: {
|
||||
size: "small",
|
||||
width: 68,
|
||||
height: 68,
|
||||
minAngle: 15,
|
||||
maxAngle: 26,
|
||||
},
|
||||
triangleBig: {
|
||||
size: "big",
|
||||
width: 138,
|
||||
height: 138,
|
||||
minAngle: 15,
|
||||
maxAngle: 26,
|
||||
},
|
||||
waves: {
|
||||
size: "small",
|
||||
width: 102,
|
||||
height: 50,
|
||||
},
|
||||
wavesBig: {
|
||||
size: "big",
|
||||
width: 252,
|
||||
height: 132,
|
||||
},
|
||||
};
|
||||
|
||||
const shapesBySize = {
|
||||
big: shapeTypes.filter((shape) => shapesSizes[shape]["size"] == "big"),
|
||||
small: shapeTypes.filter((shape) => shapesSizes[shape]["size"] == "small"),
|
||||
};
|
||||
|
||||
// Used to generate random shapes in the margins
|
||||
export const defaultGetShapesConfig = ((pageWidth, pageHeight) => {
|
||||
if (window.innerWidth <= MOBILE_WIDTH) {
|
||||
return mobileShapesConfig;
|
||||
}
|
||||
|
||||
const defaultConfig: ShapesConfig = {};
|
||||
const gap = 20;
|
||||
const minBoxWidth = 150;
|
||||
const boxWidth = Math.max(minBoxWidth, (pageWidth - 800 - 2 * gap) / 2);
|
||||
const boxHeight = 400;
|
||||
const shapeGenerationProbability = 0.85;
|
||||
|
||||
for (let y = 0; y + boxHeight <= pageHeight; y += gap + boxHeight) {
|
||||
for (let x = 0; x <= 1; ++x) {
|
||||
if (Math.random() > shapeGenerationProbability) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const size =
|
||||
boxWidth > minBoxWidth && (y == 0 || y + 2 * boxHeight > pageHeight)
|
||||
? "big"
|
||||
: "small";
|
||||
const shape: ShapeType = getRandomShape(size);
|
||||
const verticalOffset = getVerticalOffset(boxHeight, shape);
|
||||
const horizontalOffset = getHorizontalOffset(boxWidth - 2 * gap, shape);
|
||||
const shapeWidth = shapesSizes[shape]["width"];
|
||||
const shapeHeight = shapesSizes[shape]["height"];
|
||||
const angle = getRandomAngle(shape);
|
||||
const colour = getRandomColour();
|
||||
const opacity = getRandomOpacity(colour);
|
||||
|
||||
defaultConfig[shape] ??= [];
|
||||
defaultConfig[shape]?.push({
|
||||
top: `${((y + verticalOffset) / 16).toFixed(5)}rem`,
|
||||
left:
|
||||
x == 0
|
||||
? `${(((horizontalOffset + gap) / window.innerWidth) * 100).toFixed(
|
||||
5
|
||||
)}vw`
|
||||
: "unset",
|
||||
right:
|
||||
x == 1
|
||||
? `${(((horizontalOffset + gap) / window.innerWidth) * 100).toFixed(
|
||||
5
|
||||
)}vw`
|
||||
: "unset",
|
||||
width: `${(shapeWidth / 16).toFixed(5)}rem`,
|
||||
height: `${(shapeHeight / 16).toFixed(5)}rem`,
|
||||
transform: `rotate(${angle}deg)`,
|
||||
filter: `var(--${colour})`,
|
||||
opacity: `${opacity}%`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return defaultConfig;
|
||||
}) as GetShapesConfig;
|
||||
|
||||
function getRandomShape(size: "big" | "small"): ShapeType {
|
||||
const idx = Math.floor(Math.random() * shapesBySize[size].length);
|
||||
return shapesBySize[size][idx];
|
||||
}
|
||||
|
||||
function getVerticalOffset(boxHeight: number, shape: ShapeType): number {
|
||||
const padding = shapesSizes[shape]["height"];
|
||||
return Math.floor(Math.random() * (boxHeight - padding));
|
||||
}
|
||||
|
||||
function getHorizontalOffset(boxWidth: number, shape: ShapeType): number {
|
||||
const padding = shapesSizes[shape]["width"];
|
||||
return shapesSizes[shape]["size"] == "big"
|
||||
? Math.floor(Math.random() * (boxWidth - padding / 2) - padding / 2)
|
||||
: Math.floor(Math.random() * (boxWidth - padding));
|
||||
}
|
||||
|
||||
function getRandomAngle(shape: ShapeType): number {
|
||||
const minAngle = shapesSizes[shape]["minAngle"] ?? 0;
|
||||
const maxAngle = shapesSizes[shape]["maxAngle"] ?? 0;
|
||||
const direction = Math.random() < 0.5 ? 1 : -1;
|
||||
return (
|
||||
(minAngle + Math.floor(Math.random() * (maxAngle - minAngle + 1))) *
|
||||
direction
|
||||
);
|
||||
}
|
||||
|
||||
function getRandomColour(): "blue" | "teal" {
|
||||
return Math.random() < 0.7 ? "blue" : "teal";
|
||||
}
|
||||
|
||||
function getRandomOpacity(colour: "blue" | "teal"): number {
|
||||
if (colour === "blue") {
|
||||
return Math.random() < 0.8 ? 20 : 25;
|
||||
} else {
|
||||
return Math.random() < 0.8 ? 25 : 30;
|
||||
}
|
||||
}
|
||||
|
||||
// Used for most mobile pages
|
||||
export const mobileShapesConfig = {
|
||||
dots: [
|
||||
{
|
||||
top: "calc(-6rem / 16)",
|
||||
left: "calc(-95rem / 16)",
|
||||
width: "calc(166rem / 16)",
|
||||
height: "calc(150rem / 16)",
|
||||
},
|
||||
],
|
||||
hash: [
|
||||
{
|
||||
top: "calc(88rem / 16)",
|
||||
right: "15vw",
|
||||
width: "calc(40rem / 16)",
|
||||
height: "calc(40rem / 16)",
|
||||
},
|
||||
],
|
||||
triangle: [
|
||||
{
|
||||
top: "calc(20rem / 16)",
|
||||
right: "1vw",
|
||||
width: "calc(45rem / 16)",
|
||||
height: "calc(45rem / 16)",
|
||||
transform: "rotate(17deg)",
|
||||
},
|
||||
],
|
||||
};
|
|
@ -24,11 +24,31 @@
|
|||
font-style: normal;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
color: var(--blue-2);
|
||||
color: var(--primary-accent);
|
||||
}
|
||||
|
||||
.content h2,
|
||||
.content h3,
|
||||
.content h4 {
|
||||
font-size: calc(18rem / 16);
|
||||
}
|
||||
|
||||
@media only screen and (max-width: calc(768rem / 16)) {
|
||||
.card {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card aside {
|
||||
margin: 0;
|
||||
margin-bottom: 1rem;
|
||||
flex: unset;
|
||||
}
|
||||
|
||||
.card aside img {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.content ul {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,57 @@
|
|||
import React, { ReactNode } from "react";
|
||||
|
||||
import { Image } from "./Image";
|
||||
import { Link } from "./Link";
|
||||
|
||||
import styles from "./TechTalkCard.module.css";
|
||||
|
||||
interface DownloadLink {
|
||||
file: string;
|
||||
type: string;
|
||||
size?: string;
|
||||
}
|
||||
|
||||
interface TechTalkProps {
|
||||
name: string;
|
||||
poster?: string;
|
||||
title: string;
|
||||
presentors: string[];
|
||||
poster: string;
|
||||
links: DownloadLink[];
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function TechTalkCard({ name, poster, children }: TechTalkProps) {
|
||||
export function TechTalkCard({
|
||||
title,
|
||||
poster,
|
||||
presentors,
|
||||
links,
|
||||
children,
|
||||
}: TechTalkProps) {
|
||||
return (
|
||||
<article className={styles.card}>
|
||||
<aside>
|
||||
{poster && <Image alt={name} src={poster} />}
|
||||
{!poster && <div className={styles.spacer}></div>}
|
||||
<Image
|
||||
alt={`Thumbnail of tech talk by ${presentors.join(", ")}: ${title}`}
|
||||
src={poster}
|
||||
/>
|
||||
</aside>
|
||||
<section className={styles.content}>
|
||||
<h1>{name}</h1>
|
||||
<h1>{title}</h1>
|
||||
<div>{children}</div>
|
||||
|
||||
<h2>Download:</h2>
|
||||
<ul>
|
||||
{links.map((link) => (
|
||||
<li key={link.file + link.type}>
|
||||
<DownloadLink {...link} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
function DownloadLink({ file, type, size }: DownloadLink) {
|
||||
const text = size ? `${type} (${size})` : type;
|
||||
return <Link href={file}>{text}</Link>;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ export const PALETTE_NAMES = [
|
|||
"--primary-accent",
|
||||
"--primary-accent-soft",
|
||||
"--primary-accent-light",
|
||||
"--primary-accent-dim",
|
||||
"--primary-accent-lighter",
|
||||
"--primary-accent-lightest",
|
||||
|
||||
"--secondary-accent",
|
||||
"--secondary-accent-light",
|
||||
|
@ -38,6 +39,8 @@ export const PALETTE_NAMES = [
|
|||
"--input-placeholder-text",
|
||||
"--input-text",
|
||||
|
||||
"--code-background",
|
||||
|
||||
"--navbar-page-overlay",
|
||||
] as const;
|
||||
|
||||
|
|
|
@ -238,16 +238,25 @@ export function OrganizedContentDemo() {
|
|||
)!.Content;
|
||||
|
||||
return (
|
||||
<OrganizedContent sections={sections} id={id} link={FakeLink}>
|
||||
<OrganizedContent
|
||||
sections={sections}
|
||||
id={id}
|
||||
link={FakeLink}
|
||||
pageTitle="Playground"
|
||||
>
|
||||
<Content />
|
||||
</OrganizedContent>
|
||||
);
|
||||
}
|
||||
|
||||
export function TechTalkDemo() {
|
||||
const poster =
|
||||
tempTechTalkMetadata.thumbnails.large ??
|
||||
tempTechTalkMetadata.thumbnails.small;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<TechTalkCard {...tempTechTalkMetadata}>
|
||||
<TechTalkCard {...tempTechTalkMetadata} poster={poster}>
|
||||
<TempTechTalk />
|
||||
</TechTalkCard>
|
||||
</div>
|
||||
|
@ -257,15 +266,18 @@ export function TechTalkDemo() {
|
|||
export function MiniTechTalkDemo() {
|
||||
return (
|
||||
<div className={styles.miniTechTalkDemo}>
|
||||
<MiniTechTalkCard {...tempTechTalkMetadata}>
|
||||
<TempTechTalk />
|
||||
</MiniTechTalkCard>
|
||||
<MiniTechTalkCard {...tempTechTalkMetadata}>
|
||||
<TempTechTalk />
|
||||
</MiniTechTalkCard>
|
||||
<MiniTechTalkCard {...tempTechTalkMetadata}>
|
||||
<TempTechTalk />
|
||||
</MiniTechTalkCard>
|
||||
<MiniTechTalkCard
|
||||
{...tempTechTalkMetadata}
|
||||
poster={tempTechTalkMetadata.thumbnails.small}
|
||||
/>
|
||||
<MiniTechTalkCard
|
||||
{...tempTechTalkMetadata}
|
||||
poster={tempTechTalkMetadata.thumbnails.small}
|
||||
/>
|
||||
<MiniTechTalkCard
|
||||
{...tempTechTalkMetadata}
|
||||
poster={tempTechTalkMetadata.thumbnails.small}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,4 +5,4 @@ index: 10
|
|||
|
||||
Additionally, the Executive Council are available to help Club members engage with local law enforcement or to otherwise help those experiencing unacceptable behaviour feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress.
|
||||
|
||||
Changes to the Code of Conduct are governed by the Club's [constitution](https://csclub.uwaterloo.ca/about/constitution).
|
||||
Changes to the Code of Conduct are governed by the Club's [constitution](/about/constitution).
|
||||
|
|
|
@ -3,4 +3,4 @@ title: Contact Information
|
|||
index: 9
|
||||
---
|
||||
|
||||
- The Computer Science Club [Officers can be contacted as a whole](https://csclub.uwaterloo.ca/about/).
|
||||
- The Computer Science Club [Officers can be contacted as a whole](/about).
|
||||
|
|
|
@ -5,7 +5,7 @@ index: 4
|
|||
|
||||
_The Executive Council and Faculty Advisor are herein referred to as the Officers, or singularly as Officer._
|
||||
|
||||
If you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, [contact an Officer](https://csclub.uwaterloo.ca/about/). No situation is considered inconsequential. If you do not feel comfortable contacting an Executive Council member due to the nature of the incident, you may contact the [Faculty Advisor](https://csclub.uwaterloo.ca/about/exec#advisor).
|
||||
If you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, [contact an Officer](/about). No situation is considered inconsequential. If you do not feel comfortable contacting an Executive Council member due to the nature of the incident, you may contact the [Faculty Advisor](/about#advisor).
|
||||
|
||||
Upon receiving a complaint the Officer will inform the first of the following people who is not personally involved in the situation, or in a close relationship with the someone involved in the situation and is available, and this person shall handle the complaint and shall here after be referred to as the Handling Officer.
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@ title: 12. Code of Conduct
|
|||
index: 12
|
||||
---
|
||||
|
||||
1. The Club has a [Code of Conduct](https://csclub.uwaterloo.ca/about/code-of-conduct).
|
||||
2. The [scope of the Code of Conduct](https://csclub.uwaterloo.ca/about/code-of-conduct/scopes-and-spaces) is specified by the Code of Conduct.
|
||||
1. The Club has a [Code of Conduct](/about/code-of-conduct).
|
||||
2. The [scope of the Code of Conduct](/about/code-of-conduct/scopes-and-spaces) is specified by the Code of Conduct.
|
||||
3. Changes to the Code of Conduct are governed by the same rules as changes to the Constitution.
|
||||
|
|
|
@ -14,10 +14,10 @@ a bunch of ways you can join and help out.
|
|||
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)
|
||||
2. Sign our [Machine Usage Agreement](/resources/machine-usage-agreement)
|
||||
|
||||
That's all! After your account created, you'll have access to all the
|
||||
[services](https://csclub.uwaterloo.ca/services/) available to members.
|
||||
[services](/resources/services) available to members.
|
||||
|
||||
#### Membership Renewal
|
||||
|
||||
|
@ -36,7 +36,7 @@ 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).
|
||||
[Machine Usage Agreement](/resources/machine-usage-agreement).
|
||||
|
||||
#### Membership Renewal
|
||||
|
||||
|
@ -82,4 +82,4 @@ Each term the CSC holds elections to determine the executive council.
|
|||
|
||||
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).
|
||||
For details on the elections, see the [Constitution](/about/constitution).
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sjdutoit'
|
||||
date: 'Mon Sep 16 2002 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The Fall elections have occured and the [results](</about/exec>) are in.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sjdutoit"
|
||||
date: "2002-09-16"
|
||||
---
|
||||
|
||||
The Fall elections have occured and the [results](</about/exec>) are in.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sjdutoit"
|
||||
date: "2002-09-18"
|
||||
author: 'sjdutoit'
|
||||
date: 'Wed Sep 18 2002 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
We've changed to the new site! Please send your comments to the [webmaster](<mailto:webmaster@csclub.uwaterloo.ca>). The [old site](</old/>) is still available. A few things may not be working quite right yet, but I'm working on it.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sjdutoit"
|
||||
date: "2002-09-30"
|
||||
author: 'sjdutoit'
|
||||
date: 'Mon Sep 30 2002 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The business meeting of 2002-09-30 was concluded and the [constitutional change](</about/constitution-change-20020920>) was approved with a 14:2 majority (and one spoiled ballot). See the new [constitution](</about/constitution>).
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sjdutoit"
|
||||
date: "2002-10-29"
|
||||
author: 'sjdutoit'
|
||||
date: 'Tue Oct 29 2002 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
Due to lack of time for preparation, the Romp Through The Linux Kernel talks were cancelled. Sorry for the inconvenience. Hopefully these talks will happen next term.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sjdutoit'
|
||||
date: 'Sun Feb 03 2002 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
XML goodness.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sjdutoit"
|
||||
date: "2002-02-03"
|
||||
---
|
||||
|
||||
XML goodness.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sjdutoit'
|
||||
date: 'Mon Feb 04 2002 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
About/Memberlist stub up. Made the CSC logo gold. Isn't it nifty?
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sjdutoit"
|
||||
date: "2002-02-04"
|
||||
---
|
||||
|
||||
About/Memberlist stub up. Made the CSC logo gold. Isn't it nifty?
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sjdutoit"
|
||||
date: "2002-04-15"
|
||||
author: 'sjdutoit'
|
||||
date: 'Mon Apr 15 2002 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
Added the [membership list](</about/members>). [Old events](</events/old>) are working. Event terms, as well as the current term are determined automagically now. Lots of work done. Some more stubs up (office etc.). And I introduce cow - that is, the CSC Ontological Webalizer - which is just a wrapper around libxslt with some extra xpath functions. It is now what is being used to build the site, instead of xsltproc.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sjdutoit"
|
||||
date: "2002-04-22"
|
||||
author: 'sjdutoit'
|
||||
date: 'Mon Apr 22 2002 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
Added [books](<http://library.csclub.uwaterloo.ca/>)! About 2.5 shelves are there, minus a whole lot that weren't readily accessible from the Library of Congress. Getting all of the books on there is going to be a tough job. These are, by the way, managed by good-old (or new?) CEO. Thanks to Ryan Golbeck and Petio for their hard work getting ISBN numbers onto disc.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sfllaw'
|
||||
date: 'Wed Sep 17 2003 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The CSC elections took place and we have a new [executive](</about/exec>) for Fall 2003.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2003-09-17"
|
||||
---
|
||||
|
||||
The CSC elections took place and we have a new [executive](</about/exec>) for Fall 2003.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sjdutoit'
|
||||
date: 'Wed May 14 2003 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The CSC elections took place and we have a new [executive](</about/exec>) for Spring 2003.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sjdutoit"
|
||||
date: "2003-05-14"
|
||||
---
|
||||
|
||||
The CSC elections took place and we have a new [executive](</about/exec>) for Spring 2003.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2003-06-05"
|
||||
author: 'sfllaw'
|
||||
date: 'Thu Jun 05 2003 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
We have a new computer called `glucose-fructose`, or `sugar` for short. As a result, `carbonated-water` is temporarily out of service, although it should return within a month.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sfllaw'
|
||||
date: 'Thu Jul 03 2003 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
We have been notified by the Guelph Computer Club that they are unable to host our group event. Sorry for the inconvenience.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2003-07-03"
|
||||
---
|
||||
|
||||
We have been notified by the Guelph Computer Club that they are unable to host our group event. Sorry for the inconvenience.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "ja2morri"
|
||||
date: "2003-07-09"
|
||||
author: 'ja2morri'
|
||||
date: 'Wed Jul 09 2003 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
Jim Elliott gave a great talk for the CSC yesterday and has put his slides online.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "ja2morri"
|
||||
date: "2003-08-06"
|
||||
author: 'ja2morri'
|
||||
date: 'Wed Aug 06 2003 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
We've finally gotten around to disabling accounts. If you find your account has been improperly disabled please email [the executive](<mailto:exec@csclub.uwaterloo.ca>). We are keeping a back up of the files and mail for each disabled account for a short period of time.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "ja2morri"
|
||||
date: "2003-08-12"
|
||||
author: 'ja2morri'
|
||||
date: 'Tue Aug 12 2003 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The [CSC Procedures manual](<http://wiki.csclub.uwaterloo.ca/wiki/Exec_Manual>) has been added to the website. Thanks go to Shannon Mann for reminding us of this document.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sfllaw'
|
||||
date: 'Mon Jan 13 2003 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
The CSC elections took place and we have a new [executive](</about/exec>) for Winter 2003.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2003-01-13"
|
||||
---
|
||||
|
||||
The CSC elections took place and we have a new [executive](</about/exec>) for Winter 2003.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "mbiggs"
|
||||
date: "2004-09-15"
|
||||
author: 'mbiggs'
|
||||
date: 'Wed Sep 15 2004 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
[Here](<http://mirror.csclub.uwaterloo.ca/csclub/buss-talk.mp3>) is the audio for Professor Buss' talk: Game Complexity Theorists Ponder, in mp3 format. Enjoy!
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'jeperry'
|
||||
date: 'Mon Sep 27 2004 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The Fall 2004 elections have occured. We have a new [executive](</about/exec>).
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "jeperry"
|
||||
date: "2004-09-27"
|
||||
---
|
||||
|
||||
The Fall 2004 elections have occured. We have a new [executive](</about/exec>).
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'jeperry'
|
||||
date: 'Sat Oct 23 2004 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The F04 CSC Programming Contest is underway. Go to [the website](</~contest/>) for more information.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "jeperry"
|
||||
date: "2004-10-23"
|
||||
---
|
||||
|
||||
The F04 CSC Programming Contest is underway. Go to [the website](</~contest/>) for more information.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'mbiggs'
|
||||
date: 'Wed May 12 2004 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The CSC elections took place and we have a new [executive](</about/exec>) for Spring 2004.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "mbiggs"
|
||||
date: "2004-05-12"
|
||||
---
|
||||
|
||||
The CSC elections took place and we have a new [executive](</about/exec>) for Spring 2004.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "zbnichol"
|
||||
date: "2004-05-31"
|
||||
author: 'zbnichol'
|
||||
date: 'Mon May 31 2004 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
Audio has been added for the Larry Smith talk: Computing's Next Great Empires. It is available [in Ogg format](<http://mirror.csclub.uwaterloo.ca/csclub/larry-smith-talk.ogg>) or [in MP3 format](<http://mirror.csclub.uwaterloo.ca/csclub/larry-smith-talk.mp3>). Thanks to all who came out. The talk was a great success.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sfllaw'
|
||||
date: 'Thu Jan 22 2004 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
The CSC elections took place and we have a new [executive](</about/exec>) for Winter 2004.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2004-01-22"
|
||||
---
|
||||
|
||||
The CSC elections took place and we have a new [executive](</about/exec>) for Winter 2004.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sfllaw'
|
||||
date: 'Sun Jan 25 2004 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
`carbonated-water`, `h2o`, is back down. It's awaiting a new power supply.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2004-01-25"
|
||||
---
|
||||
|
||||
`carbonated-water`, `h2o`, is back down. It's awaiting a new power supply.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2004-02-02"
|
||||
author: 'sfllaw'
|
||||
date: 'Mon Feb 02 2004 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
`perpugilliam` went down over the weekend due to a failing disk. Please back up all your important data as it is starting to go bad. We are trying to acquire a replacement.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2004-02-05"
|
||||
author: 'sfllaw'
|
||||
date: 'Thu Feb 05 2004 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
We voted 15 to 0 to 0 in favour of changing the [constitution](</about/constitution>) to follow MathSoc policy. An updated copy of the document is now online.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sfllaw'
|
||||
date: 'Tue Mar 16 2004 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
The books that we purchased have arrived. Now we have two books that can be signed by Kernighan when he comes.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2004-03-16"
|
||||
---
|
||||
|
||||
The books that we purchased have arrived. Now we have two books that can be signed by Kernighan when he comes.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2004-03-19"
|
||||
author: 'sfllaw'
|
||||
date: 'Fri Mar 19 2004 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
Kernighan came to Waterloo, and the Computer Science Club got our books signed by him. Not only that, but we took [photographs of him](<http://www.csclub.uwaterloo.ca/gallery/kernighan-2004>) too.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2004-04-01"
|
||||
author: 'sfllaw'
|
||||
date: 'Thu Apr 01 2004 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
`glucose-fructose` will be going down for hardware upgrades on 2004-04-02 for an indeterminate amount of time. We thank MathSoc and MEF for their generous support in purchasing this hardware, and apologise for any inconvenience this downtime will cause.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'sfllaw'
|
||||
date: 'Fri Apr 02 2004 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
`glucose-fructose` is back on-line. It has a new 120 GB hard disk, a new power supply, and an nVidia GeForce FX 5900.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2004-04-02"
|
||||
---
|
||||
|
||||
`glucose-fructose` is back on-line. It has a new 120 GB hard disk, a new power supply, and an nVidia GeForce FX 5900.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'mbiggs'
|
||||
date: 'Wed Apr 07 2004 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
Pictures of [CTRL-D](<http://www.csclub.uwaterloo.ca/gallery/ctrl-d-w2004>) are available in the gallery.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "mbiggs"
|
||||
date: "2004-04-07"
|
||||
---
|
||||
|
||||
Pictures of [CTRL-D](<http://www.csclub.uwaterloo.ca/gallery/ctrl-d-w2004>) are available in the gallery.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2004-04-16"
|
||||
author: 'sfllaw'
|
||||
date: 'Fri Apr 16 2004 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
`perpugilliam` will be going down for hardware upgrades on 2004-04-16 to 2004-04-19. We thank MathSoc and MEF for their generous support in purchasing this hardware, and apologise for any inconvenience this downtime will cause.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "sfllaw"
|
||||
date: "2004-04-19"
|
||||
author: 'sfllaw'
|
||||
date: 'Mon Apr 19 2004 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
`perpugilliam` has been restored, with two new disks courtesy of MathSoc and MEF. There are now disk quotas for users, with a 250 MB soft quota and a 500 MB hard quota, with a 14-day grace period.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'woconnor'
|
||||
date: 'Thu Sep 21 2006 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The [executive](</about/exec>) has been elected for the Fall 2006 term.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "woconnor"
|
||||
date: "2006-09-21"
|
||||
---
|
||||
|
||||
The [executive](</about/exec>) has been elected for the Fall 2006 term.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'hkarau'
|
||||
date: 'Wed May 10 2006 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The CSC [executive](</about/exec>) for Summer 2006 term has been elected.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "hkarau"
|
||||
date: "2006-05-10"
|
||||
---
|
||||
|
||||
The CSC [executive](</about/exec>) for Summer 2006 term has been elected.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'hkarau'
|
||||
date: 'Fri May 19 2006 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
Larry Smith's talk on Creating Killer applications is now online in our new [ section ](</media/>)(in video :-)).
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "hkarau"
|
||||
date: "2006-05-19"
|
||||
---
|
||||
|
||||
Larry Smith's talk on Creating Killer applications is now online in our new [ section ](</media/>)(in video :-)).
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "hkarau"
|
||||
date: "2006-06-04"
|
||||
author: 'hkarau'
|
||||
date: 'Sun Jun 04 2006 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The BeBox lives again. BeOS is a unique operating system from the same era as Windows 95. If you'd like to see it run, port something to it (we have the developement tools!), or just watch the funny lights on the front of it, stop by the office and take a look
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'ddenisen'
|
||||
date: 'Tue Jan 10 2006 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
The CSC [executive](</about/exec>) for Winter 2006 term has been elected.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "ddenisen"
|
||||
date: "2006-01-10"
|
||||
---
|
||||
|
||||
The CSC [executive](</about/exec>) for Winter 2006 term has been elected.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'dtbartle'
|
||||
date: 'Sat Sep 01 2007 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
Our talks our now mirrored on mirror.cs for ResNet and on-campus users.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "dtbartle"
|
||||
date: "2007-09-01"
|
||||
---
|
||||
|
||||
Our talks our now mirrored on mirror.cs for ResNet and on-campus users.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'dtbartle'
|
||||
date: 'Sun Sep 09 2007 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The Fall 2007 election has been scheduled for Sept 20 at 4:30 pm in the comfy lounge.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "dtbartle"
|
||||
date: "2007-09-09"
|
||||
---
|
||||
|
||||
The Fall 2007 election has been scheduled for Sept 20 at 4:30 pm in the comfy lounge.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'mspang'
|
||||
date: 'Fri May 11 2007 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The [executive](</about/exec>) has been elected for the Spring 2007 term.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "mspang"
|
||||
date: "2007-05-11"
|
||||
---
|
||||
|
||||
The [executive](</about/exec>) has been elected for the Spring 2007 term.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'daltenty'
|
||||
date: 'Fri Jan 12 2007 00:00:00 GMT-0500 (Eastern Standard Time)'
|
||||
---
|
||||
|
||||
The [executive](</about/exec>) has been elected for the Winter 2007 term.
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
author: "daltenty"
|
||||
date: "2007-01-12"
|
||||
---
|
||||
|
||||
The [executive](</about/exec>) has been elected for the Winter 2007 term.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "dtbartle"
|
||||
date: "2008-09-16"
|
||||
author: 'dtbartle'
|
||||
date: 'Tue Sep 16 2008 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
The following people were elected today: - President: m3lawren (Matt Lawrence)
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
author: "dtbartle"
|
||||
date: "2008-05-04"
|
||||
author: 'dtbartle'
|
||||
date: 'Sun May 04 2008 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
Spring 2008 elections will be held on Tuesday May 13th at 4:30pm in the Comfy Lounge.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
author: 'b4taylor'
|
||||
date: 'Fri May 16 2008 01:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||
---
|
||||
|
||||
New positions were elected on Tuesday. Check the exec section to see who won.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue