Skip to content

Commit 438f1b0

Browse files
committed
Add support for changing account password
1 parent d43b7ea commit 438f1b0

File tree

7 files changed

+38
-13
lines changed

7 files changed

+38
-13
lines changed

resources/scripts/api/account/updateAccountPassword.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ interface Data {
88

99
export default ({ current, password, confirmPassword }: Data): Promise<void> => {
1010
return new Promise((resolve, reject) => {
11-
http.put('/account/password', {
11+
http.put('/api/client/account/password', {
1212
// eslint-disable-next-line @typescript-eslint/camelcase
1313
current_password: current,
1414
password: password,

resources/scripts/components/FlashMessageRender.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,28 @@ import { State, useStoreState } from 'easy-peasy';
44
import { ApplicationState } from '@/state/types';
55

66
type Props = Readonly<{
7+
byKey?: string;
78
spacerClass?: string;
89
withBottomSpace?: boolean;
910
}>;
1011

11-
export default ({ withBottomSpace, spacerClass }: Props) => {
12+
export default ({ withBottomSpace, spacerClass, byKey }: Props) => {
1213
const flashes = useStoreState((state: State<ApplicationState>) => state.flashes.items);
1314

14-
if (flashes.length === 0) {
15+
let filtered = flashes;
16+
if (byKey) {
17+
filtered = flashes.filter(flash => flash.key === byKey);
18+
}
19+
20+
if (filtered.length === 0) {
1521
return null;
1622
}
1723

1824
// noinspection PointlessBooleanExpressionJS
1925
return (
2026
<div className={withBottomSpace === false ? undefined : 'mb-2'}>
2127
{
22-
flashes.map((flash, index) => (
28+
filtered.map((flash, index) => (
2329
<React.Fragment key={flash.id || flash.type + flash.message}>
2430
{index > 0 && <div className={spacerClass || 'mt-2'}></div>}
2531
<MessageBox type={flash.type} title={flash.title}>

resources/scripts/components/account/AccountOverviewContainer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import UpdatePasswordForm from '@/components/account/forms/UpdatePasswordForm';
55
export default () => {
66
return (
77
<div className={'flex my-10'}>
8-
<ContentBox className={'flex-1 mr-4'} title={'Update Password'}>
8+
<ContentBox className={'flex-1 mr-4'} title={'Update Password'} showFlashes={'account:password'}>
99
<UpdatePasswordForm/>
1010
</ContentBox>
1111
<div className={'flex-1 ml-4'}>

resources/scripts/components/account/forms/UpdatePasswordForm.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import React, { useState } from 'react';
2-
import { State, useStoreState } from 'easy-peasy';
1+
import React from 'react';
2+
import { Actions, State, useStoreActions, useStoreState } from 'easy-peasy';
33
import { ApplicationState } from '@/state/types';
44
import { Form, Formik, FormikActions } from 'formik';
55
import Field from '@/components/elements/Field';
66
import * as Yup from 'yup';
77
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
8+
import updateAccountPassword from '@/api/account/updateAccountPassword';
9+
import { httpErrorToHuman } from '@/api/http';
810

911
interface Values {
1012
current: string;
@@ -22,13 +24,26 @@ const schema = Yup.object().shape({
2224

2325
export default () => {
2426
const user = useStoreState((state: State<ApplicationState>) => state.user.data);
27+
const { clearFlashes, addFlash } = useStoreActions((actions: Actions<ApplicationState>) => actions.flashes);
2528

2629
if (!user) {
2730
return null;
2831
}
2932

30-
const submit = (values: Values, { setSubmitting }: FormikActions<Values>) => {
31-
setTimeout(() => setSubmitting(false), 1500);
33+
const submit = (values: Values, { resetForm, setSubmitting }: FormikActions<Values>) => {
34+
clearFlashes('account:password');
35+
updateAccountPassword({ ...values })
36+
.then(() => {
37+
resetForm();
38+
addFlash({ key: 'account:password', type: 'success', message: 'Your password has been updated.' });
39+
})
40+
.catch(error => addFlash({
41+
key: 'account:password',
42+
type: 'error',
43+
title: 'Error',
44+
message: httpErrorToHuman(error),
45+
}))
46+
.then(() => setSubmitting(false));
3247
};
3348

3449
return (

resources/scripts/components/elements/ContentBox.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import * as React from 'react';
22
import classNames from 'classnames';
3+
import FlashMessageRender from '@/components/FlashMessageRender';
34

45
type Props = Readonly<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
56
title?: string;
67
borderColor?: string;
8+
showFlashes?: string | boolean;
79
}>;
810

9-
export default ({ title, borderColor, children, ...props }: Props) => (
11+
export default ({ title, borderColor, showFlashes, children, ...props }: Props) => (
1012
<div {...props}>
1113
{title && <h2 className={'text-neutral-300 mb-4 px-4'}>{title}</h2>}
14+
{showFlashes && <FlashMessageRender byKey={typeof showFlashes === 'string' ? showFlashes : undefined}/>}
1215
<div className={classNames('bg-neutral-700 p-4 rounded shadow-lg relative', borderColor, {
1316
'border-t-4': !!borderColor,
1417
})}>

resources/scripts/state/models/flashes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ const flashes: FlashState = {
66
addFlash: action((state, payload) => {
77
state.items.push(payload);
88
}),
9-
clearFlashes: action(state => {
10-
state.items = [];
9+
clearFlashes: action((state, payload) => {
10+
state.items = payload ? state.items.filter(flashes => flashes.key !== payload) : [];
1111
}),
1212
};
1313

resources/scripts/state/types.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export interface ApplicationState {
99
export interface FlashState {
1010
items: FlashMessage[];
1111
addFlash: Action<FlashState, FlashMessage>;
12-
clearFlashes: Action<FlashState>;
12+
clearFlashes: Action<FlashState, string | void>;
1313
}
1414

1515
export interface UserState {
@@ -30,6 +30,7 @@ export interface UserData {
3030

3131
export interface FlashMessage {
3232
id?: string;
33+
key?: string;
3334
type: FlashMessageType;
3435
title?: string;
3536
message: string;

0 commit comments

Comments
 (0)