Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/next/pages/about/events.tsx
6036 views
1
import { Alert, Button, Divider, Flex, Layout, Typography } from "antd";
2
import { GetServerSidePropsContext } from "next";
3
4
import {
5
getPastNewsChannelItems,
6
getUpcomingNewsChannelItems,
7
} from "@cocalc/database/postgres/news";
8
9
import { Icon } from "@cocalc/frontend/components/icon";
10
import Markdown from "@cocalc/frontend/editors/slate/static-markdown";
11
import { NewsItem } from "@cocalc/util/dist/types/news";
12
import { COLORS } from "@cocalc/util/theme";
13
14
import Footer from "components/landing/footer";
15
import Head from "components/landing/head";
16
import Header from "components/landing/header";
17
import IndexList, { DataSource } from "components/landing/index-list";
18
import { CSS } from "components/misc";
19
import A from "components/misc/A";
20
import { TagList } from "components/news/news";
21
import type { NewsWithStatus } from "components/news/types";
22
import { useDateStr } from "components/news/useDateStr";
23
24
import { MAX_WIDTH } from "lib/config";
25
import { Customize, CustomizeType } from "lib/customize";
26
import useProfile from "lib/hooks/profile";
27
import withCustomize from "lib/with-customize";
28
29
const BODY_STYLE: CSS = {
30
maxHeight: "max(300px, 75vh)",
31
overflowY: "auto",
32
} as const;
33
34
interface TitleComponentProps {
35
newsItem: NewsWithStatus;
36
showHelpTicket?: boolean;
37
}
38
39
const TitleComponent = ({ newsItem, showHelpTicket }: TitleComponentProps) => (
40
<Flex justify="space-between" align="baseline" wrap="wrap">
41
<Flex vertical flex={1}>
42
<Typography.Title
43
level={5}
44
style={{
45
margin: 0,
46
}}
47
>
48
<span style={{ color: COLORS.GRAY }}>
49
{`${useDateStr(newsItem, false, "MMM YYYY")}`}
50
</span>{" "}
51
{newsItem.title}
52
{newsItem.tags ? (
53
<span style={{ float: "right" }}>
54
<TagList mode="event" tags={newsItem.tags} />
55
</span>
56
) : undefined}
57
</Typography.Title>
58
</Flex>
59
{showHelpTicket && (
60
<Flex flex={0}>
61
<A
62
target="_blank"
63
href={`/support/new?${new URLSearchParams({
64
body: `Hi there! I'd love to meet at ${newsItem.title}.`,
65
subject: `Meeting Request: ${newsItem.title}`,
66
title: "Event Visit",
67
type: "question",
68
})}`}
69
>
70
<Button
71
style={{
72
fontSize: "14px",
73
}}
74
>
75
👋 Come say hi!
76
</Button>
77
</A>
78
</Flex>
79
)}
80
</Flex>
81
);
82
83
interface EventsProps {
84
customize: CustomizeType;
85
upcomingEvents: NewsWithStatus[];
86
pastEvents: NewsWithStatus[];
87
}
88
89
export default function Events({
90
customize,
91
upcomingEvents,
92
pastEvents,
93
}: EventsProps) {
94
const profile = useProfile({ noCache: true });
95
const isAdmin = profile?.is_admin;
96
97
function eventFooter(eventItem: NewsItem) {
98
return (
99
isAdmin && (
100
<Flex justify="center">
101
<A
102
key={`edit-event-${eventItem.id}`}
103
href={`/news/edit/${eventItem.id}`}
104
style={{
105
color: COLORS.ANTD_RED_WARN,
106
fontWeight: "bold",
107
}}
108
>
109
<Icon name="edit" /> Edit
110
</A>
111
</Flex>
112
)
113
);
114
}
115
116
const upcomingEventsDataSource = upcomingEvents.map((upcomingEvent) => ({
117
link: upcomingEvent.url,
118
linkText: (
119
<>
120
Event Website <Icon name="external-link" />
121
</>
122
),
123
title: <TitleComponent newsItem={upcomingEvent} showHelpTicket />,
124
description: (
125
<>
126
<Markdown value={upcomingEvent.text} style={BODY_STYLE} />
127
{eventFooter(upcomingEvent)}
128
</>
129
),
130
})) as DataSource;
131
132
const pastEventsDataSource = pastEvents.map((pastEvent) => ({
133
link: pastEvent.url,
134
linkText: (
135
<>
136
Event Website <Icon name="external-link" />
137
</>
138
),
139
title: <TitleComponent newsItem={pastEvent} />,
140
description: (
141
<>
142
<Markdown value={pastEvent.text} style={BODY_STYLE} />
143
{eventFooter(pastEvent)}
144
</>
145
),
146
})) as DataSource;
147
148
return (
149
<Customize value={customize}>
150
<Head title="Where To Find Us" />
151
<Layout>
152
<Header page="about" subPage="events" />
153
<Layout.Content
154
style={{
155
backgroundColor: "white",
156
}}
157
>
158
<div
159
style={{
160
maxWidth: MAX_WIDTH,
161
margin: "15px auto",
162
padding: "15px",
163
backgroundColor: "white",
164
}}
165
>
166
<IndexList
167
title={
168
<>
169
<Icon name="global" style={{ marginRight: "30px" }} />
170
Upcoming Events
171
</>
172
}
173
description={
174
<>
175
{isAdmin && (
176
<Alert
177
style={{
178
marginTop: "12px",
179
marginBottom: "12px",
180
}}
181
banner={true}
182
type="warning"
183
message={
184
<>
185
Admin only:{" "}
186
<A href="/news/edit/new?channel=event">
187
Create Event
188
</A>
189
</>
190
}
191
/>
192
)}
193
We are committed to engaging with the scientific community
194
this upcoming year. Here, you can stay updated with where to
195
find us "out in the wild." We have recently participated as
196
exhibitors for CoCalc at popular events such as the Joint
197
Mathematics Meeting and SIAM's Conference on Computational
198
Science and Engineering. We are beyond excited to catch up
199
with you and tell you all about CoCalc's latest features and
200
our innovative plans for the future!!
201
</>
202
}
203
dataSource={upcomingEventsDataSource}
204
/>
205
<Divider>Past Events</Divider>
206
<IndexList
207
title={<></>}
208
description={<></>}
209
dataSource={pastEventsDataSource}
210
/>
211
</div>
212
<Footer />
213
</Layout.Content>
214
</Layout>
215
</Customize>
216
);
217
}
218
219
export async function getServerSideProps(context: GetServerSidePropsContext) {
220
return await withCustomize({
221
context,
222
props: {
223
upcomingEvents: await getUpcomingNewsChannelItems("event"),
224
pastEvents: await getPastNewsChannelItems("event"),
225
},
226
});
227
}
228
229