Files
gpustack-ui/src/pages/login/components/local-user-form.tsx
T
2026-04-27 21:10:34 +08:00

159 lines
4.1 KiB
TypeScript

import externalLinks from '@/constants/external-links';
import {
InfoCircleOutlined,
LockOutlined,
UserOutlined
} from '@ant-design/icons';
import { Input as CInput, HighlightCode } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Button, Checkbox, Divider, Form, FormInstance } from 'antd';
import { createStyles } from 'antd-style';
const useStyles = createStyles(({ token, css }) => {
return {
commandInfo: css`
.content {
display: flex;
align-items: flex-start;
gap: 8px;
margin-bottom: 12px;
.icon {
padding-top: 2px;
color: ${token.colorInfo};
font-size: 16px;
}
.info {
line-height: 1.5;
color: ${token.colorTextSecondary};
font-size: 14px;
}
}
`
};
});
interface LocalUserFormProps {
handleLogin: (values: any) => void;
form: FormInstance;
loading?: boolean;
loginOption: {
saml: boolean;
oidc: boolean;
first_time_setup: boolean;
get_initial_password_command: string;
};
}
const LocalUserForm: React.FC<LocalUserFormProps> = (props) => {
const { handleLogin, form, loginOption } = props;
const intl = useIntl();
const { styles } = useStyles();
const renderCommandInfo = () => {
if (!loginOption?.first_time_setup) {
return null;
}
return (
<div className={styles.commandInfo}>
<Divider style={{ marginTop: 16, marginBottom: 12 }} />
<div className="content">
<InfoCircleOutlined className="icon" />
<span className="info">
{intl.formatMessage({ id: 'users.login.getInitialPassword' })}
</span>
</div>
<HighlightCode
theme="dark"
code={loginOption.get_initial_password_command}
copyValue={loginOption.get_initial_password_command}
lang="bash"
></HighlightCode>
</div>
);
};
return (
<Form
form={form}
style={{ width: '360px', margin: '0 auto' }}
onFinish={handleLogin}
>
<Form.Item
name="username"
rules={[
{
required: true,
message: intl.formatMessage(
{ id: 'common.form.rule.input' },
{
name: intl.formatMessage({ id: 'common.form.username' })
}
)
}
]}
>
<CInput.Input
autoComplete="username"
label={intl.formatMessage({ id: 'common.form.username' })}
prefix={<UserOutlined />}
/>
</Form.Item>
<Form.Item
name="password"
rules={[
{
required: true,
message: intl.formatMessage(
{ id: 'common.form.rule.input' },
{
name: intl.formatMessage({ id: 'common.form.password' })
}
)
}
]}
>
<CInput.Password
autoComplete="current-password"
prefix={<LockOutlined />}
label={intl.formatMessage({ id: 'common.form.password' })}
/>
</Form.Item>
<div
className="flex-center flex-between"
style={{
marginBottom: 24
}}
>
<Form.Item noStyle name="autoLogin" valuePropName="checked">
<Checkbox style={{ marginLeft: 5 }}>
<span style={{ color: 'var(--ant-color-text-secondary)' }}>
{intl.formatMessage({ id: 'common.login.rember' })}
</span>
</Checkbox>
</Form.Item>
<Button
type="link"
size="small"
href={externalLinks.resetPassword}
target="_blank"
style={{ padding: 0 }}
>
{intl.formatMessage({ id: 'common.button.forgotpassword' })}
</Button>
</div>
<Button
htmlType="submit"
type="primary"
block
loading={props.loading}
style={{ height: '48px', fontSize: '14px' }}
>
{intl.formatMessage({ id: 'common.button.login' })}
</Button>
{renderCommandInfo()}
</Form>
);
};
export default LocalUserForm;