diff options
Diffstat (limited to 'client/src/ui')
| -rw-r--r-- | client/src/ui/Menu.js | 109 |
1 files changed, 71 insertions, 38 deletions
diff --git a/client/src/ui/Menu.js b/client/src/ui/Menu.js index 6f32280..f3e912d 100644 --- a/client/src/ui/Menu.js +++ b/client/src/ui/Menu.js @@ -1,17 +1,9 @@ import { h, Fragment } from 'preact'; -import { useState, useEffect } from 'preact/hooks'; +import { useState } from 'preact/hooks'; import cn from 'classnames'; -import { API_PREFIX } from '../config'; +import { useUser, useUserCtx } from '../user'; 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; @@ -52,8 +44,9 @@ a.discussion > a:hover { } `; -const DiscussionLink = ({ id, name, url, attributedTo, user }) => { - const writable = attributedTo && attributedTo.indexOf(user) > -1; +const DiscussionLink = ({ id, name, url, attributedTo }) => { + const { user } = useUser(); + const writable = user && attributedTo && attributedTo.indexOf(user.id) > -1; return ( <a class="discussion" href={`?document=${id}`}> @@ -79,12 +72,12 @@ ul.discussions > li { } `; -const DiscussionList = ({ discussions, user }) => { +const DiscussionList = ({ discussions }) => { return ( <ul class="discussions"> {discussions.map((discussion) => ( <li> - <DiscussionLink {...discussion} user={user} /> + <DiscussionLink {...discussion} /> </li> ))} </ul> @@ -92,21 +85,73 @@ const DiscussionList = ({ discussions, user }) => { }; css` +div.menu div.user { + display: flex; + align-items: baseline; + gap: 1em; +} +`; +const UserMenu = () => { + const [showLogin, setLogin] = useState(false); + const { state: { user }, dispatch } = useUserCtx(); + + if (showLogin) { + return ( + <form class="user" onSubmit={(e) => { + e.preventDefault(); + + const elem = e.target.elements; + const username = elem.namedItem('username').value; + const password = elem.namedItem('password').value; + + dispatch({ type: 'login', username, password }) + .then( + () => setLogin(false), + (err) => setLogin("error - wrong username/password?"), + ); + + }}> + {showLogin !== true ? <p>{showLogin}</p> : null} + <div> + <label>username</label> + <input name="username" autocomplete="username" required /> + </div> + <div> + <label>password</label> + <input name="password" autocomplete="password" type="password" required /> + </div> + <input type="submit" value="login" /> + <button onClick={(e) => { e.preventDefault(); setLogin(false)}}>cancel</button> + </form> + ); + } + + return ( + <div class="user"> + {user && user.name !== 'Guest' + ? ( + <> + <span>logged in as {user.name}</span> + <button onClick={() => dispatch({ type: 'logout' })}>log out</button> + </> + ) + : ( + <> + <span>not logged in</span> + <button onClick={() => setLogin(true)}>log in</button> + </> + )} + </div> + ); +}; + +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); - }); - }, []); + const { user, discussions } = useUser(); if (user === null) { return ( @@ -120,20 +165,8 @@ export const Menu = () => { 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} /> + <UserMenu /> + <DiscussionList discussions={discussions} /> </div> ); }; |
