From cf6cfe87b46a2a3eb2913209092ab4c5639e75c3 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 11 Jun 2020 17:27:15 +0800 Subject: feat(front): Service worker is coming! --- Timeline/ClientApp/src/app/settings/Settings.tsx | 253 +++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 Timeline/ClientApp/src/app/settings/Settings.tsx (limited to 'Timeline/ClientApp/src/app/settings/Settings.tsx') diff --git a/Timeline/ClientApp/src/app/settings/Settings.tsx b/Timeline/ClientApp/src/app/settings/Settings.tsx new file mode 100644 index 00000000..96a3fab4 --- /dev/null +++ b/Timeline/ClientApp/src/app/settings/Settings.tsx @@ -0,0 +1,253 @@ +import React, { useState } from 'react'; +import { useHistory } from 'react-router'; +import { useTranslation } from 'react-i18next'; +import axios, { AxiosError } from 'axios'; +import { + Container, + Row, + Col, + Input, + Modal, + ModalHeader, + ModalBody, + ModalFooter, + Button, +} from 'reactstrap'; + +import { apiBaseUrl } from '../config'; + +import { useUser, userLogout, useUserLoggedIn } from '../data/user'; + +import AppBar from '../common/AppBar'; +import OperationDialog, { + OperationInputErrorInfo, +} from '../common/OperationDialog'; +import { CommonErrorResponse } from '../data/common'; + +interface ChangePasswordDialogProps { + open: boolean; + close: () => void; +} + +async function changePassword( + oldPassword: string, + newPassword: string, + token: string +): Promise { + const url = `${apiBaseUrl}/userop/changepassword?token=${token}`; + try { + await axios.post(url, { + oldPassword, + newPassword, + }); + } catch (e) { + const error = e as AxiosError; + if ( + error.response && + error.response.status === 400 && + error.response.data && + error.response.data.message + ) { + throw error.response.data.message; + } + throw e; + } +} + +const ChangePasswordDialog: React.FC = (props) => { + const user = useUserLoggedIn(); + const history = useHistory(); + const { t } = useTranslation(); + + const [redirect, setRedirect] = useState(false); + + return ( + + v === '' + ? 'settings.dialogChangePassword.errorEmptyOldPassword' + : null, + }, + { + type: 'text', + label: t('settings.dialogChangePassword.inputNewPassword'), + password: true, + validator: (v, values) => { + const error: OperationInputErrorInfo = {}; + error[1] = + v === '' + ? 'settings.dialogChangePassword.errorEmptyNewPassword' + : null; + if (v === values[2]) { + error[2] = null; + } else { + if (values[2] !== '') { + error[2] = 'settings.dialogChangePassword.errorRetypeNotMatch'; + } + } + return error; + }, + }, + { + type: 'text', + label: t('settings.dialogChangePassword.inputRetypeNewPassword'), + password: true, + validator: (v, values) => + v !== values[1] + ? 'settings.dialogChangePassword.errorRetypeNotMatch' + : null, + }, + ]} + onProcess={async ([oldPassword, newPassword]) => { + await changePassword( + oldPassword as string, + newPassword as string, + user.token + ); + userLogout(); + setRedirect(true); + }} + close={() => { + props.close(); + if (redirect) { + history.push('/login'); + } + }} + /> + ); +}; + +const ConfirmLogoutDialog: React.FC<{ + toggle: () => void; + onConfirm: () => void; +}> = ({ toggle, onConfirm }) => { + const { t } = useTranslation(); + + return ( + + + {t('settings.dialogConfirmLogout.title')} + + {t('settings.dialogConfirmLogout.prompt')} + + + + + + ); +}; + +const Settings: React.FC = (_) => { + const { i18n, t } = useTranslation(); + const user = useUser(); + const history = useHistory(); + + const [dialog, setDialog] = useState( + null + ); + + const language = i18n.language.slice(0, 2); + + return ( + <> + + + {user ? ( + <> + + +
{ + history.push(`/users/${user.username}`); + }} + > + {t('settings.gotoSelf')} +
+ +
+ + +
setDialog('changepassword')} + > + {t('settings.changePassword')} +
+ +
+ + +
{ + setDialog('logout'); + }} + > + {t('settings.logout')} +
+ +
+ + ) : null} + + +
{t('settings.languagePrimary')}
+

{t('settings.languageSecondary')}

+ + + { + void i18n.changeLanguage(e.target.value); + }} + > + + + + +
+ {(() => { + switch (dialog) { + case 'changepassword': + return ( + { + setDialog(null); + }} + /> + ); + case 'logout': + return ( + setDialog(null)} + onConfirm={() => { + userLogout(); + history.push('/'); + }} + /> + ); + default: + return null; + } + })()} +
+ + ); +}; + +export default Settings; -- cgit v1.2.3