]> Untitled Git - lemmy-ui.git/blob - src/shared/components/home/site-sidebar.tsx
feat: Move Badges to common component
[lemmy-ui.git] / src / shared / components / home / site-sidebar.tsx
1 import { Component, linkEvent } from "inferno";
2 import { PersonView, Site, SiteAggregates } from "lemmy-js-client";
3 import { i18n } from "../../i18next";
4 import { mdToHtml } from "../../utils";
5 import { Badges } from "../common/badges";
6 import { BannerIconHeader } from "../common/banner-icon-header";
7 import { Icon } from "../common/icon";
8 import { PersonListing } from "../person/person-listing";
9
10 interface SiteSidebarProps {
11   site: Site;
12   showLocal: boolean;
13   counts?: SiteAggregates;
14   admins?: PersonView[];
15   online?: number;
16 }
17
18 interface SiteSidebarState {
19   collapsed: boolean;
20 }
21
22 export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
23   state: SiteSidebarState = {
24     collapsed: false,
25   };
26
27   constructor(props: any, context: any) {
28     super(props, context);
29   }
30
31   render() {
32     return (
33       <div className="card border-secondary mb-3">
34         <div className="card-body">
35           <div>
36             <div className="mb-2">{this.siteName()}</div>
37             {!this.state.collapsed && (
38               <>
39                 <BannerIconHeader banner={this.props.site.banner} />
40                 {this.siteInfo()}
41               </>
42             )}
43           </div>
44         </div>
45       </div>
46     );
47   }
48
49   siteName() {
50     return (
51       <h5 className="mb-0 d-inline">
52         {this.props.site.name}
53         <button
54           className="btn btn-sm text-muted"
55           onClick={linkEvent(this, this.handleCollapseSidebar)}
56           aria-label={i18n.t("collapse")}
57           data-tippy-content={i18n.t("collapse")}
58         >
59           {this.state.collapsed ? (
60             <Icon icon="plus-square" classes="icon-inline" />
61           ) : (
62             <Icon icon="minus-square" classes="icon-inline" />
63           )}
64         </button>
65       </h5>
66     );
67   }
68
69   siteInfo() {
70     const site = this.props.site;
71     return (
72       <div>
73         {site.description && <h6>{site.description}</h6>}
74         {site.sidebar && this.siteSidebar(site.sidebar)}
75         {this.props.counts && (
76           <Badges online={this.props.online ?? 1} counts={this.props.counts} />
77         )}
78         {this.props.admins && this.admins(this.props.admins)}
79       </div>
80     );
81   }
82
83   siteSidebar(sidebar: string) {
84     return (
85       <div className="md-div" dangerouslySetInnerHTML={mdToHtml(sidebar)} />
86     );
87   }
88
89   admins(admins: PersonView[]) {
90     return (
91       <ul className="mt-1 list-inline small mb-0">
92         <li className="list-inline-item">{i18n.t("admins")}:</li>
93         {admins.map(av => (
94           <li key={av.person.id} className="list-inline-item">
95             <PersonListing person={av.person} />
96           </li>
97         ))}
98       </ul>
99     );
100   }
101
102   handleCollapseSidebar(i: SiteSidebar) {
103     i.setState({ collapsed: !i.state.collapsed });
104   }
105 }