Further updates on 03-11-2025

This commit is contained in:
2025-11-03 13:46:43 +05:30
parent 91cb073c78
commit 434d95eeaf
87 changed files with 17782 additions and 3451 deletions
@@ -1,572 +1,447 @@
<div class="container">
<div class="user-layout">
<!-- Sidebar -->
<app-menu class="sidebar"></app-menu>
<app-menu></app-menu>
<div *ngIf="false" class="row mb-2 mt-2 text-center">
<div class="col-md-4">
</div>
<div class="col-md-4">
<h5>User Management Portal</h5>
<small *ngIf="titleAction$ | async as title">{{title}}</small>
</div>
<div class="col-md-4">
</div>
</div>
<!-- nav bar -->
<nav *ngIf="false" class="navbar navbar-expand-md breadcrumb">
<div class="collapse navbar-collapse" id="navbarCollapse">
<div class="nav nav-pills">
<a class="nav-item nav-link active ml-1" (click)="changeTitle('Users')" data-bs-toggle="tab" href="#users">
<i class="fa fa-users"></i>
Users
</a>
<a class="nav-item nav-link active ml-1" (click)="changeTitle('Professors')" [routerLink]="['/dashboard/professorManagement']" >
<i class="fa fa-users"></i>
Professors
</a>
<!-- Possible attacks-->
<!-- document.getElementsByClassName('nav-item nav-link ml-3')[0].click()-->
<!-- document.getElementsByName('reset-password-email')[0].value='d.art.shishkin@gmail.com'-->
<!-- document.getElementsByName('reset-password-email')[0].closest('form').querySelector('button[type="submit"]').disabled=false -->
<!-- document.getElementsByClassName('nav-item nav-link ml-3')[0].hidden=false-->
<!-- document.getElementById('reset-password').hidden=false-->
<a class="nav-item nav-link ml-3" (click)="changeTitle('Settings')" data-bs-toggle="tab"
href="#reset-password">
<i class="fa fa-cogs"></i>
Settings
</a>
<a class="nav-item nav-link move-right mr-3" (click)="changeTitle('Profile')" data-bs-toggle="tab"
href="#profile">
Welcome, {{loggedInUser.firstName}} {{loggedInUser.lastName}}
<i class="fa fa-user"></i>
</a>
<!-- Main Content -->
<div class="user-content">
<!-- Header Section -->
<div class="user-header">
<div class="header-left">
<h1 class="page-title">User Management</h1>
<p class="page-subtitle">Manage system users, roles, and permissions</p>
</div>
<div class="header-actions">
<div class="search-box">
<i class="fa fa-search"></i>
<input
name="searchTerm"
#searchTerm="ngModel"
class="search-input"
type="search"
placeholder="Search users..."
ngModel
(ngModelChange)="searchUsers(searchTerm.value)">
</div>
<button *ngIf="isManager" class="btn-primary" (click)="openModal('add')">
<i class="fa fa-plus"></i>
<span>New User</span>
</button>
<button class="btn-refresh" (click)="getUsers(true)">
<i class="fas fa-sync" [ngClass]="{'fa-spin': refreshing }"></i>
</button>
</div>
</div>
</nav>
<!-- main content -->
<div class="tab-content mt-3" id="myTabContent">
<!-- user table -->
<div class="tab-pane fade show active" id="users">
<div class="mb-3 float-end">
<div class="btn-group mr-2">
<!-- Users Table -->
<div class="table-container">
<div class="table-wrapper">
<table class="users-table">
<thead>
<tr>
<th>Photo</th>
<th>User ID</th>
<th>Name</th>
<th>Username</th>
<th>Email</th>
<th>Role</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let appUser of users">
<td (click)="onSelectUser(appUser)">
<div class="user-avatar">
<img [src]="appUser?.profileImageUrl" [alt]="appUser?.username">
</div>
</td>
<td (click)="onSelectUser(appUser)">
<span class="user-id">{{ appUser?.userId }}</span>
</td>
<td (click)="onSelectUser(appUser)">
<div class="user-name-cell">
<span class="full-name">{{ appUser?.firstName }} {{ appUser?.lastName }}</span>
</div>
</td>
<td (click)="onSelectUser(appUser)">
<span class="username-text">{{ appUser?.username }}</span>
</td>
<td (click)="onSelectUser(appUser)">
<span class="email-text">{{ appUser?.email }}</span>
</td>
<td (click)="onSelectUser(appUser)">
<span class="role-badge">{{ appUser?.role?.substring(5) || 'USER' }}</span>
</td>
<td (click)="onSelectUser(appUser)">
<span class="status-badge" [class.status-active]="appUser?.active" [class.status-inactive]="!appUser?.active">
<i class="fa" [class.fa-check-circle]="appUser?.active" [class.fa-times-circle]="!appUser?.active"></i>
{{ appUser?.active ? 'Active' : 'Inactive' }}
</span>
</td>
<td>
<div class="action-buttons">
<button class="btn-action btn-edit" (click)="onEditUser(appUser)" title="Edit">
<i class="fas fa-edit"></i>
</button>
<button *ngIf="isAdmin" class="btn-action btn-delete" (click)="onDeleteUser(appUser)" title="Delete">
<i class="fas fa-trash"></i>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<form class="form-inline my-2 my-lg-0 justify-content-center">
<input name="searchTerm" #searchTerm="ngModel" class="form-control mr-sm-2" type="search"
placeholder="Search users..."
ngModel (ngModelChange)="searchUsers(searchTerm.value)">
<!-- Empty State -->
<div *ngIf="users.length === 0 && !refreshing" class="empty-state">
<div class="empty-icon">
<i class="fa fa-users"></i>
</div>
<h3>No users found</h3>
<p>Try adjusting your search or add a new user</p>
</div>
</div>
<!-- View User Modal -->
<div *ngIf="selectedUser && showViewUserModal" class="modal-overlay" (click)="closeModal('view')">
<div class="modal-container" (click)="$event.stopPropagation()">
<div class="modal-header">
<h3>User Details</h3>
<button class="modal-close" (click)="closeModal('view')">
<i class="fa fa-times"></i>
</button>
</div>
<div class="modal-body">
<div class="user-detail-card">
<div class="user-detail-header">
<div class="user-detail-avatar">
<img [src]="selectedUser.profileImageUrl" [alt]="selectedUser.username">
</div>
<div class="user-detail-info">
<h4>{{ selectedUser.firstName }} {{ selectedUser.lastName }}</h4>
<p class="username">@{{ selectedUser.username }}</p>
<span class="status-badge" [class.status-active]="selectedUser.active" [class.status-inactive]="!selectedUser.active">
<i class="fa" [class.fa-check-circle]="selectedUser.active" [class.fa-times-circle]="!selectedUser.active"></i>
{{ selectedUser.active ? 'Active' : 'Inactive' }}
</span>
<div *ngIf="selectedUser.lastLoginDateDisplay" class="last-login">
<i class="fa fa-clock"></i>
Last login: {{ selectedUser.lastLoginDateDisplay | date:'medium' }}
</div>
</div>
</div>
<div class="user-detail-list">
<div class="detail-item">
<i class="fa fa-id-badge"></i>
<span class="detail-label">User ID:</span>
<span class="detail-value">{{ selectedUser.userId }}</span>
</div>
<div class="detail-item">
<i class="fa fa-envelope"></i>
<span class="detail-label">Email:</span>
<span class="detail-value">{{ selectedUser.email }}</span>
</div>
<div class="detail-item">
<i class="fas fa-shield-alt"></i>
<span class="detail-label">Role:</span>
<span class="detail-value">{{ selectedUser?.role?.substring(5) }}</span>
</div>
<div class="detail-item">
<i class="fa fa-calendar"></i>
<span class="detail-label">Joined:</span>
<span class="detail-value">{{ selectedUser.joinDate | date:'medium' }}</span>
</div>
<div class="detail-item">
<i class="fa" [class.fa-unlock]="selectedUser?.notLocked" [class.fa-lock]="!selectedUser?.notLocked"></i>
<span class="detail-label">Account:</span>
<span class="detail-value">{{ selectedUser?.notLocked ? 'Unlocked' : 'Locked' }}</span>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn-secondary" (click)="closeModal('view')">Close</button>
</div>
</div>
</div>
<!-- Add User Modal -->
<div *ngIf="showAddUserModal && isManager" class="modal-overlay" (click)="closeModal('add')">
<div class="modal-container" (click)="$event.stopPropagation()">
<div class="modal-header">
<h3>Add New User</h3>
<button class="modal-close" (click)="closeModal('add')">
<i class="fa fa-times"></i>
</button>
</div>
<div class="modal-body">
<form #newUserForm="ngForm" (ngSubmit)="onAddNewUser(newUserForm)">
<div class="form-row">
<div class="form-group">
<label for="firstName">
<i class="fa fa-user"></i>
First Name
</label>
<input type="text" name="firstName" required ngModel class="form-input" placeholder="Enter first name">
</div>
<div class="form-group">
<label for="lastName">
<i class="fa fa-user"></i>
Last Name
</label>
<input type="text" name="lastName" required ngModel class="form-input" placeholder="Enter last name">
</div>
</div>
<div class="form-group">
<label for="username">
<i class="fa fa-at"></i>
Username
</label>
<input type="text" name="username" required ngModel class="form-input" placeholder="Enter username">
</div>
<div class="form-group">
<label for="email">
<i class="fa fa-envelope"></i>
Email
</label>
<input type="email" name="email" required ngModel class="form-input" placeholder="user@example.com">
</div>
<div class="form-group">
<label for="role">
<i class="fa fa-shield-alt"></i>
Role
</label>
<select *ngIf="isAdmin" name="role" required ngModel="ROLE_USER" class="form-select">
<option value="ROLE_USER">USER</option>
<option value="ROLE_HR">HR</option>
<option value="ROLE_MANAGER">MANAGER</option>
<option value="ROLE_ADMIN">ADMIN</option>
<option value="ROLE_SUPER_ADMIN">SUPER ADMIN</option>
</select>
<input *ngIf="!isAdmin" type="text" name="role" required ngModel="ROLE_USER" readonly class="form-input">
</div>
<div class="form-group">
<label>
<i class="fa fa-image"></i>
Profile Picture
</label>
<div class="file-upload-wrapper">
<input type="file"
id="newUserProfileImage"
accept="image/*"
name="profileImage"
(change)="onProfileImageChange($any($event).target.files)"
class="file-input">
<label for="newUserProfileImage" class="file-label">
<i class="fa fa-cloud-upload-alt"></i>
<span>{{ profileImageFileName || 'Choose profile picture' }}</span>
</label>
</div>
</div>
<div class="form-section">
<div class="checkbox-wrapper">
<input type="checkbox" id="newUserActive" name="active" ngModel class="checkbox-input">
<label for="newUserActive" class="checkbox-label">
<span class="checkbox-custom"></span>
<span class="checkbox-text">
<i class="fa fa-check-circle"></i>
Active
</span>
</label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" id="newUserUnlocked" name="notLocked" ngModel class="checkbox-input">
<label for="newUserUnlocked" class="checkbox-label">
<span class="checkbox-custom"></span>
<span class="checkbox-text">
<i class="fa fa-unlock"></i>
Unlocked
</span>
</label>
</div>
</div>
<button type="submit" style="display: none;" id="new-user-save"></button>
</form>
<button *ngIf="isManager" type="button" class="btn btn-info" data-bs-toggle="modal"
data-bs-target="#addUserModal">
<i class="fa fa-plus"></i>New User
</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-info" (click)="getUsers(true)">
<i class="fas fa-sync" [ngClass]="{'fa-spin': refreshing }"></i>
<div class="modal-footer">
<button class="btn-secondary" (click)="closeModal('add')">Cancel</button>
<button class="btn-primary" (click)="saveNewUser()" [disabled]="newUserForm.invalid">
<i class="fa fa-save"></i>
Create User
</button>
</div>
</div>
<table class="table table-hover">
<thead class="table-borderless">
<tr class="text-center">
<th>Photo</th>
<th>User ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
<th>Email</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr class="text-center" *ngFor="let appUser of users">
<td (click)="onSelectUser(appUser)">
<img height="40" width="40" src="{{appUser?.profileImageUrl}}"
class="rounded-circle img-fluid img-thumbnail" alt=""/>
</td>
<td (click)="onSelectUser(appUser)">{{appUser?.userId}}</td>
<td (click)="onSelectUser(appUser)">{{appUser?.firstName}}</td>
<td (click)="onSelectUser(appUser)">{{appUser?.lastName}}</td>
<td (click)="onSelectUser(appUser)">{{appUser?.username}}</td>
<td (click)="onSelectUser(appUser)">{{appUser?.email}}</td>
<td (click)="onSelectUser(appUser)">
<span class="badge" [ngClass]="{ 'bg-success': appUser?.active, 'bg-danger': !appUser?.active }">
{{appUser?.active ? 'Active' : 'Inactive'}}
</span>
</td>
<td class="">
<div class="btn-group">
<button class="btn btn-outline-info" (click)="onEditUser(appUser)"><i class="fas fa-edit"></i></button>
<button *ngIf="isAdmin" class="btn btn-outline-danger" (click)="onDeleteUser(appUser)"><i
class="fas fa-trash"></i>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<button [hidden]="true" type="button" id="openUserInfo" data-bs-toggle="modal" data-bs-target="#viewUserModal">
</button>
<button [hidden]="true" type="button" id="openUserEdit" data-bs-toggle="modal" data-bs-target="#editUserModal">
</button>
<!-- change password -->
<div *ngIf="isAdmin" class="tab-pane fade" id="reset-password">
<form #resetPasswordForm="ngForm" (ngSubmit)="onResetPassword(resetPasswordForm)">
<fieldset>
<legend>User Password Management</legend>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" name="reset-password-email" required ngModel class="form-control"
placeholder="Enter email (example@email.com)">
<small class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<button type="submit" [disabled]="resetPasswordForm.invalid" class="btn btn-primary">
<i *ngIf="refreshing" class="fas fa-spinner fa-spin"></i>&nbsp;&nbsp;
<span>{{refreshing ? 'Loading...' : 'Reset Password'}}</span>
<!-- Edit User Modal -->
<div *ngIf="showEditUserModal" class="modal-overlay" (click)="closeModal('edit')">
<div class="modal-container" (click)="$event.stopPropagation()">
<div class="modal-header">
<h3>Edit User {{ editUser.firstName }} {{ editUser.lastName }}</h3>
<button class="modal-close" (click)="closeModal('edit')">
<i class="fa fa-times"></i>
</button>
</fieldset>
</form>
</div>
<!-- user profile -->
<div class="tab-pane fade" id="profile">
<div class="container">
<div class="row flex-lg-nowrap">
<div class="col">
<div class="row">
<div class="col mb-3">
<div class="card">
<div class="card-body">
<div class="e-profile">
<div class="row">
<div class="col-12 col-sm-auto">
<div class="mx-auto" style="width: 120px;">
<div class="d-flex justify-content-center align-items-center rounded">
<img class="rounded" height="135" width="135" src="{{loggedInUser?.profileImageUrl}}"
alt="">
</div>
<div *ngIf="fileUploadStatus?.status==='progress'" class="progress mt-1">
<div class="progress-bar bg-info" role="progressbar"
[style.width.%]="fileUploadStatus?.percentage" aria-valuenow="0" aria-valuemin="0"
aria-valuemax="100">{{fileUploadStatus?.percentage}}%
</div>
</div>
</div>
</div>
<div class="col d-flex flex-column flex-sm-row justify-content-between mb-3">
<div class="text-center text-sm-left mb-2 mb-sm-0">
<h4
class="pt-sm-2 pb-1 mb-0 text-nowrap">{{loggedInUser?.firstName}} {{loggedInUser?.lastName}}</h4>
<p class="mb-0">{{loggedInUser?.username}}</p>
<div *ngIf="loggedInUser?.lastLoginDateDisplay !== null" class="text-muted"><small>Last
login:
{{loggedInUser?.lastLoginDateDisplay | date:'medium'}}</small></div>
<div class="mt-2">
<button (click)="updateProfileImage()" class="btn btn-primary" type="button">
<i class="fa fa-fw fa-camera"></i>
<span>Change Photo</span>
</button>
</div>
</div>
<div class="text-center text-sm-right">
<div class="text-muted"><small>Joined {{loggedInUser?.joinDate | date:'mediumDate'}}</small>
</div>
</div>
</div>
</div>
<div class="tab-content pt-3">
<div class="tab-pane active">
<form #profileUserForm="ngForm" (ngSubmit)="onUpdateCurrentUser(profileUserForm.value)"
class="form" novalidate>
<div class="row">
<div class="col">
<div class="row">
<div class="col">
<div class="form-group">
<label>First Name</label>
<input type="text" name="firstName" required [(ngModel)]="loggedInUser.firstName"
class="form-control">
</div>
</div>
<div class="col">
<div class="form-group">
<label>Last Name</label>
<input type="text" name="lastName" required [(ngModel)]="loggedInUser.lastName"
class="form-control">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group">
<label>Username</label>
<input type="text" name="username" required [(ngModel)]="loggedInUser.username"
class="form-control">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group">
<label>Email</label>
<input type="text" name="email" required [(ngModel)]="loggedInUser.email"
class="form-control">
</div>
</div>
</div>
<div class="row">
<div class="col mb-3">
<div class="form-group">
<label>Role</label><small [hidden]="isAdmin">(read only)</small>
<select [disabled]="!isAdmin" name="role" required [(ngModel)]="loggedInUser.role"
class="form-control">
<option value="ROLE_USER">USER</option>
<option value="ROLE_HR">HR</option>
<option value="ROLE_MANAGER">MANAGER</option>
<option value="ROLE_ADMIN">ADMIN</option>
<option value="ROLE_SUPER_ADMIN">SUPER ADMIN</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-sm-5 offset-sm-1 mb-3">
<div class="mb-2"><b>Account Settings</b></div>
<div class="row">
<div class="col">
<div class="custom-controls-stacked px-2">
<div class="custom-control custom-checkbox">
<input [disabled]="!isAdmin" name="active" type="checkbox"
[(ngModel)]="loggedInUser.active"
class="custom-control-input">
<label class="custom-control-label">Active</label>
</div>
<div class="custom-control custom-checkbox">
<input [disabled]="!isAdmin" name="notLocked" type="checkbox"
[(ngModel)]="loggedInUser.notLocked" class="custom-control-input">
<label class="custom-control-label">Unlocked</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col d-flex justify-content-end">
<button class="btn btn-primary" type="submit">
<i *ngIf="refreshing" class="fas fa-spinner fa-spin"></i>&nbsp;&nbsp;
<span>{{refreshing ? 'Loading...' : 'Save Changes'}}</span>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-body">
<form #editUserForm="ngForm">
<div class="form-row">
<div class="form-group">
<label for="editFirstName">
<i class="fa fa-user"></i>
First Name
</label>
<input type="text"
name="firstName"
required
[(ngModel)]="editUser.firstName"
class="form-input"
[disabled]="!isManager">
</div>
<div class="col-12 col-md-3 mb-3">
<div class="card mb-3">
<div class="card-body">
<div class="px-xl-3">
<button (click)="onLogOut()" class="btn btn-block btn-secondary">
<span>Logout</span>
<i class="fas fa-sign-in-alt ml-1"></i>
</button>
</div>
</div>
</div>
<div class="card">
<div class="card-body">
<h6 class="card-title font-weight-bold">Permissions From Role</h6>
<h6 *ngFor="let authority of loggedInUser?.authorities" class="card-text">{{authority}}</h6>
</div>
</div>
<div class="form-group">
<label for="editLastName">
<i class="fa fa-user"></i>
Last Name
</label>
<input type="text"
name="lastName"
required
[(ngModel)]="editUser.lastName"
class="form-input"
[disabled]="!isManager">
</div>
</div>
</div>
</div>
</div>
</div>
<!-- modal user info -->
<div *ngIf="selectedUser" class="modal fade bd-example-modal-lg" id="viewUserModal" tabindex="-1" role="dialog"
aria-labelledby=""
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title text-center"
id="exampleModalLongTitle">{{selectedUser.firstName}} {{selectedUser.lastName}}</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div>
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-12 col-sm-auto">
<div class="mx-auto" style="width: 120px;">
<div class="d-flex justify-content-center align-items-center rounded">
<img class="rounded" height="120" width="120" src="{{selectedUser.profileImageUrl}}"
alt="{{selectedUser.username}}">
</div>
</div>
</div>
<div class="col d-flex flex-column flex-sm-row justify-content-between">
<div class="text-center text-sm-left mb-sm-0">
<h6
class="pt-sm-2 pb-1 mb-0 text-nowrap">{{selectedUser.firstName}} {{selectedUser.lastName}}</h6>
<p class="mb-1">{{selectedUser.username}}</p>
<div class="">Status:
<span class="badge"
[ngClass]="{'bg-success':selectedUser.active,'bg-danger':!selectedUser.active}">
{{selectedUser.active ? 'Active' : 'Inactive'}}
</span>
</div>
<div *ngIf="selectedUser.lastLoginDateDisplay" class="text-muted">
<small>Last Login: {{selectedUser.lastLoginDateDisplay | date: 'medium' }}</small>
</div>
</div>
<div class="text-center text-sm-right">
<div class="text-muted"><small>Joined {{selectedUser.joinDate | date: 'medium' }}</small>
</div>
</div>
</div>
</div>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item"></li>
<li class="list-group-item"><i class="fa fa-id-badge float-end"></i>{{selectedUser.userId}}
</li>
<li class="list-group-item"><i class="fa fa-envelope float-end"></i>{{selectedUser.email}}
</li>
<li class="list-group-item"><i class="fas fa-shield-alt float-end"></i>
{{selectedUser?.role?.substring(5)}}
<li *ngIf="selectedUser.lastLoginDateDisplay" class="list-group-item">
<i class="fas fa-sign-in-alt float-end"></i>
{{ selectedUser.lastLoginDateDisplay | date: 'medium' }}
</li>
<li class="list-group-item">
<span>
<i class="fa float-end"
[ngClass]="{'fa-unlock':selectedUser?.notLocked, 'fa-lock':!selectedUser?.notLocked}"
[ngStyle]="{color: selectedUser?.notLocked ? 'green' : 'red'}"></i>
Account {{selectedUser?.notLocked ? 'Unlocked' : 'Locked'}}
</span>
</li>
</ul>
<div class="form-group">
<label for="editUsername">
<i class="fa fa-at"></i>
Username
</label>
<input type="text"
name="username"
required
[(ngModel)]="editUser.username"
class="form-input"
[disabled]="!isManager">
</div>
<div class="form-group">
<label for="editEmail">
<i class="fa fa-envelope"></i>
Email
</label>
<input type="email"
name="email"
required
[(ngModel)]="editUser.email"
class="form-input"
[disabled]="!isManager">
</div>
<div class="form-group">
<label for="editRole">
<i class="fa fa-shield-alt"></i>
Role <small *ngIf="!isAdmin">(read only)</small>
</label>
<select name="role"
required
[(ngModel)]="editUser.role"
class="form-select"
[disabled]="!isAdmin">
<option value="ROLE_USER">USER</option>
<option value="ROLE_HR">HR</option>
<option value="ROLE_MANAGER">MANAGER</option>
<option value="ROLE_ADMIN">ADMIN</option>
<option value="ROLE_SUPER_ADMIN">SUPER ADMIN</option>
</select>
</div>
<div class="form-group">
<label>
<i class="fa fa-image"></i>
Profile Picture
</label>
<div class="file-upload-wrapper">
<input type="file"
id="editUserProfileImage"
accept="image/*"
name="profileImage"
(change)="onProfileImageChange($any($event).target.files)"
class="file-input"
[disabled]="!isManager">
<label for="editUserProfileImage" class="file-label">
<i class="fa fa-cloud-upload-alt"></i>
<span>{{ profileImageFileName || 'Choose profile picture' }}</span>
</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- modal add user -->
<div *ngIf="isManager" class="modal draggable fade bd-example-modal-lg" id="addUserModal" tabindex="-1"
role="dialog"
aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title text-center">New User</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div>
<form #newUserForm="ngForm" (ngSubmit)="onAddNewUser(newUserForm)">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" name="firstName" required ngModel class="form-control">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" name="lastName" required ngModel class="form-control">
</div>
<div class="form-group">
<label for="username">Username</label>
<input type="text" name="username" required ngModel class="form-control">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" required ngModel class="form-control">
</div>
<div *ngIf="isAdmin" class="form-group">
<label for="authority">Role</label>
<select name="role" required ngModel="ROLE_USER" class="form-control">
<option value="ROLE_USER">USER</option>
<option value="ROLE_HR">HR</option>
<option value="ROLE_MANAGER">MANAGER</option>
<option value="ROLE_ADMIN">ADMIN</option>
<option value="ROLE_SUPER_ADMIN">SUPER ADMIN</option>
</select>
</div>
<div *ngIf="!isAdmin" class="form-group">
<label for="authority">Role</label>
<input type="text" name="role" required ngModel="USER" readonly class="form-control">
</div>
<div class="input-group mb-2">
<div class="input-group-prepend">
<span class="input-group-text">Profile Picture </span>
</div>
<div class="custom-file">
<input type="file" accept="image/*" name="profileImage"
(change)="onProfileImageChange($any($event).target.files)"
class="custom-file-input">
<label class="custom-file-label">
<span>{{profileImageFileName ? profileImageFileName : 'Choose File'}}</span>
</label>
</div>
</div>
<fieldset class="form-group">
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" name="active" ngModel class="form-check-input">
Active
</label>
</div>
<div class="form-check disabled">
<label class="form-check-label">
<input type="checkbox" name="notLocked" ngModel class="form-check-input">
Unlocked
</label>
</div>
</fieldset>
<button type="submit" style="display: none;" id="new-user-save"></button>
</form>
<div class="form-section">
<div class="checkbox-wrapper">
<input type="checkbox"
id="editUserActive"
name="active"
[(ngModel)]="editUser.active"
class="checkbox-input"
[disabled]="!isManager">
<label for="editUserActive" class="checkbox-label">
<span class="checkbox-custom"></span>
<span class="checkbox-text">
<i class="fa fa-check-circle"></i>
Active <small *ngIf="!isManager">(read only)</small>
</span>
</label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox"
id="editUserUnlocked"
name="notLocked"
[(ngModel)]="editUser.notLocked"
class="checkbox-input"
[disabled]="!isManager">
<label for="editUserUnlocked" class="checkbox-label">
<span class="checkbox-custom"></span>
<span class="checkbox-text">
<i class="fa fa-unlock"></i>
Unlocked <small *ngIf="!isManager">(read only)</small>
</span>
</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="new-user-close">Close</button>
<button type="button" class="btn btn-primary" (click)="saveNewUser()" [disabled]="newUserForm.invalid">Save
changes
</button>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn-secondary" (click)="closeModal('edit')">Cancel</button>
<button *ngIf="isManager"
class="btn-primary"
(click)="onUpdateUser()"
[disabled]="editUserForm.invalid">
<i class="fa fa-save"></i>
Save Changes
</button>
</div>
</div>
</div>
<!-- modal edit user -->
<div class="modal draggable fade bd-example-modal-lg" id="editUserModal" tabindex="-1" role="dialog"
aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title text-center">Edit {{editUser.firstName}} {{editUser.lastName}}
<small [hidden]="isManager"> (read only)</small>
</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div>
<form #editUserForm="ngForm">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" name="firstName" required [(ngModel)]="editUser.firstName" class="form-control"
[disabled]="!isManager">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" name="lastName" required [(ngModel)]="editUser.lastName" class="form-control"
[disabled]="!isManager">
</div>
<div class="form-group">
<label for="username">Username</label>
<input type="text" name="username" required [(ngModel)]="editUser.username" class="form-control"
[disabled]="!isManager">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" required [(ngModel)]="editUser.email" class="form-control"
[disabled]="!isManager">
</div>
<div class="form-group">
<label for="authority">Role<small [hidden]="isAdmin"> (read only)</small></label>
<select name="role" required [(ngModel)]="editUser.role" class="form-control"
[disabled]="!isAdmin">
<option value="ROLE_USER">USER</option>
<option value="ROLE_HR">HR</option>
<option value="ROLE_MANAGER">MANAGER</option>
<option value="ROLE_ADMIN">ADMIN</option>
<option value="ROLE_SUPER_ADMIN">SUPER ADMIN</option>
</select>
</div>
<div class="input-group mb-2">
<div class="input-group-prepend">
<span class="input-group-text">Profile Picture </span>
</div>
<div class="custom-file">
<input type="file" accept="image/*" name="profileImage"
(change)="onProfileImageChange($any($event).target.files)"
class="custom-file-input" [disabled]="!isManager">
<label class="custom-file-label">
<span>{{profileImageFileName ? profileImageFileName : 'Choose File'}}</span>
</label>
</div>
</div>
<fieldset class="form-group">
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" name="active" [(ngModel)]="editUser.active" class="form-check-input"
[disabled]="!isManager">
Active<small [hidden]="isManager"> (read only)</small>
</label>
</div>
<div class="form-check disabled">
<label class="form-check-label">
<input type="checkbox" name="notLocked" [(ngModel)]="editUser.notLocked" class="form-check-input"
[disabled]="!isManager">
Unlocked<small [hidden]="isManager"> (read only)</small>
</label>
</div>
</fieldset>
</form>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="closeEditUserButton">Close
</button>
<button *ngIf="isManager" type="button" class="btn btn-primary" (click)="onUpdateUser()"
[disabled]="editUserForm.invalid">
Save changes
</button>
</div>
</div>
</div>
</div>
<!-- profile image change form -->
<!-- Profile Image Change Form (Hidden) -->
<form enctype="multipart/form-data" style="display:none;">
<input type="file"
(change)="onProfileImageChange($any($event).target.files); onUpdateProfileImage()"
name="profile-image-input" id="profile-image-input" placeholder="file" accept="image/*"/>
name="profile-image-input"
id="profile-image-input"
accept="image/*"/>
</form>
</div>
</div>
</div>