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