]> git.localhorst.tv Git - alttp.git/blob - resources/js/hooks/user.js
improved user context
[alttp.git] / resources / js / hooks / user.js
1 import axios from 'axios';
2 import { isEqual } from 'lodash';
3 import PropTypes from 'prop-types';
4 import React from 'react';
5
6 const context = React.createContext({
7         login: () => false,
8         logout: () => false,
9         user: null,
10 });
11
12 export const useUser = () => React.useContext(context);
13
14 export const withUser = (WrappedComponent, as) => function WithUserContext(props) {
15         return <context.Consumer>
16                 {user => <WrappedComponent {...{[as || 'user']: user, ...props}} />}
17         </context.Consumer>;
18 };
19
20 export const UserProvider = ({ children }) => {
21         const [user, setUser] = React.useState(null);
22
23         const fetchUser = React.useCallback(async () => {
24                 try {
25                         const response = await axios.get('/api/user');
26                         setUser(user => isEqual(user, response.data) ? user : response.data);
27                 } catch (e) {
28                         setUser(null);
29                 }
30         }, []);
31
32         React.useEffect(() => {
33                 let timer = null;
34                 axios
35                         .get('/sanctum/csrf-cookie')
36                         .then(() => {
37                                 fetchUser();
38                                 timer = setInterval(fetchUser, 5 * 60 * 1000);
39                         });
40                 return () => {
41                         if (timer) clearInterval(timer);
42                 };
43         }, []);
44
45         const login = React.useCallback(async (creds) => {
46                 try {
47                         await axios.post('/login', {
48                                 ...creds,
49                                 remember: 'on',
50                         });
51                         await fetchUser();
52                 } catch (error) {
53                         if (error.response && error.response.status === 419) {
54                                 await axios.get('/sanctum/csrf-cookie');
55                                 await axios.post('/login', {
56                                         ...creds,
57                                         remember: 'on',
58                                 });
59                                 await fetchUser();
60                         } else {
61                                 throw error;
62                         }
63                 }
64         }, []);
65
66         const logout = React.useCallback(async () => {
67                 await axios.post('/logout');
68                 setUser(null);
69         }, []);
70
71         return <context.Provider value={{ login, logout, user }}>
72                 {children}
73         </context.Provider>;
74 };
75
76 UserProvider.propTypes = {
77         children: PropTypes.node,
78 };