This commit is contained in:
styve Lioumba
2025-11-20 14:37:41 +01:00
parent dd77e3d023
commit 06979b79e3
21 changed files with 205 additions and 152 deletions

View File

@@ -16,11 +16,11 @@ describe('MyProfileUpdateProjectFormComponent', () => {
let component: MyProfileUpdateProjectFormComponent;
let fixture: ComponentFixture<MyProfileUpdateProjectFormComponent>;
let mockToastrService: Partial<ToastrService>;
let mockProjectRepository: jest.Mocked<ProjectRepository>;
let mockToastrService: jest.Mocked<Partial<ToastrService>>;
let mockProjectRepository: jest.Mocked<Partial<ProjectRepository>>;
let mockAuthRepository: jest.Mocked<AuthRepository>;
let mockProfileRepo: jest.Mocked<ProfileRepository>;
let mockAuthRepository: jest.Mocked<Partial<AuthRepository>>;
let mockProfileRepo: jest.Mocked<Partial<ProfileRepository>>;
beforeEach(async () => {
mockToastrService = {
@@ -38,7 +38,6 @@ describe('MyProfileUpdateProjectFormComponent', () => {
mockAuthRepository = {
get: jest.fn(),
login: jest.fn(),
update: jest.fn(),
sendVerificationEmail: jest.fn(),
logout: jest.fn(),
isAuthenticated: jest.fn(),

View File

@@ -14,10 +14,10 @@ import { ProfileRepository } from '@app/domain/profiles/profile.repository';
describe('NavBarComponent', () => {
let component: NavBarComponent;
let fixture: ComponentFixture<NavBarComponent>;
let mockThemeService: Partial<ThemeService>;
let mockThemeService: jest.Mocked<Partial<ThemeService>>;
let mockAuthRepository: jest.Mocked<AuthRepository>;
let mockProfileRepo: jest.Mocked<ProfileRepository>;
let mockAuthRepository: jest.Mocked<Partial<AuthRepository>>;
let mockProfileRepo: jest.Mocked<Partial<ProfileRepository>>;
const user: User = {
id: 'adbc123',
@@ -41,7 +41,6 @@ describe('NavBarComponent', () => {
mockAuthRepository = {
get: jest.fn(),
login: jest.fn(),
update: jest.fn(),
sendVerificationEmail: jest.fn(),
logout: jest.fn(),
isAuthenticated: jest.fn(),

View File

@@ -1,12 +1,11 @@
import { Component, inject, Input } from '@angular/core';
import { JsonPipe } from '@angular/common';
import { ThemeService } from '@app/core/services/theme/theme.service';
import { UntilDestroy } from '@ngneat/until-destroy';
@Component({
selector: 'app-reseaux',
standalone: true,
imports: [JsonPipe],
imports: [],
templateUrl: './reseaux.component.html',
styleUrl: './reseaux.component.scss',
})

View File

@@ -5,7 +5,7 @@
}
<ng-template #content>
@if (user) {
@if (user != undefined) {
<div
class="w-40 h-40 rounded-full inline-flex items-center justify-center bg-gray-200 text-gray-400"
>

View File

@@ -1,4 +1,4 @@
import { Component, effect, inject, Input, output, signal } from '@angular/core';
import { Component, effect, inject, Input, signal } from '@angular/core';
import { User } from '@app/domain/users/user.model';
import { ReactiveFormsModule } from '@angular/forms';
import { environment } from '@env/environment';
@@ -7,21 +7,24 @@ import { ToastrService } from 'ngx-toastr';
import { UserFacade } from '@app/ui/users/user.facade';
import { ActionType } from '@app/domain/action-type.util';
import { LoadingComponent } from '@app/shared/components/loading/loading.component';
import { UntilDestroy } from '@ngneat/until-destroy';
import { UserViewModel } from '@app/ui/users/user.presenter.model';
@Component({
selector: 'app-user-avatar-form',
standalone: true,
providers: [UserFacade],
imports: [ReactiveFormsModule, NgClass, NgTemplateOutlet, LoadingComponent],
templateUrl: './user-avatar-form.component.html',
styleUrl: './user-avatar-form.component.scss',
})
@UntilDestroy()
export class UserAvatarFormComponent {
private readonly toastrService = inject(ToastrService);
protected readonly environment = environment;
private readonly facade = inject(UserFacade);
@Input({ required: true }) user: User | undefined = undefined;
onFormSubmitted = output<any>();
@Input({ required: true }) user: UserViewModel | undefined = undefined;
file: File | null = null; // Variable to store file
imagePreviewUrl: string | null = null; // URL for image preview
@@ -34,13 +37,13 @@ export class UserAvatarFormComponent {
let message = '';
effect(() => {
if (!this.loading().isLoading && this.onSubmitted()) {
if (!this.loading().isLoading) {
switch (this.loading().action) {
case ActionType.UPDATE:
message = `Votre photo de profile a bien été modifier !`;
this.customToast(ActionType.UPDATE, message);
this.onSubmitted.set(false);
this.onFormSubmitted.emit('');
if (this.onSubmitted()) {
this.customToast(ActionType.UPDATE, message);
}
break;
}
}
@@ -52,7 +55,7 @@ export class UserAvatarFormComponent {
const formData = new FormData();
formData.append('avatar', this.file); // "avatar" est le nom du champ dans PocketBase
this.facade.update(this.user?.id!, formData as Partial<User>);
this.facade.update(this.user!.id, formData as Partial<User>);
this.onSubmitted.set(true);
}
}

View File

@@ -1,4 +1,4 @@
import { Component, effect, inject, Input, OnInit, output, signal } from '@angular/core';
import { Component, effect, inject, Input, OnInit, signal } from '@angular/core';
import {
FormBuilder,
FormControl,
@@ -18,6 +18,7 @@ import { NgTemplateOutlet } from '@angular/common';
selector: 'app-user-form',
standalone: true,
imports: [ReactiveFormsModule, LoadingComponent, NgTemplateOutlet],
providers: [UserFacade],
templateUrl: './user-form.component.html',
styleUrl: './user-form.component.scss',
})
@@ -27,12 +28,12 @@ export class UserFormComponent implements OnInit {
private readonly facade = inject(UserFacade);
protected readonly ActionType = ActionType;
@Input({ required: true }) user: User | undefined = undefined;
onFormSubmitted = output<any>();
@Input({ required: true }) userId: string | undefined = undefined;
private fb = inject(FormBuilder);
protected userForm!: FormGroup;
protected readonly user = this.facade.user;
protected readonly loading = this.facade.loading;
protected readonly error = this.facade.error;
protected onSubmitted = signal<boolean>(false);
@@ -41,23 +42,32 @@ export class UserFormComponent implements OnInit {
let message = '';
effect(() => {
if (!this.loading().isLoading && this.onSubmitted()) {
if (!this.loading().isLoading) {
switch (this.loading().action) {
case ActionType.UPDATE:
message = `Vos informations personnelles ont bien été modifier !`;
this.customToast(ActionType.UPDATE, message);
this.onSubmitted.set(false);
if (this.onSubmitted()) {
this.customToast(ActionType.UPDATE, message);
}
break;
case ActionType.READ:
this.userForm.setValue({
firstname: this.user().name.split(' ').slice(0, -1).join(' ') ?? '',
name: this.user().name.split(' ').slice(-1)[0] ?? '',
});
break;
}
}
});
}
ngOnInit(): void {
if (this.userId !== undefined) {
this.facade.loadOne(this.userId!);
}
this.userForm = this.fb.group({
firstname: new FormControl(this.user?.name?.split(' ').slice(0, -1).join(' ') ?? '', [
Validators.required,
]),
name: new FormControl(this.user?.name?.split(' ').slice(-1)[0] ?? '', [Validators.required]),
firstname: new FormControl('', [Validators.required]),
name: new FormControl('', [Validators.required]),
});
}
@@ -72,9 +82,7 @@ export class UserFormComponent implements OnInit {
name: this.userForm.getRawValue()!.firstname! + ' ' + this.userForm.getRawValue()!.name!,
} as User;
this.facade.update(this.user?.id!, data);
this.onFormSubmitted.emit(data);
this.facade.update(this.userId!, data);
this.onSubmitted.set(true);
}

View File

@@ -10,6 +10,7 @@ import { UserFacade } from '@app/ui/users/user.facade';
@Component({
selector: 'app-vertical-profile-item',
standalone: true,
providers: [UserFacade],
imports: [ChipsComponent, ReseauxComponent, RouterLink],
templateUrl: './vertical-profile-item.component.html',
styleUrl: './vertical-profile-item.component.scss',