CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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