Merge branch 'main' into b72zhou-nav-bottom

pull/64/head
Beihao Zhou 2 months ago
commit 4b968ea89e
  1. 59
      components/About.module.css
  2. 65
      components/About.tsx
  3. 60
      components/Sections.module.css
  4. 45
      components/Sections.tsx
  5. 75
      components/Timeline.module.css
  6. 142
      components/Timeline.tsx
  7. 27
      data/mocks.ts
  8. 46
      data/routes.ts
  9. 45
      pages/_app.css
  10. 38
      pages/playground.tsx

@ -0,0 +1,59 @@
.aboutWrapper {
position: relative;
width: 90%;
}
.about {
display: flex;
flex-direction: row;
padding: calc(45rem / 16);
}
.about h1 {
margin: 0;
}
.about h4 {
margin: 0;
}
.about aside {
flex: 1;
margin-right: calc(40rem / 16);
}
.about aside h1 {
color: var(--secondary-accent)
}
.about aside p {
color: var(--primary-accent-lighter)
}
.about article {
flex: 3;
}
.about article p {
color: var(--primary-text);
}
.angle {
position: absolute;
top: 0;
left: 0;
width: calc(70rem / 16);
height: calc(70rem / 16);
}
.anglePath {
stroke: var(--primary-accent-light)
}
.left.angle {
transform: rotate(180deg);
top: unset;
left: unset;
bottom: 0;
right: 0;
}

@ -0,0 +1,65 @@
import React from "react";
import styles from "./About.module.css";
export function About() {
return (
<div className={styles.aboutWrapper}>
<AngleDecoration isBottom={false} />
<section className={styles.about}>
<aside>
<h1>About the Programs</h1>
<p>Getting an overview of the CS programs in UW</p>
</aside>
<article>
<h4>Computer Science</h4>
<p>
Offered from the Faculty of Mathematics as most commonly a co-op
program, students usually attend 8 school and 6 co-op terms in their
degree. However, CS is very flexible, as many students historically
have dropped co-ops, taking terms off, and messing with their
schedule to fit their desires.
</p>
<h4>Computing and Financial Management</h4>
<p>
Computing and Financial Management (CFM) combines the core CS
courses with electives from areas such as accounting, economics, and
financial management. This is a joint offer from the Faculty of
Mathematics and the School of Accounting and Finance, and has the
same schedule (and flexibility) as CS.
</p>
<h4>CS/BBA</h4>
<p>
Joint with Wilfrid Laurier University, the Business Administration
and Computer Science Double Degree (CS/BBA) is an exclusive offering
that allows students to get experience in CS as well as many
subfields of business. There are 10 school terms and either 4 or 5
co-op terms in the usual schedule, so its a bit more work than CS
or CFM.
</p>
</article>
</section>
<AngleDecoration isBottom={true} />
</div>
);
}
interface AngleDecorationProps {
isBottom: boolean;
}
function AngleDecoration({ isBottom }: AngleDecorationProps) {
return (
<svg
viewBox="0 0 100 100"
className={isBottom ? `${styles.left} ${styles.angle}` : styles.angle}
>
<path
d="M100,2 L2,2 L2,100"
fill="none"
strokeWidth="10"
className={styles.anglePath}
/>
</svg>
);
}

@ -0,0 +1,60 @@
.sections {
display: flex;
flex-direction: row;
gap: calc(15rem / 16);
}
.sections h1 {
flex: 3;
text-align: right;
margin: 0;
}
.separator {
flex: 1;
background-color: var(--label);
height: calc(1rem / 16);
width: 100%;
margin-top: calc(30rem / 16);
}
.nav {
flex: 3;
display: flex;
flex-direction: column;
}
.nav ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.nav li {
margin: calc(20rem / 16);
margin-left: 0;
}
.nav li:first-child {
margin-top: calc(18rem / 16);
}
.nav li .linkNumber {
color: var(--secondary-accent);
margin: 0;
display: inline;
}
.nav li a {
font-size: calc(24rem / 16);
color: var(--primary-text);
}
.nav li a:hover .linkName {
text-decoration: underline;
}
.nav li .linkName {
margin: 0;
display: inline;
}

@ -0,0 +1,45 @@
import React from "react";
import styles from "./Sections.module.css";
interface SectionsData {
name: string;
url: string;
}
interface SectionsProps {
/* Whether to display the "Sections" title and separator that appears on the left. */
showHeader?: boolean;
data: SectionsData[];
}
export function Sections({ data, showHeader = true }: SectionsProps) {
return (
<section className={styles.sections}>
{showHeader ? (
<>
<h1>Sections</h1>
<div className={styles.separator} />
</>
) : (
""
)}
<nav className={styles.nav}>
<ul>
{data.map((datum, index) => {
return (
<li key={`${datum.name}-${index}`}>
<a href={datum.url}>
<span className={styles.linkNumber}>
{String(index).padStart(2, "0")}{" "}
</span>
<span className={styles.linkName}>{datum.name}</span>
</a>
</li>
);
})}
</ul>
</nav>
</section>
);
}

@ -0,0 +1,75 @@
.wrapper {
position: relative;
}
.line {
position: absolute;
height: 100%;
border-radius: calc(10rem / 16);
background-color: var(--secondary-accent);
z-index: -1;
}
.timelineSections {
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
gap: calc(20rem / 16);
}
.timelineSection {
width: 100%;
display: flex;
flex-direction: row;
justify-content: center;
}
.time {
margin: 0;
text-align: right;
font-size: calc(30rem / 16);
font-weight: 700;
color: var(--secondary-accent);
word-wrap: break-word;
}
.circle {
background-color: var(--secondary-accent);
box-shadow: calc(0rem / 16) calc(0rem / 16) calc(30rem / 16) var(--secondary-accent);
display: flex;
justify-content: center;
align-items: center;
}
.innerCircle {
background-color: var(--label);
display: none;
}
.text {
height: fit-content;
margin: 0;
padding: calc(15rem / 16);
border-radius: calc(10rem / 16);
font-size: calc(20rem / 16);
font-weight: 700;
color: var(--label);
border: calc(2rem / 16) solid var(--card-background);
background-color: var(--card-background);
word-wrap: break-word;
box-sizing: border-box;
}
.timelineSection:hover .time {
color: var(--secondary-accent-light);
}
.timelineSection:hover .innerCircle {
display: inline;
}
.timelineSection:hover .text {
border: calc(2rem / 16) solid var(--secondary-accent-light);
box-shadow: calc(0rem / 16) calc(0rem / 16) calc(20rem / 16) var(--secondary-accent);
}

@ -0,0 +1,142 @@
import React from "react";
import styles from "./Timeline.module.css";
interface TimelineData {
time: string;
text: string;
}
interface TimelineProps {
data: TimelineData[];
/** Whether the time is transformed to uppercase. */
isTimeUppercase?: boolean;
/** Width of the middle timeline line, in pixels */
lineWidth?: number;
/** Width of the outer circles on the timeline, in pixels. */
outerCircleWidth?: number;
/** Width of the inner circles on the timeline, in pixels. */
innerCircleWidth?: number;
/** Width of time label, in pixels. */
timeWidth?: number;
/** Width of text label, in pixels. */
textWidth?: number;
/** Distance between the time label AND the text label to middle line, in pixels. */
gap?: number;
className?: string;
}
export function Timeline({
data,
isTimeUppercase = true,
lineWidth = 5,
outerCircleWidth = 30,
innerCircleWidth = 15,
timeWidth = 200,
textWidth = 300,
gap = 50,
className,
}: TimelineProps) {
const largerMiddleElement =
outerCircleWidth > lineWidth ? outerCircleWidth : lineWidth;
const width = timeWidth + gap + largerMiddleElement + gap + textWidth;
if (innerCircleWidth > outerCircleWidth) {
throw new Error(
`<Timeline /> - innerCircleWidth (${innerCircleWidth}) is larger than outerCircleWidth (${outerCircleWidth})`
);
}
return (
<div
className={
className ? `${className} ${styles.wrapper}` : `${styles.wrapper}`
}
style={{ width: width }}
>
<div
className={styles.line}
style={{
width: lineWidth,
left: width / 2 - lineWidth / 2,
}}
/>
<div className={styles.timelineSections}>
{data.map((datum) => (
<TimelineSection
key={datum.time}
datum={datum}
width={width}
isTimeUppercase={isTimeUppercase}
outerCircleWidth={outerCircleWidth}
innerCircleWidth={innerCircleWidth}
timeWidth={timeWidth}
textWidth={textWidth}
gap={gap}
/>
))}
</div>
</div>
);
}
interface TimelineSectionProps {
datum: TimelineData;
width: number;
isTimeUppercase: boolean;
outerCircleWidth: number;
innerCircleWidth: number;
timeWidth: number;
textWidth: number;
gap: number;
}
function TimelineSection({
datum,
width,
isTimeUppercase,
outerCircleWidth,
innerCircleWidth,
timeWidth,
textWidth,
gap,
}: TimelineSectionProps) {
return (
<div className={styles.timelineSection} style={{ gap: gap }}>
<div
className={styles.time}
style={{
width: timeWidth,
marginLeft: (width - 2 * gap - outerCircleWidth) / 2 - timeWidth,
}}
>
{isTimeUppercase ? datum.time.toUpperCase() : datum.time}
</div>
<div
className={styles.circle}
style={{
width: outerCircleWidth,
height: outerCircleWidth,
borderRadius: outerCircleWidth,
}}
>
<div
className={styles.innerCircle}
style={{
width: innerCircleWidth,
height: innerCircleWidth,
borderRadius: innerCircleWidth,
}}
/>
</div>
<div
className={styles.text}
style={{
width: textWidth,
marginRight: (width - 2 * gap - outerCircleWidth) / 2 - textWidth,
}}
>
{datum.text}
</div>
</div>
);
}

@ -80,6 +80,33 @@ export const moreMockCategoricalData = [
{ key: "Dart", value: 2.21 },
];
export const mockTimelineData = [
{
time: "Fall 2020",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
},
{
time: "Winter 2021",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad",
},
{
time: "Spring 2021",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor i",
},
{
time: "Fall 2021",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proid",
},
{
time: "Winter 2022",
text: "Lorem ipsum dolor sit amet, consectetur adipi",
},
{
time: "Spring 2022",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut en",
},
];
export const mockBoxPlotData = [
{
category: "1A",

@ -0,0 +1,46 @@
export const sectionsData = [
{
name: "Demographics",
url: "/",
},
{
name: "Academics",
url: "/",
},
{
name: "Co-op",
url: "/",
},
{
name: "Lifestyle and Interests",
url: "/",
},
{
name: "Intimacy and Drugs",
url: "/",
},
{
name: "Post-grad",
url: "/",
},
{
name: "Friends",
url: "/",
},
{
name: "Miscellaneous",
url: "/",
},
{
name: "Mental Health",
url: "/",
},
{
name: "Personal",
url: "/",
},
{
name: "Contributors",
url: "/",
},
];

@ -24,7 +24,6 @@ body {
--light--secondary-accent-light: #FEA0C8;
--light--primary-heading: #D02B53;
--light--primary-text: #483B35;
--light--secondary-text: var(--pink);
--light--link: var(--orange);
--light--link-hover: #FFBC9F;
--light--card-background: #FFFFFF;
@ -69,22 +68,52 @@ body {
color: var(--primary-text);
font-family: "Inconsolata", monospace;
margin: 0;
/* Font styling for body */
font-size: calc(18rem / 16);
font-weight: 500;
}
/* Page titles (e.g. Demographics) */
h1 {
font-size: calc(48rem / 16);
font-weight: 700;
color: var(--primary-accent-light);
margin-top: calc(32rem / 16);
margin-bottom: calc(16rem / 16);
}
h1,
/* Major section headings (e.g. About the Programs) */
h2 {
font-size: calc(36rem / 16);
font-weight: 700;
color: var(--primary-heading);
margin-top: calc(32rem / 16);
margin-bottom: calc(16rem / 16);
}
/* Minor section headings & questions (e.g. What Program Are You In?) */
h3 {
font-size: calc(32rem / 16);
font-weight: 700;
color: var(--secondary-heading);
font-size: calc(45rem / 16);
margin-top: calc(24rem / 16);
margin-bottom: calc(16rem / 16);
}
h4,
h5,
h6 {
/* Titles within paragraphs (e.g. About the Programs -> Computer Science)*/
h4 {
font-size: calc(24rem / 16);
font-weight: 700;
color: var(--secondary-heading);
margin-top: calc(24rem / 16);
margin-bottom: calc(8rem / 16);
}
p {
color: var(--primary-text);
margin-top: 1rem;
margin-bottom: 1rem;
}
a {
@ -96,10 +125,6 @@ a:hover {
color: var(--link-hover);
}
p {
font-size: calc(28rem / 16);
}
@media only screen and (prefers-color-scheme: dark) {
body {
--primary-background: var(--dark--primary-background);

@ -7,11 +7,16 @@ import {
mockQuoteData,
mockQuoteDataLong,
mockPieData,
mockTimelineData,
} from "data/mocks";
import { sectionsData } from "data/routes";
import React from "react";
import { About } from "@/components/About";
import { PieChart } from "@/components/PieChart";
import { QuotationCarousel } from "@/components/QuotationCarousel";
import { Sections } from "@/components/Sections";
import { Timeline } from "@/components/Timeline";
import { BottomNav } from "../components/BottomNav";
import { CenterWrapper } from "../components/CenterWrapper";
@ -25,13 +30,26 @@ export default function Home() {
<div className={styles.page}>
<h1>Playground</h1>
<p>Show off your components here!</p>
<ColorPalette />
<h2>
<code>Text Styles</code>
</h2>
<h1>h1 h1 h1 h1 h1 h1 h1 h1 h1 h1 h1 h1 h1 h1 h1 h1 h1 h1</h1>
<h2>h2 h2 h2 h2 h2 h2 h2 h2 h2 h2 h2 h2 h2 h2 h2 h2 h2 h2</h2>
<h3>h3 h3 h3 h3 h3 h3 h3 h3 h3 h3 h3 h3 h3 h3 h3 h3 h3 h3</h3>
<h4>h4 h4 h4 h4 h4 h4 h4 h4 h4 h4 h4 h4 h4 h4 h4 h4 h4 h4</h4>
<p>p p p p p p p p p p p p p p p p p p p p p p p p p p p p</p>
<a href="#">a a a a a a a a a a a a a a a a a a a a a a a a a a a a</a>
<h2>
<code>{"<PieChart />"}</code>
</h2>
<div style={{ padding: "30px" }}>
<PieChart data={mockPieData} width={800} labelWidth={215} />
</div>
<ColorPalette />
<h2>
<code>{"<BarGraphHorizontal />"}</code>
</h2>
@ -47,6 +65,7 @@ export default function Home() {
right: 20,
}}
/>
<h2>
<code>{"<BarGraphVertical />"}</code>
</h2>
@ -66,6 +85,7 @@ export default function Home() {
right: 20,
}}
/>
<h2>
<code>{"<WordCloud />"}</code>
</h2>
@ -75,6 +95,12 @@ export default function Home() {
value: word.value,
}))}
/>
<h2>
<code>{"<Timeline />"}</code>
</h2>
<Timeline data={mockTimelineData} />
<h2>
<code>{"<Textbox />"}</code>
</h2>
@ -107,6 +133,16 @@ export default function Home() {
</p>
</CenterWrapper>
<h2>
<code>{"<Sections />"}</code>
</h2>
<Sections data={sectionsData} />
<h2>
<code>{"<About />"}</code>
</h2>
<About />
<h2>
<code>{"<BoxPlot />"}</code>
</h2>

Loading…
Cancel
Save