Skip to content

Commit 7511f56

Browse files
Fix crash in password reset page (#3512)
1 parent ab2d889 commit 7511f56

5 files changed

Lines changed: 66 additions & 48 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from 'react';
2+
import FatalError from '../FatalError';
3+
4+
export default class CrashHandler extends React.Component<
5+
{ children: React.ReactNode },
6+
{ error: Error | null }
7+
> {
8+
constructor(props: { children: React.ReactNode }) {
9+
super(props);
10+
11+
this.state = {
12+
error: null,
13+
};
14+
}
15+
16+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
17+
static getDerivedStateFromError(error: any) {
18+
return { error };
19+
}
20+
21+
render() {
22+
const { children } = this.props;
23+
const { error } = this.state;
24+
25+
if (error != null) {
26+
return (
27+
<FatalError error={error} />
28+
);
29+
}
30+
31+
return children;
32+
}
33+
}

src/containers/App.tsx

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { isConnectedSelector } from '../reducers/server';
1111
import createTheme from '../utils/createTheme';
1212
import DesktopApp from '../components/App';
1313
import MobileApp from '../mobile/components/App';
14-
import FatalError from '../components/FatalError';
14+
import CrashHandler from '../components/CrashHandler';
1515
import UwaveContext from '../context/UwaveContext';
1616
import { ClockProvider } from '../context/ClockContext';
1717
import MediaSourceContext, { type MediaSource } from '../context/MediaSourceContext';
@@ -26,37 +26,6 @@ const {
2626
useRef,
2727
} = React;
2828

29-
class ErrorWrapper extends React.Component<
30-
{ children: React.ReactNode },
31-
{ error: Error | null }
32-
> {
33-
constructor(props: { children: React.ReactNode }) {
34-
super(props);
35-
36-
this.state = {
37-
error: null,
38-
};
39-
}
40-
41-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
42-
static getDerivedStateFromError(error: any) {
43-
return { error };
44-
}
45-
46-
render() {
47-
const { children } = this.props;
48-
const { error } = this.state;
49-
50-
if (error != null) {
51-
return (
52-
<FatalError error={error} />
53-
);
54-
}
55-
56-
return children;
57-
}
58-
}
59-
6029
function usePageVisibility(fn: (visible: boolean) => void) {
6130
useEffect(() => {
6231
const handler = () => {
@@ -114,7 +83,7 @@ function AppContainer({ uwave, mediaSources }: AppContainerProps) {
11483

11584
return (
11685
<ThemeProvider theme={theme}>
117-
<ErrorWrapper>
86+
<CrashHandler>
11887
<TranslateProvider translator={translator}>
11988
<BusProvider>
12089
<ClockProvider>
@@ -128,7 +97,7 @@ function AppContainer({ uwave, mediaSources }: AppContainerProps) {
12897
</ClockProvider>
12998
</BusProvider>
13099
</TranslateProvider>
131-
</ErrorWrapper>
100+
</CrashHandler>
132101
</ThemeProvider>
133102
);
134103
}

src/password-reset/app.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
@import url("@openfonts/open-sans_all");
33
@import url("../vars.css");
44
@import url("../components/App/index.css");
5+
@import url("../components/FatalError/index.css");
56
@import url("../components/Form/index.css");
7+
@import url("../components/SvgIcon/index.css");
68
@import url("./components/PasswordResetPage/index.css");
79

810
body {

src/password-reset/components/PasswordResetPage/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ function PasswordResetPage({ resetKey, email, onSuccess }: PasswordResetPageProp
2222
const [newPasswordConfirm, setNewPasswordConfirm] = useState('');
2323

2424
const valid = newPassword.length >= 6 && newPassword === newPasswordConfirm;
25-
const handleSubmit = useAsyncCallback(async () => {
25+
const handleSubmit = useAsyncCallback(async (event: React.FormEvent<HTMLFormElement>) => {
26+
event.preventDefault();
27+
2628
if (!valid) {
2729
return;
2830
}

src/password-reset/containers/PasswordResetApp.tsx

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
import { useState } from 'react';
2+
import { Provider } from 'react-redux';
3+
import { combineReducers, configureStore } from '@reduxjs/toolkit';
24
import { createTheme, ThemeProvider } from '@mui/material/styles';
35
// @ts-expect-error TS2305: no types
46
import { TranslateProvider } from '@u-wave/react-translate';
57
import ErrorArea from '../../containers/ErrorArea';
68
import PasswordResetPage from '../components/PasswordResetPage';
79
import PasswordResetSuccessPage from '../components/PasswordResetSuccessPage';
810
import theme from '../../theme';
11+
import CrashHandler from '../../components/CrashHandler';
12+
import errors from '../../reducers/errors';
913

1014
const muiTheme = createTheme({ ...theme, cssVariables: true });
1115

16+
const store = configureStore({
17+
reducer: combineReducers({ errors }),
18+
});
19+
1220
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1321
type Translator = any; // from @u-wave/translate
1422
type PasswordResetAppProps = {
@@ -19,19 +27,23 @@ function PasswordResetApp({ translator, resetKey }: PasswordResetAppProps) {
1927
const [success, setSuccess] = useState(false);
2028

2129
return (
22-
<ThemeProvider theme={muiTheme}>
23-
<TranslateProvider translator={translator}>
24-
{success ? (
25-
<PasswordResetSuccessPage />
26-
) : (
27-
<PasswordResetPage
28-
resetKey={resetKey}
29-
onSuccess={() => setSuccess(true)}
30-
/>
31-
)}
32-
<ErrorArea />
33-
</TranslateProvider>
34-
</ThemeProvider>
30+
<Provider store={store}>
31+
<ThemeProvider theme={muiTheme}>
32+
<CrashHandler>
33+
<TranslateProvider translator={translator}>
34+
{success ? (
35+
<PasswordResetSuccessPage />
36+
) : (
37+
<PasswordResetPage
38+
resetKey={resetKey}
39+
onSuccess={() => setSuccess(true)}
40+
/>
41+
)}
42+
<ErrorArea />
43+
</TranslateProvider>
44+
</CrashHandler>
45+
</ThemeProvider>
46+
</Provider>
3547
);
3648
}
3749

0 commit comments

Comments
 (0)