]> Untitled Git - lemmy-ui.git/blob - src/shared/components/common/registration-application.tsx
6e6914b3fb616396f79fae51191a33334e4c63e9
[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 { i18n } from "../../i18next";
9 import { mdToHtml } from "../../markdown";
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           {i18n.t("applicant")}: <PersonListing person={a.creator} />
65         </div>
66         <div>
67           {i18n.t("created")}: <MomentTime showAgo published={ra.published} />
68         </div>
69         <div>{i18n.t("answer")}:</div>
70         <div className="md-div" dangerouslySetInnerHTML={mdToHtml(ra.answer)} />
71
72         {a.admin && (
73           <div>
74             {accepted ? (
75               <T i18nKey="approved_by">
76                 #
77                 <PersonListing person={a.admin} />
78               </T>
79             ) : (
80               <div>
81                 <T i18nKey="denied_by">
82                   #
83                   <PersonListing person={a.admin} />
84                 </T>
85                 {ra.deny_reason && (
86                   <div>
87                     {i18n.t("deny_reason")}:{" "}
88                     <div
89                       className="md-div d-inline-flex"
90                       dangerouslySetInnerHTML={mdToHtml(ra.deny_reason)}
91                     />
92                   </div>
93                 )}
94               </div>
95             )}
96           </div>
97         )}
98
99         {this.state.denyExpanded && (
100           <div className="mb-3 row">
101             <label className="col-sm-2 col-form-label">
102               {i18n.t("deny_reason")}
103             </label>
104             <div className="col-sm-10">
105               <MarkdownTextArea
106                 initialContent={this.state.denyReason}
107                 onContentChange={this.handleDenyReasonChange}
108                 hideNavigationWarnings
109                 allLanguages={[]}
110                 siteLanguages={[]}
111               />
112             </div>
113           </div>
114         )}
115         {(!ra.admin_id || (ra.admin_id && !accepted)) && (
116           <button
117             className="btn btn-secondary me-2 my-2"
118             onClick={linkEvent(this, this.handleApprove)}
119             aria-label={i18n.t("approve")}
120           >
121             {this.state.approveLoading ? <Spinner /> : i18n.t("approve")}
122           </button>
123         )}
124         {(!ra.admin_id || (ra.admin_id && accepted)) && (
125           <button
126             className="btn btn-secondary me-2"
127             onClick={linkEvent(this, this.handleDeny)}
128             aria-label={i18n.t("deny")}
129           >
130             {this.state.denyLoading ? <Spinner /> : i18n.t("deny")}
131           </button>
132         )}
133       </div>
134     );
135   }
136
137   handleApprove(i: RegistrationApplication) {
138     i.setState({ denyExpanded: false, approveLoading: true });
139     i.props.onApproveApplication({
140       id: i.props.application.registration_application.id,
141       approve: true,
142       auth: myAuthRequired(),
143     });
144   }
145
146   handleDeny(i: RegistrationApplication) {
147     if (i.state.denyExpanded) {
148       i.setState({ denyExpanded: false, denyLoading: true });
149       i.props.onApproveApplication({
150         id: i.props.application.registration_application.id,
151         approve: false,
152         deny_reason: i.state.denyReason,
153         auth: myAuthRequired(),
154       });
155     } else {
156       i.setState({ denyExpanded: true });
157     }
158   }
159
160   handleDenyReasonChange(val: string) {
161     this.setState({ denyReason: val });
162   }
163 }