aboutsummaryrefslogtreecommitdiffstats
path: root/client/src/ui/Menu.js
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2022-01-13 17:29:38 +0000
committers-ol <s+removethis@s-ol.nu>2022-01-13 17:29:38 +0000
commit31159ddff5bc489ab6216a72304e1f7c7ce4a432 (patch)
treee0c6efe46d4590c77ceabb4094c8ecd7c4289e00 /client/src/ui/Menu.js
parentmove everything into server/ (diff)
parentmove everything into client/ (diff)
downloadfedidag-31159ddff5bc489ab6216a72304e1f7c7ce4a432.tar.gz
fedidag-31159ddff5bc489ab6216a72304e1f7c7ce4a432.zip
Merge server and client repositories
Diffstat (limited to 'client/src/ui/Menu.js')
-rw-r--r--client/src/ui/Menu.js139
1 files changed, 139 insertions, 0 deletions
diff --git a/client/src/ui/Menu.js b/client/src/ui/Menu.js
new file mode 100644
index 0000000..6f32280
--- /dev/null
+++ b/client/src/ui/Menu.js
@@ -0,0 +1,139 @@
+import { h, Fragment } from 'preact';
+import { useState, useEffect } from 'preact/hooks';
+import cn from 'classnames';
+import { API_PREFIX } from '../config';
+import css from './css';
+
+const fetchJSON = async (url) => {
+ const res = await fetch(API_PREFIX + url, { credentials: 'include' });
+ if (res.status !== 200)
+ throw new Error("wrong status");
+
+ return res.json();
+};
+
+css`
+a.discussion {
+ display: flex;
+
+ padding: 0.25rem 0.5rem;
+ text-size: 2rem;
+ line-height: 2rem;
+ text-decoration: none;
+
+ border-radius: 0.3rem;
+
+ color: var(--theme-note-fg);
+ background: var(--theme-note-bg);
+}
+
+a.discussion .access {
+ opacity: 0.5;
+ margin-right: 0.75rem;
+}
+
+a.discussion .name {
+ flex: 1 1 auto;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+a.discussion > a {
+ margin-left: 0.75rem;
+ text-decoration: underline;
+ color: inherit;
+ opacity: 0.5;
+
+ transition: opacity 0.3s;
+}
+a.discussion > a:hover {
+ opacity: 1;
+}
+`;
+
+const DiscussionLink = ({ id, name, url, attributedTo, user }) => {
+ const writable = attributedTo && attributedTo.indexOf(user) > -1;
+
+ return (
+ <a class="discussion" href={`?document=${id}`}>
+ <span class="access">{writable ? 'W' : 'R'}</span>
+ <span class="name">{name}</span>
+ {url && (
+ <a href={url.href}>ext</a>
+ )}
+ </a>
+ );
+};
+
+css`
+ul.discussions {
+ list-style: none;
+ padding: 0;
+
+ width: 26rem;
+}
+
+ul.discussions > li {
+ margin: 0.2rem 0;
+}
+`;
+
+const DiscussionList = ({ discussions, user }) => {
+ return (
+ <ul class="discussions">
+ {discussions.map((discussion) => (
+ <li>
+ <DiscussionLink {...discussion} user={user} />
+ </li>
+ ))}
+ </ul>
+ );
+};
+
+css`
+div.menu {
+ margin: 1rem 2rem;
+}
+`;
+export const Menu = () => {
+ const [user, setUser] = useState(null);
+ const [discussions, setDiscussions] = useState([]);
+
+ useEffect(() => {
+ fetchJSON('/discdag/list')
+ .then(({ user, discussions }) => {
+ setUser(user ?? null);
+ setDiscussions(discussions);
+ });
+ }, []);
+
+ if (user === null) {
+ return (
+ <div class="menu">
+ <h2>Discussions</h2>
+ loading...
+ </div>
+ );
+ }
+
+ return (
+ <div class="menu">
+ <h2>Discussions</h2>
+ {/*user && user.name !== 'Guest'
+ ? (
+ <>
+ <span>logged in as {user.name}</span>
+ <button>log out</button>
+ </>
+ )
+ : (
+ <>
+ <span>not logged in</span>
+ <button>log in</button>
+ </>
+ )*/}
+ <DiscussionList discussions={discussions} user={user?.id} />
+ </div>
+ );
+};