]> Untitled Git - lemmy-ui.git/blob - src/shared/components/home/site-sidebar.tsx
Adding new site setup fields. (#840)
[lemmy-ui.git] / src / shared / components / home / site-sidebar.tsx
1 import { None, Option } from "@sniptt/monads";
2 import { Component, linkEvent } from "inferno";
3 import { Link } from "inferno-router";
4 import { PersonViewSafe, Site, SiteAggregates } from "lemmy-js-client";
5 import { i18n } from "../../i18next";
6 import { mdToHtml, numToSI } from "../../utils";
7 import { BannerIconHeader } from "../common/banner-icon-header";
8 import { Icon } from "../common/icon";
9 import { PersonListing } from "../person/person-listing";
10
11 interface SiteSidebarProps {
12   site: Site;
13   showLocal: boolean;
14   counts: Option<SiteAggregates>;
15   admins: Option<PersonViewSafe[]>;
16   online: Option<number>;
17 }
18
19 interface SiteSidebarState {
20   collapsed: boolean;
21 }
22
23 export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
24   private emptyState: SiteSidebarState = {
25     collapsed: false,
26   };
27
28   constructor(props: any, context: any) {
29     super(props, context);
30     this.state = this.emptyState;
31   }
32
33   render() {
34     return (
35       <div className="card border-secondary mb-3">
36         <div className="card-body">
37           <div>
38             <div className="mb-2">{this.siteName()}</div>
39             {!this.state.collapsed && (
40               <>
41                 <BannerIconHeader banner={this.props.site.banner} icon={None} />
42                 {this.siteInfo()}
43               </>
44             )}
45           </div>
46         </div>
47       </div>
48     );
49   }
50
51   siteName() {
52     return (
53       <h5 className="mb-0 d-inline">
54         {this.props.site.name}
55         <button
56           className="btn btn-sm text-muted"
57           onClick={linkEvent(this, this.handleCollapseSidebar)}
58           aria-label={i18n.t("collapse")}
59           data-tippy-content={i18n.t("collapse")}
60         >
61           {this.state.collapsed ? (
62             <Icon icon="plus-square" classes="icon-inline" />
63           ) : (
64             <Icon icon="minus-square" classes="icon-inline" />
65           )}
66         </button>
67       </h5>
68     );
69   }
70
71   siteInfo() {
72     let site = this.props.site;
73     return (
74       <div>
75         {site.description.match({
76           some: description => <h6>{description}</h6>,
77           none: <></>,
78         })}
79         {site.sidebar.match({
80           some: sidebar => this.siteSidebar(sidebar),
81           none: <></>,
82         })}
83         {this.props.counts.match({
84           some: counts => this.badges(counts),
85           none: <></>,
86         })}
87         {this.props.admins.match({
88           some: admins => this.admins(admins),
89           none: <></>,
90         })}
91       </div>
92     );
93   }
94
95   siteSidebar(sidebar: string) {
96     return (
97       <div className="md-div" dangerouslySetInnerHTML={mdToHtml(sidebar)} />
98     );
99   }
100
101   admins(admins: PersonViewSafe[]) {
102     return (
103       <ul className="mt-1 list-inline small mb-0">
104         <li className="list-inline-item">{i18n.t("admins")}:</li>
105         {admins.map(av => (
106           <li key={av.person.id} className="list-inline-item">
107             <PersonListing person={av.person} />
108           </li>
109         ))}
110       </ul>
111     );
112   }
113
114   badges(siteAggregates: SiteAggregates) {
115     let counts = siteAggregates;
116     let online = this.props.online.unwrapOr(1);
117     return (
118       <ul className="my-2 list-inline">
119         <li className="list-inline-item badge badge-secondary">
120           {i18n.t("number_online", {
121             count: online,
122             formattedCount: numToSI(online),
123           })}
124         </li>
125         <li
126           className="list-inline-item badge badge-secondary pointer"
127           data-tippy-content={i18n.t("active_users_in_the_last_day", {
128             count: counts.users_active_day,
129             formattedCount: numToSI(counts.users_active_day),
130           })}
131         >
132           {i18n.t("number_of_users", {
133             count: counts.users_active_day,
134             formattedCount: numToSI(counts.users_active_day),
135           })}{" "}
136           / {i18n.t("day")}
137         </li>
138         <li
139           className="list-inline-item badge badge-secondary pointer"
140           data-tippy-content={i18n.t("active_users_in_the_last_week", {
141             count: counts.users_active_week,
142             formattedCount: counts.users_active_week,
143           })}
144         >
145           {i18n.t("number_of_users", {
146             count: counts.users_active_week,
147             formattedCount: numToSI(counts.users_active_week),
148           })}{" "}
149           / {i18n.t("week")}
150         </li>
151         <li
152           className="list-inline-item badge badge-secondary pointer"
153           data-tippy-content={i18n.t("active_users_in_the_last_month", {
154             count: counts.users_active_month,
155             formattedCount: counts.users_active_month,
156           })}
157         >
158           {i18n.t("number_of_users", {
159             count: counts.users_active_month,
160             formattedCount: numToSI(counts.users_active_month),
161           })}{" "}
162           / {i18n.t("month")}
163         </li>
164         <li
165           className="list-inline-item badge badge-secondary pointer"
166           data-tippy-content={i18n.t("active_users_in_the_last_six_months", {
167             count: counts.users_active_half_year,
168             formattedCount: counts.users_active_half_year,
169           })}
170         >
171           {i18n.t("number_of_users", {
172             count: counts.users_active_half_year,
173             formattedCount: numToSI(counts.users_active_half_year),
174           })}{" "}
175           / {i18n.t("number_of_months", { count: 6, formattedCount: 6 })}
176         </li>
177         <li className="list-inline-item badge badge-secondary">
178           {i18n.t("number_of_users", {
179             count: counts.users,
180             formattedCount: numToSI(counts.users),
181           })}
182         </li>
183         <li className="list-inline-item badge badge-secondary">
184           {i18n.t("number_of_communities", {
185             count: counts.communities,
186             formattedCount: numToSI(counts.communities),
187           })}
188         </li>
189         <li className="list-inline-item badge badge-secondary">
190           {i18n.t("number_of_posts", {
191             count: counts.posts,
192             formattedCount: numToSI(counts.posts),
193           })}
194         </li>
195         <li className="list-inline-item badge badge-secondary">
196           {i18n.t("number_of_comments", {
197             count: counts.comments,
198             formattedCount: numToSI(counts.comments),
199           })}
200         </li>
201         <li className="list-inline-item">
202           <Link className="badge badge-primary" to="/modlog">
203             {i18n.t("modlog")}
204           </Link>
205         </li>
206       </ul>
207     );
208   }
209
210   handleCollapseSidebar(i: SiteSidebar) {
211     i.setState({ collapsed: !i.state.collapsed });
212   }
213 }