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