mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-10 04:30:25 +02:00
Update login
This commit is contained in:
@@ -1 +1 @@
|
|||||||
export * from './routes/LoginRoute';
|
export * from './routes/login-route';
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
import md5 from 'md5';
|
|
||||||
import { nanoid } from 'nanoid';
|
|
||||||
import { useMutation, useQuery } from 'react-query';
|
|
||||||
import { authApi } from '../../../api/authApi';
|
|
||||||
import { queryKeys } from '../../../api/queryKeys';
|
|
||||||
import { useAuthStore } from '../../../store';
|
|
||||||
|
|
||||||
export const useLogin = (
|
|
||||||
serverUrl: string,
|
|
||||||
body: {
|
|
||||||
password: string;
|
|
||||||
username: string;
|
|
||||||
}
|
|
||||||
) => {
|
|
||||||
const login = useAuthStore((state) => state.login);
|
|
||||||
|
|
||||||
return useMutation({
|
|
||||||
mutationFn: () => authApi.login(serverUrl, body),
|
|
||||||
onSuccess: (res) => {
|
|
||||||
const key = md5(serverUrl);
|
|
||||||
login({ key, serverUrl });
|
|
||||||
|
|
||||||
if (!localStorage.getItem('device_id')) {
|
|
||||||
localStorage.setItem('device_id', nanoid());
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.setItem(
|
|
||||||
'authentication',
|
|
||||||
JSON.stringify({
|
|
||||||
accessToken: res.data.accessToken,
|
|
||||||
isAuthenticated: true,
|
|
||||||
key,
|
|
||||||
refreshToken: res.data.refreshToken,
|
|
||||||
serverUrl,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const usePingServer = (server: string) => {
|
|
||||||
return useQuery({
|
|
||||||
enabled: !!server,
|
|
||||||
queryFn: () => authApi.ping(server),
|
|
||||||
queryKey: queryKeys.ping(server),
|
|
||||||
retry: false,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { useMutation } from '@tanstack/react-query';
|
||||||
|
import md5 from 'md5';
|
||||||
|
import { nanoid } from 'nanoid';
|
||||||
|
import { api } from '@/renderer/api';
|
||||||
|
import { useAuthStore } from '@/renderer/store';
|
||||||
|
|
||||||
|
export const useLogin = (
|
||||||
|
serverUrl: string,
|
||||||
|
body: {
|
||||||
|
password: string;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
const login = useAuthStore((state) => state.login);
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: () => api.auth.login(serverUrl, body),
|
||||||
|
onSuccess: (res) => {
|
||||||
|
const props = {
|
||||||
|
accessToken: res.data.accessToken,
|
||||||
|
permissions: { isAdmin: res.data.isAdmin },
|
||||||
|
refreshToken: res.data.refreshToken,
|
||||||
|
serverKey: md5(serverUrl),
|
||||||
|
serverUrl,
|
||||||
|
};
|
||||||
|
|
||||||
|
login(props);
|
||||||
|
|
||||||
|
if (!localStorage.getItem('device_id')) {
|
||||||
|
localStorage.setItem('device_id', nanoid());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import { api } from '@/renderer/api';
|
||||||
|
import { queryKeys } from '@/renderer/api/query-keys';
|
||||||
|
|
||||||
|
export const usePingServer = (server: string) => {
|
||||||
|
return useQuery({
|
||||||
|
enabled: !!server,
|
||||||
|
queryFn: () => api.auth.ping(server),
|
||||||
|
queryKey: queryKeys.ping(server),
|
||||||
|
retry: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
.container {
|
|
||||||
min-width: 400px;
|
|
||||||
max-width: 50%;
|
|
||||||
margin: auto;
|
|
||||||
padding: 3rem;
|
|
||||||
background: rgba(50, 50, 50, 0.4);
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
background: var(--primary-color);
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:active,
|
|
||||||
&:focus {
|
|
||||||
background: var(--primary-color);
|
|
||||||
filter: brightness(1.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+20
-13
@@ -1,4 +1,5 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
import {
|
import {
|
||||||
TextInput,
|
TextInput,
|
||||||
PasswordInput,
|
PasswordInput,
|
||||||
@@ -7,14 +8,24 @@ import {
|
|||||||
Title,
|
Title,
|
||||||
Loader,
|
Loader,
|
||||||
Alert,
|
Alert,
|
||||||
|
Box,
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { useDebouncedValue } from '@mantine/hooks';
|
import { useDebouncedValue } from '@mantine/hooks';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { RiCheckboxCircleFill } from 'react-icons/ri';
|
import { RiCheckboxCircleFill } from 'react-icons/ri';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { normalizeServerUrl } from '../../../utils';
|
import { useLogin } from '@/renderer/features/auth/queries/use-login';
|
||||||
import { useLogin, usePingServer } from '../queries/login';
|
import { usePingServer } from '@/renderer/features/auth/queries/use-ping-server';
|
||||||
import styles from './LoginRoute.module.scss';
|
import { normalizeServerUrl } from '@/renderer/utils';
|
||||||
|
|
||||||
|
const Container = styled(Box)`
|
||||||
|
min-width: 400px;
|
||||||
|
max-width: 50%;
|
||||||
|
margin: auto;
|
||||||
|
padding: 3rem;
|
||||||
|
background: rgba(50, 50, 50, 40%);
|
||||||
|
border-radius: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
export const LoginRoute = () => {
|
export const LoginRoute = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -23,7 +34,7 @@ export const LoginRoute = () => {
|
|||||||
const [username, setUsername] = useState(searchParams.get('username') || '');
|
const [username, setUsername] = useState(searchParams.get('username') || '');
|
||||||
const [password, setPassword] = useState(searchParams.get('password') || '');
|
const [password, setPassword] = useState(searchParams.get('password') || '');
|
||||||
const [server, setServer] = useState(
|
const [server, setServer] = useState(
|
||||||
searchParams.get('server') || 'http://localhost:9321'
|
searchParams.get('server') || 'http://localhost:8843'
|
||||||
);
|
);
|
||||||
const [debouncedServer] = useDebouncedValue(server, 500);
|
const [debouncedServer] = useDebouncedValue(server, 500);
|
||||||
|
|
||||||
@@ -43,7 +54,7 @@ export const LoginRoute = () => {
|
|||||||
} = usePingServer(normalizeServerUrl(debouncedServer));
|
} = usePingServer(normalizeServerUrl(debouncedServer));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<Container>
|
||||||
<Title>{t('auth.login')}</Title>
|
<Title>{t('auth.login')}</Title>
|
||||||
<form
|
<form
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
@@ -59,8 +70,8 @@ export const LoginRoute = () => {
|
|||||||
required
|
required
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
error={!isValidServer && isFetched}
|
error={!isValidServer && isFetched}
|
||||||
label={`${t('auth.server.label')}`}
|
label={t('auth.server.label')}
|
||||||
placeholder={`${t('auth.server.placeholder')}`}
|
placeholder={t('auth.server.placeholder')}
|
||||||
rightSection={
|
rightSection={
|
||||||
isCheckingServer ? (
|
isCheckingServer ? (
|
||||||
<Loader size="xs" />
|
<Loader size="xs" />
|
||||||
@@ -96,11 +107,7 @@ export const LoginRoute = () => {
|
|||||||
setPassword(e.currentTarget.value)
|
setPassword(e.currentTarget.value)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button disabled={!isValidServer} type="submit">
|
||||||
className={styles.button}
|
|
||||||
disabled={!isValidServer}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
{isError && (
|
{isError && (
|
||||||
@@ -110,6 +117,6 @@ export const LoginRoute = () => {
|
|||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user