Merge pull request #6792 from MontejoJorge/refactor/forgotPassword-react
Migrate forgot password page to react component
This commit is contained in:
@@ -1 +1,2 @@
|
||||
export * from './user';
|
||||
export * from './public';
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { AsyncRoute } from '../../../../components/router/AsyncRoute';
|
||||
|
||||
export const ASYNC_PUBLIC_ROUTES: AsyncRoute[] = [
|
||||
{ path: 'forgotpassword', page: 'session/forgotPassword' }
|
||||
];
|
||||
@@ -22,13 +22,6 @@ export const LEGACY_PUBLIC_ROUTES: LegacyRoute[] = [
|
||||
view: 'session/login/index.html'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'forgotpassword',
|
||||
pageProps: {
|
||||
controller: 'session/forgotPassword/index',
|
||||
view: 'session/forgotPassword/index.html'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'forgotpasswordpin',
|
||||
pageProps: {
|
||||
|
||||
@@ -9,7 +9,7 @@ import FallbackRoute from 'components/router/FallbackRoute';
|
||||
|
||||
import AppLayout from '../AppLayout';
|
||||
|
||||
import { ASYNC_USER_ROUTES } from './asyncRoutes';
|
||||
import { ASYNC_PUBLIC_ROUTES, ASYNC_USER_ROUTES } from './asyncRoutes';
|
||||
import { LEGACY_PUBLIC_ROUTES, LEGACY_USER_ROUTES } from './legacyRoutes';
|
||||
|
||||
export const STABLE_APP_ROUTES: RouteObject[] = [
|
||||
@@ -33,6 +33,7 @@ export const STABLE_APP_ROUTES: RouteObject[] = [
|
||||
/* Public routes */
|
||||
element: <ConnectionRequired level='public' />,
|
||||
children: [
|
||||
...ASYNC_PUBLIC_ROUTES.map(toAsyncPageRoute),
|
||||
...LEGACY_PUBLIC_ROUTES.map(toViewManagerPageRoute),
|
||||
/* Fallback route for invalid paths */
|
||||
{
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import Page from 'components/Page';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import globalize from 'lib/globalize';
|
||||
import Button from 'elements/emby-button/Button';
|
||||
import Input from 'elements/emby-input/Input';
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import alert from 'components/alert';
|
||||
import { getUserApi } from '@jellyfin/sdk/lib/utils/api/user-api';
|
||||
import { ForgotPasswordAction } from '@jellyfin/sdk/lib/generated-client/models/forgot-password-action';
|
||||
import ServerConnections from 'components/ServerConnections';
|
||||
|
||||
export const ForgotPasswordPage = () => {
|
||||
const navigate = useNavigate();
|
||||
const [username, setUsername] = useState('');
|
||||
|
||||
const forgotPasswordMutation = useMutation({
|
||||
mutationFn: async (enteredUsername: string) => {
|
||||
const currentApi = ServerConnections.getCurrentApi();
|
||||
if (!currentApi) {
|
||||
throw new Error('API not available');
|
||||
}
|
||||
const response = await getUserApi(currentApi).forgotPassword({
|
||||
forgotPasswordDto: {
|
||||
EnteredUsername: enteredUsername
|
||||
}
|
||||
});
|
||||
|
||||
return response.data;
|
||||
},
|
||||
onSuccess: (result) => {
|
||||
let msg = '';
|
||||
let callback: () => void | undefined = () => undefined;
|
||||
|
||||
switch (result.Action) {
|
||||
case ForgotPasswordAction.ContactAdmin:
|
||||
msg = globalize.translate('MessageContactAdminToResetPassword');
|
||||
break;
|
||||
case ForgotPasswordAction.InNetworkRequired:
|
||||
msg = globalize.translate('MessageForgotPasswordInNetworkRequired');
|
||||
break;
|
||||
case ForgotPasswordAction.PinCode:
|
||||
msg = globalize.translate('MessageForgotPasswordFileCreated');
|
||||
msg += '<br/><br/>';
|
||||
msg += globalize.translate('MessageForgotPasswordPinReset');
|
||||
msg += '<br/><br/>';
|
||||
msg += result.PinFile;
|
||||
msg += '<br/>';
|
||||
callback = () => navigate('/forgotpasswordpin');
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
return alert({
|
||||
text: msg,
|
||||
title: globalize.translate('ButtonForgotPassword')
|
||||
}).then(() => {
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const handleCancel = useCallback(() => {
|
||||
navigate(-1);
|
||||
}, [navigate]);
|
||||
|
||||
const handleSubmit = useCallback(async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
forgotPasswordMutation.mutate(username);
|
||||
}, [username, forgotPasswordMutation]);
|
||||
|
||||
const handleUsernameChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setUsername(e.target.value);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Page
|
||||
id='forgotPasswordPage'
|
||||
className='standalonePage forgotPasswordPage mainAnimatedPage'
|
||||
>
|
||||
<div className='padded-left padded-right padded-bottom-page'>
|
||||
<form
|
||||
className='forgotPasswordForm'
|
||||
style={{ textAlign: 'center', margin: '0 auto' }}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<div style={{ textAlign: 'left' }}>
|
||||
<h1>{globalize.translate('ButtonForgotPassword')}</h1>
|
||||
|
||||
<div className='inputContainer'>
|
||||
<Input
|
||||
type='text'
|
||||
id='txtName'
|
||||
label={globalize.translate('LabelUser')}
|
||||
autoComplete='off'
|
||||
value={username}
|
||||
onChange={handleUsernameChange}
|
||||
/>
|
||||
<div className='fieldDescription'>
|
||||
{globalize.translate('LabelForgotPasswordUsernameHelp')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Button
|
||||
type='submit'
|
||||
id='btnSubmit'
|
||||
className='raised submit block'
|
||||
title={globalize.translate('ButtonSubmit')}
|
||||
/>
|
||||
|
||||
<Button
|
||||
type='button'
|
||||
id='btnCancel'
|
||||
className='raised cancel block btnCancel'
|
||||
title={globalize.translate('ButtonCancel')}
|
||||
onClick={handleCancel}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForgotPasswordPage;
|
||||
Reference in New Issue
Block a user