-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathEventsPageEventCard.tsx
138 lines (127 loc) · 3.32 KB
/
EventsPageEventCard.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import React from "react";
import { makeStyles, createStyles, Theme } from "@material-ui/core/styles";
import { Skeleton } from "@material-ui/lab";
import clsx from "clsx";
import CoreTypography from "@core/typography";
import FocusVisibleOnly from "components/FocusVisibleOnly";
import { formatDateRange } from "utils/date";
import { EventCardData } from "utils/types";
const useStyles = makeStyles(({ palette }: Theme) =>
createStyles({
card: {
width: 248,
height: 267,
borderRadius: 10,
overflow: "hidden",
backgroundColor: palette.background.paper,
/* 1px borders don't play nice on Chrome, so we use an equivalent
* box-shadow and wrap the div in another div */
boxShadow: `0 0 0 1px ${palette.object.lightOutline}`
},
cardContainer: {
width: 250,
height: 269,
padding: 1,
"&:focusVisible": {
outline: "none"
}
},
image: {
display: "block",
height: 128,
width: "inherit",
objectFit: "cover"
},
content: {
padding: "16px 24px"
},
header: {
marginBottom: 6,
/* line-clamp isn't supported yet, so the next four rules handle it for us */
display: "-webkit-box",
WebkitBoxOrient: "vertical",
WebkitLineClamp: 2,
overflow: "hidden"
},
body: {
marginBottom: 6
},
meta: {
color: palette.primary.main,
marginBottom: 6
},
/* Only works for truncating a single line */
truncate: {
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap"
}
})
);
type Props =
| {
eventCardData: EventCardData;
onClick: () => void;
type: "data";
}
| { type: "glimmer" };
const EventsPageEventCard: React.FC<Props> = props => {
const classes = useStyles();
let image, date, name, body;
switch (props.type) {
case "data": {
const { eventCardData } = props;
image = (
<img
src={eventCardData.image}
className={classes.image}
alt={`${eventCardData.name}`}
/>
);
date = formatDateRange(eventCardData.startDate, eventCardData.endDate);
name = eventCardData.name;
body = eventCardData.address.text.main;
break;
}
case "glimmer": {
image = (
<Skeleton animation="wave" className={classes.image} variant="rect" />
);
date = <Skeleton />;
name = <Skeleton />;
body = <Skeleton />;
break;
}
default: {
const _exhaustiveCheck: never = props;
return _exhaustiveCheck;
}
}
const card = (
<div className={classes.cardContainer}>
<div className={classes.card}>
{image}
<div className={classes.content}>
<CoreTypography
variant="h4"
className={clsx(classes.meta, classes.truncate)}
>
{date}
</CoreTypography>
<CoreTypography variant="h4" className={classes.header}>
{name}
</CoreTypography>
<CoreTypography className={clsx(classes.body, classes.truncate)}>
{body}
</CoreTypography>
</div>
</div>
</div>
);
return props.type === "glimmer" ? (
card
) : (
<FocusVisibleOnly onClick={props.onClick}>{card}</FocusVisibleOnly>
);
};
export default EventsPageEventCard;