chore: custom brand color
This commit is contained in:
@@ -1,14 +1,17 @@
|
|||||||
|
import { colorPrimary } from '@/config/theme';
|
||||||
import { atom } from 'jotai';
|
import { atom } from 'jotai';
|
||||||
import { atomWithStorage } from 'jotai/utils';
|
import { atomWithStorage } from 'jotai/utils';
|
||||||
|
|
||||||
type UserSettings = {
|
type UserSettings = {
|
||||||
theme: 'light' | 'realDark' | 'auto';
|
theme: 'light' | 'realDark' | 'auto';
|
||||||
|
colorPrimary: string;
|
||||||
isDarkTheme?: boolean;
|
isDarkTheme?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const userSettingsAtom = atomWithStorage<UserSettings>('userSettings', {
|
export const userSettingsAtom = atomWithStorage<UserSettings>('userSettings', {
|
||||||
theme: 'light',
|
theme: 'light',
|
||||||
isDarkTheme: false
|
isDarkTheme: false,
|
||||||
|
colorPrimary: colorPrimary
|
||||||
});
|
});
|
||||||
|
|
||||||
export const userSettingsHelperAtom = atom(
|
export const userSettingsHelperAtom = atom(
|
||||||
@@ -21,6 +24,7 @@ export const userSettingsHelperAtom = atom(
|
|||||||
};
|
};
|
||||||
set(userSettingsAtom, {
|
set(userSettingsAtom, {
|
||||||
...newSettings,
|
...newSettings,
|
||||||
|
colorPrimary: newSettings.colorPrimary || colorPrimary,
|
||||||
isDarkTheme: newSettings.theme === 'realDark'
|
isDarkTheme: newSettings.theme === 'realDark'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { theme } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, { FC } from 'react';
|
import React, { FC } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
@@ -191,6 +192,8 @@ const Wrapper: FC<WrapperProps> = ({
|
|||||||
labelExtra,
|
labelExtra,
|
||||||
onClick
|
onClick
|
||||||
}) => {
|
}) => {
|
||||||
|
const { token } = theme.useToken();
|
||||||
|
console.log('token=====', token);
|
||||||
const wrapperClass = classNames(
|
const wrapperClass = classNames(
|
||||||
status ? `validate-status-${status}` : '',
|
status ? `validate-status-${status}` : '',
|
||||||
className,
|
className,
|
||||||
@@ -201,8 +204,21 @@ const Wrapper: FC<WrapperProps> = ({
|
|||||||
'seal-input-wrapper-disabled': disabled
|
'seal-input-wrapper-disabled': disabled
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
const wrapperStyle: Record<string, any> = {
|
||||||
|
'--ant-line-width': '1px',
|
||||||
|
'--ant-line-type': 'solid',
|
||||||
|
'--ant-color-border': token.colorBorder,
|
||||||
|
'--ant-color-bg-container': token.colorBgContainer,
|
||||||
|
'--ant-color-bg-container-disabled': token.colorBgContainerDisabled,
|
||||||
|
'--ant-color-error': token.colorError,
|
||||||
|
'--ant-input-hover-border-color': token.colorPrimaryHover,
|
||||||
|
'--ant-color-error-border-hover': token.colorErrorBorderHover,
|
||||||
|
'--ant-input-active-border-color': token.colorPrimary,
|
||||||
|
'--ant-input-active-shadow': `0 0 0 2px ${token.controlOutline}`,
|
||||||
|
'--ant-input-active-bg': token.colorBgContainer
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<WrapperBox className={wrapperClass}>
|
<WrapperBox className={wrapperClass} style={wrapperStyle}>
|
||||||
<InnerWrapper
|
<InnerWrapper
|
||||||
$noWrapperStyle={noWrapperStyle}
|
$noWrapperStyle={noWrapperStyle}
|
||||||
$nolabel={!label}
|
$nolabel={!label}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export default {
|
|||||||
"Helvetica Neue, -apple-system, BlinkMacSystemFont, Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'",
|
"Helvetica Neue, -apple-system, BlinkMacSystemFont, Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'",
|
||||||
colorText: '#ccc',
|
colorText: '#ccc',
|
||||||
colorPrimary: '#007BFF',
|
colorPrimary: '#007BFF',
|
||||||
// colorSuccess: '#48A77E',
|
colorSuccess: '#48A77E',
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
borderRadiusSM: 2,
|
borderRadiusSM: 2,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import dark from './dark';
|
import dark from './dark';
|
||||||
import light from './light';
|
import light from './light';
|
||||||
|
|
||||||
|
export const colorPrimary = '#007BFF';
|
||||||
export default {
|
export default {
|
||||||
light,
|
light,
|
||||||
dark
|
dark,
|
||||||
|
colorPrimary: '#007BFF'
|
||||||
};
|
};
|
||||||
|
|||||||
+8
-8
@@ -155,15 +155,15 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// input
|
// input
|
||||||
.ant-input-css-var.ant-input {
|
// .ant-input-css-var.ant-input {
|
||||||
height: 40px;
|
// height: 40px;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.ant-input-outlined,
|
// .ant-input-outlined,
|
||||||
.ant-input-affix-wrapper,
|
// .ant-input-affix-wrapper,
|
||||||
.ant-picker {
|
// .ant-picker {
|
||||||
height: 40px;
|
// height: 40px;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.ant-input-outlined.ant-input-status-error:not(.ant-input-disabled) {
|
.ant-input-outlined.ant-input-status-error:not(.ant-input-disabled) {
|
||||||
border: none;
|
border: none;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { getActiveStatus, setActiveStatus } from '@/atoms/tab-active';
|
import { getActiveStatus, setActiveStatus } from '@/atoms/tab-active';
|
||||||
|
|
||||||
const tabsMap = {
|
const tabsMap = {
|
||||||
resources: 'resources'
|
resources: 'resources',
|
||||||
|
userSettings: 'userSettings'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function useTabActive() {
|
export default function useTabActive() {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { useEffect, useMemo } from 'react';
|
|||||||
type Theme = 'light' | 'realDark' | 'auto';
|
type Theme = 'light' | 'realDark' | 'auto';
|
||||||
|
|
||||||
export default function useUserSettings() {
|
export default function useUserSettings() {
|
||||||
const { light, dark } = themeConfig;
|
const { light, dark, colorPrimary } = themeConfig;
|
||||||
const [userSettings, setUserSettings] = useAtom(userSettingsHelperAtom);
|
const [userSettings, setUserSettings] = useAtom(userSettingsHelperAtom);
|
||||||
|
|
||||||
const setHtmlThemeAttr = (theme: string) => {
|
const setHtmlThemeAttr = (theme: string) => {
|
||||||
@@ -17,15 +17,16 @@ export default function useUserSettings() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const themeData = useMemo(() => {
|
const themeData = useMemo(() => {
|
||||||
|
const themeTokens = userSettings.theme === 'realDark' ? dark : light;
|
||||||
|
themeTokens.token.colorPrimary = userSettings.colorPrimary || colorPrimary;
|
||||||
return {
|
return {
|
||||||
...(userSettings.theme === 'realDark' ? dark : light)
|
...themeTokens
|
||||||
};
|
};
|
||||||
}, [userSettings.theme]);
|
}, [userSettings.theme, userSettings.colorPrimary]);
|
||||||
|
|
||||||
const setTheme = (theme: Theme) => {
|
const setTheme = (theme: Theme) => {
|
||||||
setHtmlThemeAttr(theme);
|
setHtmlThemeAttr(theme);
|
||||||
setUserSettings({
|
setUserSettings({
|
||||||
...userSettings,
|
|
||||||
theme: theme,
|
theme: theme,
|
||||||
isDarkTheme: theme === 'realDark'
|
isDarkTheme: theme === 'realDark'
|
||||||
});
|
});
|
||||||
@@ -35,7 +36,6 @@ export default function useUserSettings() {
|
|||||||
setHtmlThemeAttr(userSettings.theme);
|
setHtmlThemeAttr(userSettings.theme);
|
||||||
}, [userSettings.theme]);
|
}, [userSettings.theme]);
|
||||||
|
|
||||||
// set theme by system theme: only for theme is auto
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleChange = (e: MediaQueryListEvent) => {
|
const handleChange = (e: MediaQueryListEvent) => {
|
||||||
setTheme(e.matches ? 'realDark' : 'light');
|
setTheme(e.matches ? 'realDark' : 'light');
|
||||||
|
|||||||
@@ -407,9 +407,21 @@ export default (props: any) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const currentTheme = useMemo(() => {
|
||||||
|
const data = {
|
||||||
|
algorithm: userSettings.isDarkTheme
|
||||||
|
? theme.darkAlgorithm
|
||||||
|
: theme.defaultAlgorithm,
|
||||||
|
...themeData
|
||||||
|
};
|
||||||
|
console.log('currentTheme====', data);
|
||||||
|
return data;
|
||||||
|
}, [userSettings.isDarkTheme, themeData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigProvider
|
<ConfigProvider
|
||||||
componentSize="large"
|
componentSize="large"
|
||||||
|
key={userSettings.colorPrimary}
|
||||||
theme={{
|
theme={{
|
||||||
algorithm: userSettings.isDarkTheme
|
algorithm: userSettings.isDarkTheme
|
||||||
? theme.darkAlgorithm
|
? theme.darkAlgorithm
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
import FormButtons from '@/components/form-buttons';
|
||||||
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
|
import { PasswordReg } from '@/config';
|
||||||
|
import { INPUT_WIDTH } from '@/constants';
|
||||||
|
import { updatePassword } from '@/pages/login/apis';
|
||||||
|
import { PageContainer } from '@ant-design/pro-components';
|
||||||
|
import { useIntl } from '@umijs/max';
|
||||||
|
import { Form, message } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
interface ProfileProps {
|
||||||
|
username?: string;
|
||||||
|
new_password: string;
|
||||||
|
current_password: string;
|
||||||
|
}
|
||||||
|
const Profile: React.FC = () => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const handleOnFinish = async (values: any) => {
|
||||||
|
try {
|
||||||
|
await updatePassword({
|
||||||
|
new_password: values.new_password,
|
||||||
|
current_password: values.current_password
|
||||||
|
});
|
||||||
|
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOnFinishFailed = (errorInfo: any) => {
|
||||||
|
console.log('handleOnFinishFailed', errorInfo);
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
form.resetFields();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer
|
||||||
|
ghost
|
||||||
|
header={{
|
||||||
|
title: intl.formatMessage({ id: 'users.form.updatepassword' }),
|
||||||
|
style: {
|
||||||
|
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
extra={[]}
|
||||||
|
>
|
||||||
|
<Form
|
||||||
|
style={{ width: '524px' }}
|
||||||
|
name="profileForm"
|
||||||
|
form={form}
|
||||||
|
onFinish={handleOnFinish}
|
||||||
|
onFinishFailed={handleOnFinishFailed}
|
||||||
|
>
|
||||||
|
<Form.Item<ProfileProps>
|
||||||
|
name="current_password"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: intl.formatMessage(
|
||||||
|
{ id: 'common.form.rule.input' },
|
||||||
|
{
|
||||||
|
name: intl.formatMessage({
|
||||||
|
id: 'users.form.currentpassword'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Password
|
||||||
|
label={intl.formatMessage({ id: 'users.form.currentpassword' })}
|
||||||
|
required
|
||||||
|
style={{ width: INPUT_WIDTH.default }}
|
||||||
|
></SealInput.Password>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item<ProfileProps>
|
||||||
|
name="new_password"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
pattern: PasswordReg,
|
||||||
|
message: intl.formatMessage({
|
||||||
|
id: 'users.form.rule.password'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Password
|
||||||
|
label={intl.formatMessage({ id: 'users.form.newpassword' })}
|
||||||
|
required
|
||||||
|
style={{ width: INPUT_WIDTH.default }}
|
||||||
|
></SealInput.Password>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="confirm_password"
|
||||||
|
dependencies={['new_password']}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: intl.formatMessage({
|
||||||
|
id: 'users.password.confirm.empty'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
({ getFieldValue }) => ({
|
||||||
|
validator(_, value) {
|
||||||
|
if (!value || getFieldValue('new_password') === value) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
return Promise.reject(
|
||||||
|
new Error(
|
||||||
|
intl.formatMessage({ id: 'users.password.confirm.error' })
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Password
|
||||||
|
required={true}
|
||||||
|
style={{ width: INPUT_WIDTH.default }}
|
||||||
|
label={intl.formatMessage({ id: 'users.password.confirm' })}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<FormButtons
|
||||||
|
htmlType="submit"
|
||||||
|
onCancel={handleCancel}
|
||||||
|
showCancel={false}
|
||||||
|
></FormButtons>
|
||||||
|
</Form>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Profile;
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import useUserSettings from '@/hooks/use-user-settings';
|
||||||
|
import { Button, ColorPicker } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const CustomUI: React.FC = () => {
|
||||||
|
const { setUserSettings, userSettings } = useUserSettings();
|
||||||
|
|
||||||
|
const handleOnChange = (color: any, css: string) => {
|
||||||
|
const colorPrimary = color.toHexString();
|
||||||
|
if (!colorPrimary) return;
|
||||||
|
setUserSettings({
|
||||||
|
...userSettings,
|
||||||
|
colorPrimary: color.toHexString()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Custom UI Component</h1>
|
||||||
|
<Button type="primary">主题色</Button>
|
||||||
|
<div>
|
||||||
|
<ColorPicker onChange={handleOnChange} format="hex"></ColorPicker>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
CustomUI.displayName = 'CustomUI';
|
||||||
|
|
||||||
|
export default CustomUI;
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
import FormButtons from '@/components/form-buttons';
|
||||||
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
|
import { PasswordReg } from '@/config';
|
||||||
|
import { INPUT_WIDTH } from '@/constants';
|
||||||
|
import { updatePassword } from '@/pages/login/apis';
|
||||||
|
import { useIntl } from '@umijs/max';
|
||||||
|
import { Form, message } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
interface ProfileProps {
|
||||||
|
username?: string;
|
||||||
|
new_password: string;
|
||||||
|
current_password: string;
|
||||||
|
}
|
||||||
|
const Profile: React.FC = () => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const handleOnFinish = async (values: any) => {
|
||||||
|
try {
|
||||||
|
await updatePassword({
|
||||||
|
new_password: values.new_password,
|
||||||
|
current_password: values.current_password
|
||||||
|
});
|
||||||
|
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOnFinishFailed = (errorInfo: any) => {
|
||||||
|
console.log('handleOnFinishFailed', errorInfo);
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
form.resetFields();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form
|
||||||
|
style={{ width: '524px' }}
|
||||||
|
name="profileForm"
|
||||||
|
form={form}
|
||||||
|
onFinish={handleOnFinish}
|
||||||
|
onFinishFailed={handleOnFinishFailed}
|
||||||
|
>
|
||||||
|
<Form.Item<ProfileProps>
|
||||||
|
name="current_password"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: intl.formatMessage(
|
||||||
|
{ id: 'common.form.rule.input' },
|
||||||
|
{
|
||||||
|
name: intl.formatMessage({
|
||||||
|
id: 'users.form.currentpassword'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Password
|
||||||
|
label={intl.formatMessage({ id: 'users.form.currentpassword' })}
|
||||||
|
required
|
||||||
|
style={{ width: INPUT_WIDTH.default }}
|
||||||
|
></SealInput.Password>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item<ProfileProps>
|
||||||
|
name="new_password"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
pattern: PasswordReg,
|
||||||
|
message: intl.formatMessage({
|
||||||
|
id: 'users.form.rule.password'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Password
|
||||||
|
label={intl.formatMessage({ id: 'users.form.newpassword' })}
|
||||||
|
required
|
||||||
|
style={{ width: INPUT_WIDTH.default }}
|
||||||
|
></SealInput.Password>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="confirm_password"
|
||||||
|
dependencies={['new_password']}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: intl.formatMessage({
|
||||||
|
id: 'users.password.confirm.empty'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
({ getFieldValue }) => ({
|
||||||
|
validator(_, value) {
|
||||||
|
if (!value || getFieldValue('new_password') === value) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
return Promise.reject(
|
||||||
|
new Error(
|
||||||
|
intl.formatMessage({ id: 'users.password.confirm.error' })
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Password
|
||||||
|
required={true}
|
||||||
|
style={{ width: INPUT_WIDTH.default }}
|
||||||
|
label={intl.formatMessage({ id: 'users.password.confirm' })}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<FormButtons
|
||||||
|
htmlType="submit"
|
||||||
|
onCancel={handleCancel}
|
||||||
|
showCancel={false}
|
||||||
|
></FormButtons>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Profile.displayName = 'ModifyPassword';
|
||||||
|
|
||||||
|
export default Profile;
|
||||||
+55
-121
@@ -1,134 +1,68 @@
|
|||||||
import FormButtons from '@/components/form-buttons';
|
import useTabActive from '@/hooks/use-tab-active';
|
||||||
import SealInput from '@/components/seal-form/seal-input';
|
|
||||||
import { PasswordReg } from '@/config';
|
|
||||||
import { INPUT_WIDTH } from '@/constants';
|
|
||||||
import { updatePassword } from '@/pages/login/apis';
|
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
import { PageContainer } from '@ant-design/pro-components';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Form, message } from 'antd';
|
import { TabsProps } from 'antd';
|
||||||
|
import React, { useCallback, useState } from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import CustomUI from './components/custom-ui';
|
||||||
|
import ModifyPasswordn from './components/modify-password';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
.ant-page-header-heading {
|
||||||
|
padding-inline: 8px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
interface ProfileProps {
|
|
||||||
username?: string;
|
|
||||||
new_password: string;
|
|
||||||
current_password: string;
|
|
||||||
}
|
|
||||||
const Profile: React.FC = () => {
|
const Profile: React.FC = () => {
|
||||||
const [form] = Form.useForm();
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
const { setTabActive, getTabActive, tabsMap } = useTabActive();
|
||||||
|
const [activeKey, setActiveKey] = useState(
|
||||||
|
getTabActive(tabsMap.userSettings) || 'modify-password'
|
||||||
|
);
|
||||||
|
|
||||||
const handleOnFinish = async (values: any) => {
|
const items: TabsProps['items'] = [
|
||||||
try {
|
{
|
||||||
await updatePassword({
|
key: 'modify-password',
|
||||||
new_password: values.new_password,
|
label: intl.formatMessage({ id: 'users.form.updatepassword' }),
|
||||||
current_password: values.current_password
|
children: <ModifyPasswordn />
|
||||||
});
|
},
|
||||||
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
{
|
||||||
} catch (error) {}
|
key: 'custom-ui',
|
||||||
};
|
label: 'Custom UI',
|
||||||
|
children: <CustomUI />
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
const handleOnFinishFailed = (errorInfo: any) => {
|
const handleChangeTab = useCallback((key: string) => {
|
||||||
console.log('handleOnFinishFailed', errorInfo);
|
setActiveKey(key);
|
||||||
};
|
setTabActive(tabsMap.userSettings, key);
|
||||||
const handleCancel = () => {
|
}, []);
|
||||||
form.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<Wrapper>
|
||||||
ghost
|
<PageContainer
|
||||||
header={{
|
ghost
|
||||||
title: intl.formatMessage({ id: 'users.form.updatepassword' }),
|
header={{
|
||||||
style: {
|
title: 'User Settings',
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
style: {
|
||||||
}
|
paddingInline: 'var(--layout-content-inlinepadding)'
|
||||||
}}
|
}
|
||||||
extra={[]}
|
}}
|
||||||
>
|
tabList={items}
|
||||||
<Form
|
onTabChange={handleChangeTab}
|
||||||
style={{ width: '524px' }}
|
tabActiveKey={activeKey}
|
||||||
name="profileForm"
|
tabProps={{
|
||||||
form={form}
|
type: 'card',
|
||||||
onFinish={handleOnFinish}
|
style: {
|
||||||
onFinishFailed={handleOnFinishFailed}
|
marginTop: 78
|
||||||
>
|
}
|
||||||
<Form.Item<ProfileProps>
|
}}
|
||||||
name="current_password"
|
extra={[]}
|
||||||
rules={[
|
></PageContainer>
|
||||||
{
|
</Wrapper>
|
||||||
required: true,
|
|
||||||
message: intl.formatMessage(
|
|
||||||
{ id: 'common.form.rule.input' },
|
|
||||||
{
|
|
||||||
name: intl.formatMessage({
|
|
||||||
id: 'users.form.currentpassword'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<SealInput.Password
|
|
||||||
label={intl.formatMessage({ id: 'users.form.currentpassword' })}
|
|
||||||
required
|
|
||||||
style={{ width: INPUT_WIDTH.default }}
|
|
||||||
></SealInput.Password>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item<ProfileProps>
|
|
||||||
name="new_password"
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
pattern: PasswordReg,
|
|
||||||
message: intl.formatMessage({
|
|
||||||
id: 'users.form.rule.password'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<SealInput.Password
|
|
||||||
label={intl.formatMessage({ id: 'users.form.newpassword' })}
|
|
||||||
required
|
|
||||||
style={{ width: INPUT_WIDTH.default }}
|
|
||||||
></SealInput.Password>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
name="confirm_password"
|
|
||||||
dependencies={['new_password']}
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: intl.formatMessage({
|
|
||||||
id: 'users.password.confirm.empty'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
({ getFieldValue }) => ({
|
|
||||||
validator(_, value) {
|
|
||||||
if (!value || getFieldValue('new_password') === value) {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
return Promise.reject(
|
|
||||||
new Error(
|
|
||||||
intl.formatMessage({ id: 'users.password.confirm.error' })
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<SealInput.Password
|
|
||||||
required={true}
|
|
||||||
style={{ width: INPUT_WIDTH.default }}
|
|
||||||
label={intl.formatMessage({ id: 'users.password.confirm' })}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
<FormButtons
|
|
||||||
htmlType="submit"
|
|
||||||
onCancel={handleCancel}
|
|
||||||
showCancel={false}
|
|
||||||
></FormButtons>
|
|
||||||
</Form>
|
|
||||||
</PageContainer>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Profile.displayName = 'Profile';
|
||||||
|
|
||||||
export default Profile;
|
export default Profile;
|
||||||
|
|||||||
Reference in New Issue
Block a user