]> Untitled Git - lemmy-ui.git/blob - src/shared/components/common/registration-application.tsx
Fix I18 next circular reference
[lemmy-ui.git] / src / shared / components / common / registration-application.tsx
1 import { myAuthRequired } from "@utils/app";
2 import { Component, InfernoNode, linkEvent } from "inferno";
3 import { T } from "inferno-i18next-dess";
4 import {
5   ApproveRegistrationApplication,
6   RegistrationApplicationView,
7 } from "lemmy-js-client";
8 import { mdToHtml } from "../../markdown";
9 import { I18NextService } from "../../services";
10 import { PersonListing } from "../person/person-listing";
11 import { Spinner } from "./icon";
12 import { MarkdownTextArea } from "./markdown-textarea";
13 import { MomentTime } from "./moment-time";
14
15 interface RegistrationApplicationProps {
16   application: RegistrationApplicationView;
17   onApproveApplication(form: ApproveRegistrationApplication): void;
18 }
19
20 interface RegistrationApplicationState {
21   denyReason?: string;
22   denyExpanded: boolean;
23   approveLoading: boolean;
24   denyLoading: boolean;
25 }
26
27 export class RegistrationApplication extends Component<
28   RegistrationApplicationProps,
29   RegistrationApplicationState
30 > {
31   state: RegistrationApplicationState = {
32     denyReason: this.props.application.registration_application.deny_reason,
33     denyExpanded: false,
34     approveLoading: false,
35     denyLoading: false,
36   };
37
38   constructor(props: any, context: any) {
39     super(props, context);
40     this.handleDenyReasonChange = this.handleDenyReasonChange.bind(this);
41   }
42   componentWillReceiveProps(
43     nextProps: Readonly<
44       { children?: InfernoNode } & RegistrationApplicationProps
45     >
46   ): void {
47     if (this.props != nextProps) {
48       this.setState({
49         denyExpanded: false,
50         approveLoading: false,
51         denyLoading: false,
52       });
53     }
54   }
55
56   render() {
57     const a = this.props.application;
58     const ra = this.props.application.registration_application;
59     const accepted = a.creator_local_user.accepted_application;
60
61     return (
62       <div className="registration-application">
63         <div>
64           {I18NextService.i18n.t("applicant")}:{" "}
65           <PersonListing person={a.creator} />
66         </div>
67         <div>
68           {I18NextService.i18n.t("created")}:{" "}
69           <MomentTime showAgo published={ra.published} />
70         </div>
71         <div>{I18NextService.i18n.t("answer")}:</div>
72         <div className="md-div" dangerouslySetInnerHTML={mdToHtml(ra.answer)} />
73
74         {a.admin && (
75           <div>
76             {accepted ? (
77               <T i18nKey="approved_by">
78                 #
79                 <PersonListing person={a.admin} />
80               </T>
81             ) : (
82               <div>
83                 <T i18nKey="denied_by">
84                   #
85                   <PersonListing person={a.admin} />
86                 </T>
87                 {ra.deny_reason && (
88                   <div>
89                     {I18NextService.i18n.t("deny_reason")}:{" "}
90                     <div
91                       className="md-div d-inline-flex"
92                       dangerouslySetInnerHTML={mdToHtml(ra.deny_reason)}
93                     />
94                   </div>
95                 )}
96               </div>
97             )}
98           </div>
99         )}
100
101         {this.state.denyExpanded && (
102           <div className="mb-3 row">
103             <label className="col-sm-2 col-form-label">
104               {I18NextService.i18n.t("deny_reason")}
105             </label>
106             <div className="col-sm-10">
107               <MarkdownTextArea
108                 initialContent={this.state.denyReason}
109                 onContentChange={this.handleDenyReasonChange}
110                 hideNavigationWarnings
111                 allLanguages={[]}
112                 siteLanguages={[]}
113               />
114             </div>
115           </div>
116         )}
117         {(!ra.admin_id || (ra.admin_id && !accepted)) && (
118           <button
119             className="btn btn-secondary me-2 my-2"
120             onClick={linkEvent(this, this.handleApprove)}
121             aria-label={I18NextService.i18n.t("approve")}
122           >
123             {this.state.approveLoading ? (
124               <Spinner />
125             ) : (
126               I18NextService.i18n.t("approve")
127             )}
128           </button>
129         )}
130         {(!ra.admin_id || (ra.admin_id && accepted)) && (
131           <button
132             className="btn btn-secondary me-2"
133             onClick={linkEvent(this, this.handleDeny)}
134             aria-label={I18NextService.i18n.t("deny")}
135           >
136             {this.state.denyLoading ? (
137               <Spinner />
138             ) : (
139               I18NextService.i18n.t("deny")
140             )}
141           </button>
142         )}
143       </div>
144     );
145   }
146
147   handleApprove(i: RegistrationApplication) {
148     i.setState({ denyExpanded: false, approveLoading: true });
149     i.props.onApproveApplication({
150       id: i.props.application.registration_application.id,
151       approve: true,
152       auth: myAuthRequired(),
153     });
154   }
155
156   handleDeny(i: RegistrationApplication) {
157     if (i.state.denyExpanded) {
158       i.setState({ denyExpanded: false, denyLoading: true });
159       i.props.onApproveApplication({
160         id: i.props.application.registration_application.id,
161         approve: false,
162         deny_reason: i.state.denyReason,
163         auth: myAuthRequired(),
164       });
165     } else {
166       i.setState({ denyExpanded: true });
167     }
168   }
169
170   handleDenyReasonChange(val: string) {
171     this.setState({ denyReason: val });
172   }
173 }