Preview:
//HTML
<div class="text-center mb-3">
          <div class="profile-photo-wrapper">
            <img src="https://cdn.create.vista.com/api/media/small/248105354/stock-vector-user-vector-icon-grey-background" alt src="assets/images/user.jpg" class="img-fluid rounded-circle profile-photo">
            <div class="edit-photo-wrapper">
              <a href="#" (click)="enableEditMode($event)" class="edit-link">Edit</a>
              <label [class.disabled-icon]="!isEditMode" for="photoUpload" class="photo-upload-icon">
                <i class="bi bi-camera"></i>
              </label>
            </div>
            <input type="file" id="photoUpload" formControlName="photo" class="d-none" (change)="onPhotoChange($event)" [readonly]="!isEditMode" >
          </div>
        </div>

//TS
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
import { UserProfile } from '../Models/UserProfile';
import { UserService } from '../Services/userprofile.service';
import { Router, ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';
import { updateUser } from '../shared/update-user';

declare var $: any; // Import jQuery

@Component({
  selector: 'app-profile-page',
  standalone: true,
  imports: [CommonModule, ReactiveFormsModule],
  templateUrl: './profile-page.component.html',
  styleUrls: ['./profile-page.component.css']
})
export class ProfilePageComponent implements OnInit {
  profileForm: FormGroup;
  user!: updateUser;
  isEditMode = false;
  errorMessage = '';

  constructor(
    private userService: UserService,
    private router: Router,
    private fb: FormBuilder,
    private location: Location) 
  {
    this.profileForm = this.fb.group({
      email: ['', [Validators.required, Validators.email]],
      name: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(20)]],
      surname: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(20)]],
      phoneNumber: ['', [Validators.required, Validators.maxLength(10)]],
      physical_Address: ['', [Validators.required, Validators.maxLength(255)]],
      photo: ['']
    });
  }

  ngOnInit(): void {
    const userId = JSON.parse(localStorage.getItem('User')!).userId;
    console.log('User ID from local storage:', userId);
    this.userService.getUserById(userId).subscribe({
      next: (result) => {
        console.log('User data received:', result);
        this.user = result;
        this.profileForm.patchValue(this.user);
      },
      error: () => {
        console.error('Error fetching user profile:'); // Add error console log
        alert('Error fetching user profile');
      }
    });
    this.isEditMode = false;
  }

  clearForm() {
    this.profileForm.reset();
  }

  enableEditMode(event: Event) {
    event.preventDefault();
    this.isEditMode = true;
    this.profileForm.enable();
  }

  openSaveModal() {
    if (this.profileForm.invalid) {
      this.showValidationErrors();
      $('#errorModal').modal('show');
      return;
    }
    $('#saveConfirmationModal').modal('show');
  }

  showValidationErrors() {
    const invalidFields: string[] = [];
    Object.keys(this.profileForm.controls).forEach(key => {
      const controlErrors = this.profileForm.get(key)?.errors;
      if (controlErrors) {
        Object.keys(controlErrors).forEach(errorKey => {
          invalidFields.push(`${key}: ${errorKey}`);
        });
      }
    });
    this.errorMessage = `Please enter a valid input: ${invalidFields.join(', ')}`;
  }

  dismissModal() {
    $('#saveConfirmationModal').modal('hide');
  }

  dismissErrorModal() {
    $('#errorModal').modal('hide');
  }

  confirmSave() {
    this.dismissModal();
    this.onSubmit();
    this.isEditMode = false; // Disable edit mode after confirmation
  }

  onSubmit() {
    if (this.profileForm.valid) {
      const userId = JSON.parse(localStorage.getItem('User')!).userId;
      this.userService.updateUser(userId,this.profileForm.value).subscribe({
        next: (result) => {
          console.log('User to be updated:', result);
          this.router.navigateByUrl(`/ProfilePage/${userId}`);
          alert('Successfully updated profile');
        },
        error: () => {
          console.error('Error updating user profile:');
          alert('Error updating profile');
        }
      });
    }
  }

  onPhotoChange(event: Event): void {
    if (!this.isEditMode) return;

    const input = event.target as HTMLInputElement;
    if (input.files && input.files[0]) {
      const reader = new FileReader();
      reader.onload = (e: any) => {
        const img = document.querySelector('.profile-photo') as HTMLImageElement;
        img.src = e.target.result;
      };
      reader.readAsDataURL(input.files[0]);
    }
  }

  goBack() {
    const userTypeId = JSON.parse(localStorage.getItem('User')!).userTypeId;
    const userId = JSON.parse(localStorage.getItem('User')!).userId;
    if (userTypeId === 1) {  // Ensure userTypeID is compared as string
      this.router.navigateByUrl(`/OwnerHome/${userId}`);
    } else if (userTypeId === 2) {
      this.router.navigateByUrl(`/EmployeeHome/${userId}`);
    } else if (userTypeId === 3) {
      this.router.navigateByUrl(`/Home/${userId}`);
    }
  }

  changePassword() {
    this.router.navigateByUrl('/ChangePasswordPage');
  }
}
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter