Skip to content

Commit 0cdad26

Browse files
committed
next/store: basic scaffolding for a "course" purchase
1 parent 08b40db commit 0cdad26

File tree

6 files changed

+63
-51
lines changed

6 files changed

+63
-51
lines changed

src/packages/next/components/store/index.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import { Alert, Layout } from "antd";
66
import { useRouter } from "next/router";
77
import { useEffect, useState, type JSX } from "react";
8+
89
import * as purchasesApi from "@cocalc/frontend/purchases/api";
910
import { COLORS } from "@cocalc/util/theme";
1011
import Anonymous from "components/misc/anonymous";
@@ -16,28 +17,19 @@ import useProfile from "lib/hooks/profile";
1617
import useCustomize from "lib/use-customize";
1718
import Cart from "./cart";
1819
import Checkout from "./checkout";
19-
import Processing from "./processing";
2020
import Congrats from "./congrats";
2121
import Menu from "./menu";
2222
import Overview from "./overview";
23+
import Processing from "./processing";
2324
import SiteLicense from "./site-license";
2425
import { StoreInplaceSignInOrUp } from "./store-inplace-signup";
26+
import { StorePagesTypes } from "./types";
2527
import Vouchers from "./vouchers";
2628

2729
const { Content } = Layout;
2830

2931
interface Props {
30-
page: (
31-
| "site-license"
32-
| "boost"
33-
| "dedicated"
34-
| "cart"
35-
| "checkout"
36-
| "processing"
37-
| "congrats"
38-
| "vouchers"
39-
| undefined
40-
)[];
32+
page: (StorePagesTypes | undefined)[];
4133
}
4234

4335
export default function StoreLayout({ page }: Props) {
@@ -131,7 +123,9 @@ export default function StoreLayout({ page }: Props) {
131123

132124
switch (main) {
133125
case "site-license":
134-
return <SiteLicense noAccount={noAccount} />;
126+
return <SiteLicense noAccount={noAccount} type="license" />;
127+
case "course":
128+
return <SiteLicense noAccount={noAccount} type="course" />;
135129
case "cart":
136130
return requireAccount(Cart);
137131
case "checkout":

src/packages/next/components/store/menu.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
* License: MS-RSL – see LICENSE.md for details
44
*/
55

6-
import React, { useContext } from "react";
7-
import { Button, Menu, MenuProps, Flex, Spin } from "antd";
6+
import type { MenuProps } from "antd";
7+
import { Button, Flex, Menu, Spin } from "antd";
88
import { useRouter } from "next/router";
9+
import React, { useContext } from "react";
10+
11+
import { Icon } from "@cocalc/frontend/components/icon";
912
import { currency, round2down } from "@cocalc/util/misc";
1013
import { COLORS } from "@cocalc/util/theme";
11-
import { Icon } from "@cocalc/frontend/components/icon";
1214
import { StoreBalanceContext } from "../../lib/balance";
1315

1416
type MenuItem = Required<MenuProps>["items"][number];
@@ -17,7 +19,7 @@ const styles: { [k: string]: React.CSSProperties } = {
1719
menuBookend: {
1820
height: "100%",
1921
whiteSpace: "nowrap",
20-
flexGrow: 1,
22+
flex: "0 1 auto",
2123
textAlign: "end",
2224
},
2325
menu: {
@@ -38,7 +40,7 @@ const styles: { [k: string]: React.CSSProperties } = {
3840
maxWidth: "100%",
3941
flexGrow: 1,
4042
},
41-
};
43+
} as const;
4244

4345
export interface ConfigMenuProps {
4446
main?: string;
@@ -64,6 +66,7 @@ export default function ConfigMenu({ main }: ConfigMenuProps) {
6466
key: "site-license",
6567
icon: <Icon name="key" />,
6668
},
69+
{ label: "Course", key: "course", icon: <Icon name="graduation-cap" /> },
6770
{
6871
label: "Vouchers",
6972
key: "vouchers",

src/packages/next/components/store/overview.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,17 @@ export default function Overview() {
4747
</Paragraph>
4848
) : undefined}
4949
<OverviewRow>
50-
<Product icon="key" title="Licenses" href="/store/site-license">
50+
<Product icon="key" title="License" href="/store/site-license">
5151
Buy a license to upgrade projects, get internet access, more CPU, disk
5252
and memory.
5353
</Product>
54-
<Product href={"/store/vouchers"} icon="gift" title="Vouchers">
55-
Purchase a <A href={"/vouchers"}>voucher code</A> to make <SiteName />{" "}
56-
credit easily available to somebody else.
54+
<Product icon="graduation-cap" title="Course" href="/store/course">
55+
Purchase a license for teaching a course.
5756
</Product>
57+
<Paragraph style={{ textAlign: "center", width: "100%" }}>
58+
<Icon name="gift" /> Purchase a <A href={"/vouchers"}>voucher code</A>{" "}
59+
to make <SiteName /> credit easily available to somebody else.
60+
</Paragraph>
5861
<Divider />
5962
<Product
6063
href={"/features/compute-server"}
@@ -74,7 +77,7 @@ export default function Overview() {
7477
<A href="/store/cart">shopping cart</A> or go straight to{" "}
7578
<A href="/store/checkout">checkout</A>.
7679
</Paragraph>
77-
<Paragraph>
80+
<Paragraph style={{ marginBottom: "4em" }}>
7881
You can also browse your{" "}
7982
<A href="/settings/purchases">purchase history</A>,{" "}
8083
<A href="/settings/licenses">licenses</A>, and{" "}

src/packages/next/components/store/site-license.tsx

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ Create a new site license.
88
*/
99
import { Form, Input } from "antd";
1010
import { isEmpty } from "lodash";
11+
import { useRouter } from "next/router";
1112
import { useEffect, useRef, useState } from "react";
13+
1214
import { Icon } from "@cocalc/frontend/components/icon";
1315
import { get_local_storage } from "@cocalc/frontend/misc/local-storage";
1416
import { CostInputPeriod } from "@cocalc/util/licenses/purchase/types";
@@ -20,7 +22,6 @@ import SiteName from "components/share/site-name";
2022
import apiPost from "lib/api/post";
2123
import { MAX_WIDTH } from "lib/config";
2224
import { useScrollY } from "lib/use-scroll-y";
23-
import { useRouter } from "next/router";
2425
import { AddBox } from "./add-box";
2526
import { ApplyLicenseToProject } from "./apply-license-to-project";
2627
import { InfoBar } from "./cost-info-bar";
@@ -46,9 +47,10 @@ const STYLE: React.CSSProperties = {
4647

4748
interface Props {
4849
noAccount: boolean;
50+
type: "license" | "course";
4951
}
5052

51-
export default function SiteLicense({ noAccount }: Props) {
53+
export default function SiteLicense({ noAccount, type }: Props) {
5254
const router = useRouter();
5355
const headerRef = useRef<HTMLHeadingElement>(null);
5456

@@ -75,30 +77,39 @@ export default function SiteLicense({ noAccount }: Props) {
7577
: "Configure a License"}
7678
</Title>
7779
{router.query.id == null && (
78-
<div>
79-
<Paragraph style={{ fontSize: "12pt" }}>
80-
<A href="https://doc.cocalc.com/licenses.html">
81-
<SiteName /> licenses
82-
</A>{" "}
83-
allow you to upgrade projects to run more quickly, have network
84-
access, more disk space and memory. Licenses cover a wide range of
85-
use cases, ranging from a single hobbyist project to thousands of
86-
simultaneous users across a large organization.
87-
</Paragraph>
80+
<>
81+
{type === "license" && (
82+
<div>
83+
<Paragraph style={{ fontSize: "12pt" }}>
84+
<A href="https://doc.cocalc.com/licenses.html">
85+
<SiteName /> licenses
86+
</A>{" "}
87+
allow you to upgrade projects to run more quickly, have network
88+
access, more disk space and memory. Licenses cover a wide range
89+
of use cases, ranging from a single hobbyist project to
90+
thousands of simultaneous users across a large organization.
91+
</Paragraph>
8892

89-
<Paragraph style={{ fontSize: "12pt" }}>
90-
Create a license using the form below then add it to your{" "}
91-
<A href="/store/cart">shopping cart</A>. If you aren't sure exactly
92-
what to buy, you can always edit your licenses later. Subscriptions
93-
are also flexible and can be{" "}
94-
<A
95-
href="https://doc.cocalc.com/account/purchases.html#recent-updates-to-subscriptions"
96-
external
97-
>
98-
edited at any time.{" "}
99-
</A>
100-
</Paragraph>
101-
</div>
93+
<Paragraph style={{ fontSize: "12pt" }}>
94+
Create a license using the form below then add it to your{" "}
95+
<A href="/store/cart">shopping cart</A>. If you aren't sure
96+
exactly what to buy, you can always edit your licenses later.
97+
Subscriptions are also flexible and can be{" "}
98+
<A
99+
href="https://doc.cocalc.com/account/purchases.html#recent-updates-to-subscriptions"
100+
external
101+
>
102+
edited at any time.{" "}
103+
</A>
104+
</Paragraph>
105+
</div>
106+
)}
107+
{type === "course" && (
108+
<div>
109+
<Paragraph style={{ fontSize: "12pt" }}>Course License</Paragraph>
110+
</div>
111+
)}
112+
</>
102113
)}
103114
<CreateSiteLicense
104115
showInfoBar={scrollY > offsetHeader}

src/packages/next/components/store/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export const StorePages = [
22
"site-license",
3+
"course",
34
"boost",
45
"dedicated",
56
"cart",

src/packages/next/lib/styles/layouts.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { Col, Row } from "antd";
77

8-
import { Icon } from "@cocalc/frontend/components/icon";
8+
import { Icon, IconName } from "@cocalc/frontend/components/icon";
99
import { COLORS } from "@cocalc/util/theme";
1010
import { CSS, Paragraph, Title } from "components/misc";
1111
import A from "components/misc/A";
@@ -48,8 +48,8 @@ export function Product({
4848
children,
4949
external,
5050
}: {
51-
icon;
52-
icon2?;
51+
icon: IconName;
52+
icon2?: IconName;
5353
title;
5454
href;
5555
children;

0 commit comments

Comments
 (0)