]> Untitled Git - lemmy-ui.git/blob - src/shared/components/home/tagline-form.tsx
Merge pull request #1421 from djvs/feat/component-classes-v2
[lemmy-ui.git] / src / shared / components / home / tagline-form.tsx
1 import { Component, InfernoMouseEvent, linkEvent } from "inferno";
2 import { EditSite, Tagline } from "lemmy-js-client";
3 import { i18n } from "../../i18next";
4 import { capitalizeFirstLetter, myAuthRequired } from "../../utils";
5 import { HtmlTags } from "../common/html-tags";
6 import { Icon, Spinner } from "../common/icon";
7 import { MarkdownTextArea } from "../common/markdown-textarea";
8
9 interface TaglineFormProps {
10   taglines: Array<Tagline>;
11   onSaveSite(form: EditSite): void;
12   loading: boolean;
13 }
14
15 interface TaglineFormState {
16   taglines: Array<string>;
17   editingRow?: number;
18 }
19
20 export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
21   state: TaglineFormState = {
22     editingRow: undefined,
23     taglines: this.props.taglines.map(x => x.content),
24   };
25   constructor(props: any, context: any) {
26     super(props, context);
27   }
28   get documentTitle(): string {
29     return i18n.t("taglines");
30   }
31
32   render() {
33     return (
34       <div className="tagline-form col-12">
35         <HtmlTags
36           title={this.documentTitle}
37           path={this.context.router.route.match.url}
38         />
39         <h5 className="col-12">{i18n.t("taglines")}</h5>
40         <div className="table-responsive col-12">
41           <table id="taglines_table" className="table table-sm table-hover">
42             <thead className="pointer">
43               <th></th>
44               <th style="width:121px"></th>
45             </thead>
46             <tbody>
47               {this.state.taglines.map((cv, index) => (
48                 <tr key={index}>
49                   <td>
50                     {this.state.editingRow == index && (
51                       <MarkdownTextArea
52                         initialContent={cv}
53                         onContentChange={s =>
54                           this.handleTaglineChange(this, index, s)
55                         }
56                         hideNavigationWarnings
57                         allLanguages={[]}
58                         siteLanguages={[]}
59                       />
60                     )}
61                     {this.state.editingRow != index && <div>{cv}</div>}
62                   </td>
63                   <td className="text-right">
64                     <button
65                       className="btn btn-link btn-animate text-muted"
66                       onClick={linkEvent(
67                         { i: this, index: index },
68                         this.handleEditTaglineClick
69                       )}
70                       data-tippy-content={i18n.t("edit")}
71                       aria-label={i18n.t("edit")}
72                     >
73                       <Icon icon="edit" classes={`icon-inline`} />
74                     </button>
75
76                     <button
77                       className="btn btn-link btn-animate text-muted"
78                       onClick={linkEvent(
79                         { i: this, index: index },
80                         this.handleDeleteTaglineClick
81                       )}
82                       data-tippy-content={i18n.t("delete")}
83                       aria-label={i18n.t("delete")}
84                     >
85                       <Icon icon="trash" classes={`icon-inline text-danger`} />
86                     </button>
87                   </td>
88                 </tr>
89               ))}
90             </tbody>
91           </table>
92           <div className="mb-3 row">
93             <div className="col-12">
94               <button
95                 className="btn btn-sm btn-secondary me-2"
96                 onClick={linkEvent(this, this.handleAddTaglineClick)}
97               >
98                 {i18n.t("add_tagline")}
99               </button>
100             </div>
101           </div>
102
103           <div className="mb-3 row">
104             <div className="col-12">
105               <button
106                 onClick={linkEvent(this, this.handleSaveClick)}
107                 className="btn btn-secondary me-2"
108                 disabled={this.props.loading}
109               >
110                 {this.props.loading ? (
111                   <Spinner />
112                 ) : (
113                   capitalizeFirstLetter(i18n.t("save"))
114                 )}
115               </button>
116             </div>
117           </div>
118         </div>
119       </div>
120     );
121   }
122
123   handleTaglineChange(i: TaglineForm, index: number, val: string) {
124     if (i.state.taglines) {
125       i.setState(prev => ({
126         ...prev,
127         taglines: prev.taglines.map((tl, i) => (i === index ? val : tl)),
128       }));
129     }
130   }
131
132   handleDeleteTaglineClick(d: { i: TaglineForm; index: number }, event: any) {
133     event.preventDefault();
134     d.i.setState(prev => ({
135       ...prev,
136       taglines: prev.taglines.filter((_, i) => i !== d.index),
137       editingRow: undefined,
138     }));
139   }
140
141   handleEditTaglineClick(d: { i: TaglineForm; index: number }, event: any) {
142     event.preventDefault();
143     if (this.state.editingRow == d.index) {
144       d.i.setState({ editingRow: undefined });
145     } else {
146       d.i.setState({ editingRow: d.index });
147     }
148   }
149
150   async handleSaveClick(i: TaglineForm) {
151     i.props.onSaveSite({
152       taglines: i.state.taglines,
153       auth: myAuthRequired(),
154     });
155   }
156
157   handleAddTaglineClick(
158     i: TaglineForm,
159     event: InfernoMouseEvent<HTMLButtonElement>
160   ) {
161     event.preventDefault();
162     const newTaglines = [...i.state.taglines];
163     newTaglines.push("");
164
165     i.setState({
166       taglines: newTaglines,
167       editingRow: newTaglines.length - 1,
168     });
169   }
170 }