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