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