171 lines
6.2 KiB
HTML
171 lines
6.2 KiB
HTML
<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">
|
|
Adresse email
|
|
</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>
|
|
</div>
|
|
<input
|
|
formControlName="email"
|
|
type="email"
|
|
id="email"
|
|
name="email"
|
|
placeholder="votre@email.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>
|
|
@if (loginForm.get('email')?.invalid && loginForm.get('email')?.touched) {
|
|
<p class="text-xs text-red-500 mt-1">Veuillez entrer une adresse email valide</p>
|
|
}
|
|
</div>
|
|
|
|
<!-- Champ Mot de passe -->
|
|
<div class="space-y-2">
|
|
<label for="password" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
Mot de passe
|
|
</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>
|
|
</div>
|
|
<input
|
|
#pwdInput
|
|
formControlName="password"
|
|
type="password"
|
|
id="password"
|
|
name="password"
|
|
placeholder="••••••••"
|
|
autocomplete="current-password"
|
|
class="w-full pl-10 pr-12 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"
|
|
/>
|
|
<button
|
|
type="button"
|
|
(click)="pwdInput.type = pwdInput.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 (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>
|
|
} @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>
|
|
}
|
|
</button>
|
|
</div>
|
|
@if (loginForm.get('password')?.invalid && loginForm.get('password')?.touched) {
|
|
<p class="text-xs text-red-500 mt-1">Le mot de passe est requis</p>
|
|
}
|
|
</div>
|
|
|
|
<!-- 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"
|
|
>
|
|
Mot de passe oublié ?
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Bouton de connexion -->
|
|
<button
|
|
type="submit"
|
|
[disabled]="loginForm.invalid || isLoading()"
|
|
class="w-full py-3 px-4 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"
|
|
>
|
|
@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>
|
|
Connexion en cours...
|
|
</span>
|
|
} @else {
|
|
Se connecter
|
|
}
|
|
</button>
|
|
|
|
<!-- Lien vers l'inscription -->
|
|
<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"
|
|
>
|
|
Créez-en un ici
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Progress bar -->
|
|
@if (isLoading()) {
|
|
<div class="mt-6">
|
|
<p-progressBar mode="indeterminate" [style]="{ height: '4px' }" />
|
|
</div>
|
|
}
|