Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/next/components/store/menu.tsx
5900 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 type { MenuProps } from "antd";
7
import { Button, Flex, Menu, Spin } from "antd";
8
import { useRouter } from "next/router";
9
import React, { useContext } from "react";
10
11
import { Icon } from "@cocalc/frontend/components/icon";
12
import { currency, round2down } from "@cocalc/util/misc";
13
import { COLORS } from "@cocalc/util/theme";
14
import { StoreBalanceContext } from "lib/balance";
15
16
type MenuItem = Required<MenuProps>["items"][number];
17
18
const styles: { [k: string]: React.CSSProperties } = {
19
menuBookend: {
20
height: "100%",
21
whiteSpace: "nowrap",
22
flex: "0 1 auto",
23
textAlign: "end",
24
},
25
menu: {
26
width: "100%",
27
height: "100%",
28
flex: "1 1 auto",
29
border: 0,
30
},
31
menuRoot: {
32
marginBottom: "24px",
33
alignItems: "center",
34
border: 0,
35
borderBottom: "1px solid rgba(5, 5, 5, 0.06)",
36
boxShadow: "none",
37
},
38
menuContainer: {
39
alignItems: "center",
40
whiteSpace: "nowrap",
41
maxWidth: "100%",
42
flexGrow: 1,
43
},
44
} as const;
45
46
export interface ConfigMenuProps {
47
main?: string;
48
}
49
50
export default function ConfigMenu({ main }: ConfigMenuProps) {
51
const router = useRouter();
52
const { balance, refreshBalance, loading } = useContext(StoreBalanceContext);
53
54
const handleMenuItemSelect: MenuProps["onSelect"] = ({ keyPath }) => {
55
router.push(`/store/${keyPath[0]}`, undefined, {
56
scroll: false,
57
});
58
refreshBalance();
59
setTimeout(() => {
60
refreshBalance();
61
}, 7500);
62
};
63
64
const items: MenuItem[] = [
65
{
66
label: "Licenses",
67
key: "site-license",
68
icon: <Icon name="key" />,
69
},
70
{ label: "Course", key: "course", icon: <Icon name="graduation-cap" /> },
71
{
72
label: "Vouchers",
73
key: "vouchers",
74
icon: <Icon name="gift" />,
75
},
76
{
77
label: "Cart",
78
key: "cart",
79
icon: <Icon name="shopping-cart" />,
80
},
81
{
82
label: "Checkout",
83
key: "checkout",
84
icon: <Icon name="list" />,
85
},
86
{
87
label: "Processing",
88
key: "processing",
89
icon: <Icon name="run" />,
90
},
91
{
92
label: "Congrats",
93
key: "congrats",
94
icon: <Icon name="check-circle" />,
95
},
96
];
97
98
return (
99
<Flex
100
gap="middle"
101
justify="space-between"
102
style={styles.menuRoot}
103
wrap="wrap"
104
>
105
<Flex style={styles.menuContainer} align="center">
106
<strong>
107
<a
108
onClick={() => {
109
router.push("/store", undefined, {
110
scroll: false,
111
});
112
}}
113
style={{ color: COLORS.GRAY_D, marginRight: "12px" }}
114
>
115
Store
116
</a>
117
</strong>
118
<Menu
119
mode="horizontal"
120
selectedKeys={main ? [main] : undefined}
121
style={styles.menu}
122
onSelect={handleMenuItemSelect}
123
items={items}
124
/>
125
</Flex>
126
<Button
127
type="text"
128
style={styles.menuBookend}
129
onClick={() => {
130
refreshBalance();
131
}}
132
>
133
{balance !== undefined
134
? `Balance: ${currency(round2down(balance))}`
135
: null}
136
{loading && (
137
<Spin delay={2000} size="small" style={{ marginLeft: "15px" }} />
138
)}
139
</Button>
140
</Flex>
141
);
142
}
143
144