Commit e63279f3 by sawit

ใบงาน 43992 การจัดการบริษัท

parent a4fa0dac
...@@ -187,7 +187,7 @@ ...@@ -187,7 +187,7 @@
<div class="xl:col-span-12 col-span-12" *ngIf="action == 'edit'"> <div class="xl:col-span-12 col-span-12" *ngIf="action == 'edit'">
<label for="companyId" class="form-label">{{'รหัสบริษัท' | translate}}</label> <label for="companyId" class="form-label">{{'รหัสบริษัท' | translate}}</label>
<input type="text" class="form-control !bg-input-readonly" id="companyId" placeholder="" <input type="text" class="form-control !bg-gray-200 cursor-not-allowed" id="companyId" placeholder=""
[(ngModel)]="selectModel.companyId" [disabled]="action === 'edit'"> [(ngModel)]="selectModel.companyId" [disabled]="action === 'edit'">
<!-- <div class="text-danger" *ngIf="!selectModel.companyId && action === 'add'"> <!-- <div class="text-danger" *ngIf="!selectModel.companyId && action === 'add'">
{{'Please fill in information' | translate}} {{'Please fill in information' | translate}}
...@@ -227,7 +227,7 @@ ...@@ -227,7 +227,7 @@
</div> </div>
</div> </div>
<!-- <div class="xl:col-span-6 col-span-12" *ngIf="action !== 'edit'"> <div class="xl:col-span-6 col-span-12" *ngIf="action !== 'edit'">
<label for="password" class="form-label">{{'Password' | translate}}</label> <label for="password" class="form-label">{{'Password' | translate}}</label>
<input type="password" class="form-control" id="password" placeholder="" [(ngModel)]="password"> <input type="password" class="form-control" id="password" placeholder="" [(ngModel)]="password">
<div class="text-danger" *ngIf="!password"> <div class="text-danger" *ngIf="!password">
...@@ -244,7 +244,7 @@ ...@@ -244,7 +244,7 @@
<div class="text-danger" *ngIf="confirmPassword && (confirmPassword != password)"> <div class="text-danger" *ngIf="confirmPassword && (confirmPassword != password)">
{{'Password Not Match' | translate}} {{'Password Not Match' | translate}}
</div> </div>
</div> --> </div>
<!-- <div class="xl:col-span-12 col-span-12"> <!-- <div class="xl:col-span-12 col-span-12">
<label for="companyDetail" class="form-label">{{'ข้อมูลบริษัท' | translate}}</label> <label for="companyDetail" class="form-label">{{'ข้อมูลบริษัท' | translate}}</label>
...@@ -287,6 +287,52 @@ ...@@ -287,6 +287,52 @@
</ng-select> </ng-select>
</div> </div>
<!-- Change Password Section -->
<div class="xl:col-span-12 col-span-12" *ngIf="action === 'edit'">
<hr class="my-4 border-gray-200 dark:border-white/10">
<div class="flex justify-end">
<button type="button" (click)="togglePasswordFields()" class="ti-btn ti-btn-link text-primary !p-0">
{{ (showPasswordFields ? ('Cancel' | translate) : ('Change Password' | translate)) }}
</button>
</div>
</div>
<ng-container *ngIf="showPasswordFields && action === 'edit'">
<div class="xl:col-span-6 col-span-12">
<label for="newPassword" class="form-label">{{'Password' | translate}}</label>
<div class="relative">
<input [type]="newPasswordVisible ? 'text' : 'password'" class="form-control" id="newPassword" placeholder="{{'Enter new password' | translate}}" [(ngModel)]="newPassword">
<button type="button" class="absolute top-1/2 end-3 -translate-y-1/2" (click)="newPasswordVisible = !newPasswordVisible">
<i class="ri-eye-line" *ngIf="!newPasswordVisible"></i>
<i class="ri-eye-off-line" *ngIf="newPasswordVisible"></i>
</button>
</div>
<div class="text-danger" *ngIf="!newPassword">
{{ 'Please fill in information' | translate }}
</div>
<!-- <div class="text-danger text-xs mt-1" *ngIf="newPassword && newPassword.length < 8">
{{ 'Password must be at least 8 characters' | translate }}
</div> -->
</div>
<div class="xl:col-span-6 col-span-12">
<label for="confirmNewPassword" class="form-label">{{'Confirm Password' | translate}}</label>
<div class="relative">
<input [type]="confirmNewPasswordVisible ? 'text' : 'password'" class="form-control" id="confirmNewPassword" placeholder="{{'Confirm new password' | translate}}" [(ngModel)]="confirmNewPassword">
<button type="button" class="absolute top-1/2 end-3 -translate-y-1/2" (click)="confirmNewPasswordVisible = !confirmNewPasswordVisible">
<i class="ri-eye-line" *ngIf="!confirmNewPasswordVisible"></i>
<i class="ri-eye-off-line" *ngIf="confirmNewPasswordVisible"></i>
</button>
</div>
<div class="text-danger" *ngIf="!confirmNewPassword">
{{ 'Please fill in information' | translate }}
</div>
<div class="text-danger text-xs mt-1" *ngIf="confirmNewPassword && (confirmNewPassword != newPassword)">
{{'Password Not Match' | translate}}
</div>
</div>
</ng-container>
</div> </div>
</div> </div>
<div class="ti-modal-footer"> <div class="ti-modal-footer">
...@@ -298,11 +344,12 @@ ...@@ -298,11 +344,12 @@
<button *ngIf="action === 'add'" type="button" (click)="save()" <button *ngIf="action === 'add'" type="button" (click)="save()"
class="ti-btn bg-primary text-white !font-medium" [class.ti-btn-disabled]="!selectModel.thName|| class="ti-btn bg-primary text-white !font-medium" [class.ti-btn-disabled]="!selectModel.thName||
!selectModel.engName || !selectModel.engName ||
!password || !confirmPassword || (confirmPassword !== password) ||
(!selectModel.email || isEmailDuplicate || !selectModel.email.includes('@') || !selectModel.email.includes('.'))" (!selectModel.email || isEmailDuplicate || !selectModel.email.includes('@') || !selectModel.email.includes('.'))"
[disabled]="!selectModel.thName|| [disabled]="!selectModel.thName||
!selectModel.engName || !selectModel.engName ||
!password || !confirmPassword || (confirmPassword !== password) ||
(!selectModel.email || isEmailDuplicate || !selectModel.email.includes('@') || !selectModel.email.includes('.'))"> (!selectModel.email || isEmailDuplicate || !selectModel.email.includes('@') || !selectModel.email.includes('.'))">
<!-- !password || !confirmPassword || (confirmPassword !== password)" -->
{{'Save' | translate}}</button> {{'Save' | translate}}</button>
......
...@@ -14,8 +14,10 @@ import { environment } from '../../../../environments/environment'; ...@@ -14,8 +14,10 @@ import { environment } from '../../../../environments/environment';
import { TokenService } from '../../../shared/services/token.service'; import { TokenService } from '../../../shared/services/token.service';
import { CompanyModelS } from '../../models/companys.mode'; import { CompanyModelS } from '../../models/companys.mode';
import { CompanyServiceS } from '../../services/companys.service'; import { CompanyServiceS } from '../../services/companys.service';
import { UserService } from '../../services/user.service';
import { AuthModel } from '../../models/auth.model'; import { AuthModel } from '../../models/auth.model';
import { RoleModel } from '../../models/role.model'; import { RoleModel } from '../../models/role.model';
import { Observable, forkJoin } from 'rxjs';
@Component({ @Component({
selector: 'app-company-manage', selector: 'app-company-manage',
...@@ -59,6 +61,12 @@ export class CompanyManageComponent { ...@@ -59,6 +61,12 @@ export class CompanyManageComponent {
isEmailDuplicate = false; isEmailDuplicate = false;
showPasswordFields = false;
newPassword = '';
confirmNewPassword = '';
newPasswordVisible = false;
confirmNewPasswordVisible = false;
get searchTerm(): string { get searchTerm(): string {
return this._searchTerm; return this._searchTerm;
} }
...@@ -76,10 +84,23 @@ export class CompanyManageComponent { ...@@ -76,10 +84,23 @@ export class CompanyManageComponent {
_searchTerm = ""; _searchTerm = "";
constructor(private comService: CompanyServiceS, public translate: TranslateService, private tokenService: TokenService) { constructor(
private comService: CompanyServiceS,
private userService: UserService,
public translate: TranslateService,
private tokenService: TokenService
) {
this.uploadConfig(); this.uploadConfig();
} }
togglePasswordFields() {
this.showPasswordFields = !this.showPasswordFields;
if (!this.showPasswordFields) {
this.newPassword = '';
this.confirmNewPassword = '';
}
}
uploadConfig() { uploadConfig() {
this.uploaderProfile = new FileUploader({ this.uploaderProfile = new FileUploader({
url: environment.baseUrl + "/files/upload-image", url: environment.baseUrl + "/files/upload-image",
...@@ -201,11 +222,19 @@ export class CompanyManageComponent { ...@@ -201,11 +222,19 @@ export class CompanyManageComponent {
this.selectModel.companyDetail = ""; this.selectModel.companyDetail = "";
this.selectModel.thFirstnameContact = ""; this.selectModel.thFirstnameContact = "";
this.selectModel.updatedAt = new Date().toISOString(); this.selectModel.updatedAt = new Date().toISOString();
this.password = '';
this.confirmPassword = '';
this.showPasswordFields = false;
this.newPassword = '';
this.confirmNewPassword = '';
} }
view(item: CompanyModelS) { view(item: CompanyModelS) {
this.action = 'edit'; this.action = 'edit';
this.selectModel = new CompanyModelS(item); this.selectModel = new CompanyModelS(item);
this.showPasswordFields = false;
this.newPassword = '';
this.confirmNewPassword = '';
console.log(this.selectModel); console.log(this.selectModel);
} }
...@@ -220,25 +249,68 @@ export class CompanyManageComponent { ...@@ -220,25 +249,68 @@ export class CompanyManageComponent {
.then((willSave: any) => { .then((willSave: any) => {
if (willSave) { if (willSave) {
if (this.action === 'add') { if (this.action === 'add') {
this.comService.saveOrUpdateCompany(this.selectModel).subscribe(result => { const body = new AuthModel();
console.log(result); body.username = this.selectModel.email;
swal("บันทึกสำเร็จ!!", "บันทึกข้อมูลสมาชิก", "success"); body.password = this.password;
this.ngOnInit(); body.role = new RoleModel({ roleId: 'employer' });
const rawCompany = { ...this.selectModel };
body.company = new CompanyModelS(rawCompany);
body.company.status = 1; // Fix status to 1 on creation
this.userService.registerCompany(body).subscribe({
next: res => {
swal("Save Success!!", "บันทึกข้อมูลบริษัท", "success");
// Optimistic UI Update
const newCompany = new CompanyModelS(this.selectModel, this.translate);
newCompany.status = 1; // Ensure status is 1 in the UI as well
this.itemsList.unshift(newCompany);
this.filterList.unshift(newCompany);
this.updatePagedItems();
this.childModal?.nativeElement.click(); this.childModal?.nativeElement.click();
}, error => { },
console.error("เกิดข้อผิดพลาดในการบันทึก/อัปเดต:", error); error: err => {
swal("ข้อผิดพลาด!!", "ไม่สามารถบันทึก/อัปเดตข้อมูลได้", "error"); console.error('Error response:', err);
const errorMessage = err?.error?.message || err?.message || 'ไม่ทราบสาเหตุ';
if (errorMessage.includes('email')) {
swal("Save Failed", "อีเมลซ้ำหรือไม่ถูกต้อง", "warning");
} else {
swal("Error", errorMessage, "error");
}
}
}); });
} else if (this.action === 'edit') { } else if (this.action === 'edit') {
this.comService.saveOrUpdateCompany(this.selectModel).subscribe({ const observables: Observable<any>[] = [];
next: result => {
swal("Update Success!!", "บันทึกข้อมูลบริษัท", "success"); // Observable for updating company details
observables.push(this.comService.saveOrUpdateCompany(this.selectModel));
// Check if password needs to be updated
if (this.showPasswordFields && this.newPassword && this.newPassword.length >= 8 && this.newPassword === this.confirmNewPassword) {
const authData = new AuthModel();
authData.username = this.selectModel.email;
authData.password = this.newPassword;
authData.company = new CompanyModelS({ companyId: this.selectModel.companyId });
// Observable for updating password
observables.push(this.userService.editPasswordCompany(authData));
} else if (this.showPasswordFields && (this.newPassword || this.confirmNewPassword)) {
// If password fields are shown but validation fails, show an error and stop.
swal("Invalid Password", "Please ensure passwords match and are at least 8 characters long.", "warning");
return; // Stop the save process
}
forkJoin(observables).subscribe({
next: results => {
swal("Update Success!!", "บันทึกข้อมูลบริษัทเรียบร้อยแล้ว", "success");
this.ngOnInit(); this.ngOnInit();
this.childModal?.nativeElement.click(); this.childModal?.nativeElement.click();
}, },
error: err => { error: err => {
swal("Error", "ไม่สามารถอัปเดตได้", "error"); console.error('Update failed:', err);
swal("Error", "เกิดข้อผิดพลาดในการอัปเดตข้อมูล", "error");
} }
}); });
} }
......
...@@ -14,6 +14,7 @@ import { ProfileModel } from '../models/profile.model'; ...@@ -14,6 +14,7 @@ import { ProfileModel } from '../models/profile.model';
export class UserService { export class UserService {
apiBaseUrl = "/admin"; apiBaseUrl = "/admin";
apiAuthUrl = "/auth" apiAuthUrl = "/auth"
apiAuthComUrl = "/auth/company"
constructor( constructor(
private http: HttpClient, private http: HttpClient,
private translateService: TranslateService private translateService: TranslateService
...@@ -105,6 +106,12 @@ export class UserService { ...@@ -105,6 +106,12 @@ export class UserService {
register(body: AuthModel) { register(body: AuthModel) {
return this.http.post<ResponseModel>(this.apiAuthUrl + "/register", body); return this.http.post<ResponseModel>(this.apiAuthUrl + "/register", body);
} }
registerCompany(body: AuthModel) {
return this.http.post<ResponseModel>(this.apiAuthComUrl + "/register", body);
}
editPasswordCompany(body: AuthModel) {
return this.http.post<ResponseModel>("/users/company", body)
}
save(body: ProfileModel) { save(body: ProfileModel) {
return this.http.post<ResponseModel>(this.apiBaseUrl + '/manage-profile', new ProfileModel(body)); return this.http.post<ResponseModel>(this.apiBaseUrl + '/manage-profile', new ProfileModel(body));
......
...@@ -138,5 +138,10 @@ ...@@ -138,5 +138,10 @@
"EDIT_PERMISSIONS": "Edit Permissions", "EDIT_PERMISSIONS": "Edit Permissions",
"ROLE": "Role", "ROLE": "Role",
"SAVE_CHANGES": "Save Changes", "SAVE_CHANGES": "Save Changes",
"Article":"Article" "Article":"Article",
"Please ensure passwords match and are at least 8 characters long.":"Please ensure passwords match and are at least 8 characters long.",
"Password must be at least 8 characters":"Password must be at least 8 characters",
"Change Password":"Change Password",
"Enter new password":"Enter new password",
"Confirm new password":"Confirm new password"
} }
...@@ -138,5 +138,10 @@ ...@@ -138,5 +138,10 @@
"EDIT_PERMISSIONS": "แก้ไขสิทธิ์", "EDIT_PERMISSIONS": "แก้ไขสิทธิ์",
"ROLE": "บทบาท", "ROLE": "บทบาท",
"SAVE_CHANGES": "บันทึกการเปลี่ยนแปลง", "SAVE_CHANGES": "บันทึกการเปลี่ยนแปลง",
"Article":"บทความ" "Article":"บทความ",
"Please ensure passwords match and are at least 8 characters long.":"กรุณากรอกรหัสผ่านให้ตรงกันและมีความยาวอย่างน้อย 8 ตัวอักษร",
"Password must be at least 8 characters":"รหัสผ่านต้องมีความยาวอย่างน้อย 8 ตัวอักษร",
"Change Password":"เปลี่ยนรหัสผ่าน",
"Enter new password":"กรอกรหัสผ่านใหม่",
"Confirm new password":"ยืนยันรหัสผ่านใหม่"
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment