fix(web-client): split DisplayName into FirstName/LastName for registration

This commit is contained in:
Ho Ngoc Hai
2026-02-28 04:03:04 +07:00
parent 1caaf5e1e4
commit 1e211dec27
6 changed files with 62 additions and 22 deletions

View File

@@ -22,14 +22,25 @@
<EditForm Model="@registerModel" OnValidSubmit="HandleRegister" FormName="RegisterForm">
<DataAnnotationsValidator />
<div class="form-group">
<label for="reg-name">@L["Auth_Register_DisplayName"] *</label>
<InputText id="reg-name"
@bind-Value="registerModel.DisplayName"
class="form-input"
placeholder="John Doe"
autocomplete="name" />
<ValidationMessage For="() => registerModel.DisplayName" class="validation-message" />
<div class="form-row">
<div class="form-group">
<label for="reg-lastname">@L["Auth_Register_LastName"] *</label>
<InputText id="reg-lastname"
@bind-Value="registerModel.LastName"
class="form-input"
placeholder="Nguyễn"
autocomplete="family-name" />
<ValidationMessage For="() => registerModel.LastName" class="validation-message" />
</div>
<div class="form-group">
<label for="reg-firstname">@L["Auth_Register_FirstName"] *</label>
<InputText id="reg-firstname"
@bind-Value="registerModel.FirstName"
class="form-input"
placeholder="Văn A"
autocomplete="given-name" />
<ValidationMessage For="() => registerModel.FirstName" class="validation-message" />
</div>
</div>
<div class="form-group">

View File

@@ -50,19 +50,22 @@ public class AuthService
{
try
{
// EN: Build payload with FirstName/LastName from DisplayName (IAM requires these)
// VI: Tạo payload với FirstName/LastName từ DisplayName (IAM yêu cầu)
var parts = (dto.DisplayName ?? "User").Trim().Split(' ', 2);
// EN: Build payload with FirstName/LastName from form (IAM requires these)
// VI: Tạo payload với FirstName/LastName từ form (IAM yêu cầu)
var payload = new
{
dto.Email,
dto.Password,
FirstName = parts[0],
LastName = parts.Length > 1 ? parts[1] : parts[0],
DisplayName = dto.DisplayName
dto.FirstName,
dto.LastName
};
var response = await _http.PostAsJsonAsync("/api/auth/register", payload);
// EN: Use PascalCase serialization to match backend RegisterUserCommand record params
// VI: Dùng PascalCase serialization để khớp với record params backend
var jsonOptions = new JsonSerializerOptions { PropertyNamingPolicy = null };
var jsonContent = JsonContent.Create(payload, options: jsonOptions);
var response = await _http.PostAsync("/api/auth/register", jsonContent);
if (response.IsSuccessStatusCode)
{
return (true, null);

View File

@@ -1020,6 +1020,22 @@ a {
}
/* Form Components */
.form-row {
display: flex;
gap: var(--space-4);
}
.form-row>.form-group {
flex: 1;
}
@media (max-width: 480px) {
.form-row {
flex-direction: column;
gap: 0;
}
}
.form-group {
margin-bottom: var(--space-6);
}

View File

@@ -297,7 +297,8 @@
"Auth_Login_Error": "Invalid email or password",
"Auth_Login_RegisterLink": "Register now",
"Auth_Login_Success": "Welcome {0}! Redirecting...",
"Auth_Register_DisplayName": "Display name",
"Auth_Register_FirstName": "First name",
"Auth_Register_LastName": "Last name",
"Auth_Register_Error": "Registration failed",
"Auth_Register_HaveAccount": "Already have an account?",
"Auth_Register_LoginLink": "Sign In",

View File

@@ -297,7 +297,8 @@
"Auth_Login_Error": "Email hoặc mật khẩu không đúng",
"Auth_Login_RegisterLink": "Đăng ký ngay",
"Auth_Login_Success": "Chào mừng {0}! Đang chuyển hướng...",
"Auth_Register_DisplayName": "Tên hiển thị",
"Auth_Register_FirstName": "Tên",
"Auth_Register_LastName": "Họ",
"Auth_Register_Error": "Đăng ký thất bại",
"Auth_Register_HaveAccount": "Đã có tài khoản?",
"Auth_Register_LoginLink": "Đăng nhập",

View File

@@ -35,12 +35,20 @@ public class RegisterDto
public string ConfirmPassword { get; set; } = string.Empty;
/// <summary>
/// EN: User display name.
/// VI: Tên hiển thị của user.
/// EN: User first name.
/// VI: Tên của user.
/// </summary>
[Required(ErrorMessage = "Tên là bắt buộc / Name is required")]
[StringLength(50, MinimumLength = 2, ErrorMessage = "Tên phải từ 2-50 ký tự / Name must be 2-50 chars")]
public string DisplayName { get; set; } = string.Empty;
[Required(ErrorMessage = "Tên là bắt buộc / First name is required")]
[StringLength(50, MinimumLength = 1, ErrorMessage = "Tên phải từ 1-50 ký tự / First name must be 1-50 chars")]
public string FirstName { get; set; } = string.Empty;
/// <summary>
/// EN: User last name.
/// VI: Họ của user.
/// </summary>
[Required(ErrorMessage = "Họ là bắt buộc / Last name is required")]
[StringLength(50, MinimumLength = 1, ErrorMessage = "Họ phải từ 1-50 ký tự / Last name must be 1-50 chars")]
public string LastName { get; set; } = string.Empty;
/// <summary>
/// EN: Accept terms of service.