refacto page mon profile

This commit is contained in:
styve Lioumba
2025-11-15 17:30:09 +01:00
parent 620b781219
commit b669190bce
29 changed files with 1702 additions and 743 deletions

View File

@@ -1,10 +1,14 @@
<!-- État de chargement amélioré -->
<div class="flex flex-col items-center justify-center h-96 space-y-4">
<div class="relative">
<div class="w-16 h-16 border-4 border-indigo-200 dark:border-indigo-800 rounded-full animate-spin border-t-indigo-600 dark:border-t-indigo-400"></div>
<div class="absolute inset-0 w-16 h-16 border-4 border-transparent border-t-purple-600 dark:border-t-purple-400 rounded-full animate-spin-slow"></div>
<div
class="w-16 h-16 border-4 border-indigo-200 dark:border-indigo-800 rounded-full animate-spin border-t-indigo-600 dark:border-t-indigo-400"
></div>
<div
class="absolute inset-0 w-16 h-16 border-4 border-transparent border-t-purple-600 dark:border-t-purple-400 rounded-full animate-spin-slow"
></div>
</div>
<p class="text-lg text-gray-600 dark:text-gray-300 font-medium animate-pulse">
{{message}}
{{ message }}
</p>
</div>

View File

@@ -8,10 +8,9 @@ describe('LoadingComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [LoadingComponent]
})
.compileComponents();
imports: [LoadingComponent],
}).compileComponents();
fixture = TestBed.createComponent(LoadingComponent);
component = fixture.componentInstance;
fixture.detectChanges();

View File

@@ -1,11 +1,11 @@
import {Component, Input} from '@angular/core';
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-loading',
standalone: true,
imports: [],
templateUrl: './loading.component.html',
styleUrl: './loading.component.scss'
styleUrl: './loading.component.scss',
})
export class LoadingComponent {
@Input() message: string = 'Chargement...';

View File

@@ -1,6 +0,0 @@
@if (profile != undefined) {
<h2 class="text-3xl font-extrabold text-black dark:text-white">
{{ profile.profession | uppercase }}
</h2>
<p class="leading-relaxed text-lg mb-4 dark:text-white">{{ profile.apropos }}</p>
}

View File

@@ -1,24 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MyHomeProfileComponent } from './my-home-profile.component';
describe('MyHomeProfileComponent', () => {
let component: MyHomeProfileComponent;
let fixture: ComponentFixture<MyHomeProfileComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MyHomeProfileComponent],
}).compileComponents();
fixture = TestBed.createComponent(MyHomeProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
await fixture.whenStable();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,16 +0,0 @@
import { Component, Input } from '@angular/core';
import { UpperCasePipe } from '@angular/common';
import { UntilDestroy } from '@ngneat/until-destroy';
import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
@Component({
selector: 'app-my-home-profile',
standalone: true,
imports: [UpperCasePipe],
templateUrl: './my-home-profile.component.html',
styleUrl: './my-home-profile.component.scss',
})
@UntilDestroy()
export class MyHomeProfileComponent {
@Input({ required: true }) profile: ProfileViewModel | undefined = undefined;
}

View File

@@ -1,283 +1,450 @@
<form
class="space-y-6 font-[sans-serif] max-w-md"
[formGroup]="profileForm"
(ngSubmit)="onSubmit()"
>
<h3 class="font-ubuntu font-bold text-xl uppercase dark:text-white mb-4">
Mon curriculum vitae (CV)
</h3>
<app-my-profile-update-cv-form [profile]="profile" />
<h3 class="font-ubuntu font-bold text-xl uppercase dark:text-white">
Ce qu'il faut savoir de moi
</h3>
<div class="mx-8">
<div>
<label class="mb-2 text-sm text-black block dark:text-white">Biographie</label>
<div class="relative flex items-center">
<textarea
placeholder="Type Message"
formControlName="bio"
class="p-4 bg-white max-w-md mx-auto w-full block text-sm border border-gray-300 outline-[#007bff] rounded"
rows="4"
></textarea>
</div>
</div>
<div>
<label class="mb-2 text-sm text-black block dark:text-white">A propos de vous</label>
<div class="relative flex items-center">
<textarea
placeholder="Type Message"
formControlName="apropos"
class="p-4 bg-white max-w-md mx-auto w-full block text-sm border border-gray-300 outline-[#007bff] rounded"
rows="4"
></textarea>
</div>
</div>
</div>
<h3 class="font-ubuntu font-bold text-xl uppercase dark:text-white">Mon domaine de competence</h3>
<div class="mx-8">
<div>
<label class="mb-2 text-sm text-black block dark:text-white">Profession</label>
<div class="relative flex items-center">
<input
type="text"
placeholder="votre metier"
formControlName="profession"
class="pr-4 pl-14 py-3 text-sm text-black rounded bg-white border border-gray-400 w-full outline-[#333]"
/>
<div class="absolute left-4">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="size-4"
>
<path
fill-rule="evenodd"
d="M11 4V3a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v1H4a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2h-1ZM9 2.5H7a.5.5 0 0 0-.5.5v1h3V3a.5.5 0 0 0-.5-.5ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"
clip-rule="evenodd"
/>
<path
d="M3 11.83V12a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-.17c-.313.11-.65.17-1 .17H4c-.35 0-.687-.06-1-.17Z"
/>
</svg>
</div>
</div>
</div>
<div>
<label class="mb-2 text-sm text-black block dark:text-white">Secteur</label>
<div class="relative flex items-center">
<select
formControlName="secteur"
class="pr-4 pl-14 py-3 text-sm text-black rounded bg-white border border-gray-400 w-full outline-[#333]"
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()" class="space-y-8">
<!-- Section CV -->
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 animate-fade-in">
<div class="flex items-center gap-3 mb-6">
<div
class="w-10 h-10 bg-indigo-100 dark:bg-indigo-900 rounded-lg flex items-center justify-center"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6 text-indigo-600 dark:text-indigo-400"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<option [ngValue]="null" disabled>Selectionner votre secteur d'activité</option>
@for (sector of sectors(); track sector.id) {
<option [value]="sector.id">{{ sector.nom }}</option>
}
</select>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
/>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-900 dark:text-white">Mon curriculum vitae (CV)</h3>
</div>
<app-my-profile-update-cv-form [profile]="profile" />
</div>
<h3 class="font-ubuntu font-bold text-xl uppercase dark:text-white">Mes réseaux</h3>
<div formGroupName="reseaux" class="mx-8">
<div>
<label class="mb-2 text-sm text-black block dark:text-white uppercase">Facebook</label>
<div class="relative flex items-center">
<input
type="text"
placeholder="lien vers votre facebook"
formControlName="facebook"
class="pr-4 pl-14 py-3 text-sm text-black rounded bg-white border border-gray-400 w-full outline-[#333]"
/>
<div class="absolute left-4">
<svg
class="w-6 h-6"
fill="#0866FF"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<title>Facebook</title>
<path
d="M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z"
/>
</svg>
</div>
</div>
</div>
<div>
<label class="mb-2 text-sm text-black block dark:text-white uppercase">Github</label>
<div class="relative flex items-center">
<input
type="text"
placeholder="Lien vers votre github"
formControlName="github"
class="pr-4 pl-14 py-3 text-sm text-black rounded bg-white border border-gray-400 w-full outline-[#333]"
/>
<div class="absolute left-4">
<svg
class="w-6 h-6"
fill="#181717"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<title>GitHub</title>
<path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
/>
</svg>
</div>
</div>
</div>
<div>
<label class="mb-2 text-sm text-black block dark:text-white uppercase">Instagram</label>
<div class="relative flex items-center">
<input
type="text"
placeholder="Lien vers votre instagram"
formControlName="instagram"
class="pr-4 pl-14 py-3 text-sm text-black rounded bg-white border border-gray-400 w-full outline-[#333]"
/>
<div class="absolute left-4">
<svg
class="w-6 h-6"
fill="#E4405F"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<title>Instagram</title>
<path
d="M7.0301.084c-1.2768.0602-2.1487.264-2.911.5634-.7888.3075-1.4575.72-2.1228 1.3877-.6652.6677-1.075 1.3368-1.3802 2.127-.2954.7638-.4956 1.6365-.552 2.914-.0564 1.2775-.0689 1.6882-.0626 4.947.0062 3.2586.0206 3.6671.0825 4.9473.061 1.2765.264 2.1482.5635 2.9107.308.7889.72 1.4573 1.388 2.1228.6679.6655 1.3365 1.0743 2.1285 1.38.7632.295 1.6361.4961 2.9134.552 1.2773.056 1.6884.069 4.9462.0627 3.2578-.0062 3.668-.0207 4.9478-.0814 1.28-.0607 2.147-.2652 2.9098-.5633.7889-.3086 1.4578-.72 2.1228-1.3881.665-.6682 1.0745-1.3378 1.3795-2.1284.2957-.7632.4966-1.636.552-2.9124.056-1.2809.0692-1.6898.063-4.948-.0063-3.2583-.021-3.6668-.0817-4.9465-.0607-1.2797-.264-2.1487-.5633-2.9117-.3084-.7889-.72-1.4568-1.3876-2.1228C21.2982 1.33 20.628.9208 19.8378.6165 19.074.321 18.2017.1197 16.9244.0645 15.6471.0093 15.236-.005 11.977.0014 8.718.0076 8.31.0215 7.0301.0839m.1402 21.6932c-1.17-.0509-1.8053-.2453-2.2287-.408-.5606-.216-.96-.4771-1.3819-.895-.422-.4178-.6811-.8186-.9-1.378-.1644-.4234-.3624-1.058-.4171-2.228-.0595-1.2645-.072-1.6442-.079-4.848-.007-3.2037.0053-3.583.0607-4.848.05-1.169.2456-1.805.408-2.2282.216-.5613.4762-.96.895-1.3816.4188-.4217.8184-.6814 1.3783-.9003.423-.1651 1.0575-.3614 2.227-.4171 1.2655-.06 1.6447-.072 4.848-.079 3.2033-.007 3.5835.005 4.8495.0608 1.169.0508 1.8053.2445 2.228.408.5608.216.96.4754 1.3816.895.4217.4194.6816.8176.9005 1.3787.1653.4217.3617 1.056.4169 2.2263.0602 1.2655.0739 1.645.0796 4.848.0058 3.203-.0055 3.5834-.061 4.848-.051 1.17-.245 1.8055-.408 2.2294-.216.5604-.4763.96-.8954 1.3814-.419.4215-.8181.6811-1.3783.9-.4224.1649-1.0577.3617-2.2262.4174-1.2656.0595-1.6448.072-4.8493.079-3.2045.007-3.5825-.006-4.848-.0608M16.953 5.5864A1.44 1.44 0 1 0 18.39 4.144a1.44 1.44 0 0 0-1.437 1.4424M5.8385 12.012c.0067 3.4032 2.7706 6.1557 6.173 6.1493 3.4026-.0065 6.157-2.7701 6.1506-6.1733-.0065-3.4032-2.771-6.1565-6.174-6.1498-3.403.0067-6.156 2.771-6.1496 6.1738M8 12.0077a4 4 0 1 1 4.008 3.9921A3.9996 3.9996 0 0 1 8 12.0077"
/>
</svg>
</div>
</div>
</div>
<div>
<label class="mb-2 text-sm text-black block dark:text-white uppercase">linkedIn</label>
<div class="relative flex items-center">
<input
type="text"
placeholder="Lien vers votre linkedIn"
formControlName="linkedIn"
class="pr-4 pl-14 py-3 text-sm text-black rounded bg-white border border-gray-400 w-full outline-[#333]"
/>
<div class="absolute left-4">
<svg
class="w-6 h-6"
fill="#0A66C2"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<title>LinkedIn</title>
<path
d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"
/>
</svg>
</div>
</div>
</div>
<div>
<label class="mb-2 text-sm text-black block dark:text-white uppercase">web</label>
<div class="relative flex items-center">
<input
type="text"
placeholder="Lien vers votre site web"
formControlName="web"
class="pr-4 pl-14 py-3 text-sm text-black rounded bg-white border border-gray-400 w-full outline-[#333]"
/>
<div class="absolute left-4">
<svg
id="Layer_1"
class="w-6 h-6"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<title>world-globe-outline</title>
<path
d="M256,0Q362.11,0,436.9,75.1,512,149.89,512,256T436.9,436.9Q362.11,512,256,512T75.1,436.9Q0,362.11,0,256T75.1,75.1Q149.89,0,256,0ZM55.34,190.63a211.82,211.82,0,0,0,0,130.73h66a416,416,0,0,1,0-130.73Zm14.9,165.7q34.36,63.55,100.64,92.73a232.64,232.64,0,0,1-20.07-31.92,302.59,302.59,0,0,1-22.2-60.81ZM170.87,63.24Q104.59,92.43,70.54,155.37h58.07a304.36,304.36,0,0,1,22.2-60.51A198.45,198.45,0,0,1,170.87,63.24ZM151.72,190.63A390.59,390.59,0,0,0,145.94,256a390.48,390.48,0,0,0,5.78,65.37H241.1V190.63Zm82.7-143.51q-32.83,13.38-57.16,61.11-9.43,19.16-17.63,47.13H241.1V45.61a3.4,3.4,0,0,1-1.52.3h-1.82Zm3.34,419h1.82a5.12,5.12,0,0,0,1.52.3V356.33H159.62q8.21,28.28,17.63,47.43,24.32,47.74,57.16,61.11ZM274.24,45.91h-1.83a3.38,3.38,0,0,1-1.52-.3V155.37h81.48q-8.21-28-17.63-47.13-24.33-47.73-57.16-61.11Zm86,275.46A391.23,391.23,0,0,0,366.06,256a395,395,0,0,0-5.78-65.37H270.9V321.37Zm-82.7,143.51q32.84-13.39,57.16-61.11,9.73-19.16,17.63-47.43H270.9V466.39a5.1,5.1,0,0,0,1.52-.3h1.83ZM441.46,155.37q-34.06-62.94-100-92.12A212.61,212.61,0,0,1,361.2,94.86a295.22,295.22,0,0,1,22.2,60.51Zm-100,293.7q66-29.49,100-92.73H383.39q-8.52,33.74-22.2,60.81A226,226,0,0,1,341.43,449.06Zm49.25-258.43A412,412,0,0,1,395.86,256a415.71,415.71,0,0,1-5.17,65.37h66a211.89,211.89,0,0,0,0-130.73Z"
/>
</svg>
</div>
</div>
</div>
<div>
<label class="mb-2 text-sm text-black block dark:text-white uppercase">x</label>
<div class="relative flex items-center">
<input
type="text"
placeholder="Lien vers votre compte X"
formControlName="x"
class="pr-4 pl-14 py-3 text-sm text-black rounded bg-white border border-gray-400 w-full outline-[#333]"
/>
<div class="absolute left-4">
<svg
class="w-6 h-6"
fill="#000000"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<title>X</title>
<path
d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"
/>
</svg>
</div>
</div>
</div>
<div>
<label class="mb-2 text-sm text-black block dark:text-white uppercase">YouTube</label>
<div class="relative flex items-center">
<input
type="text"
placeholder="Lien vers votre compte youtube"
formControlName="youTube"
class="pr-4 pl-14 py-3 text-sm text-black rounded bg-white border border-gray-400 w-full outline-[#333]"
/>
<div class="absolute left-4">
<svg
class="w-6 h-6"
fill="#FF0000"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<title>YouTube</title>
<path
d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"
/>
</svg>
</div>
</div>
</div>
</div>
<button
type="submit"
[ngClass]="{ 'bg-purple-600': profileForm.valid }"
class="!mt-8 px-6 py-2 w-full bg-[#333] hover:bg-[#444] text-sm text-white mx-auto block"
<!-- Section À propos de moi -->
<div
class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 animate-fade-in animation-delay-100"
>
Sauvegarder
</button>
<div class="flex items-center gap-3 mb-6">
<div
class="w-10 h-10 bg-purple-100 dark:bg-purple-900 rounded-lg flex items-center justify-center"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6 text-purple-600 dark:text-purple-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-6-3a2 2 0 11-4 0 2 2 0 014 0zm-2 4a5 5 0 00-4.546 2.916A5.986 5.986 0 0010 16a5.986 5.986 0 004.546-2.084A5 5 0 0010 11z"
clip-rule="evenodd"
/>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-900 dark:text-white">Ce qu'il faut savoir de moi</h3>
</div>
<div class="space-y-4">
<!-- Biographie -->
<div>
<label for="bio" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Biographie
</label>
<textarea
id="bio"
formControlName="bio"
placeholder="Parlez de vous en quelques lignes..."
rows="4"
class="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all resize-none"
></textarea>
</div>
<!-- À propos -->
<div>
<label
for="apropos"
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
À propos de vous
</label>
<textarea
id="apropos"
formControlName="apropos"
placeholder="Décrivez votre parcours, vos objectifs..."
rows="4"
class="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all resize-none"
></textarea>
</div>
</div>
</div>
<!-- Section Compétences -->
<div
class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 animate-fade-in animation-delay-200"
>
<div class="flex items-center gap-3 mb-6">
<div
class="w-10 h-10 bg-blue-100 dark:bg-blue-900 rounded-lg flex items-center justify-center"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6 text-blue-600 dark:text-blue-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M6 6V5a3 3 0 013-3h2a3 3 0 013 3v1h2a2 2 0 012 2v3.57A22.952 22.952 0 0110 13a22.95 22.95 0 01-8-1.43V8a2 2 0 012-2h2zm2-1a1 1 0 011-1h2a1 1 0 011 1v1H8V5zm1 5a1 1 0 011-1h.01a1 1 0 110 2H10a1 1 0 01-1-1z"
clip-rule="evenodd"
/>
<path
d="M2 13.692V16a2 2 0 002 2h12a2 2 0 002-2v-2.308A24.974 24.974 0 0110 15c-2.796 0-5.487-.46-8-1.308z"
/>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-900 dark:text-white">Mon domaine de compétence</h3>
</div>
<div class="space-y-4">
<!-- Profession -->
<div>
<label
for="profession"
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
Profession
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M6 6V5a3 3 0 013-3h2a3 3 0 013 3v1h2a2 2 0 012 2v3.57A22.952 22.952 0 0110 13a22.95 22.95 0 01-8-1.43V8a2 2 0 012-2h2zm2-1a1 1 0 011-1h2a1 1 0 011 1v1H8V5zm1 5a1 1 0 011-1h.01a1 1 0 110 2H10a1 1 0 01-1-1z"
clip-rule="evenodd"
/>
<path
d="M2 13.692V16a2 2 0 002 2h12a2 2 0 002-2v-2.308A24.974 24.974 0 0110 15c-2.796 0-5.487-.46-8-1.308z"
/>
</svg>
</div>
<input
id="profession"
type="text"
formControlName="profession"
placeholder="Ex: Développeur Web, Designer..."
class="w-full pl-10 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all"
/>
</div>
</div>
<!-- Secteur -->
<div>
<label
for="secteur"
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
Secteur d'activité
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
d="M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zM8 7a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM14 4a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z"
/>
</svg>
</div>
<select
id="secteur"
formControlName="secteur"
class="w-full pl-10 pr-10 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all appearance-none cursor-pointer"
>
<option [ngValue]="null" disabled>Sélectionnez votre secteur</option>
@for (sector of sectors(); track sector.id) {
<option [value]="sector.id">{{ sector.nom }}</option>
}
</select>
<div class="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
<svg
class="h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
/>
</svg>
</div>
</div>
</div>
</div>
</div>
<!-- Section Réseaux sociaux -->
<div
class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 animate-fade-in animation-delay-300"
>
<div class="flex items-center gap-3 mb-6">
<div
class="w-10 h-10 bg-pink-100 dark:bg-pink-900 rounded-lg flex items-center justify-center"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6 text-pink-600 dark:text-pink-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path d="M2 5a2 2 0 012-2h7a2 2 0 012 2v4a2 2 0 01-2 2H9l-3 3v-3H4a2 2 0 01-2-2V5z" />
<path
d="M15 7v2a4 4 0 01-4 4H9.828l-1.766 1.767c.28.149.599.233.938.233h2l3 3v-3h2a2 2 0 002-2V9a2 2 0 00-2-2h-1z"
/>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-900 dark:text-white">Mes réseaux sociaux</h3>
</div>
<div formGroupName="reseaux" class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- Facebook -->
<div>
<label
for="facebook"
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
Facebook
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg
class="w-5 h-5"
fill="#0866FF"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z"
/>
</svg>
</div>
<input
id="facebook"
type="url"
formControlName="facebook"
placeholder="https://facebook.com/votreprofil"
class="w-full pl-10 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all"
/>
</div>
</div>
<!-- GitHub -->
<div>
<label for="github" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
GitHub
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg
class="w-5 h-5"
fill="#181717"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
/>
</svg>
</div>
<input
id="github"
type="url"
formControlName="github"
placeholder="https://github.com/votreprofil"
class="w-full pl-10 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all"
/>
</div>
</div>
<!-- Instagram -->
<div>
<label
for="instagram"
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
Instagram
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg
class="w-5 h-5"
fill="#E4405F"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.0301.084c-1.2768.0602-2.1487.264-2.911.5634-.7888.3075-1.4575.72-2.1228 1.3877-.6652.6677-1.075 1.3368-1.3802 2.127-.2954.7638-.4956 1.6365-.552 2.914-.0564 1.2775-.0689 1.6882-.0626 4.947.0062 3.2586.0206 3.6671.0825 4.9473.061 1.2765.264 2.1482.5635 2.9107.308.7889.72 1.4573 1.388 2.1228.6679.6655 1.3365 1.0743 2.1285 1.38.7632.295 1.6361.4961 2.9134.552 1.2773.056 1.6884.069 4.9462.0627 3.2578-.0062 3.668-.0207 4.9478-.0814 1.28-.0607 2.147-.2652 2.9098-.5633.7889-.3086 1.4578-.72 2.1228-1.3881.665-.6682 1.0745-1.3378 1.3795-2.1284.2957-.7632.4966-1.636.552-2.9124.056-1.2809.0692-1.6898.063-4.948-.0063-3.2583-.021-3.6668-.0817-4.9465-.0607-1.2797-.264-2.1487-.5633-2.9117-.3084-.7889-.72-1.4568-1.3876-2.1228C21.2982 1.33 20.628.9208 19.8378.6165 19.074.321 18.2017.1197 16.9244.0645 15.6471.0093 15.236-.005 11.977.0014 8.718.0076 8.31.0215 7.0301.0839m.1402 21.6932c-1.17-.0509-1.8053-.2453-2.2287-.408-.5606-.216-.96-.4771-1.3819-.895-.422-.4178-.6811-.8186-.9-1.378-.1644-.4234-.3624-1.058-.4171-2.228-.0595-1.2645-.072-1.6442-.079-4.848-.007-3.2037.0053-3.583.0607-4.848.05-1.169.2456-1.805.408-2.2282.216-.5613.4762-.96.895-1.3816.4188-.4217.8184-.6814 1.3783-.9003.423-.1651 1.0575-.3614 2.227-.4171 1.2655-.06 1.6447-.072 4.848-.079 3.2033-.007 3.5835.005 4.8495.0608 1.169.0508 1.8053.2445 2.228.408.5608.216.96.4754 1.3816.895.4217.4194.6816.8176.9005 1.3787.1653.4217.3617 1.056.4169 2.2263.0602 1.2655.0739 1.645.0796 4.848.0058 3.203-.0055 3.5834-.061 4.848-.051 1.17-.245 1.8055-.408 2.2294-.216.5604-.4763.96-.8954 1.3814-.419.4215-.8181.6811-1.3783.9-.4224.1649-1.0577.3617-2.2262.4174-1.2656.0595-1.6448.072-4.8493.079-3.2045.007-3.5825-.006-4.848-.0608M16.953 5.5864A1.44 1.44 0 1 0 18.39 4.144a1.44 1.44 0 0 0-1.437 1.4424M5.8385 12.012c.0067 3.4032 2.7706 6.1557 6.173 6.1493 3.4026-.0065 6.157-2.7701 6.1506-6.1733-.0065-3.4032-2.771-6.1565-6.174-6.1498-3.403.0067-6.156 2.771-6.1496 6.1738M8 12.0077a4 4 0 1 1 4.008 3.9921A3.9996 3.9996 0 0 1 8 12.0077"
/>
</svg>
</div>
<input
id="instagram"
type="url"
formControlName="instagram"
placeholder="https://instagram.com/votreprofil"
class="w-full pl-10 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all"
/>
</div>
</div>
<!-- LinkedIn -->
<div>
<label
for="linkedIn"
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
LinkedIn
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg
class="w-5 h-5"
fill="#0A66C2"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"
/>
</svg>
</div>
<input
id="linkedIn"
type="url"
formControlName="linkedIn"
placeholder="https://linkedin.com/in/votreprofil"
class="w-full pl-10 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all"
/>
</div>
</div>
<!-- Site Web -->
<div>
<label for="web" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Site Web
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg
class="w-5 h-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M4.083 9h1.946c.089-1.546.383-2.97.837-4.118A6.004 6.004 0 004.083 9zM10 2a8 8 0 100 16 8 8 0 000-16zm0 2c-.076 0-.232.032-.465.262-.238.234-.497.623-.737 1.182-.389.907-.673 2.142-.766 3.556h3.936c-.093-1.414-.377-2.649-.766-3.556-.24-.56-.5-.948-.737-1.182C10.232 4.032 10.076 4 10 4zm3.971 5c-.089-1.546-.383-2.97-.837-4.118A6.004 6.004 0 0115.917 9h-1.946zm-2.003 2H8.032c.093 1.414.377 2.649.766 3.556.24.56.5.948.737 1.182.233.23.389.262.465.262.076 0 .232-.032.465-.262.238-.234.498-.623.737-1.182.389-.907.673-2.142.766-3.556zm1.166 4.118c.454-1.147.748-2.572.837-4.118h1.946a6.004 6.004 0 01-2.783 4.118zm-6.268 0C6.412 13.97 6.118 12.546 6.03 11H4.083a6.004 6.004 0 002.783 4.118z"
clip-rule="evenodd"
/>
</svg>
</div>
<input
id="web"
type="url"
formControlName="web"
placeholder="https://votresite.com"
class="w-full pl-10 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all"
/>
</div>
</div>
<!-- X (Twitter) -->
<div>
<label for="x" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
X (Twitter)
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg
class="w-5 h-5"
fill="#000000"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"
/>
</svg>
</div>
<input
id="x"
type="url"
formControlName="x"
placeholder="https://x.com/votreprofil"
class="w-full pl-10 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all"
/>
</div>
</div>
<!-- Youtube -->
<div>
<label for="x" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Youtube
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg
class="w-6 h-6"
fill="#FF0000"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<title>YouTube</title>
<path
d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"
/>
</svg>
</div>
<input
id="x"
type="url"
formControlName="youTube"
placeholder="https://youtube.com/votreprofil"
class="w-full pl-10 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all"
/>
</div>
</div>
</div>
</div>
<div class="flex justify-end animate-fade-in animation-delay-400">
<button
type="submit"
[disabled]="profileForm.invalid"
class="px-8 py-3 bg-gradient-to-r from-indigo-600 to-purple-600 hover:from-indigo-700 hover:to-purple-700 text-white font-medium rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-0.5 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none"
>
<span class="flex items-center gap-2">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
d="M7.707 10.293a1 1 0 10-1.414 1.414l3 3a1 1 0 001.414 0l3-3a1 1 0 00-1.414-1.414L11 11.586V6h5a2 2 0 012 2v7a2 2 0 01-2 2H4a2 2 0 01-2-2V8a2 2 0 012-2h5v5.586l-1.293-1.293zM9 4a1 1 0 012 0v2H9V4z"
/>
</svg>
Sauvegarder les modifications
</span>
</button>
</div>
</form>

View File

@@ -0,0 +1,48 @@
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-fade-in {
animation: fadeIn 0.6s ease-out;
}
.animation-delay-100 {
animation-delay: 0.1s;
opacity: 0;
animation-fill-mode: forwards;
}
.animation-delay-200 {
animation-delay: 0.2s;
opacity: 0;
animation-fill-mode: forwards;
}
.animation-delay-300 {
animation-delay: 0.3s;
opacity: 0;
animation-fill-mode: forwards;
}
.animation-delay-400 {
animation-delay: 0.4s;
opacity: 0;
animation-fill-mode: forwards;
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}

View File

@@ -35,10 +35,10 @@ export class UserFormComponent implements OnInit {
ngOnInit(): void {
this.userForm = this.fb.group({
firstname: new FormControl(this.user?.name!.split(' ').slice(0, -1).join(' ') ?? '', [
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]),
name: new FormControl(this.user?.name?.split(' ').slice(-1)[0] ?? '', [Validators.required]),
});
}

View File

@@ -1,5 +1,4 @@
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()" class="space-y-4">
<!-- Champ Email -->
<div class="space-y-2">
<label for="email" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
@@ -7,9 +6,14 @@
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor">
<path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z"/>
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z" />
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" />
</svg>
</div>
<input
@@ -33,8 +37,17 @@
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z"
clip-rule="evenodd"
/>
</svg>
</div>
<input
@@ -53,14 +66,34 @@
class="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
>
@if (pwdInput.type === 'password') {
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path d="M10 12a2 2 0 100-4 2 2 0 000 4z"/>
<path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path d="M10 12a2 2 0 100-4 2 2 0 000 4z" />
<path
fill-rule="evenodd"
d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z"
clip-rule="evenodd"
/>
</svg>
} @else {
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z" clip-rule="evenodd"/>
<path d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z"
clip-rule="evenodd"
/>
<path
d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z"
/>
</svg>
}
</button>
@@ -72,7 +105,10 @@
<!-- Mot de passe oublié -->
<div class="flex justify-end">
<a [routerLink]="['/forgot-password']" class="text-sm text-indigo-600 hover:text-indigo-700 dark:text-indigo-400 dark:hover:text-indigo-300 font-medium transition-colors">
<a
[routerLink]="['/forgot-password']"
class="text-sm text-indigo-600 hover:text-indigo-700 dark:text-indigo-400 dark:hover:text-indigo-300 font-medium transition-colors"
>
Mot de passe oublié ?
</a>
</div>
@@ -85,9 +121,25 @@
>
@if (isLoading()) {
<span class="flex items-center justify-center gap-2">
<svg class="animate-spin h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
<svg
class="animate-spin h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
class="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="4"
></circle>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
Connexion en cours...
</span>
@@ -100,12 +152,14 @@
<div class="text-center">
<p class="text-sm text-gray-600 dark:text-gray-400">
Vous n'avez pas de compte ?
<a [routerLink]="['register']" class="text-indigo-600 hover:text-indigo-700 dark:text-indigo-400 dark:hover:text-indigo-300 font-semibold transition-colors">
<a
[routerLink]="['register']"
class="text-indigo-600 hover:text-indigo-700 dark:text-indigo-400 dark:hover:text-indigo-300 font-semibold transition-colors"
>
Créez-en un ici
</a>
</p>
</div>
</form>
<!-- Progress bar -->

View File

@@ -1,5 +1,4 @@
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()" class="space-y-4">
<!-- Champ Email -->
<div class="space-y-2">
<label for="email" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
@@ -7,9 +6,14 @@
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor">
<path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z"/>
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z" />
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" />
</svg>
</div>
<input
@@ -33,8 +37,17 @@
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z"
clip-rule="evenodd"
/>
</svg>
</div>
<input
@@ -53,14 +66,34 @@
class="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
>
@if (pwdInput.type === 'password') {
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path d="M10 12a2 2 0 100-4 2 2 0 000 4z"/>
<path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path d="M10 12a2 2 0 100-4 2 2 0 000 4z" />
<path
fill-rule="evenodd"
d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z"
clip-rule="evenodd"
/>
</svg>
} @else {
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z" clip-rule="evenodd"/>
<path d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z"
clip-rule="evenodd"
/>
<path
d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z"
/>
</svg>
}
</button>
@@ -77,8 +110,17 @@
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z"
clip-rule="evenodd"
/>
</svg>
</div>
<input
@@ -93,23 +135,47 @@
/>
<button
type="button"
(click)="pwdInputConfirmation.type = pwdInputConfirmation.type === 'password' ? 'text' : 'password'"
(click)="
pwdInputConfirmation.type = pwdInputConfirmation.type === 'password' ? 'text' : 'password'
"
class="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
>
@if (pwdInputConfirmation.type === 'password') {
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path d="M10 12a2 2 0 100-4 2 2 0 000 4z"/>
<path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path d="M10 12a2 2 0 100-4 2 2 0 000 4z" />
<path
fill-rule="evenodd"
d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z"
clip-rule="evenodd"
/>
</svg>
} @else {
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z" clip-rule="evenodd"/>
<path d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z"/>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z"
clip-rule="evenodd"
/>
<path
d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z"
/>
</svg>
}
</button>
</div>
@if (registerForm.get('passwordConfirm')?.invalid && registerForm.get('passwordConfirm')?.touched) {
@if (
registerForm.get('passwordConfirm')?.invalid && registerForm.get('passwordConfirm')?.touched
) {
<p class="text-xs text-red-500 mt-1">Les mots de passe ne correspondent pas</p>
}
</div>
@@ -119,8 +185,16 @@
<div class="space-y-2">
<div class="flex gap-1">
<div class="h-1 flex-1 rounded-full bg-red-500"></div>
<div class="h-1 flex-1 rounded-full" [class.bg-yellow-500]="pwd.length >= 8" [class.bg-gray-200]="pwd.length < 8"></div>
<div class="h-1 flex-1 rounded-full" [class.bg-green-500]="pwd.length >= 10" [class.bg-gray-200]="pwd.length < 10"></div>
<div
class="h-1 flex-1 rounded-full"
[class.bg-yellow-500]="pwd.length >= 8"
[class.bg-gray-200]="pwd.length < 8"
></div>
<div
class="h-1 flex-1 rounded-full"
[class.bg-green-500]="pwd.length >= 10"
[class.bg-gray-200]="pwd.length < 10"
></div>
</div>
<p class="text-xs text-gray-500 dark:text-gray-400">
@if (pwd.length < 8) {
@@ -142,9 +216,25 @@
>
@if (isLoading()) {
<span class="flex items-center justify-center gap-2">
<svg class="animate-spin h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
<svg
class="animate-spin h-5 w-5"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
class="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="4"
></circle>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
Inscription en cours...
</span>
@@ -157,7 +247,10 @@
<div class="text-center">
<p class="text-sm text-gray-600 dark:text-gray-400">
Vous avez déjà un compte ?
<a [routerLink]="['/auth']" class="text-indigo-600 hover:text-indigo-700 dark:text-indigo-400 dark:hover:text-indigo-300 font-semibold transition-colors">
<a
[routerLink]="['/auth']"
class="text-indigo-600 hover:text-indigo-700 dark:text-indigo-400 dark:hover:text-indigo-300 font-semibold transition-colors"
>
Connectez-vous ici
</a>
</p>

View File

@@ -1,38 +1,53 @@
<div class="flex w-full justify-between items-center mb-6">
<span
(click)="isCancelEditMode.emit(true)"
class="cursor-pointer px-3 py-3 text-white bg-purple-600 w-max flex space-x-2 items-center rounded-full justify-center"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4">
<path
fill-rule="evenodd"
d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z"
clip-rule="evenodd"
/>
</svg>
<small>Terminer</small>
</span>
<span
(click)="isCancelEditMode.emit(true)"
class="cursor-pointer px-3 py-3 text-white bg-red-600 w-max flex space-x-2 items-center rounded-full justify-center"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4">
<path
fill-rule="evenodd"
d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14Zm2.78-4.22a.75.75 0 0 1-1.06 0L8 9.06l-1.72 1.72a.75.75 0 1 1-1.06-1.06L6.94 8 5.22 6.28a.75.75 0 0 1 1.06-1.06L8 6.94l1.72-1.72a.75.75 0 1 1 1.06 1.06L9.06 8l1.72 1.72a.75.75 0 0 1 0 1.06Z"
clip-rule="evenodd"
/>
</svg>
<small>Annuler</small>
</span>
</div>
@if (user != undefined) {
<div class="w-full flex flex-col space-y-4">
<app-user-avatar-form [user]="user" />
<app-user-form [user]="user" />
<div class="space-y-6">
<!-- Section Avatar -->
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 animate-fade-in">
<div class="flex items-center gap-3 mb-6">
<div
class="w-10 h-10 bg-indigo-100 dark:bg-indigo-900 rounded-lg flex items-center justify-center"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6 text-indigo-600 dark:text-indigo-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm12 12H4l4-8 3 6 2-4 3 6z"
clip-rule="evenodd"
/>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-900 dark:text-white">Photo de profil</h3>
</div>
<app-user-avatar-form [user]="user" />
</div>
<!-- Section Informations utilisateur -->
<div
class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 animate-fade-in animation-delay-100"
>
<div class="flex items-center gap-3 mb-6">
<div
class="w-10 h-10 bg-purple-100 dark:bg-purple-900 rounded-lg flex items-center justify-center"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6 text-purple-600 dark:text-purple-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"
clip-rule="evenodd"
/>
</svg>
</div>
<h3 class="text-xl font-bold text-gray-900 dark:text-white">Informations personnelles</h3>
</div>
<app-user-form [user]="user" />
</div>
</div>
}

View File

@@ -0,0 +1,30 @@
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-fade-in {
animation: fadeIn 0.6s ease-out;
}
.animation-delay-100 {
animation-delay: 0.1s;
opacity: 0;
animation-fill-mode: forwards;
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}

View File

@@ -1,4 +1,4 @@
import { Component, Input, output } from '@angular/core';
import { Component, Input } from '@angular/core';
import { User } from '@app/shared/models/user';
import { UserFormComponent } from '@app/shared/components/user-form/user-form.component';
import { UserAvatarFormComponent } from '@app/shared/components/user-avatar-form/user-avatar-form.component';
@@ -12,6 +12,4 @@ import { UserAvatarFormComponent } from '@app/shared/components/user-avatar-form
})
export class UpdateUserComponent {
@Input({ required: true }) user: User | undefined = undefined;
onFormSubmitted = output<any>();
isCancelEditMode = output<boolean>();
}