Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/next/pages/pricing/courses.tsx
1450 views
1
/*
2
* This file is part of CoCalc: Copyright © 2022 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { Layout, List } from "antd";
7
8
import { Icon, IconName } from "@cocalc/frontend/components/icon";
9
import { LicenseIdleTimeouts, Uptime } from "@cocalc/util/consts/site-license";
10
import { compute_cost } from "@cocalc/util/licenses/purchase/compute-cost";
11
import { discount_pct } from "@cocalc/util/licenses/purchase/consts";
12
import { PurchaseInfo } from "@cocalc/util/licenses/purchase/types";
13
import { money } from "@cocalc/util/licenses/purchase/utils";
14
import { COLORS } from "@cocalc/util/theme";
15
import Footer from "components/landing/footer";
16
import Head from "components/landing/head";
17
import Header from "components/landing/header";
18
import PricingItem, { Line } from "components/landing/pricing-item";
19
import { Paragraph, Title } from "components/misc";
20
import A from "components/misc/A";
21
import { listedPrices } from "components/share/pricing";
22
import { LinkToStore, StoreConf } from "components/store/link";
23
import { encodeRange } from "components/store/quota-query-params";
24
import { MAX_WIDTH } from "lib/config";
25
import { Customize } from "lib/customize";
26
import withCustomize from "lib/with-customize";
27
28
import type { JSX } from "react";
29
30
interface Item {
31
title: string;
32
icon: IconName;
33
teachers: number;
34
students: number;
35
duration: string;
36
disk: number;
37
shared_ram: number;
38
shared_cores: number;
39
academic: boolean;
40
retail?: number;
41
online: number;
42
uptime?: string;
43
conf: StoreConf;
44
}
45
46
const training: Item = (() => {
47
const students = 10;
48
const days = 5;
49
const conf = {
50
run_limit: students + 1,
51
user: "business",
52
days,
53
ram: 5,
54
disk: 5,
55
cpu: 1,
56
uptime: "medium" as Uptime,
57
start: new Date(),
58
end: new Date(new Date().getTime() + days * 24 * 60 * 60 * 1000),
59
} as const;
60
61
const profPrice = compute_cost({
62
type: "quota",
63
user: conf.user,
64
upgrade: "custom",
65
quantity: conf.run_limit,
66
subscription: "no",
67
start: conf.start,
68
end: conf.end,
69
custom_ram: conf.ram,
70
custom_cpu: conf.cpu,
71
custom_disk: conf.disk,
72
custom_member: true,
73
custom_dedicated_ram: 0,
74
custom_dedicated_cpu: 0,
75
custom_uptime: conf.uptime,
76
} as PurchaseInfo);
77
78
return {
79
title: `${conf.days} Day Professional Training`,
80
icon: "battery-quarter",
81
teachers: 1,
82
students,
83
duration: `${conf.days} days`,
84
disk: conf.disk,
85
uptime: LicenseIdleTimeouts[conf.uptime].labelShort,
86
shared_ram: conf.ram,
87
dedicated_ram: 0,
88
shared_cores: conf.cpu,
89
dedicated_cores: 0,
90
academic: false,
91
online: profPrice.cost,
92
conf,
93
};
94
})();
95
96
const courseSmall: Item = (() => {
97
const students = 10;
98
const days = 30;
99
const conf = {
100
run_limit: students + 1,
101
days,
102
ram: 2,
103
disk: 3,
104
cpu: 1,
105
uptime: "short",
106
user: "academic",
107
start: new Date(),
108
end: new Date(new Date().getTime() + days * 24 * 60 * 60 * 1000),
109
} as const;
110
111
const price = compute_cost({
112
type: "quota",
113
user: conf.user,
114
upgrade: "custom",
115
quantity: conf.run_limit,
116
subscription: "no",
117
start: conf.start,
118
end: conf.end,
119
custom_ram: conf.ram,
120
custom_cpu: conf.cpu,
121
custom_disk: conf.disk,
122
custom_member: true,
123
custom_dedicated_ram: 0,
124
custom_dedicated_cpu: 0,
125
custom_uptime: conf.uptime,
126
} as PurchaseInfo);
127
128
return {
129
title: `${students} students for ${conf.days} days`,
130
icon: "battery-half",
131
teachers: 1,
132
students,
133
duration: `${conf.days} days`,
134
disk: conf.disk,
135
uptime: LicenseIdleTimeouts[conf.uptime].labelShort,
136
shared_ram: conf.ram,
137
shared_cores: conf.cpu,
138
academic: true,
139
retail: price.cost,
140
online: price.cost,
141
conf,
142
};
143
})();
144
145
const courseLarge: Item = (() => {
146
const students = 150;
147
const months = 4;
148
const days = months * 30;
149
const conf = {
150
run_limit: students + 1,
151
days,
152
user: "academic",
153
ram: 2,
154
disk: 3,
155
cpu: 1,
156
uptime: "short",
157
start: new Date(),
158
end: new Date(new Date().getTime() + days * 24 * 60 * 60 * 1000),
159
} as const;
160
161
const price = compute_cost({
162
type: "quota",
163
user: conf.user,
164
upgrade: "custom",
165
quantity: conf.run_limit,
166
subscription: "no",
167
start: conf.start,
168
end: conf.end,
169
custom_ram: conf.ram,
170
custom_cpu: conf.cpu,
171
custom_disk: conf.disk,
172
custom_member: true,
173
custom_dedicated_ram: 0,
174
custom_dedicated_cpu: 0,
175
custom_uptime: conf.uptime,
176
} as PurchaseInfo);
177
178
return {
179
title: `${students} Students for ${months} Months`,
180
icon: "battery-full",
181
teachers: 1,
182
students,
183
duration: `${days} days`,
184
disk: conf.disk,
185
uptime: LicenseIdleTimeouts[conf.uptime].labelShort,
186
shared_ram: conf.ram,
187
shared_cores: conf.cpu,
188
academic: true,
189
retail: price.cost,
190
online: price.cost,
191
conf,
192
};
193
})();
194
195
const data: Item[] = [training, courseSmall, courseLarge];
196
197
export default function Courses({ customize }) {
198
const { siteName } = customize;
199
return (
200
<Customize value={customize}>
201
<Head title={`${siteName} – Pricing – Course Licenses`} />
202
<Layout>
203
<Header page="pricing" subPage="courses" />
204
<Layout.Content style={{ backgroundColor: "white" }}>
205
<Body />
206
<Footer />
207
</Layout.Content>
208
</Layout>
209
</Customize>
210
);
211
}
212
213
function Body(): JSX.Element {
214
return (
215
<div
216
style={{
217
maxWidth: MAX_WIDTH,
218
margin: "15px auto",
219
padding: "15px",
220
backgroundColor: "white",
221
}}
222
>
223
<div style={{ textAlign: "center" }}>
224
<Title level={1}>
225
<Icon name="graduation-cap" style={{ marginRight: "30px" }} />
226
CoCalc – Course Licenses
227
</Title>
228
</div>
229
<Paragraph>
230
You{" "}
231
<A href="https://doc.cocalc.com/teaching-instructors.html">
232
teach a course
233
</A>{" "}
234
on <span>CoCalc</span> by creating one project for each student, sending
235
your students assignments and handouts, then guiding their progress
236
using collaboration and chat. You can then collect, grade, comment on,
237
and return their work.
238
</Paragraph>
239
<Paragraph>
240
You will need to purchase an appropriate license for your course, or
241
have the students pay the one-time fee, since CoCalc is not funded by
242
advertisers or other intrusive methods.
243
</Paragraph>
244
245
<h2>How to get started?</h2>
246
<Paragraph>
247
You can{" "}
248
<A href="/store/site-license" external>
249
purchase a license for your course
250
</A>{" "}
251
in the{" "}
252
<A href="/store" external>
253
store
254
</A>
255
.
256
</Paragraph>
257
<Paragraph>
258
Minimal upgrades might be okay for beginner courses, but we find that
259
many data and computational science courses run better with additional
260
RAM and CPU. <A href="mailto:[email protected]">Contact us</A> if you have
261
questions or need a trial license to test out different possibilities.
262
</Paragraph>
263
<Paragraph>
264
Once you obtain a license key,{" "}
265
<A href="https://doc.cocalc.com/teaching-upgrade-course.html">
266
apply it to all your student projects
267
</A>
268
.
269
</Paragraph>
270
<Paragraph>
271
You can acquire several licenses, e.g., to partition a semester into
272
smaller parts with different requirements, or to keep upgrades separate
273
between certain groups of courses or instructors.
274
</Paragraph>
275
276
<Title level={2}>Payment options</Title>
277
<Paragraph>
278
<ul style={{ paddingLeft: "20px" }}>
279
<li>
280
<b>
281
<A href="https://doc.cocalc.com/teaching-upgrade-course.html#teacher-or-institution-pays-for-upgrades">
282
You or your institution pays
283
</A>
284
</b>{" "}
285
for one or more license upgrades. You distribute the license
286
upgrades to all projects of the course via the course configuration
287
tab of the course management interface.
288
</li>
289
<li>
290
<b>
291
<A href="https://doc.cocalc.com/teaching-upgrade-course.html#students-pay-for-upgrades">
292
Students pay a one-time fee.
293
</A>
294
</b>{" "}
295
In the configuration frame of the course management file, you opt to
296
require all students to pay a one-time fee to upgrade their own
297
projects. You can decide on the exact parameters of the license the
298
students will purchase, depending on the needs for your course.
299
</li>
300
</ul>
301
</Paragraph>
302
303
<Title level={2}>Examples</Title>
304
<Paragraph>
305
Here are three typical configurations, which you can{" "}
306
<A href="/store/site-license" external>
307
modify and purchase here
308
</A>
309
. All parameters can be adjusted to fit your needs. Listed upgrades are
310
for each project. Exact prices may vary. Only self-service online
311
purchases are available below $100.
312
</Paragraph>
313
314
<List
315
grid={{ gutter: 15, column: 3, xs: 1, sm: 1 }}
316
dataSource={data}
317
renderItem={(item) => {
318
const conf = {
319
...item.conf,
320
period: "range" as "range",
321
range: encodeRange([item.conf.start, item.conf.end]),
322
};
323
return (
324
<PricingItem title={item.title} icon={item.icon}>
325
<Line amount={item.teachers} desc="Teacher" />
326
<Line amount={item.students} desc="Students" />
327
<Line amount={item.duration} desc="Duration" />
328
<Line amount={item.uptime} desc="Idle timeout" />
329
<Line amount={item.shared_ram} desc="Shared RAM" />
330
<Line amount={item.shared_cores} desc="Shared CPU" />
331
<Line amount={item.disk} desc="Disk space" />
332
{item.academic && (
333
<Line amount={`${discount_pct}%`} desc="Academic discount" />
334
)}
335
<br />
336
<br />
337
<div>
338
<span
339
style={{
340
fontWeight: "bold",
341
fontSize: "18pt",
342
color: COLORS.GRAY_DD,
343
}}
344
>
345
{money(item.online, true)}
346
</span>{" "}
347
</div>
348
<LinkToStore conf={conf} />
349
</PricingItem>
350
);
351
}}
352
/>
353
354
{listedPrices()}
355
356
<Title level={2}>Contact us</Title>
357
<Paragraph>
358
To learn more about your teaching options, email us at{" "}
359
<A href="mailto:[email protected]">[email protected]</A> with a description
360
of your specific requirements.
361
</Paragraph>
362
</div>
363
);
364
}
365
366
export async function getServerSideProps(context) {
367
return await withCustomize({ context });
368
}
369
370