Add mobile styles to the event card #190

Merged
a3thakra merged 3 commits from adi-mobile-events-card into main 2021-08-28 15:56:25 -04:00
13 changed files with 160 additions and 39 deletions

View File

@ -2,5 +2,5 @@
padding: 0 calc(4rem / 16); padding: 0 calc(4rem / 16);
background: var(--code-background); background: var(--code-background);
border-radius: calc(5rem / 16); border-radius: calc(5rem / 16);
word-wrap: break-word; overflow-wrap: break-word;
} }

View File

@ -2,7 +2,7 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
box-sizing: border-box; box-sizing: border-box;
padding: calc(24rem / 16); padding: calc(20rem / 16) 0;
} }
.card aside { .card aside {
@ -12,18 +12,17 @@
.card aside img { .card aside img {
width: 100%; width: 100%;
margin-bottom: 1rem;
}
.spacer {
margin-top: calc(76rem / 16);
} }
.registerButton { .registerButton {
display: block; margin-top: 1rem;
font-weight: bold; font-weight: bold;
} }
.registerButtonWithPoster {
display: block;
}
.content > h1 { .content > h1 {
font-size: calc(24rem / 16); font-size: calc(24rem / 16);
font-weight: 700; font-weight: 700;
@ -45,3 +44,70 @@
font-size: 1rem; font-size: 1rem;
margin-bottom: calc(14rem / 16); margin-bottom: calc(14rem / 16);
} }
.mobileLearnMore {
display: none;
}
@media only screen and (max-width: calc(768rem / 16)) {
.card {
flex-direction: column;
}
.card aside {
margin: 0 auto;
max-width: calc(300rem / 16);
}
.card aside img {
box-sizing: border-box;
border: calc(1rem / 16) solid var(--text);
}
.content {
margin-top: 1rem;
}
.content {
text-align: center;
}
.content > h1,
.content > h2 {
font-size: 1rem;
line-height: calc(30 / 16);
}
.content > h2 {
margin-bottom: 0;
}
.mobileShowDescriptionContent {
text-align: unset;
}
.mobileShowDescriptionContent > h1 {
font-size: calc(24rem / 16);
margin-bottom: calc(8rem / 16);
}
.registerButton {
display: block;
}
.mobileLearnMore {
display: unset;
}
.mobileShowDescriptionContent .mobileLearnMore {
display: none;
}
.children {
display: none;
}
.mobileShowDescriptionContent .children {
display: unset;
}
}

View File

@ -3,10 +3,11 @@ import React, { ReactNode } from "react";
import { Button } from "./Button"; import { Button } from "./Button";
import { EventSetting } from "./EventSetting"; import { EventSetting } from "./EventSetting";
import { Image } from "./Image"; import { Image } from "./Image";
import { Link } from "./Link";
import styles from "./EventCard.module.css"; import styles from "./EventCard.module.css";
interface EventCardProps { interface BaseProps {
name: string; name: string;
short: string; short: string;
date: Date; date: Date;
@ -17,7 +18,12 @@ interface EventCardProps {
children: ReactNode; children: ReactNode;
} }
type EventCardProps =
| (BaseProps & { showDescription?: false; link: string })
| (BaseProps & { showDescription: true; link?: string });
export function EventCard({ export function EventCard({
link,
name, name,
date, date,
online, online,
@ -25,13 +31,42 @@ export function EventCard({
poster, poster,
registerLink, registerLink,
children, children,
showDescription = false,
}: EventCardProps) { }: EventCardProps) {
return ( return (
<article className={styles.card}> <article className={styles.card}>
<aside> {poster && (
{poster && <Image alt={name} src={poster} />} <aside>
{!poster && <div className={styles.spacer}></div>} <Image alt={name} src={poster} />
{registerLink && ( {registerLink && (
<Button
isLink={true}
href={registerLink}
size="small"
className={`${styles.registerButton} ${styles.registerButtonWithPoster}`}
>
Register
</Button>
)}
</aside>
)}
<section
className={[
styles.content,
showDescription ? styles.mobileShowDescriptionContent : "",
].join(" ")}
a3thakra marked this conversation as resolved
Review

Would something like this work? (I don't know if it's any cleaner/better than what we already have though...)

className=`${styles.content} ${showDescription ? styles.mobileShowDescriptionContent : ""}`
Would something like this work? (I don't know if it's any cleaner/better than what we already have though...) ``` className=`${styles.content} ${showDescription ? styles.mobileShowDescriptionContent : ""}` ```
Review

it kinda results in a lot of nested ${} which i kinda dont like lol

it kinda results in a lot of nested ${} which i kinda dont like lol
Review

the only clean way would be to use the classnames library 🤷‍♂️

the only clean way would be to use the classnames library 🤷‍♂️
>
<h1>{name}</h1>
<h2>
<EventSetting date={date} online={online} location={location} />
</h2>
{!showDescription && link && (
<Link href={link}>
<span className={styles.mobileLearnMore}>Learn more</span>
</Link>
)}
<div className={styles.children}>{children}</div>
{!poster && registerLink && (
<Button <Button
isLink={true} isLink={true}
href={registerLink} href={registerLink}
@ -41,13 +76,6 @@ export function EventCard({
Register Register
</Button> </Button>
)} )}
</aside>
<section className={styles.content}>
<h1>{name}</h1>
<h2>
<EventSetting date={date} online={online} location={location} />
</h2>
<div>{children}</div>
</section> </section>
</article> </article>
); );

View File

@ -2,7 +2,7 @@
.separator { .separator {
display: none; display: none;
} }
.setting { .setting {
display: block; display: block;
} }

View File

@ -0,0 +1,4 @@
.image {
/* So that image doesn't overflow on mobile screens */
max-width: 100%;
}

View File

@ -1,8 +1,14 @@
import React, { ImgHTMLAttributes } from "react"; import React, { ImgHTMLAttributes } from "react";
import styles from "./Image.module.css";
export function Image(props: ImgHTMLAttributes<HTMLImageElement>) { export function Image(props: ImgHTMLAttributes<HTMLImageElement>) {
const classes = props.className
? [props.className, styles.image]
: [styles.image];
a3thakra marked this conversation as resolved
Review

Similar to line 57 of components/EventCard.tsx, not sure if the suggestion there would be helpful here or not.

Similar to line 57 of `components/EventCard.tsx`, not sure if the suggestion there would be helpful here or not.
Review

same as above

same as above
if (props.src?.startsWith("http://") || props.src?.startsWith("https://")) { if (props.src?.startsWith("http://") || props.src?.startsWith("https://")) {
return <img {...props} />; return <img {...props} className={classes.join(" ")} />;
} }
const { src: relativeSrc = "" } = props; const { src: relativeSrc = "" } = props;
@ -16,5 +22,5 @@ export function Image(props: ImgHTMLAttributes<HTMLImageElement>) {
absoluteSrc += "/" + relativeSrc; absoluteSrc += "/" + relativeSrc;
} }
return <img {...props} src={absoluteSrc} />; return <img {...props} src={absoluteSrc} className={classes.join(" ")} />;
} }

View File

@ -3,6 +3,7 @@
transition-duration: 0.3s; transition-duration: 0.3s;
text-decoration: none; text-decoration: none;
white-space: normal; white-space: normal;
overflow-wrap: anywhere;
} }
.link:hover { .link:hover {

View File

@ -146,13 +146,23 @@ export function EventDescriptionCardDemo() {
export function EventCardDemo() { export function EventCardDemo() {
return ( return (
<> <>
{events.map(({ Content, metadata }) => ( {events.map(({ Content, metadata }, idx) => (
<EventCard <>
{...metadata} <EventCard
key={metadata.name + metadata.date.toDateString()} {...metadata}
> key={metadata.name + metadata.date.toDateString() + "1"}
<Content /> showDescription
</EventCard> >
<Content />
</EventCard>
<EventCard
{...metadata}
key={metadata.name + metadata.date.toDateString() + "2"}
link="#"
>
<Content />
</EventCard>
</>
))} ))}
</> </>
); );

View File

@ -27,7 +27,9 @@ export async function getEventTermsByYear(year: string): Promise<string[]> {
} }
interface Metadata { interface Metadata {
slug: string;
name: string; name: string;
poster?: string;
short: string; short: string;
date: string; date: string;
online: boolean; online: boolean;
@ -52,7 +54,7 @@ export async function getEventBySlug(
return { return {
content: await serialize(content), content: await serialize(content),
metadata: metadata as Metadata, metadata: { ...metadata, slug } as Metadata,
}; };
} }
@ -122,12 +124,14 @@ export async function getEventsPageProps({
new Date(a.metadata.date).getTime() - new Date(b.metadata.date).getTime() new Date(a.metadata.date).getTime() - new Date(b.metadata.date).getTime()
); );
const currentDate = Date.now();
const pastEvents = events const pastEvents = events
.filter((event) => new Date(event.metadata.date).getTime() < Date.now()) .filter((event) => new Date(event.metadata.date).getTime() < currentDate)
.reverse(); .reverse();
const futureEvents = events.filter( const futureEvents = events.filter(
(event) => new Date(event.metadata.date).getTime() >= Date.now() (event) => new Date(event.metadata.date).getTime() >= currentDate
); );
const current = getCurrentTerm(); const current = getCurrentTerm();

View File

@ -8,6 +8,7 @@ import { Code } from "@/components/Code";
import { DefaultLayout } from "@/components/DefaultLayout"; import { DefaultLayout } from "@/components/DefaultLayout";
import { Footer } from "@/components/Footer"; import { Footer } from "@/components/Footer";
import { HorizontalLine } from "@/components/HorizontalLine"; import { HorizontalLine } from "@/components/HorizontalLine";
import { Image } from "@/components/Image";
import { Link } from "@/components/Link"; import { Link } from "@/components/Link";
import { Navbar } from "@/components/Navbar"; import { Navbar } from "@/components/Navbar";
import { Pre } from "@/components/Pre"; import { Pre } from "@/components/Pre";
@ -35,6 +36,7 @@ export default function App({ Component, pageProps }: AppProps): JSX.Element {
button: Button, button: Button,
pre: Pre, pre: Pre,
inlineCode: Code, inlineCode: Code,
img: Image,
}} }}
> >
<div className={styles.appContainer}> <div className={styles.appContainer}>

View File

@ -18,6 +18,7 @@ export default function EventInfoPage(props: Props) {
<EventCard <EventCard
{...props.event.metadata} {...props.event.metadata}
date={new Date(props.event.metadata.date)} date={new Date(props.event.metadata.date)}
showDescription
> >
<MDXRemote {...props.event.content} /> <MDXRemote {...props.event.content} />
</EventCard> </EventCard>

View File

@ -8,12 +8,6 @@
border-bottom: 1px solid var(--primary-heading); border-bottom: 1px solid var(--primary-heading);
} }
@media only screen and (max-width: calc(768rem / 16)) {
.main {
margin-top: calc(60rem / 16);
}
}
.header a { .header a {
color: var(--text); color: var(--text);
font-size: calc(18rem / 16); font-size: calc(18rem / 16);
@ -31,3 +25,7 @@
.miniEventCards { .miniEventCards {
margin-top: calc(30rem / 16); margin-top: calc(30rem / 16);
} }
.main > .miniEventCards {
margin-top: 0;
}

View File

@ -72,6 +72,7 @@ export default function Term(props: Props) {
{...metadata} {...metadata}
date={new Date(metadata.date)} date={new Date(metadata.date)}
key={metadata.name + metadata.date.toString()} key={metadata.name + metadata.date.toString()}
link={`/events/${props.year}/${props.term}/${metadata.slug}`}
> >
<MDXRemote {...content} /> <MDXRemote {...content} />
</EventCard> </EventCard>