~vpzom/bracketmonster

ref: 3f93e6a525a10bee455767ccfdf8e16d002b1ff2 bracketmonster/rosebush/src/client/pages/register.tsx -rw-r--r-- 2.5 KiB
3f93e6a5Colin Reeder no-js match edit 6 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { Component, JSX, h } from "preact";
import { useContext } from "preact/hooks";
import { Text } from "preact-jsx-i18n";
import { route } from "preact-router";

import { AppContext } from "../App";
import { COOKIE_AGE } from "../constants";
import Data from "../Data";
import Helmet from "../Helmet";

interface Props {
	continue?: string;
}

interface State {
	submitting: boolean;
	success: boolean;
}

export default class RegisterPage extends Component<Props, State> {
	public render(props: Props, state: State) {
		const app = useContext(AppContext)!;

		if(state.success) {
			return <div>
				<Helmet title={Text({id: "register"})} />

				<h1><Text id="register" /></h1>
				<p><Text id="pages_register_success" /></p>
			</div>;
		}

		return <Data state={app.userInfo}>
			{userInfo => {
				return <div>
					<Helmet title={Text({id: "register"})} />

					<h1><Text id="register" /></h1>
					{userInfo !== null && <p><Text id="pages_register_anonymousUpgrade" /></p>}
					<form onSubmit={this.submit.bind(this)}>
						<p>
							<label>
								<Text id="username" />: <input type="text" name="username" />
							</label>
						</p>
						<p>
							<label>
								<Text id="password" />: <input type="password" name="password" />
							</label>
						</p>
						<button class="primary" type="submit" disabled={state.submitting}>
							<Text id={state.submitting ? "pages_register_submitting" : "pages_register_submit"} />
						</button>
					</form>
				</div>;
			}}
		</Data>;
	}

	private submit(evt: JSX.TargetedEvent<HTMLFormElement>): void {
		evt.preventDefault();

		const form = evt.currentTarget;

		const username = form.username.value;

		this.setState({submitting: true}, () => {
			const app = useContext(AppContext)!;

			if(app.userInfo.state !== "done") throw new Error("UserInfo is not available. This shouldn't be possible.");

			const data = {username, password: form.password.value};

			(
				app.userInfo.value === null ?
					fetch("/api/v1/users", {method: "POST", body: JSON.stringify(data)})
						.then(res => res.json())
						.then(({token, user}) => {
							document.cookie = "rosebushToken=" + token + ";path=/;max-age=" + COOKIE_AGE;

							app.setUserInfo(user);

							if(this.props.continue) {
								route(this.props.continue);
							}
						}) :
					fetch("/api/v1/users/~me", {method: "PATCH", body: JSON.stringify(data)})
						.then(() => undefined)
			)
				.then(() => this.setState({success: true}))
				.catch(console.error)
				.then(() => this.setState({submitting: false}));
		});
	}
}