54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
import { useState, type ReactNode, useEffect } from 'react';
|
|
import { loginAll, logoutAll, currentToken, orderBookingClient } from '../api/clients';
|
|
import { AuthCtx, type AuthValue } from './context';
|
|
|
|
export function AuthProvider({ children }: { children: ReactNode }) {
|
|
const [authed, setAuthed] = useState(() => !!currentToken());
|
|
const [userEmail, setUserEmail] = useState<string | null>(() => {
|
|
return typeof window !== 'undefined' ? localStorage.getItem('krishna_sales_user_email') : null;
|
|
});
|
|
const [isAdmin, setIsAdmin] = useState<boolean>(() => {
|
|
return orderBookingClient.currentUser()?.is_admin ?? false;
|
|
});
|
|
const [roles, setRoles] = useState<string[]>(() => {
|
|
return orderBookingClient.currentUser()?.roles ?? [];
|
|
});
|
|
|
|
// If we are authenticated but don't have isAdmin from cache, we might want to fetch it
|
|
useEffect(() => {
|
|
if (authed && (!isAdmin || roles.length === 0)) {
|
|
orderBookingClient.getMe().then(me => {
|
|
if (me.is_admin) setIsAdmin(true);
|
|
if (me.roles) setRoles(me.roles);
|
|
}).catch(console.error);
|
|
}
|
|
}, [authed]);
|
|
|
|
const value: AuthValue = {
|
|
authed,
|
|
isAdmin,
|
|
roles,
|
|
userEmail,
|
|
login: async (email, password, orgId) => {
|
|
const res = await loginAll(email, password, orgId);
|
|
setAuthed(true);
|
|
if (res.user?.email) {
|
|
setUserEmail(res.user.email);
|
|
localStorage.setItem('krishna_sales_user_email', res.user.email);
|
|
}
|
|
setIsAdmin(!!res.user?.is_admin);
|
|
setRoles(res.user?.roles ?? []);
|
|
},
|
|
logout: () => {
|
|
logoutAll();
|
|
setAuthed(false);
|
|
setUserEmail(null);
|
|
setIsAdmin(false);
|
|
setRoles([]);
|
|
localStorage.clear();
|
|
},
|
|
};
|
|
|
|
return <AuthCtx.Provider value={value}>{children}</AuthCtx.Provider>;
|
|
}
|