]> Untitled Git - lemmy-ui.git/blob - src/shared/components/home/setup.tsx
f4bdb5551d6deb48dc74af2224eea158e4f83579
[lemmy-ui.git] / src / shared / components / home / setup.tsx
1 import { fetchThemeList, setIsoData } from "@utils/app";
2 import { Component, linkEvent } from "inferno";
3 import { Helmet } from "inferno-helmet";
4 import {
5   CreateSite,
6   GetSiteResponse,
7   LoginResponse,
8   Register,
9 } from "lemmy-js-client";
10 import { I18NextService, UserService } from "../../services";
11 import { HttpService, RequestState } from "../../services/HttpService";
12 import { Spinner } from "../common/icon";
13 import { SiteForm } from "./site-form";
14
15 interface State {
16   form: {
17     username?: string;
18     email?: string;
19     password?: string;
20     password_verify?: string;
21     show_nsfw: boolean;
22     captcha_uuid?: string;
23     captcha_answer?: string;
24     honeypot?: string;
25     answer?: string;
26   };
27   doneRegisteringUser: boolean;
28   registerRes: RequestState<LoginResponse>;
29   themeList: string[];
30   siteRes: GetSiteResponse;
31 }
32
33 export class Setup extends Component<any, State> {
34   private isoData = setIsoData(this.context);
35
36   state: State = {
37     registerRes: { state: "empty" },
38     themeList: [],
39     form: {
40       show_nsfw: true,
41     },
42     doneRegisteringUser: !!UserService.Instance.myUserInfo,
43     siteRes: this.isoData.site_res,
44   };
45
46   constructor(props: any, context: any) {
47     super(props, context);
48
49     this.handleCreateSite = this.handleCreateSite.bind(this);
50   }
51
52   async componentDidMount() {
53     this.setState({ themeList: await fetchThemeList() });
54   }
55
56   get documentTitle(): string {
57     return `${I18NextService.i18n.t("setup")} - Lemmy`;
58   }
59
60   render() {
61     return (
62       <div className="home-setup container-lg">
63         <Helmet title={this.documentTitle} />
64         <div className="row">
65           <div className="col-12 offset-lg-3 col-lg-6">
66             <h1 className="h4 mb-4">
67               {I18NextService.i18n.t("lemmy_instance_setup")}
68             </h1>
69             {!this.state.doneRegisteringUser ? (
70               this.registerUser()
71             ) : (
72               <SiteForm
73                 showLocal
74                 onSaveSite={this.handleCreateSite}
75                 siteRes={this.state.siteRes}
76                 themeList={this.state.themeList}
77                 loading={false}
78               />
79             )}
80           </div>
81         </div>
82       </div>
83     );
84   }
85
86   registerUser() {
87     return (
88       <form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
89         <h2 className="h5 mb-3">{I18NextService.i18n.t("setup_admin")}</h2>
90         <div className="mb-3 row">
91           <label className="col-sm-2 col-form-label" htmlFor="username">
92             {I18NextService.i18n.t("username")}
93           </label>
94           <div className="col-sm-10">
95             <input
96               type="text"
97               className="form-control"
98               id="username"
99               value={this.state.form.username}
100               onInput={linkEvent(this, this.handleRegisterUsernameChange)}
101               required
102               minLength={3}
103               pattern="[a-zA-Z0-9_]+"
104             />
105           </div>
106         </div>
107         <div className="mb-3 row">
108           <label className="col-sm-2 col-form-label" htmlFor="email">
109             {I18NextService.i18n.t("email")}
110           </label>
111
112           <div className="col-sm-10">
113             <input
114               type="email"
115               id="email"
116               className="form-control"
117               placeholder={I18NextService.i18n.t("optional")}
118               value={this.state.form.email}
119               onInput={linkEvent(this, this.handleRegisterEmailChange)}
120               minLength={3}
121             />
122           </div>
123         </div>
124         <div className="mb-3 row">
125           <label className="col-sm-2 col-form-label" htmlFor="password">
126             {I18NextService.i18n.t("password")}
127           </label>
128           <div className="col-sm-10">
129             <input
130               type="password"
131               id="password"
132               value={this.state.form.password}
133               onInput={linkEvent(this, this.handleRegisterPasswordChange)}
134               className="form-control"
135               required
136               autoComplete="new-password"
137               minLength={10}
138               maxLength={60}
139             />
140           </div>
141         </div>
142         <div className="mb-3 row">
143           <label className="col-sm-2 col-form-label" htmlFor="verify-password">
144             {I18NextService.i18n.t("verify_password")}
145           </label>
146           <div className="col-sm-10">
147             <input
148               type="password"
149               id="verify-password"
150               value={this.state.form.password_verify}
151               onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)}
152               className="form-control"
153               required
154               autoComplete="new-password"
155               minLength={10}
156               maxLength={60}
157             />
158           </div>
159         </div>
160         <div className="mb-3 row">
161           <div className="col-sm-10">
162             <button type="submit" className="btn btn-secondary">
163               {this.state.registerRes.state == "loading" ? (
164                 <Spinner />
165               ) : (
166                 I18NextService.i18n.t("sign_up")
167               )}
168             </button>
169           </div>
170         </div>
171       </form>
172     );
173   }
174
175   async handleRegisterSubmit(i: Setup, event: any) {
176     event.preventDefault();
177     i.setState({ registerRes: { state: "loading" } });
178     const {
179       username,
180       password_verify,
181       password,
182       email,
183       show_nsfw,
184       captcha_uuid,
185       captcha_answer,
186       honeypot,
187       answer,
188     } = i.state.form;
189
190     if (username && password && password_verify) {
191       const form: Register = {
192         username,
193         password,
194         password_verify,
195         email,
196         show_nsfw,
197         captcha_uuid,
198         captcha_answer,
199         honeypot,
200         answer,
201       };
202       i.setState({
203         registerRes: await HttpService.client.register(form),
204       });
205
206       if (i.state.registerRes.state == "success") {
207         const data = i.state.registerRes.data;
208
209         UserService.Instance.login({ res: data });
210         i.setState({ doneRegisteringUser: true });
211       }
212     }
213   }
214
215   async handleCreateSite(form: CreateSite) {
216     const createRes = await HttpService.client.createSite(form);
217     if (createRes.state === "success") {
218       this.props.history.replace("/");
219       location.reload();
220     }
221   }
222
223   handleRegisterUsernameChange(i: Setup, event: any) {
224     i.state.form.username = event.target.value.trim();
225     i.setState(i.state);
226   }
227
228   handleRegisterEmailChange(i: Setup, event: any) {
229     i.state.form.email = event.target.value;
230     i.setState(i.state);
231   }
232
233   handleRegisterPasswordChange(i: Setup, event: any) {
234     i.state.form.password = event.target.value;
235     i.setState(i.state);
236   }
237
238   handleRegisterPasswordVerifyChange(i: Setup, event: any) {
239     i.state.form.password_verify = event.target.value;
240     i.setState(i.state);
241   }
242 }