aboutsummaryrefslogtreecommitdiffstats
path: root/client/src/user.js
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2022-01-14 15:53:47 +0000
committers-ol <s+removethis@s-ol.nu>2022-01-14 15:53:47 +0000
commit569d322f516ddb7271f89222f11ede68caf7fefb (patch)
treed826b0bab30595af161f588fc4b47068ce8be3c7 /client/src/user.js
parentsmall fixes (diff)
downloadfedidag-569d322f516ddb7271f89222f11ede68caf7fefb.tar.gz
fedidag-569d322f516ddb7271f89222f11ede68caf7fefb.zip
login/logout
Diffstat (limited to 'client/src/user.js')
-rw-r--r--client/src/user.js71
1 files changed, 71 insertions, 0 deletions
diff --git a/client/src/user.js b/client/src/user.js
new file mode 100644
index 0000000..dfa6384
--- /dev/null
+++ b/client/src/user.js
@@ -0,0 +1,71 @@
+import { h, createContext } from 'preact';
+import { useRef, useState, useCallback, useEffect, useContext } from 'preact/hooks';
+import { API_PREFIX } from './config';
+
+const fetchJSON = async (url, method='GET', data=undefined) => {
+ const res = await fetch(API_PREFIX + url, {
+ method,
+ credentials: 'include',
+ headers: { 'content-type': data && 'application/json' },
+ body: data && JSON.stringify(data),
+ });
+
+ if (res.status !== 200)
+ throw new Error("wrong status");
+
+ return res.json();
+};
+
+const initialState = { user: null, discussions: [] };
+const reducer = async (action, ref) => {
+ switch (action.type) {
+ case 'login': {
+ const { username, password } = action;
+ await fetchJSON('/discdag/login', 'POST', { username, password });
+ return await reducer({ type: 'refresh' }, ref);
+ }
+
+ case 'logout': {
+ await fetchJSON('/discdag/logout', 'POST');
+ return await reducer({ type: 'refresh' }, ref);
+ }
+
+ case 'refresh': {
+ const { user, discussions } = await fetchJSON('/discdag/list');
+ return { ...ref.current, user, discussions };
+ }
+
+ default:
+ throw new Error('Unexpected action');
+ }
+};
+
+const UserContext = createContext({
+ state: initialState,
+ dispatch: () => {
+ throw new Error("no UserContext Provider!");
+ },
+});
+
+export const UserContainer = ({ children }) => {
+ const ref = useRef();
+ const [state, setState] = useState(initialState);
+ ref.current = state;
+
+ const dispatch = useCallback(async (action) => {
+ const nextState = await reducer(action, ref);
+ setState(nextState);
+ }, [ref]);
+
+ useEffect(() => dispatch({ type: 'refresh' }), []);
+
+ return (
+ <UserContext.Provider value={{ state, dispatch }}>
+ {children}
+ </UserContext.Provider>
+ );
+};
+
+export const useUser = () => useContext(UserContext).state;
+export const useDispatch = () => useContext(UserContext).dispatch;
+export const useUserCtx = () => useContext(UserContext);