@dbs-portal/module-identity
Version:
Identity management module for user and role management
110 lines • 9.1 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
* User Create Component
*/
import React, { useState } from 'react';
import { Card, Form, Input, Button, Row, Col, Switch, Select, Alert, Typography, Divider, message } from 'antd';
import { UserOutlined, MailOutlined, PhoneOutlined, LockOutlined, EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';
import { useCreateUser, useRoles } from '../hooks';
const { Title, Text } = Typography;
const { Option } = Select;
// Password strength utility
function getPasswordStrength(password) {
let score = 0;
if (password.length >= 8)
score += 25;
if (/[a-z]/.test(password))
score += 25;
if (/[A-Z]/.test(password))
score += 25;
if (/[0-9]/.test(password))
score += 25;
if (/[^A-Za-z0-9]/.test(password))
score += 25;
return {
score,
level: score < 50 ? 'weak' : score < 75 ? 'medium' : 'strong'
};
}
export const UserCreate = ({ onSubmit, loading: externalLoading, error: externalError, className }) => {
const [form] = Form.useForm();
const [password, setPassword] = useState('');
const createUserMutation = useCreateUser();
const { data: rolesData } = useRoles();
const isLoading = externalLoading || createUserMutation.isPending;
const error = externalError || createUserMutation.error?.message;
const passwordStrength = getPasswordStrength(password);
const handleSubmit = async (values) => {
try {
if (onSubmit) {
onSubmit(values);
}
else {
await createUserMutation.mutateAsync({
userName: values.userName,
email: values.email,
password: values.password,
firstName: values.firstName,
lastName: values.lastName,
phoneNumber: values.phoneNumber,
isActive: values.isActive ?? true,
roleNames: values.roleNames,
sendActivationEmail: values.sendActivationEmail ?? true
});
message.success('User created successfully!');
form.resetFields();
}
}
catch (err) {
console.error('Failed to create user:', err);
}
};
return (_jsxs(Card, { className: className, children: [_jsx(Title, { level: 2, children: "Create New User" }), _jsx(Text, { type: "secondary", children: "Create a new user account with the required information below." }), error && (_jsx(Alert, { message: "User Creation Failed", description: error, type: "error", showIcon: true, style: { marginTop: 16, marginBottom: 16 } })), _jsxs(Form, { form: form, name: "createUser", onFinish: handleSubmit, layout: "vertical", size: "large", style: { marginTop: 24 }, initialValues: {
isActive: true,
sendActivationEmail: true,
}, children: [_jsxs(Row, { gutter: 16, children: [_jsx(Col, { xs: 24, md: 12, children: _jsx(Form.Item, { name: "firstName", label: "First Name", rules: [
{ required: true, message: 'Please enter the first name!' },
{ min: 2, message: 'First name must be at least 2 characters!' },
], children: _jsx(Input, { prefix: _jsx(UserOutlined, {}), placeholder: "Enter first name", autoComplete: "given-name" }) }) }), _jsx(Col, { xs: 24, md: 12, children: _jsx(Form.Item, { name: "lastName", label: "Last Name", rules: [
{ required: true, message: 'Please enter the last name!' },
{ min: 2, message: 'Last name must be at least 2 characters!' },
], children: _jsx(Input, { prefix: _jsx(UserOutlined, {}), placeholder: "Enter last name", autoComplete: "family-name" }) }) })] }), _jsxs(Row, { gutter: 16, children: [_jsx(Col, { xs: 24, md: 12, children: _jsx(Form.Item, { name: "userName", label: "Username", rules: [
{ required: true, message: 'Please enter the username!' },
{ min: 3, message: 'Username must be at least 3 characters!' },
{
pattern: /^[a-zA-Z0-9_-]+$/,
message: 'Username can only contain letters, numbers, underscores, and hyphens!'
},
], children: _jsx(Input, { prefix: _jsx(UserOutlined, {}), placeholder: "Enter username", autoComplete: "username" }) }) }), _jsx(Col, { xs: 24, md: 12, children: _jsx(Form.Item, { name: "email", label: "Email", rules: [
{ required: true, message: 'Please enter the email!' },
{ type: 'email', message: 'Please enter a valid email!' },
], children: _jsx(Input, { prefix: _jsx(MailOutlined, {}), placeholder: "Enter email address", autoComplete: "email" }) }) })] }), _jsx(Form.Item, { name: "phoneNumber", label: "Phone Number", rules: [
{
pattern: /^\+?[1-9]\d{1,14}$/,
message: 'Please enter a valid phone number!'
},
], children: _jsx(Input, { prefix: _jsx(PhoneOutlined, {}), placeholder: "Enter phone number (optional)", autoComplete: "tel" }) }), _jsx(Divider, { children: "Security" }), _jsx(Form.Item, { name: "password", label: "Password", rules: [
{ required: true, message: 'Please enter the password!' },
{ min: 8, message: 'Password must be at least 8 characters!' },
{
validator: (_, value) => {
if (!value || getPasswordStrength(value).score >= 50) {
return Promise.resolve();
}
return Promise.reject(new Error('Password is too weak!'));
},
},
], children: _jsx(Input.Password, { prefix: _jsx(LockOutlined, {}), placeholder: "Enter password", autoComplete: "new-password", iconRender: visible => (visible ? _jsx(EyeTwoTone, {}) : _jsx(EyeInvisibleOutlined, {})), onChange: e => setPassword(e.target.value) }) }), password && (_jsxs("div", { style: { marginBottom: 16 }, children: [_jsx(Text, { type: "secondary", children: "Password strength: " }), _jsx(Text, { type: passwordStrength.level === 'weak' ? 'danger' :
passwordStrength.level === 'medium' ? 'warning' : 'success', children: passwordStrength.level.toUpperCase() })] })), _jsx(Form.Item, { name: "confirmPassword", label: "Confirm Password", dependencies: ['password'], rules: [
{ required: true, message: 'Please confirm the password!' },
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('Passwords do not match!'));
},
}),
], children: _jsx(Input.Password, { prefix: _jsx(LockOutlined, {}), placeholder: "Confirm password", autoComplete: "new-password", iconRender: visible => (visible ? _jsx(EyeTwoTone, {}) : _jsx(EyeInvisibleOutlined, {})) }) }), _jsx(Divider, { children: "Roles & Permissions" }), _jsx(Form.Item, { name: "roleNames", label: "Assign Roles", children: _jsx(Select, { mode: "multiple", placeholder: "Select roles (optional)", loading: !rolesData, allowClear: true, children: rolesData?.data?.map((role) => (_jsx(Option, { value: role.name, children: role.displayName || role.name }, role.id))) }) }), _jsx(Divider, { children: "Settings" }), _jsxs(Row, { gutter: 16, children: [_jsx(Col, { xs: 24, md: 12, children: _jsx(Form.Item, { name: "isActive", label: "Active User", valuePropName: "checked", children: _jsx(Switch, {}) }) }), _jsx(Col, { xs: 24, md: 12, children: _jsx(Form.Item, { name: "sendActivationEmail", label: "Send Activation Email", valuePropName: "checked", children: _jsx(Switch, {}) }) })] }), _jsxs(Form.Item, { style: { marginTop: 32 }, children: [_jsx(Button, { type: "primary", htmlType: "submit", loading: isLoading, size: "large", style: { marginRight: 8 }, children: "Create User" }), _jsx(Button, { size: "large", onClick: () => form.resetFields(), disabled: isLoading, children: "Reset" })] })] })] }));
};
//# sourceMappingURL=UserCreate.js.map