1import { useState, useEffect } from "react";
2import { Link } from "react-router-dom";
3import { ExternalLink } from "lucide-react";
4import {
5 SiFirefox,
6 SiGooglechrome,
7 SiGithub,
8 SiBluesky,
9 SiApple,
10 SiKofi,
11 SiDiscord,
12} from "react-icons/si";
13import { FaEdge } from "react-icons/fa";
14import { useAuth } from "../context/AuthContext";
15import { getTrendingTags } from "../api/client";
16
17const isFirefox =
18 typeof navigator !== "undefined" && /Firefox/i.test(navigator.userAgent);
19const isEdge =
20 typeof navigator !== "undefined" && /Edg/i.test(navigator.userAgent);
21const isMobileSafari =
22 typeof navigator !== "undefined" &&
23 /iPhone|iPad|iPod/.test(navigator.userAgent) &&
24 /Safari/.test(navigator.userAgent) &&
25 !/CriOS|FxiOS|OPiOS|EdgiOS/.test(navigator.userAgent);
26
27function getExtensionInfo() {
28 if (isMobileSafari) {
29 return {
30 url: "https://margin.at/soon",
31 icon: SiApple,
32 name: "iOS",
33 label: "Coming Soon",
34 };
35 }
36 if (isFirefox) {
37 return {
38 url: "https://addons.mozilla.org/en-US/firefox/addon/margin/",
39 icon: SiFirefox,
40 name: "Firefox",
41 label: "Install for Firefox",
42 };
43 }
44 if (isEdge) {
45 return {
46 url: "https://microsoftedge.microsoft.com/addons/detail/margin/nfjnmllpdgcdnhmmggjihjbidmeadddn",
47 icon: FaEdge,
48 name: "Edge",
49 label: "Install for Edge",
50 };
51 }
52 return {
53 url: "https://chromewebstore.google.com/detail/margin/cgpmbiiagnehkikhcbnhiagfomajncpa/",
54 icon: SiGooglechrome,
55 name: "Chrome",
56 label: "Install for Chrome",
57 };
58}
59
60export default function RightSidebar() {
61 const { isAuthenticated } = useAuth();
62 const ext = getExtensionInfo();
63 const ExtIcon = ext.icon;
64 const [trendingTags, setTrendingTags] = useState([]);
65 const [loading, setLoading] = useState(true);
66
67 useEffect(() => {
68 getTrendingTags()
69 .then((tags) => setTrendingTags(tags))
70 .catch((err) => console.error("Failed to fetch trending tags:", err))
71 .finally(() => setLoading(false));
72 }, []);
73
74 return (
75 <aside className="right-sidebar">
76 <div className="right-section">
77 <h3 className="right-section-title">
78 {isMobileSafari ? "Save from Safari" : "Get the Extension"}
79 </h3>
80 <p className="right-section-desc">
81 {isMobileSafari
82 ? "Bookmark pages using Safari's share sheet"
83 : "Annotate, highlight, and bookmark any webpage"}
84 </p>
85 <a
86 href={ext.url}
87 target="_blank"
88 rel="noopener noreferrer"
89 className="right-extension-btn"
90 >
91 <ExtIcon size={18} />
92 {ext.label}
93 <ExternalLink size={14} />
94 </a>
95 </div>
96
97 {isAuthenticated ? (
98 <div className="right-section">
99 <h3 className="right-section-title">Trending Tags</h3>
100 <div className="right-links">
101 {loading ? (
102 <span className="right-section-desc">Loading...</span>
103 ) : trendingTags.length > 0 ? (
104 trendingTags.map(({ tag, count }) => (
105 <Link
106 key={tag}
107 to={`/?tag=${encodeURIComponent(tag)}`}
108 className="right-link"
109 >
110 <span>#{tag}</span>
111 <span style={{ fontSize: "0.75rem", opacity: 0.6 }}>
112 {count}
113 </span>
114 </Link>
115 ))
116 ) : (
117 <span className="right-section-desc">No trending tags yet</span>
118 )}
119 </div>
120 </div>
121 ) : (
122 <div className="right-section">
123 <h3 className="right-section-title">Explore</h3>
124 <nav className="right-links">
125 <Link to="/url" className="right-link">
126 Browse by URL
127 </Link>
128 </nav>
129 </div>
130 )}
131
132 <div className="right-section">
133 <h3 className="right-section-title">Resources</h3>
134 <nav className="right-links">
135 <a
136 href="https://github.com/margin-at/margin"
137 target="_blank"
138 rel="noopener noreferrer"
139 className="right-link"
140 >
141 <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
142 <SiGithub size={16} />
143 GitHub
144 </div>
145 <ExternalLink size={12} />
146 </a>
147 <a
148 href="https://tangled.org/margin.at/margin"
149 target="_blank"
150 rel="noopener noreferrer"
151 className="right-link"
152 >
153 <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
154 <div className="tangled-icon" />
155 Tangled
156 </div>
157 <ExternalLink size={12} />
158 </a>
159 <a
160 href="https://bsky.app/profile/margin.at"
161 target="_blank"
162 rel="noopener noreferrer"
163 className="right-link"
164 >
165 <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
166 <SiBluesky size={16} />
167 Bluesky
168 </div>
169 <ExternalLink size={12} />
170 </a>
171 <a
172 href="https://discord.gg/ZQbkGqwzBH"
173 target="_blank"
174 rel="noopener noreferrer"
175 className="right-link"
176 >
177 <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
178 <SiDiscord size={16} />
179 Discord
180 </div>
181 <ExternalLink size={12} />
182 </a>
183 <a
184 href="https://ko-fi.com/scan"
185 target="_blank"
186 rel="noopener noreferrer"
187 className="right-link"
188 >
189 <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
190 <SiKofi size={16} />
191 Donate
192 </div>
193 <ExternalLink size={12} />
194 </a>
195 </nav>
196 </div>
197
198 <div className="right-footer">
199 <Link to="/privacy">Privacy</Link>
200 <span>·</span>
201 <Link to="/terms">Terms</Link>
202 </div>
203 </aside>
204 );
205}