Added auth to endpoints

This commit is contained in:
Benjamin Sherriff
2023-10-18 15:36:36 -04:00
parent 7ba0e070ac
commit f072a47d22
12 changed files with 160 additions and 84 deletions

View File

@@ -21,9 +21,16 @@ import {
import Cookies from 'js-cookie';
import { useEffect, useState } from 'react';
import { useForm } from '@mantine/form';
import { login, logout, ping } from '@/api/users';
import { login, logout, me } from '@/api/auth';
import { User } from '@/api/auth.types';
const headerItems = [
interface HeaderItem {
name: string;
link: string;
role?: string;
}
const headerItems: HeaderItem[] = [
{
name: 'Races',
link: '/races'
@@ -54,24 +61,38 @@ const headerItems = [
},
{
name: 'Management',
link: '/management'
link: '/management',
role: 'admin'
}
];
export default function Topbar() {
const pathName = usePathname();
const [showLogin, setShowLogin] = useState(false);
const [authenticated, setAuthenticated] = useState(false);
// Check if the auth cookie is set
// If it is, show the user avatar
// If not, show the login button
const [headers, setHeaders] = useState<HeaderItem[]>([]);
const [user, setUser] = useState<User | undefined>(undefined);
useEffect(() => {
console.log('cookies', Cookies.get());
if (Cookies.get('auth')) {
setAuthenticated(true);
if (Cookies.get('logged_in')) {
me().then((response) => {
if (response?.status == 200) {
setUser(response.data);
}
});
} else {
setUser(undefined);
}
}, []);
useEffect(() => {
const h: HeaderItem[] = [];
headerItems.forEach((item) => {
if (item.role == undefined || user?.role == item.role) {
h.push(item);
}
setHeaders(h);
});
}, [user]);
return (
<>
<nav className='navbar'>
@@ -80,7 +101,7 @@ export default function Topbar() {
Siren
</Link>
<div className='header-items'>
{headerItems.map((item) => (
{headers.map((item) => (
<Link className={`header-item ${pathName == item.link && 'active'}`} href={item.link} key={item.name}>
{item.name}
</Link>
@@ -93,26 +114,25 @@ export default function Topbar() {
<Avatar style={{ cursor: 'pointer' }} />
</Menu.Target>
<Menu.Dropdown>
{!authenticated && <Menu.Item onClick={() => setShowLogin(true)}>Login</Menu.Item>}
{authenticated && (
{!user && <Menu.Item onClick={() => setShowLogin(true)}>Login</Menu.Item>}
{user && (
<Menu.Item
onClick={async () => {
const response = await logout();
if (response?.status == 200) {
Cookies.remove('auth');
setAuthenticated(false);
Cookies.remove('logged_in');
setUser(undefined);
}
}}
>
Logout
</Menu.Item>
)}
<Menu.Item onClick={() => ping()}>Ping</Menu.Item>
</Menu.Dropdown>
</Menu>
</div>
</nav>
<LoginModal showLogin={showLogin} setShowLogin={setShowLogin} setAuthenticated={setAuthenticated} />
<LoginModal showLogin={showLogin} setShowLogin={setShowLogin} setUser={setUser} />
</>
);
}
@@ -120,20 +140,29 @@ export default function Topbar() {
function LoginModal({
showLogin,
setShowLogin,
setAuthenticated
setUser
}: {
showLogin: boolean;
setShowLogin: (show: boolean) => void;
setAuthenticated: (authenticated: boolean) => void;
setUser: (user: User) => void;
}) {
const form = useForm({
initialValues: {
email: '',
password: ''
password: '',
remember: false
}
});
function onClose() {
setShowLogin(false);
if (!form.values.remember) {
form.reset();
}
}
return (
<Modal opened={showLogin} onClose={() => setShowLogin(false)} withCloseButton={false}>
<Modal opened={showLogin} onClose={onClose} withCloseButton={false}>
<Container>
<Title ta='center'>Welcome back!</Title>
<Text c='dimmed' size='sm' ta='center' mt={5}>
@@ -148,8 +177,12 @@ function LoginModal({
onSubmit={form.onSubmit(async (values) => {
const response = await login(values.email, values.password);
if (response?.status == 200) {
setShowLogin(false);
setAuthenticated(true);
me().then((response) => {
if (response?.status == 200) {
setUser(response.data);
}
onClose();
});
}
})}
>
@@ -162,7 +195,7 @@ function LoginModal({
{...form.getInputProps('password')}
/>
<Group justify='space-between' mt='lg'>
<Checkbox label='Remember me' />
<Checkbox label='Remember me' {...form.getInputProps('remember')} />
<Anchor component='button' size='sm'>
Forgot password?
</Anchor>