aboutsummaryrefslogtreecommitdiff
path: root/src/hooks
diff options
context:
space:
mode:
Diffstat (limited to 'src/hooks')
-rw-r--r--src/hooks/useAuth.tsx77
-rw-r--r--src/hooks/useNavigate.tsx41
2 files changed, 118 insertions, 0 deletions
diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx
new file mode 100644
index 0000000..55e142c
--- /dev/null
+++ b/src/hooks/useAuth.tsx
@@ -0,0 +1,77 @@
+import React, {
+ useState, useEffect, useContext, createContext
+} from 'react';
+import { User } from 'which-types';
+import { post, get } from '../requests';
+
+
+interface ContextType {
+ user: User | null,
+ setUser: (user: User) => void;
+ login: (username: string, password: string, remember?: boolean) => Promise<boolean>;
+ logout: () => void;
+ isAuthenticated: () => boolean;
+}
+
+const authContext = createContext<ContextType>({
+ user: null,
+ setUser: () => {},
+ login: async () => false,
+ logout: () => {},
+ isAuthenticated: () => false
+});
+
+const useProvideAuth = () => {
+ const [user, setUser] = useState<User | null>(null);
+
+ const login: ContextType['login'] = (username, password, remember = true) => {
+ return post('/authentication', {
+ strategy: 'local',
+ username,
+ password
+ }).then(response => {
+ const me = response.data.user;
+ const token = response.data.accessToken;
+ setUser(me);
+ localStorage.setItem('userId', me._id);
+ localStorage.setItem('token', token);
+ if (!remember) localStorage.setItem('shouldClear', 'true');
+ return true;
+ }).catch(() => false);
+ };
+
+ const logout = () => {
+ setUser(null);
+ localStorage.removeItem('userId');
+ localStorage.removeItem('token');
+ };
+
+ const isAuthenticated = () => Boolean(user);
+
+ useEffect(() => {
+ if (localStorage.getItem('shouldClear')) {
+ localStorage.clear();
+ }
+ const userId = localStorage.getItem('userId');
+ if (userId) {
+ get(`/users/${userId}`).then(response => {
+ setUser(response.data);
+ });
+ }
+ }, []);
+
+ return {
+ user, setUser, login, logout, isAuthenticated
+ };
+};
+
+export const AuthProvider: React.FC = ({ children }) => {
+ const auth = useProvideAuth();
+ const { Provider } = authContext;
+ return <Provider value={auth}>{children}</Provider>;
+};
+
+export const useAuth = (): ContextType => {
+ return useContext(authContext);
+};
+
diff --git a/src/hooks/useNavigate.tsx b/src/hooks/useNavigate.tsx
new file mode 100644
index 0000000..befc529
--- /dev/null
+++ b/src/hooks/useNavigate.tsx
@@ -0,0 +1,41 @@
+import React, { useState, useContext, createContext } from 'react';
+
+export interface Page {
+ prefix: string;
+ id?: string;
+}
+
+interface ContextType {
+ page: Page;
+ setPage: (page: Page) => void;
+ navigate: (prefix: string, id?: string) => void;
+}
+
+const landingPage = { prefix: 'feed' };
+
+const context = createContext<ContextType>({
+ page: landingPage,
+ setPage: () => {},
+ navigate: () => {}
+});
+
+const useProvideNavigation = () => {
+ const [page, setPage] = useState<Page>(landingPage);
+
+ const navigate: ContextType['navigate'] = (prefix, id?) => {
+ setPage({ prefix, id });
+ };
+
+ return { page, setPage, navigate };
+};
+
+export const NavigationProvider: React.FC = ({ children }) => {
+ const navigation = useProvideNavigation();
+ const { Provider } = context;
+ return <Provider value={navigation}>{children}</Provider>;
+};
+
+export const useNavigate = (): ContextType => {
+ return useContext(context);
+};
+