Event Description Card
|
@ -0,0 +1,55 @@
|
||||||
|
.card {
|
||||||
|
display: flex;
|
||||||
|
box-sizing: border-box;
|
||||||
|
max-width: 540px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.poster {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
margin-right: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.details {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
color: var(--purple-2);
|
||||||
|
font-weight: bolder;
|
||||||
|
font-size: 1.125rem;
|
||||||
|
line-height: 1.6875rem;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
color: var(--purple-2);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 30px;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
.card {
|
||||||
|
padding: 0;
|
||||||
|
background-color: #e1eefa;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
import React, { ReactNode } from "react";
|
||||||
|
// import { Button } from "./Button";
|
||||||
|
import { EventSetting } from "./EventSetting";
|
||||||
|
import styles from "./EventDescriptionCard.module.css";
|
||||||
|
|
||||||
|
interface BaseProps {
|
||||||
|
name: string;
|
||||||
|
date: Date;
|
||||||
|
poster: string;
|
||||||
|
registerLink?: string;
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props = BaseProps &
|
||||||
|
(
|
||||||
|
| { online: true; location: keyof typeof links }
|
||||||
|
| { online: false; location: string }
|
||||||
|
);
|
||||||
|
|
||||||
|
const links = {
|
||||||
|
Twitch: "https://www.twitch.tv/uwcsclub",
|
||||||
|
Discord: "https://discord.gg/pHfYBCg",
|
||||||
|
Facebook: "https://www.facebook.com/uw.computerscienceclub",
|
||||||
|
Instagram: "https://www.instagram.com/uwcsclub/",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @remarks
|
||||||
|
* - Child elements will display as the event's description
|
||||||
|
* - Assuming date prop is in EST
|
||||||
|
* - poster is the event's image name, including file ending (.jpg/.png/etc)
|
||||||
|
* - If event is online, location will be the platform, with capital first letter and no trailing spaces
|
||||||
|
* - ie. location="Discord"
|
||||||
|
* @todo
|
||||||
|
* get Link component
|
||||||
|
*/
|
||||||
|
export function EventDescriptionCard(props: Props) {
|
||||||
|
return (
|
||||||
|
<article className={styles.card}>
|
||||||
|
<img className={styles.poster} src={props.poster} alt={props.name} />
|
||||||
|
|
||||||
|
<div className={styles.details}>
|
||||||
|
<h3 className={styles.name}>{props.name}</h3>
|
||||||
|
|
||||||
|
<EventSetting
|
||||||
|
date={props.date}
|
||||||
|
online={props.online}
|
||||||
|
location={props.location}
|
||||||
|
/>
|
||||||
|
<div className={styles.desc}>{props.children}</div>
|
||||||
|
<div className={styles.spacer}></div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
{props.registerLink && (
|
||||||
|
<div className={styles.button}>
|
||||||
|
<button>
|
||||||
|
<a href={props.registerLink}>Register</a>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{props.online && (
|
||||||
|
<a target="_blank" href={links[props.location]} rel="noreferrer">
|
||||||
|
<img
|
||||||
|
className={styles.logo}
|
||||||
|
alt={props.location}
|
||||||
|
src={"logos/" + props.location + ".png"}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
.setting {
|
||||||
|
color: var(--blue-1);
|
||||||
|
font-weight: bolder;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
import React from "react";
|
||||||
|
import styles from "./EventSetting.module.css";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
date: Date;
|
||||||
|
online: boolean;
|
||||||
|
location: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EventSetting(props: Props) {
|
||||||
|
const date = props.date.toLocaleDateString("en-US", {
|
||||||
|
day: "numeric",
|
||||||
|
month: "long",
|
||||||
|
year: "numeric",
|
||||||
|
});
|
||||||
|
const time = props.date.toLocaleTimeString("en-US", {
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "numeric",
|
||||||
|
});
|
||||||
|
const location = props.online ? `Online - ${props.location}` : props.location;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.setting}>
|
||||||
|
<time dateTime={props.date.toISOString()}>{`${date} | ${time}`}</time>
|
||||||
|
{` | ${location}`}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -8,12 +8,6 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 768px) {
|
|
||||||
.news {
|
|
||||||
background-color: #e1eefa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsTitle {
|
.newsTitle {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -39,3 +33,32 @@
|
||||||
background-color: var(--purple-2);
|
background-color: var(--purple-2);
|
||||||
margin: 0 0 13px 0;
|
margin: 0 0 13px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.eventDescriptionCardDemo {
|
||||||
|
padding: 50px 0;
|
||||||
|
background-color: var(--off-white);
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eventDescriptionCardDemo > * {
|
||||||
|
margin: 12px 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eventDescriptionCardDemo > *:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eventDescriptionCardDemo > *:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
.news,
|
||||||
|
.eventDescriptionCardDemo {
|
||||||
|
background-color: #e1eefa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eventDescriptionCardDemo > * {
|
||||||
|
margin: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { EventDescriptionCard } from "./EventDescriptionCard";
|
||||||
|
|
||||||
import styles from "./playground.module.css";
|
import styles from "./playground.module.css";
|
||||||
|
|
||||||
|
@ -71,3 +72,42 @@ export function NewsCardDemo() {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function EventDescriptionCardDemo() {
|
||||||
|
const { name, short, date } = afterHoursMetadata;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.eventDescriptionCardDemo}>
|
||||||
|
<EventDescriptionCard
|
||||||
|
name={name}
|
||||||
|
date={date}
|
||||||
|
online={true}
|
||||||
|
location="Twitch"
|
||||||
|
poster="images/playground/intro-ootb.jpg"
|
||||||
|
registerLink="/"
|
||||||
|
>
|
||||||
|
<p>{short}</p>
|
||||||
|
</EventDescriptionCard>
|
||||||
|
<EventDescriptionCard
|
||||||
|
name={name}
|
||||||
|
date={date}
|
||||||
|
online={true}
|
||||||
|
location="Twitch"
|
||||||
|
poster="images/playground/alt-tab.jpg"
|
||||||
|
registerLink="/"
|
||||||
|
>
|
||||||
|
<p>{short}</p>
|
||||||
|
</EventDescriptionCard>
|
||||||
|
<EventDescriptionCard
|
||||||
|
name={name}
|
||||||
|
date={date}
|
||||||
|
online={true}
|
||||||
|
location="Twitch"
|
||||||
|
poster="images/playground/intro-ootb.jpg"
|
||||||
|
registerLink="/"
|
||||||
|
>
|
||||||
|
<p>{short}</p>
|
||||||
|
</EventDescriptionCard>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
import {MiniEventCardDemo, NewsCardDemo} from '../components/playground'
|
import {
|
||||||
|
MiniEventCardDemo,
|
||||||
|
NewsCardDemo,
|
||||||
|
EventDescriptionCardDemo,
|
||||||
|
} from "../components/playground";
|
||||||
|
|
||||||
# Playground
|
# Playground
|
||||||
|
|
||||||
## `<MiniEventCard />`
|
## `<MiniEventCard />`
|
||||||
|
|
||||||
The `<MiniEventCard />` component has a collapsible description, and it used on
|
The `<MiniEventCard />` component has a collapsible description, and it is used
|
||||||
the events page. It uses the `<details>` tag and works without JS!
|
on the events page. It uses the `<details>` tag and works without JS!
|
||||||
|
|
||||||
<MiniEventCardDemo />
|
<MiniEventCardDemo />
|
||||||
|
|
||||||
|
@ -15,4 +19,15 @@ the events page. It uses the `<details>` tag and works without JS!
|
||||||
|
|
||||||
unavailable
|
unavailable
|
||||||
|
|
||||||
<NewsCardDemo />
|
<NewsCardDemo />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `<EventDescriptionCard />`
|
||||||
|
|
||||||
|
The `<EventDescriptionCard />` component is used on the home page, and uses the
|
||||||
|
`<Button />` and `<EventSetting />` components.
|
||||||
|
|
||||||
|
<EventDescriptionCardDemo />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
After Width: | Height: | Size: 268 KiB |
After Width: | Height: | Size: 321 KiB |
Before Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 900 B |
After Width: | Height: | Size: 615 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 575 B |