diff --git a/.gitignore b/.gitignore index cc7b141..717df67 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,6 @@ testem.log # System files .DS_Store Thumbs.db + +# Folder config +/api-config/api-url.ts diff --git a/angular.json b/angular.json index 301c8df..dc3b2e2 100644 --- a/angular.json +++ b/angular.json @@ -54,7 +54,13 @@ "maximumError": "4kB" } ], - "outputHashing": "all" + "outputHashing": "all", + "fileReplacements": [ + { + "replace": "api-config/api-url.ts", + "with": "api-config/api-url.prod.ts" + } + ] }, "development": { "optimization": false, diff --git a/api-config/api-url.prod.ts b/api-config/api-url.prod.ts new file mode 100644 index 0000000..6c48c51 --- /dev/null +++ b/api-config/api-url.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + apiUrl: 'https://localhost:44322', +}; diff --git a/src/app/graph/data-analysis/data-analysis.component.ts b/src/app/graph/data-analysis/data-analysis.component.ts index 9a6a8e3..ad7c465 100644 --- a/src/app/graph/data-analysis/data-analysis.component.ts +++ b/src/app/graph/data-analysis/data-analysis.component.ts @@ -30,10 +30,10 @@ export class DataAnalysisComponent implements AfterViewInit { const container = this.el.nativeElement; // create some nodes const nodes = new DataSet([ - { id: 0, label: 'محمد رضا یاقوتی \n\n 16546220216446' }, - { id: 1, label: 'محمد رضا یاقوتی \n\n 16546220216446' }, - { id: 2, label: 'محمد رضا یاقوتی \n\n 16546220216446' }, - { id: 50, label: 'محمد رضا یاقوتی \n\n 16546220216446' }, + { id: 0, label: '16546220216446' }, + { id: 1, label: '16546220216446' }, + { id: 2, label: '16546220216446' }, + { id: 50, label: '16546220216446' }, ] as unknown as Node[]); // create some edges @@ -71,7 +71,7 @@ export class DataAnalysisComponent implements AfterViewInit { const options: Options = { physics: false, edges: { - width: 2, + width: 1, smooth: { enabled: false, type: 'vertical', roundness: 0 }, arrows: 'to', arrowStrikethrough: false, @@ -85,7 +85,7 @@ export class DataAnalysisComponent implements AfterViewInit { nodes: { shape: 'image', image: svgDataUrl, - size: 15, + size: 10, color: { background: labelColor, border: labelBorder, diff --git a/src/app/shared/components/dashboard-header/dashboard-header.component.html b/src/app/shared/components/dashboard-header/dashboard-header.component.html index 5addaee..5929b87 100644 --- a/src/app/shared/components/dashboard-header/dashboard-header.component.html +++ b/src/app/shared/components/dashboard-header/dashboard-header.component.html @@ -1,15 +1,21 @@

{{ title }}

- settings routine - info + info
diff --git a/src/app/shared/components/dashboard-header/dashboard-header.component.ts b/src/app/shared/components/dashboard-header/dashboard-header.component.ts index aaa2775..a963728 100644 --- a/src/app/shared/components/dashboard-header/dashboard-header.component.ts +++ b/src/app/shared/components/dashboard-header/dashboard-header.component.ts @@ -27,6 +27,9 @@ export class DashboardHeaderComponent { } infoClick() { - this._snackBar.open('Coming soon...', 'Ok :('); + this._snackBar.open('Coming soon...', 'Ok :(', { + duration: 2000, + panelClass: ['info-notification'], + }); } } diff --git a/src/app/user/components/dashboard/add-user/add-user.component.html b/src/app/user/components/dashboard/manage-users/add-user/add-user.component.html similarity index 91% rename from src/app/user/components/dashboard/add-user/add-user.component.html rename to src/app/user/components/dashboard/manage-users/add-user/add-user.component.html index ac971b0..612a180 100644 --- a/src/app/user/components/dashboard/add-user/add-user.component.html +++ b/src/app/user/components/dashboard/manage-users/add-user/add-user.component.html @@ -77,8 +77,12 @@

Add User

formControlName="roleName" > Admin - Option 2 - Option 3 + Data Manager + System Manager
+
+ + diff --git a/src/app/user/components/dashboard/add-user/add-user.component.scss b/src/app/user/components/dashboard/manage-users/edit-user/edit-user.component.scss similarity index 100% rename from src/app/user/components/dashboard/add-user/add-user.component.scss rename to src/app/user/components/dashboard/manage-users/edit-user/edit-user.component.scss diff --git a/src/app/user/components/dashboard/manage-users/edit-user/edit-user.component.spec.ts b/src/app/user/components/dashboard/manage-users/edit-user/edit-user.component.spec.ts new file mode 100644 index 0000000..643be33 --- /dev/null +++ b/src/app/user/components/dashboard/manage-users/edit-user/edit-user.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditUserComponent } from './edit-user.component'; + +describe('EditUserComponent', () => { + let component: EditUserComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [EditUserComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(EditUserComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/user/components/dashboard/manage-users/edit-user/edit-user.component.ts b/src/app/user/components/dashboard/manage-users/edit-user/edit-user.component.ts new file mode 100644 index 0000000..9f2c9a8 --- /dev/null +++ b/src/app/user/components/dashboard/manage-users/edit-user/edit-user.component.ts @@ -0,0 +1,61 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { AdminService } from '../../../../services/admin/admin.service'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { UserData } from '../../../../interfaces/manage-users.interface'; + +@Component({ + selector: 'app-edit-user', + templateUrl: './edit-user.component.html', + styleUrl: './edit-user.component.scss', +}) +export class EditUserComponent implements OnInit { + constructor( + private adminService: AdminService, + @Inject(MAT_DIALOG_DATA) + protected pageData: { + user: UserData; + pagSize: number; + pageIndex: number; + }, + ) {} + + myForm: FormGroup = new FormGroup({}); + + ngOnInit() { + this.myForm = new FormGroup({ + firstName: new FormControl( + this.pageData.user.firstName, + Validators.required, + ), + lastName: new FormControl( + this.pageData.user.lastName, + Validators.required, + ), + username: new FormControl( + this.pageData.user.username, + Validators.required, + ), + email: new FormControl(this.pageData.user.email, [ + Validators.required, + Validators.email, + ]), + phoneNumber: new FormControl(this.pageData.user.phoneNumber, [ + Validators.required, + Validators.pattern('^[0-9]*$'), + ]), + roleName: new FormControl(this.pageData.user.roleName), + }); + } + + onSubmit() { + if (this.myForm.valid) { + this.adminService.updateUser( + this.pageData.user.guid, + this.myForm.value, + this.pageData.pagSize, + this.pageData.pageIndex, + ); + } + } +} diff --git a/src/app/user/components/dashboard/manage-users/manage-users.component.html b/src/app/user/components/dashboard/manage-users/manage-users.component.html index 4b3fac4..828a325 100644 --- a/src/app/user/components/dashboard/manage-users/manage-users.component.html +++ b/src/app/user/components/dashboard/manage-users/manage-users.component.html @@ -27,10 +27,15 @@ {{ element.email }} + + Role + {{ element.roleName }} + + edit/delete - @@ -25,11 +26,20 @@ import { AdminService } from '../../../../services/admin/admin.service'; }) export class UserDeleteConfirmationComponent { constructor( - @Inject(MAT_DIALOG_DATA) protected userData: UserData, - private adminService: AdminService + @Inject(MAT_DIALOG_DATA) + protected pageData: { + user: UserData; + pagSize: number; + pageIndex: number; + }, + private adminService: AdminService, ) {} deleteUser() { - this.adminService.deleteUser(this.userData.guid); + this.adminService.deleteUser( + this.pageData.user.guid, + this.pageData.pagSize, + this.pageData.pageIndex, + ); } } diff --git a/src/app/user/components/dashboard/manage-users/user-manage-notification/user-manage-notification.component.spec.ts b/src/app/user/components/dashboard/manage-users/user-manage-notification/user-manage-notification.component.spec.ts new file mode 100644 index 0000000..539a58d --- /dev/null +++ b/src/app/user/components/dashboard/manage-users/user-manage-notification/user-manage-notification.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { UserManageNotificationComponent } from './user-manage-notification.component'; + +describe('UserManageNotificationComponent', () => { + let component: UserManageNotificationComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [UserManageNotificationComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(UserManageNotificationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/user/components/dashboard/manage-users/user-manage-notification/user-manage-notification.component.ts b/src/app/user/components/dashboard/manage-users/user-manage-notification/user-manage-notification.component.ts new file mode 100644 index 0000000..5b48244 --- /dev/null +++ b/src/app/user/components/dashboard/manage-users/user-manage-notification/user-manage-notification.component.ts @@ -0,0 +1,17 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_SNACK_BAR_DATA } from '@angular/material/snack-bar'; + +@Component({ + selector: 'app-user-manage-notification', + template: ` {{ this.userData }} `, + + styles: `:host{display:flex;color:white}`, +}) +export class UserManageNotificationComponent { + constructor( + @Inject(MAT_SNACK_BAR_DATA) + protected userData: string + ) { + console.log(userData); + } +} diff --git a/src/app/user/services/admin/admin.service.ts b/src/app/user/services/admin/admin.service.ts index 579ee0f..6bcb04e 100644 --- a/src/app/user/services/admin/admin.service.ts +++ b/src/app/user/services/admin/admin.service.ts @@ -1,30 +1,46 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { RegisterRequest, UpdateUserRequest } from '../../models/User'; -import { - GetUserResponse, - UserData, -} from '../../interfaces/manage-users.interface'; +import { GetUserResponse } from '../../interfaces/manage-users.interface'; import { Subject } from 'rxjs'; +import { environment } from '../../../../../api-config/api-url'; @Injectable({ providedIn: 'root', }) export class AdminService { - private readonly apiUrl = 'http://localhost:8085/api/Admin'; + private readonly apiUrl = environment.apiUrl + '/api/Admin'; private usersData = new Subject(); + private notification = new Subject<{ status: boolean; message: string }>(); usersData$ = this.usersData.asObservable(); + notification$ = this.notification.asObservable(); constructor(private http: HttpClient) {} - createUser(request: RegisterRequest) { - return this.http.post(`${this.apiUrl}/register`, request, { - withCredentials: true, - }); + createUser(request: RegisterRequest, pageSize: number, pageIndex: number) { + return this.http + .post(`${this.apiUrl}/register`, request, { + withCredentials: true, + }) + .subscribe({ + next: () => { + this.getUsers(pageSize, pageIndex); + this.notification.next({ + status: true, + message: 'User added successfully!', + }); + }, + error: (error) => { + this.notification.next({ + status: false, + message: error, + }); + }, + }); } - getUsers(limit = 10, page = 1) { + getUsers(limit = 10, page = 0) { this.http .get( `${this.apiUrl}/GetUsersPagination?limit=${limit}&page=${page}`, @@ -37,22 +53,52 @@ export class AdminService { }); } - deleteUser(id: string) { + deleteUser(id: string, pageSize: number, pageIndex: number) { this.http .delete(`${this.apiUrl}/DeleteUser?id=${id}`, { withCredentials: true, }) - .subscribe(() => { - this.getUsers(); + .subscribe({ + next: () => { + this.getUsers(pageSize, pageIndex); + this.notification.next({ + status: true, + message: 'User deleted successfully!', + }); + }, + error: (error) => { + this.notification.next({ + status: false, + message: error, + }); + }, }); } - updateUser(id: string, request: UpdateUserRequest) { - return this.http.put(`${this.apiUrl}/UpdateUser?id=${id}`, request); - } - - getUserById(id: string) { - console.log(id); - return {} as UserData; + updateUser( + id: string, + request: UpdateUserRequest, + pageSize: number, + pageIndex: number, + ) { + return this.http + .put(`${this.apiUrl}/UpdateUser?id=${id}`, request, { + withCredentials: true, + }) + .subscribe({ + next: () => { + this.getUsers(pageSize, pageIndex); + this.notification.next({ + status: true, + message: 'User updated successfully!', + }); + }, + error: (error) => { + this.notification.next({ + status: false, + message: error, + }); + }, + }); } } diff --git a/src/app/user/services/auth/auth.service.ts b/src/app/user/services/auth/auth.service.ts index 7852732..7b9420f 100644 --- a/src/app/user/services/auth/auth.service.ts +++ b/src/app/user/services/auth/auth.service.ts @@ -6,12 +6,13 @@ import { LoginResponse, UserPermissions, } from '../../models/User'; +import { environment } from '../../../../../api-config/api-url'; @Injectable({ providedIn: 'root', }) export class AuthService { - private apiUrl = 'http://localhost:8085/api/User'; + private apiUrl = environment.apiUrl + '/api/User'; private userData = new Subject(); private isLoggedIn = new BehaviorSubject(false); diff --git a/src/app/user/services/user/user.service.ts b/src/app/user/services/user/user.service.ts index f1a192d..dad8b12 100644 --- a/src/app/user/services/user/user.service.ts +++ b/src/app/user/services/user/user.service.ts @@ -2,12 +2,13 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { ForgetPasswordRequest, NewPasswordRequest } from '../../models/User'; +import { environment } from '../../../../../api-config/api-url'; @Injectable({ providedIn: 'root', }) export class UserService { - private apiUrl = 'http://localhost:8085/api/User'; + private apiUrl = environment.apiUrl + '/api/User'; constructor(private http: HttpClient) {} diff --git a/src/app/user/user.module.ts b/src/app/user/user.module.ts index 2b8f03f..9bce372 100644 --- a/src/app/user/user.module.ts +++ b/src/app/user/user.module.ts @@ -15,7 +15,7 @@ import { MatRippleModule } from '@angular/material/core'; import { AppRoutingModule } from '../app-routing.module'; import { MainPageComponent } from './components/dashboard/main-page/main-page.component'; import { SharedModule } from '../shared/shared.module'; -import { AddUserComponent } from './components/dashboard/add-user/add-user.component'; +import { AddUserComponent } from './components/dashboard/manage-users/add-user/add-user.component'; import { MatRadioModule } from '@angular/material/radio'; import { ManageAccountComponent } from './components/dashboard/manage-account/manage-account.component'; import { ManageUsersComponent } from './components/dashboard/manage-users/manage-users.component'; @@ -28,6 +28,9 @@ import { MatDialogContent, MatDialogTitle, } from '@angular/material/dialog'; +import { EditUserComponent } from './components/dashboard/manage-users/edit-user/edit-user.component'; +import { UserManageNotificationComponent } from './components/dashboard/manage-users/user-manage-notification/user-manage-notification.component'; +import { MatSnackBarLabel } from '@angular/material/snack-bar'; @NgModule({ declarations: [ @@ -38,6 +41,8 @@ import { ManageAccountComponent, ManageUsersComponent, UserDeleteConfirmationComponent, + EditUserComponent, + UserManageNotificationComponent, ], imports: [ CommonModule, @@ -61,6 +66,7 @@ import { MatDialogActions, MatDialogClose, MatDialogTitle, + MatSnackBarLabel, ], }) export class UserModule {} diff --git a/src/styles.scss b/src/styles.scss index 5805916..38010ed 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -4,7 +4,8 @@ @include mat.core(); @font-face { font-family: "MyCustomFont"; - src: url("../assets/font/Vazir.ttf") format("truetype"), + src: + url("../assets/font/Vazir.ttf") format("truetype"), url("../assets/font/Vazir.woff") format("woff"), url("../assets/font/Vazir.woff2") format("woff2"), url("../assets/font/Vazir.eot") format("embedded-opentype"); @@ -295,6 +296,7 @@ body, --nav-link-text-color-active: rgba(27, 89, 248, 1); --card-background-color: #fefbff; --mat-sidenav-content-background-color: #fbf8fd; + --hover-bg-color: #e0e0e0; --logo-image-filter: invert(20%); --logo-filter: invert(10%); @@ -311,6 +313,7 @@ body, --mat-sidenav-container-background-color: #1f1f23; --mat-table-background-color: #292a2d; --mat-paginator-container-background-color: #292a2d; + --hover-bg-color: #333333; --logo-image-filter: invert(75%); --logo-filter: invert(85%); @@ -328,3 +331,22 @@ body, .mat-mdc-paginator-container { justify-content: center !important; } + +.notification-class-danger { + background-color: #f44336; + border-radius: 0.25rem; +} + +.notification-class-success { + background-color: #388e3c; + border-radius: 0.25rem; +} + +.info-notification { + background-color: var(--mdc-snackbar-container-color); + border-radius: 0.25rem; +} + +.mat-mdc-snack-bar-container .mat-mdc-snackbar-surface { + background-color: inherit !important; +}