generalization of useAuth hook

This commit is contained in:
Anton 2023-08-08 10:15:46 +02:00
parent 3c276c8fdf
commit 2fa78bc4ff
6 changed files with 53 additions and 47 deletions

View File

@ -63,7 +63,7 @@ export default function NavBar({appName, useAuth} : {appName: string, useAuth :
{isAuthenticated && token ? {isAuthenticated ?
<div className="tw-flex-none"> <div className="tw-flex-none">
{user.avatar ? <div className="tw-avatar"> {user.avatar ? <div className="tw-avatar">
<div className="tw-w-10 tw-rounded-full"> <div className="tw-w-10 tw-rounded-full">
@ -85,6 +85,8 @@ export default function NavBar({appName, useAuth} : {appName: string, useAuth :
</div> </div>
: :
<div> <div>
<div className="tw-dropdown tw-dropdown-end tw-mr-2"> <div className="tw-dropdown tw-dropdown-end tw-mr-2">
<label tabIndex={0} className="tw-btn tw-btn-ghost"> <label tabIndex={0} className="tw-btn tw-btn-ghost">
Login Login
@ -114,7 +116,8 @@ export default function NavBar({appName, useAuth} : {appName: string, useAuth :
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
} }
</div> </div>
</> </>

View File

@ -1 +1 @@
export {AuthProviderDirectus, useAuthDirectus} from "./authDirectus" export {AuthProvider, useAuth} from "./useAuth"

View File

@ -1,9 +1,10 @@
import { createContext, useState, useContext, useEffect } from "react"; import { createContext, useState, useContext, useEffect } from "react";
import * as React from "react"; import * as React from "react";
import { UserApi, UserItem } from "../../types";
type AuthProviderProps = { type AuthProviderProps = {
directus: any, userApi: UserApi,
children?: React.ReactNode children?: React.ReactNode
} }
@ -15,23 +16,14 @@ type AuthCredentials = {
export type MyUserItem = {
id: string;
avatar: string;
first_name: string;
description: string;
email: string;
password?: string;
}
type AuthContextProps = { type AuthContextProps = {
isAuthenticated: Boolean, isAuthenticated: Boolean,
user: MyUserItem | null; user: UserItem | null;
login: (credentials: AuthCredentials) => Promise<MyUserItem | undefined>, login: (credentials: AuthCredentials) => Promise<UserItem | undefined>,
register: (credentials: AuthCredentials, userName: string) => Promise<MyUserItem | undefined>, register: (credentials: AuthCredentials, userName: string) => Promise<UserItem | undefined>,
loading: Boolean, loading: Boolean,
logout: () => void, logout: () => void,
updateUser: (user: MyUserItem) => any, updateUser: (user: UserItem) => any,
token: String | null token: String | null
} }
@ -46,82 +38,75 @@ const AuthContext = createContext<AuthContextProps>({
token: "" token: ""
}); });
export const AuthProviderDirectus = ({ directus, children }: AuthProviderProps) => { export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
const [user, setUser] = useState<MyUserItem | null>(null); const [user, setUser] = useState<UserItem | null>(null);
const [token, setToken] = useState<String | null>(null); const [token, setToken] = useState<String | null>(null);
const [loading, setLoading] = useState<Boolean>(false); const [loading, setLoading] = useState<Boolean>(false);
const isAuthenticated = !!user; const isAuthenticated = !!user;
useEffect(() => { useEffect(() => {
setLoading(true); setLoading(true);
loadUserFromDirectus(); loadUser();
setLoading(false) setLoading(false)
}, []); }, []);
async function loadUserFromDirectus(): Promise<MyUserItem | undefined> { async function loadUser(): Promise<UserItem | undefined> {
try { try {
const token = await directus.auth.token const me = await userApi.getUser();
if (token) { setUser(me as UserItem);
const me = await directus.users.me.read(); const token = await userApi.getToken();
setUser(me as MyUserItem);
setToken(token); setToken(token);
setLoading(false); setLoading(false);
return me as MyUserItem; return me as UserItem;
}
else return undefined;
} catch (error) { } catch (error) {
setLoading(false) setLoading(false)
return undefined; return undefined;
} }
} }
const login = async (credentials: AuthCredentials): Promise<MyUserItem | undefined> => { const login = async (credentials: AuthCredentials): Promise<UserItem | undefined> => {
setLoading(true); setLoading(true);
try { try {
const res = await directus.auth.login(credentials); const res = await userApi.login(credentials.email, credentials.password);
return (await loadUserFromDirectus()); setToken(res.access_token);
return (await loadUser());
} catch (error: any) { } catch (error: any) {
setLoading(false); setLoading(false);
console.log(error.response.data.error[0]); console.log(error.response.data.error[0]);
return error.response.data.error[0]; return error.response.data.error[0];
}; };
} }
const register = async (credentials: AuthCredentials, userName): Promise<MyUserItem | undefined> => { const register = async (credentials: AuthCredentials, userName): Promise<UserItem | undefined> => {
setLoading(true); setLoading(true);
try { try {
const res = await directus.users.createOne({email: credentials.email, password: credentials.password, first_name: userName}); const res = await userApi.register(credentials.email, credentials.password, userName)
return (await login(credentials)); return (await login(credentials));
} catch (error: any) { } catch (error: any) {
setLoading(false); setLoading(false);
console.log(error); console.log(error);
return error.response.data.error[0]; return error.response.data.error[0];
}; };
} }
const logout = async () => { const logout = async () => {
await directus.auth.logout(); await userApi.logout();
setUser(null); setUser(null);
}; };
const updateUser = async (user: MyUserItem) => { const updateUser = async (user: UserItem) => {
setLoading(true); setLoading(true);
const { id, ...userRest } = user; const { id, ...userRest } = user;
try { try {
const res = await directus.users.updateOne(user.id!, userRest) const res = await userApi.updateUser(userRest);
setUser(res as any); setUser(res as any);
setLoading(false); setLoading(false);
return res as any; return res as any;
} catch (error: any) { } catch (error: any) {
setLoading(false); setLoading(false);
console.log(error.response.data.error[0]);
return error.response.data.error[0]; return error.response.data.error[0];
} }
@ -136,4 +121,4 @@ export const AuthProviderDirectus = ({ directus, children }: AuthProviderProps)
</AuthContext.Provider> </AuthContext.Provider>
); );
}; };
export const useAuthDirectus = () => useContext(AuthContext); export const useAuth = () => useContext(AuthContext);

View File

@ -56,8 +56,8 @@ export const Layer = (props: LayerProps) => {
}) })
props.api?.getItems().then(result => { props.api?.getItems().then(result => {
if (result.data) { if (result) {
result.data.map(item => { result.map(item => {
if (item.position) { if (item.position) {
addItem(({ layer: props, api: props.api, ...item })); addItem(({ layer: props, api: props.api, ...item }));
} }

View File

@ -1,6 +1,6 @@
export { UtopiaMap, Layer, Tags, Item, Tag, ItemsApi } from './Components/Map/index'; export { UtopiaMap, Layer, Tags, Item, Tag } from './Components/Map/index';
export {AppShell, Content, SideBar} from "./Components/AppShell" export {AppShell, Content, SideBar} from "./Components/AppShell"
export {AuthProviderDirectus, useAuthDirectus} from "./Components/Auth" export {AuthProvider, useAuth} from "./Components/Auth"
export {Settings} from './Components/Profile' export {Settings} from './Components/Profile'
export {Quests, Modal} from './Components/Gaming' export {Quests, Modal} from './Components/Gaming'
export {TitleCard, CardPage} from './Components/Templates' export {TitleCard, CardPage} from './Components/Templates'

View File

@ -68,3 +68,21 @@ export interface ItemsApi<T> {
updateItem?(item : T): Promise<any>, updateItem?(item : T): Promise<any>,
deleteItem?(id : number | string): Promise<any>, deleteItem?(id : number | string): Promise<any>,
} }
export interface UserApi {
register(email: string, password: string, userName: string): Promise<void>,
login(email: string, password: string): Promise<any>,
logout(): Promise<void>,
getUser(): Promise<UserItem>,
getToken(): Promise<any>,
updateUser(user: UserItem): Promise<void>
}
export type UserItem = {
id?: string;
avatar: string;
first_name: string;
description: string;
email: string;
password?: string;
}