Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;

namespace ParkingReservationSystem.ViewModels
{
public class ForgotPasswordViewModel
{
[Required(ErrorMessage = "Email là bắt buộc")]
[EmailAddress(ErrorMessage = "Email không hợp lệ")]
[Display(Name = "Email")]
public string Email { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.ComponentModel.DataAnnotations;

namespace ParkingReservationSystem.ViewModels
{
public class ResetPasswordViewModel
{
[Required]
public string Token { get; set; }

[Required]
[EmailAddress]
public string Email { get; set; }

[Required(ErrorMessage = "Mật khẩu mới là bắt buộc")]
[StringLength(100, ErrorMessage = "Mật khẩu phải có ít nhất {2} ký tự", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Mật khẩu mới")]
public string NewPassword { get; set; }

[Required(ErrorMessage = "Xác nhận mật khẩu là bắt buộc")]
[DataType(DataType.Password)]
[Display(Name = "Xác nhận mật khẩu")]
[Compare("NewPassword", ErrorMessage = "Mật khẩu xác nhận không khớp")]
public string ConfirmPassword { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace ParkingReservationSystem.ViewModels
{
public class ServiceResult
{
public bool Success { get; set; }
public string ErrorMessage { get; set; }
public string SuccessMessage { get; set; }

public static ServiceResult CreateSuccess(string message = null)
{
return new ServiceResult
{
Success = true,
SuccessMessage = message
};
}

public static ServiceResult CreateFailure(string errorMessage)
{
return new ServiceResult
{
Success = false,
ErrorMessage = errorMessage
};
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.ComponentModel.DataAnnotations;

namespace ParkingReservationSystem.ViewModels.User
{
public class CreateUserViewModel
{
[Required(ErrorMessage = "Họ tên không được để trống")]
[Display(Name = "Họ và Tên")]
public string Name { get; set; }

[Required(ErrorMessage = "Email không được để trống")]
[EmailAddress(ErrorMessage = "Email không hợp lệ")]
[Display(Name = "Email")]
public string Email { get; set; }

[Required(ErrorMessage = "Mật khẩu không được để trống")]
[MinLength(8, ErrorMessage = "Mật khẩu phải có ít nhất 8 ký tự")]
[Display(Name = "Mật khẩu")]
public string Password { get; set; }

[Required(ErrorMessage = "Vui lòng chọn vai trò")]
[Display(Name = "Vai trò")]
public string Role { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.ComponentModel.DataAnnotations;

namespace ParkingReservationSystem.ViewModels.User
{
public class EditUserViewModel
{
public int Id { get; set; }

[Required(ErrorMessage = "Họ tên không được để trống")]
[Display(Name = "Họ và Tên")]
public string Name { get; set; }

[Required(ErrorMessage = "Email không được để trống")]
[EmailAddress(ErrorMessage = "Email không hợp lệ")]
[Display(Name = "Email")]
public string Email { get; set; }

[Display(Name = "Mật khẩu mới")]
public string Password { get; set; } // Để trống nếu không đổi

// Thêm field này để lưu mật khẩu cũ
public string CurrentPasswordHash { get; set; }

[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "Mật khẩu xác nhận không khớp")]
public string? ConfirmPassword { get; set; }

[Required(ErrorMessage = "Vui lòng chọn vai trò")]
[Display(Name = "Vai trò")]
public string Role { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
@model ParkingReservationSystem.ViewModels.ForgotPasswordViewModel
@{
ViewData["Title"] = "Quên mật khẩu";
}

@section Styles {
<link rel="stylesheet" href="~/css/auth-styles.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
}

<div class="auth-wrapper">
<div class="auth-container">
<!-- Header Section -->
<div class="auth-header">
<div class="auth-icon">
<i class="fas fa-key"></i>
</div>
<h1 class="auth-title">Quên mật khẩu</h1>
<p class="auth-subtitle">Nhập email của bạn để nhận liên kết đặt lại mật khẩu</p>
</div>

<!-- Error Alert -->
@if (ViewBag.Error != null)
{
<div class="auth-alert alert-danger fade-in">
<i class="fas fa-exclamation-circle"></i>
<span>@ViewBag.Error</span>
</div>
}

<!-- Success Alert -->
@if (ViewBag.Success != null)
{
<div class="auth-alert alert-success fade-in">
<i class="fas fa-check-circle"></i>
<span>@ViewBag.Success</span>
</div>
}

<!-- Forgot Password Form -->
<form asp-action="ForgotPassword" method="post" class="auth-form">
<div class="form-group">
<label asp-for="Email" class="form-label">
<i class="fas fa-envelope"></i>
Email
</label>
<input asp-for="Email"
type="email"
class="form-input"
required
placeholder="Nhập địa chỉ email đã đăng ký"
autocomplete="email" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>

<button type="submit" class="auth-button">
<span class="button-text">
<i class="fas fa-paper-plane"></i>
Gửi liên kết đặt lại
</span>
<div class="button-loader"></div>
</button>
</form>

<!-- Footer -->
<div class="auth-footer">
<p class="auth-link-text">Nhớ lại mật khẩu?</p>
<a asp-action="Login" class="auth-link">
Quay lại đăng nhập
<i class="fas fa-arrow-left"></i>
</a>
</div>
</div>
</div>

@section Scripts {
<script src="~/js/auth-scripts.js"></script>
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
@model ParkingReservationSystem.ViewModels.ResetPasswordViewModel
@{
ViewData["Title"] = "Đặt lại mật khẩu";
}

@section Styles {
<link rel="stylesheet" href="~/css/auth-styles.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
}

<div class="auth-wrapper">
<div class="auth-container">
<!-- Header Section -->
<div class="auth-header">
<div class="auth-icon">
<i class="fas fa-shield-alt"></i>
</div>
<h1 class="auth-title">Đặt lại mật khẩu</h1>
<p class="auth-subtitle">Tạo mật khẩu mới cho tài khoản của bạn</p>
</div>

<!-- Error Alert -->
@if (ViewBag.Error != null)
{
<div class="auth-alert alert-danger fade-in">
<i class="fas fa-exclamation-circle"></i>
<span>@ViewBag.Error</span>
</div>
}

<!-- Success Alert -->
@if (ViewBag.Success != null)
{
<div class="auth-alert alert-success fade-in">
<i class="fas fa-check-circle"></i>
<span>@ViewBag.Success</span>
</div>
}

<!-- Reset Password Form -->
<form asp-action="ResetPassword" method="post" class="auth-form">
<input asp-for="Token" type="hidden" />
<input asp-for="Email" type="hidden" />

<div class="form-group">
<label for="newPassword" class="form-label">
<i class="fas fa-lock"></i>
Mật khẩu mới
</label>
<input id="newPassword"
name="newPassword"
type="password"
class="form-input"
required
placeholder="Nhập mật khẩu mới (ít nhất 6 ký tự)"
autocomplete="new-password" />
<span class="text-danger field-validation-error" data-valmsg-for="newPassword" data-valmsg-replace="true"></span>
</div>

<div class="form-group">
<label for="confirmPassword" class="form-label">
<i class="fas fa-lock"></i>
Xác nhận mật khẩu mới
</label>
<input id="confirmPassword"
name="confirmPassword"
type="password"
class="form-input"
required
placeholder="Nhập lại mật khẩu mới để xác nhận"
autocomplete="new-password" />
<span class="text-danger field-validation-error" data-valmsg-for="confirmPassword" data-valmsg-replace="true"></span>
</div>

<button type="submit" class="auth-button">
<span class="button-text">
<i class="fas fa-save"></i>
Cập nhật mật khẩu
</span>
<div class="button-loader"></div>
</button>
</form>

<!-- Footer -->
<div class="auth-footer">
<p class="auth-link-text">Nhớ lại mật khẩu?</p>
<a asp-action="Login" class="auth-link">
Quay lại đăng nhập
<i class="fas fa-arrow-left"></i>
</a>
</div>
</div>
</div>

@section Scripts {
<script src="~/js/auth-scripts.js"></script>
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}

}