CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/next/components/auth/try.tsx
Views: 687
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
Create an anonymous account.
8
*/
9
10
import { Button } from "antd";
11
import { useState } from "react";
12
import {
13
GoogleReCaptchaProvider,
14
useGoogleReCaptcha,
15
} from "react-google-recaptcha-v3";
16
17
import { len } from "@cocalc/util/misc";
18
import A from "components/misc/A";
19
import Loading from "components/share/loading";
20
import api from "lib/api/post";
21
import useCustomize from "lib/use-customize";
22
23
import AuthPageContainer from "./fragments/auth-page-container";
24
25
interface Props {
26
minimal?: boolean;
27
publicPathId?: string;
28
onSuccess: () => void; // if given, call after sign up *succeeds*.
29
}
30
31
export default function Try(props: Props) {
32
const { reCaptchaKey } = useCustomize();
33
const body = <Try0 {...props} />;
34
if (reCaptchaKey == null) {
35
return body;
36
}
37
return (
38
<GoogleReCaptchaProvider reCaptchaKey={reCaptchaKey}>
39
{body}
40
</GoogleReCaptchaProvider>
41
);
42
}
43
44
function Try0({ minimal, onSuccess, publicPathId }: Props) {
45
const {
46
siteName,
47
anonymousSignup,
48
reCaptchaKey,
49
anonymousSignupLicensedShares,
50
} = useCustomize();
51
const [state, setState] = useState<"wait" | "creating" | "done">("wait");
52
const [error, setError] = useState<string>("");
53
const { executeRecaptcha } = useGoogleReCaptcha();
54
55
if (!anonymousSignup && !(anonymousSignupLicensedShares && publicPathId)) {
56
return (
57
<h1 style={{ textAlign: "center", margin: "45px auto" }}>
58
Anonymous Trial of {siteName} Not Currently Available
59
</h1>
60
);
61
}
62
63
async function createAnonymousAccount() {
64
setState("creating");
65
try {
66
let reCaptchaToken: undefined | string;
67
if (reCaptchaKey) {
68
if (!executeRecaptcha) {
69
throw Error("Please wait a few seconds, then try again.");
70
}
71
reCaptchaToken = await executeRecaptcha("anonymous");
72
}
73
74
const result = await api("/auth/sign-up", {
75
reCaptchaToken,
76
publicPathId,
77
});
78
if (result.issues && len(result.issues) > 0) {
79
throw Error(JSON.stringify(result.issues)); // TODO: should not happen, except for captcha error...
80
}
81
onSuccess?.();
82
setState("done");
83
} catch (err) {
84
setError(err.message);
85
setState("wait");
86
}
87
}
88
89
function renderFooter() {
90
return !minimal && (
91
<>
92
<div>
93
Already have an account? <A href="/auth/sign-in">Sign In</A>
94
</div>
95
<div style={{ marginTop: "15px" }}>
96
Need an account? <A href="/auth/sign-up">Sign Up</A>
97
</div>
98
</>
99
);
100
}
101
102
return (
103
<AuthPageContainer
104
error={error}
105
footer={renderFooter()}
106
minimal={minimal}
107
title={`Use ${siteName} Anonymously`}
108
>
109
<div style={{ margin: "10px 0" }}>
110
Use {siteName} <b>without</b>{" "}
111
<A href="/auth/sign-up" external={!!minimal}>
112
creating an account
113
</A>
114
!
115
<Button
116
disabled={state != "wait"}
117
shape="round"
118
size="large"
119
type="primary"
120
style={{ width: "100%", marginTop: "20px" }}
121
onClick={createAnonymousAccount}
122
>
123
{state == "creating" ? (
124
<Loading>Configuring Anonymous Access...</Loading>
125
) : (
126
<>Use {siteName} Anonymously</>
127
)}
128
</Button>
129
</div>
130
</AuthPageContainer>
131
);
132
}
133
134