2025-05-18 03:12:20 +07:00
|
|
|
use crate::{RolesDetailItemDto, RolesDetailQueryDto};
|
2025-03-23 12:32:00 +07:00
|
|
|
use lazy_static::lazy_static;
|
2025-02-26 15:45:05 +07:00
|
|
|
use serde::{Deserialize, Serialize};
|
2025-03-26 13:06:34 +07:00
|
|
|
use surrealdb::sql::Thing;
|
2025-02-26 15:45:05 +07:00
|
|
|
use utoipa::ToSchema;
|
2025-03-23 12:32:00 +07:00
|
|
|
use validator::Validate;
|
2025-08-11 22:31:51 +07:00
|
|
|
use crate::UsersSchema; // Import UsersSchema
|
2025-02-26 15:45:05 +07:00
|
|
|
|
2025-03-23 12:32:00 +07:00
|
|
|
lazy_static! {
|
2025-07-21 21:29:04 +07:00
|
|
|
static ref PASSWORD_REGEX: regex::Regex =
|
|
|
|
|
regex::Regex::new(r"^[A-Za-z\d@$!%*?&]{8,}$").unwrap();
|
2025-03-23 12:32:00 +07:00
|
|
|
}
|
|
|
|
|
|
2025-05-18 03:12:20 +07:00
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
|
|
|
|
pub struct UsersActiveInactiveRequestDto {
|
|
|
|
|
pub is_active: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
|
|
|
|
pub struct UsersSetNewPasswordRequestDto {
|
|
|
|
|
pub password: String,
|
|
|
|
|
pub old_password: String,
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-23 12:32:00 +07:00
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema, Validate)]
|
2025-03-20 22:41:20 +07:00
|
|
|
pub struct UsersCreateRequestDto {
|
2025-03-23 12:32:00 +07:00
|
|
|
#[validate(
|
|
|
|
|
length(min = 1, message = "Email cannot be empty"),
|
|
|
|
|
email(message = "Email not valid")
|
|
|
|
|
)]
|
2025-03-20 22:41:20 +07:00
|
|
|
pub email: String,
|
2025-05-17 02:08:59 +07:00
|
|
|
|
2025-03-23 12:32:00 +07:00
|
|
|
#[validate(length(
|
|
|
|
|
min = 8,
|
|
|
|
|
message = "Password must have at least 8 characters"
|
|
|
|
|
))]
|
|
|
|
|
#[validate(regex(
|
2025-07-21 21:29:04 +07:00
|
|
|
path = "*PASSWORD_REGEX",
|
2025-03-23 12:32:00 +07:00
|
|
|
message = "Password must include uppercase, lowercase, number, and special character"
|
|
|
|
|
))]
|
2025-03-20 22:41:20 +07:00
|
|
|
pub password: String,
|
2025-05-17 02:08:59 +07:00
|
|
|
|
2025-03-23 12:32:00 +07:00
|
|
|
#[validate(length(min = 2, message = "Fullname at least have 2 character"))]
|
|
|
|
|
pub fullname: String,
|
2025-05-17 02:08:59 +07:00
|
|
|
|
2025-03-23 12:32:00 +07:00
|
|
|
#[validate(length(
|
|
|
|
|
min = 10,
|
|
|
|
|
message = "Phone number at least have 10 character"
|
|
|
|
|
))]
|
|
|
|
|
pub phone_number: String,
|
|
|
|
|
pub is_active: bool,
|
2025-03-23 20:42:38 +07:00
|
|
|
pub role_id: String,
|
2025-03-23 12:32:00 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema, Validate)]
|
|
|
|
|
pub struct UsersUpdateRequestDto {
|
|
|
|
|
#[validate(
|
|
|
|
|
length(min = 1, message = "Email cannot be empty"),
|
|
|
|
|
email(message = "Email not valid")
|
|
|
|
|
)]
|
|
|
|
|
pub email: String,
|
|
|
|
|
#[validate(length(
|
|
|
|
|
min = 8,
|
|
|
|
|
message = "Password must have at least 8 characters"
|
|
|
|
|
))]
|
2025-07-21 21:29:04 +07:00
|
|
|
pub password: String,
|
2025-03-23 12:32:00 +07:00
|
|
|
#[validate(length(min = 2, message = "Fullname at least have 2 character"))]
|
|
|
|
|
pub fullname: String,
|
|
|
|
|
#[validate(length(
|
|
|
|
|
min = 10,
|
|
|
|
|
message = "Phone number at least have 10 character"
|
|
|
|
|
))]
|
|
|
|
|
pub phone_number: String,
|
|
|
|
|
pub is_active: bool,
|
2025-03-30 02:46:16 +07:00
|
|
|
#[validate(length(min = 1, message = "Gender is required"))]
|
2025-03-23 12:32:00 +07:00
|
|
|
pub gender: Option<String>,
|
2025-03-30 02:46:16 +07:00
|
|
|
#[validate(length(min = 1, message = "Birthdate is required"))]
|
2025-03-23 12:32:00 +07:00
|
|
|
pub birthdate: Option<String>,
|
2025-03-30 02:46:16 +07:00
|
|
|
#[validate(length(min = 1, message = "Avatar is required"))]
|
2025-03-23 12:32:00 +07:00
|
|
|
pub avatar: Option<String>,
|
2025-03-23 20:42:38 +07:00
|
|
|
pub role_id: String,
|
2025-03-20 22:41:20 +07:00
|
|
|
}
|
|
|
|
|
|
2025-03-30 02:46:16 +07:00
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
|
|
|
|
pub struct UsersDetailItemDto {
|
|
|
|
|
pub id: String,
|
2025-05-18 03:12:20 +07:00
|
|
|
pub role: RolesDetailItemDto,
|
2025-03-26 13:06:34 +07:00
|
|
|
pub fullname: String,
|
|
|
|
|
pub email: String,
|
|
|
|
|
pub avatar: Option<String>,
|
|
|
|
|
pub phone_number: String,
|
|
|
|
|
pub is_active: bool,
|
|
|
|
|
pub gender: Option<String>,
|
|
|
|
|
pub birthdate: Option<String>,
|
2025-05-17 02:08:59 +07:00
|
|
|
pub created_at: String,
|
|
|
|
|
pub updated_at: String,
|
2025-03-26 13:06:34 +07:00
|
|
|
}
|
|
|
|
|
|
2025-05-18 03:12:20 +07:00
|
|
|
impl UsersDetailItemDto {
|
2025-08-11 22:31:51 +07:00
|
|
|
pub fn from(dto: &UsersDetailQueryDto) -> Self { // Reverted to taking a reference
|
2025-05-18 03:12:20 +07:00
|
|
|
Self {
|
2025-05-20 00:26:24 +07:00
|
|
|
id: dto.id.id.to_raw().clone(),
|
2025-05-18 03:12:20 +07:00
|
|
|
role: RolesDetailItemDto::from(&dto.role),
|
2025-05-20 00:26:24 +07:00
|
|
|
fullname: dto.fullname.clone(),
|
|
|
|
|
email: dto.email.clone(),
|
|
|
|
|
avatar: dto.avatar.clone(),
|
2025-08-11 22:31:51 +07:00
|
|
|
phone_number: dto.phone_number.clone(), // Corrected from dto.phone.clone()
|
2025-07-21 21:29:04 +07:00
|
|
|
is_active: dto.is_active,
|
2025-05-20 00:26:24 +07:00
|
|
|
gender: dto.gender.clone(),
|
|
|
|
|
birthdate: dto.birthdate.clone(),
|
|
|
|
|
created_at: dto.created_at.clone(),
|
|
|
|
|
updated_at: dto.updated_at.clone(),
|
2025-05-18 03:12:20 +07:00
|
|
|
}
|
|
|
|
|
}
|
2025-08-11 22:31:51 +07:00
|
|
|
|
|
|
|
|
pub fn from_schema(schema: &UsersSchema) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
id: schema.id.id.to_raw(),
|
|
|
|
|
role: RolesDetailItemDto::default(), // Placeholder, role needs to be fetched
|
|
|
|
|
fullname: schema.fullname.clone(),
|
|
|
|
|
email: schema.email.clone(),
|
|
|
|
|
avatar: schema.avatar.clone(),
|
|
|
|
|
phone_number: schema.phone_number.clone(),
|
|
|
|
|
is_active: schema.is_active,
|
|
|
|
|
gender: schema.gender.clone(),
|
|
|
|
|
birthdate: schema.birthdate.clone(),
|
|
|
|
|
created_at: schema.created_at.clone(),
|
|
|
|
|
updated_at: schema.updated_at.clone(),
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-18 03:12:20 +07:00
|
|
|
}
|
|
|
|
|
|
2025-03-23 12:32:00 +07:00
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
2025-03-30 02:46:16 +07:00
|
|
|
pub struct UsersListItemDto {
|
|
|
|
|
pub id: String,
|
|
|
|
|
pub role: String,
|
|
|
|
|
pub fullname: String,
|
|
|
|
|
pub email: String,
|
|
|
|
|
pub avatar: Option<String>,
|
|
|
|
|
pub phone_number: String,
|
2025-03-23 12:32:00 +07:00
|
|
|
pub is_active: bool,
|
2025-03-30 16:08:58 +07:00
|
|
|
pub created_at: String,
|
|
|
|
|
pub updated_at: String,
|
2025-02-26 15:45:05 +07:00
|
|
|
}
|
2025-03-30 02:46:16 +07:00
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
2025-05-17 02:08:59 +07:00
|
|
|
pub struct UsersListQueryDto {
|
2025-03-30 02:46:16 +07:00
|
|
|
pub id: Thing,
|
2025-05-17 02:08:59 +07:00
|
|
|
pub role: RolesDetailQueryDto,
|
2025-03-30 02:46:16 +07:00
|
|
|
pub fullname: String,
|
2025-08-11 22:31:51 +07:00
|
|
|
pub email: String, // Corrected from pub pub email: String,
|
2025-03-30 02:46:16 +07:00
|
|
|
pub avatar: Option<String>,
|
|
|
|
|
pub phone_number: String,
|
|
|
|
|
pub is_active: bool,
|
2025-03-30 16:08:58 +07:00
|
|
|
pub created_at: String,
|
|
|
|
|
pub updated_at: String,
|
2025-03-30 02:46:16 +07:00
|
|
|
}
|
|
|
|
|
|
2025-05-17 02:08:59 +07:00
|
|
|
impl UsersListQueryDto {
|
2025-05-20 11:54:15 +07:00
|
|
|
pub fn from(self) -> UsersListItemDto {
|
2025-05-17 02:08:59 +07:00
|
|
|
UsersListItemDto {
|
|
|
|
|
id: self.id.id.to_raw(),
|
2025-05-20 01:49:50 +07:00
|
|
|
role: self.role.name.clone(),
|
2025-05-17 02:08:59 +07:00
|
|
|
fullname: self.fullname.clone(),
|
|
|
|
|
email: self.email.clone(),
|
|
|
|
|
avatar: self.avatar.clone(),
|
|
|
|
|
phone_number: self.phone_number.clone(),
|
|
|
|
|
is_active: self.is_active,
|
|
|
|
|
created_at: self.created_at.clone(),
|
|
|
|
|
updated_at: self.updated_at.clone(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-30 02:46:16 +07:00
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
2025-05-17 02:08:59 +07:00
|
|
|
pub struct UsersDetailQueryDto {
|
2025-03-30 02:46:16 +07:00
|
|
|
pub id: Thing,
|
|
|
|
|
pub fullname: String,
|
|
|
|
|
pub email: String,
|
|
|
|
|
pub avatar: Option<String>,
|
|
|
|
|
pub phone_number: String,
|
|
|
|
|
pub is_active: bool,
|
|
|
|
|
pub is_deleted: bool,
|
|
|
|
|
pub gender: Option<String>,
|
|
|
|
|
pub birthdate: Option<String>,
|
|
|
|
|
pub password: String,
|
2025-05-17 02:08:59 +07:00
|
|
|
pub role: RolesDetailQueryDto,
|
2025-03-30 02:46:16 +07:00
|
|
|
pub created_at: String,
|
|
|
|
|
pub updated_at: String,
|
2025-07-21 21:29:04 +07:00
|
|
|
pub mentor_id: Option<Thing>,
|
2025-03-30 02:46:16 +07:00
|
|
|
}
|
2025-05-20 01:49:50 +07:00
|
|
|
|
|
|
|
|
impl UsersDetailQueryDto {
|
|
|
|
|
pub fn from(&self) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
id: self.id.clone(),
|
2025-07-21 21:29:04 +07:00
|
|
|
role: self.role.clone(),
|
2025-05-20 01:49:50 +07:00
|
|
|
fullname: self.fullname.clone(),
|
|
|
|
|
email: self.email.clone(),
|
|
|
|
|
avatar: self.avatar.clone(),
|
|
|
|
|
phone_number: self.phone_number.clone(),
|
|
|
|
|
is_active: self.is_active,
|
2025-07-21 21:29:04 +07:00
|
|
|
mentor_id: self.mentor_id.clone(),
|
2025-05-20 01:49:50 +07:00
|
|
|
gender: self.gender.clone(),
|
|
|
|
|
is_deleted: self.is_deleted,
|
|
|
|
|
password: self.password.clone(),
|
|
|
|
|
birthdate: self.birthdate.clone(),
|
|
|
|
|
created_at: self.created_at.clone(),
|
|
|
|
|
updated_at: self.updated_at.clone(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-21 21:29:04 +07:00
|
|
|
|
|
|
|
|
impl From<&UsersDetailItemDto> for UsersDetailQueryDto {
|
|
|
|
|
fn from(dto: &UsersDetailItemDto) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
id: crate::make_thing(&imphnen_libs::ResourceEnum::Users.to_string(), &dto.id),
|
|
|
|
|
fullname: dto.fullname.clone(),
|
|
|
|
|
email: dto.email.clone(),
|
|
|
|
|
avatar: dto.avatar.clone(),
|
|
|
|
|
phone_number: dto.phone_number.clone(),
|
|
|
|
|
is_active: dto.is_active,
|
|
|
|
|
is_deleted: false,
|
|
|
|
|
gender: dto.gender.clone(),
|
|
|
|
|
birthdate: dto.birthdate.clone(),
|
|
|
|
|
password: String::new(),
|
|
|
|
|
role: RolesDetailQueryDto::default(),
|
|
|
|
|
created_at: dto.created_at.clone(),
|
|
|
|
|
updated_at: dto.updated_at.clone(),
|
|
|
|
|
mentor_id: None,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|