Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/admin/users/user.tsx
1496 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
/*
7
Display of basic information about a user, with link to get more information about that user.
8
*/
9
10
import { useState } from "react";
11
import { Icon, TimeAgo } from "@cocalc/frontend/components";
12
import { capitalize } from "@cocalc/util/misc";
13
import { Card, Space, Tag } from "antd";
14
import type { User } from "@cocalc/frontend/frame-editors/generic/client";
15
import { Projects } from "./projects";
16
import { Impersonate } from "./impersonate";
17
import { PasswordReset } from "./password-reset";
18
import { Ban } from "./ban";
19
import PayAsYouGoMinBalance from "@cocalc/frontend/frame-editors/crm-editor/users/pay-as-you-go-min-balance";
20
import { PurchasesButton } from "@cocalc/frontend/purchases/purchases";
21
import { PaymentsButton } from "@cocalc/frontend/purchases/payments";
22
import { CreatePaymentButton } from "./create-payment";
23
import { CopyToClipBoard } from "@cocalc/frontend/components";
24
import Money from "./money";
25
26
interface State {
27
projects: boolean;
28
purchases: boolean;
29
activity: boolean;
30
impersonate: boolean;
31
password: boolean;
32
ban: boolean;
33
}
34
35
type More =
36
| "projects"
37
| "purchases"
38
| "activity"
39
| "impersonate"
40
| "password"
41
| "ban";
42
43
export function UserResult({
44
first_name,
45
last_name,
46
email_address,
47
created,
48
last_active,
49
account_id,
50
banned,
51
}: User) {
52
const [details, setDetails] = useState<boolean>(false);
53
const [state, setState] = useState<State>({
54
projects: false,
55
purchases: false,
56
activity: false,
57
impersonate: false,
58
password: false,
59
ban: false,
60
});
61
62
const renderCreated = () => {
63
if (!created) {
64
return <span>ancient times</span>;
65
}
66
return <TimeAgo date={created} />;
67
};
68
69
const renderLastActive = () => {
70
if (!last_active) {
71
return <span>never</span>;
72
}
73
return <TimeAgo date={last_active} />;
74
};
75
76
const renderMoreLink = (name: More) => {
77
return (
78
<Tag.CheckableTag
79
style={{ fontSize: "11pt" }}
80
checked={state[name]}
81
onChange={() => setState({ ...state, [name]: !state[name] })}
82
>
83
{capitalize(name)}
84
</Tag.CheckableTag>
85
);
86
};
87
88
return (
89
<Card
90
style={{ margin: "15px 0", background: "#fafafa" }}
91
styles={{
92
body: { padding: "0 24px" },
93
title: { padding: "0" },
94
}}
95
title={
96
<div
97
style={{ cursor: "pointer" }}
98
onClick={details ? undefined : () => setDetails(true)}
99
>
100
<Icon
101
onClick={() => setDetails(!details)}
102
name={details ? "minus-square" : "plus-square"}
103
style={{ marginRight: "15px" }}
104
/>
105
<div style={{ float: "right", color: "#666" }}>
106
Active {renderLastActive()} (Created {renderCreated()})
107
</div>
108
<Space style={{ color: "#666" }}>
109
{first_name} {last_name}{" "}
110
{email_address ? (
111
<CopyToClipBoard
112
style={{ color: "#666" }}
113
value={email_address}
114
/>
115
) : (
116
"NO Email"
117
)}
118
</Space>
119
</div>
120
}
121
>
122
{details && (
123
<div>
124
<div style={{ float: "right" }}>
125
<CopyToClipBoard
126
copyTip={"Copied account_id!"}
127
style={{ color: "#666" }}
128
before
129
value={account_id}
130
/>
131
{banned && (
132
<div
133
style={{
134
fontSize: "10pt",
135
color: "white",
136
paddingLeft: "5px",
137
background: "red",
138
}}
139
>
140
BANNED
141
</div>
142
)}
143
</div>
144
<Space style={{ marginTop: "5px" }}>
145
{renderMoreLink("impersonate")}
146
{renderMoreLink("password")}
147
{renderMoreLink("ban")}
148
{renderMoreLink("projects")}
149
{renderMoreLink("purchases")}
150
</Space>
151
{state.impersonate && (
152
<Impersonate
153
account_id={account_id}
154
first_name={first_name ?? ""}
155
last_name={last_name ?? ""}
156
/>
157
)}
158
{state.password && email_address && (
159
<Card title="Password">
160
<PasswordReset
161
account_id={account_id}
162
email_address={email_address}
163
/>
164
</Card>
165
)}
166
{state.ban && (
167
<Card
168
title={
169
<>
170
Ban {first_name} {last_name} {email_address}
171
</>
172
}
173
>
174
<Ban
175
account_id={account_id}
176
banned={banned}
177
name={`${first_name} ${last_name} ${email_address}`}
178
/>
179
</Card>
180
)}
181
{state.projects && (
182
<Projects
183
account_id={account_id}
184
title={`Recently active projects that ${first_name} ${last_name} collaborates on`}
185
/>
186
)}
187
{state.purchases && (
188
<Card title="Purchases">
189
<div style={{ margin: "15px 0" }}>
190
<Money account_id={account_id} />
191
<div style={{ height: "15px" }} />
192
<PayAsYouGoMinBalance account_id={account_id} />
193
<div style={{ height: "15px" }} />
194
<PurchasesButton account_id={account_id} />
195
<div style={{ height: "15px" }} />
196
<PaymentsButton account_id={account_id} />
197
<div style={{ height: "15px" }} />
198
<CreatePaymentButton account_id={account_id} />
199
</div>
200
</Card>
201
)}
202
</div>
203
)}
204
</Card>
205
);
206
}
207
208
export default UserResult;
209
210