import { Component, EventEmitter, inject, Input, Output, ViewChild } from '@angular/core'; import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator'; import { CustomPaginator } from '../../shared/custom-paginator'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { PhonePipe } from '../../shared/pipes/phone.pipe'; import { CommonModule } from '@angular/common'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { UserPreferences } from '../../core/models/user-preference'; import { ContactService } from '../../core/services/preparer/contact.service'; import { NotificationService } from '../../core/services/common/notification.service'; import { MatDialog } from '@angular/material/dialog'; import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { Contact } from '../../core/models/preparer/contact'; import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component'; import { ContactLogin } from '../../core/models/preparer/contact-login'; import { LocationService } from '../../core/services/preparer/location.service'; import { Location } from '../../core/models/preparer/location'; import { finalize } from 'rxjs'; @Component({ selector: 'app-contacts', imports: [AngularMaterialModule, ReactiveFormsModule, PhonePipe, CommonModule], templateUrl: './contacts.component.html', styleUrl: './contacts.component.scss', providers: [{ provide: MatPaginatorIntl, useClass: CustomPaginator }], }) export class ContactsComponent { @ViewChild(MatPaginator) paginator!: MatPaginator; @ViewChild(MatSort) sort!: MatSort; displayedColumns: string[] = ['firstName', 'lastName', 'title', 'phone', 'mobile', 'email', 'defaultContact', 'actions']; dataSource = new MatTableDataSource(); contactForm: FormGroup; // contactLoginForm: FormGroup; isEditing = false; currentContactId: number | null = null; isLoading = false; changeInProgress = false; showForm = false; showInactiveContacts = false; contacts: Contact[] = []; locations: Location[] = []; contactReadOnlyFields: any = { lastChangedDate: null, lastChangedBy: null, isInactive: null, inactivatedDate: null }; contactLoginReadOnlyFields: any = { email: null }; @Input() clientid: number = 0; @Input() userPreferences: UserPreferences = {}; @Output() hasContacts = new EventEmitter(); private fb = inject(FormBuilder); private contactService = inject(ContactService); private dialog = inject(MatDialog); private notificationService = inject(NotificationService); private errorHandler = inject(ApiErrorHandlerService); private locationService = inject(LocationService); constructor() { this.contactForm = this.fb.group({ firstName: ['', [Validators.required, Validators.maxLength(50)]], lastName: ['', [Validators.required, Validators.maxLength(50)]], middleInitial: ['', [Validators.maxLength(1)]], title: ['', [Validators.required, Validators.maxLength(100)]], phone: ['', [Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]], mobile: ['', [Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]], fax: ['', [Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]], email: ['', [Validators.required, Validators.email, Validators.maxLength(100)]], locationid: [''], defaultContact: [false] }); // this.contactLoginForm = this.fb.group({ // password: ['', [Validators.required]] // }); } ngOnInit(): void { this.loadLocations(); } ngAfterViewInit() { this.dataSource.paginator = this.paginator; this.dataSource.sort = this.sort; } public refreshLocationData() { this.loadLocations(); } loadLocations(): void { this.locationService.getLocationsById(this.clientid).subscribe({ next: (locations: Location[]) => { this.locations = locations; this.loadContacts(); }, error: (error: any) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load locations'); this.notificationService.showError(errorMessage); console.error('Error loading locations:', error); } }); } loadContacts(): void { this.isLoading = true; this.contactService.getContactsById(this.clientid).pipe(finalize(() => { this.isLoading = false; })).subscribe({ next: (contacts: Contact[]) => { this.contacts = contacts; this.renderContacts(); }, error: (error: any) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load contacts'); this.notificationService.showError(errorMessage); console.error('Error loading contacts:', error); } }); } addNewContact(): void { this.showForm = true; this.isEditing = false; this.currentContactId = null; this.contactForm.reset(); // this.contactForm.patchValue({ defaultContact: false }); this.contactForm.get('locationid')?.setValidators([Validators.required]); } editContact(contact: Contact): void { this.showForm = true; this.isEditing = true; this.currentContactId = contact.clientContactId; this.contactForm.patchValue({ firstName: contact.firstName, lastName: contact.lastName, middleInitial: contact.middleInitial, title: contact.title, phone: contact.phone, mobile: contact.mobile, fax: contact.fax, email: contact.email, //location: contact.locationid, // defaultContact: contact.defaultContact }); this.contactReadOnlyFields.lastChangedDate = contact.lastUpdatedDate ?? contact.dateCreated; this.contactReadOnlyFields.lastChangedBy = contact.lastUpdatedBy ?? contact.createdBy; this.contactReadOnlyFields.isInactive = contact.isInactive; this.contactReadOnlyFields.inactivatedDate = contact.inactivatedDate; this.contactForm.get('locationid')?.setValidators([]); } saveContact(): void { if (this.contactForm.invalid) { this.contactForm.markAllAsTouched(); return; } // default the first contact const contactData: Contact = this.contactForm.value; contactData.defaultContact = this.dataSource?.data?.length === 0; const saveObservable = this.isEditing && (this.currentContactId! > 0) ? this.contactService.updateContact(this.currentContactId!, contactData) : this.contactService.createContact(contactData); this.changeInProgress = true; saveObservable.pipe(finalize(() => this.changeInProgress = false)).subscribe({ next: () => { this.notificationService.showSuccess(`Contact ${this.isEditing ? 'updated' : 'added'} successfully`); this.loadContacts(); this.cancelEdit(); this.hasContacts.emit(true); }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, `Failed to ${this.isEditing ? 'update' : 'add'} contact`); this.notificationService.showError(errorMessage); console.error('Error saving contact:', error); } }); } toggleShowInactiveContacts(): void { this.showInactiveContacts = !this.showInactiveContacts; this.renderContacts(); } renderContacts(): void { if (this.showInactiveContacts) { this.dataSource.data = this.contacts.filter(contact => contact.isInactive); } else { this.dataSource.data = this.contacts.filter(contact => !contact.isInactive); } } inactivateContact(contactId: string): void { const dialogRef = this.dialog.open(ConfirmDialogComponent, { width: '350px', data: { title: 'Confirm Inactivation', message: 'Are you sure you want to inactivate this contact?', confirmText: 'Yes', cancelText: 'Cancel' } }); dialogRef.afterClosed().subscribe(result => { if (result) { this.contactService.inactivateContact(contactId).subscribe({ next: () => { this.notificationService.showSuccess('Contact inactivated successfully'); this.loadContacts(); }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to inactivate contact'); this.notificationService.showError(errorMessage); console.error('Error inactivating contact:', error); } }); } }); } reactivateContact(contactId: string): void { const dialogRef = this.dialog.open(ConfirmDialogComponent, { width: '350px', data: { title: 'Confirm Reactivation', message: 'Are you sure you want to reactivate this contact?', confirmText: 'Yes', cancelText: 'Cancel' } }); dialogRef.afterClosed().subscribe(result => { if (result) { this.contactService.reactivateContact(contactId).subscribe({ next: () => { this.notificationService.showSuccess('Contact reactivated successfully'); this.loadContacts(); }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to reactivate contact'); this.notificationService.showError(errorMessage); console.error('Error reactivating contact:', error); } }); } }); } createLogin(contactId: string): void { const dialogRef = this.dialog.open(ConfirmDialogComponent, { width: '350px', data: { title: 'Confirm Login Creation', message: 'Are you sure you want to create a login for this contact?', confirmText: 'Yes', cancelText: 'Cancel' } }); dialogRef.afterClosed().subscribe(result => { if (result) { const contactLoginData: ContactLogin = { clientContactId: +contactId }; this.contactService.createContactLogin(contactLoginData).subscribe({ next: () => { this.notificationService.showSuccess(`Login created successfully`); this.loadContacts(); this.cancelEdit(); }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, `Failed to create login`); this.notificationService.showError(errorMessage); console.error('Error saving login:', error); } }); } }); } cancelEdit(): void { this.showForm = false; this.isEditing = false; this.currentContactId = null; this.contactForm.reset(); // this.contactLoginForm.reset(); } setDefaultContact(contactId: string): void { const dialogRef = this.dialog.open(ConfirmDialogComponent, { width: '450px', data: { title: 'Confirm Default Contact', message: 'Are you sure you want to set this contact as default contact?', confirmText: 'Yes', cancelText: 'Cancel' } }); dialogRef.afterClosed().subscribe(result => { if (result) { this.contactService.setDefaultServiceProviderContact(contactId).subscribe({ next: () => { this.notificationService.showSuccess('Default contact updated successfully'); this.loadContacts(); }, error: (error) => { let errorMessage = this.errorHandler.handleApiError(error, 'Failed to set default contact'); this.notificationService.showError(errorMessage); console.error('Error setting default contact:', error); } }); } }); } }