diff --git a/Frontend/quizz-game/src/app/app-routing.module.ts b/Frontend/quizz-game/src/app/app-routing.module.ts index 46ab1728a7a04b09fe85fd507496e4c11008abce..abaec07b37ba5fdb9cc4a4fe60ab5ae339d34b86 100644 --- a/Frontend/quizz-game/src/app/app-routing.module.ts +++ b/Frontend/quizz-game/src/app/app-routing.module.ts @@ -3,6 +3,7 @@ import { RouterModule, Routes } from '@angular/router'; import { LoginComponent } from "./login/login.component"; import {SignInComponent} from "./login/sign-in/sign-in.component"; import {SignUpComponent} from "./login/sign-up/sign-up.component"; +import {ManageComponent} from "./manage/manage.component"; const routes: Routes = [ { path: '', redirectTo: 'login', pathMatch: 'full' }, @@ -24,7 +25,8 @@ const routes: Routes = [ component: SignUpComponent } ] - } + }, + { path: ':admin/manage', component: ManageComponent } ]; diff --git a/Frontend/quizz-game/src/app/app.module.ts b/Frontend/quizz-game/src/app/app.module.ts index 0a873dfa0bfee2dd90373d3c6e359b48648ad465..29cd8ebc75b244a2dcd21f266f55b2554de7239f 100644 --- a/Frontend/quizz-game/src/app/app.module.ts +++ b/Frontend/quizz-game/src/app/app.module.ts @@ -10,6 +10,8 @@ import {CommonModule} from "@angular/common"; import { FormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; +import { ErrorloginComponent } from './login/errorlogin/errorlogin.component'; +import { ManageComponent } from './manage/manage.component'; @@ -18,7 +20,9 @@ import { HttpClientModule } from '@angular/common/http'; AppComponent, SignInComponent, SignUpComponent, - LoginComponent + LoginComponent, + ErrorloginComponent, + ManageComponent ], imports: [ BrowserModule, diff --git a/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.css b/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.html b/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.html new file mode 100644 index 0000000000000000000000000000000000000000..6124b52a675069dd3c6bf3bfae9d402bc4fd61a5 --- /dev/null +++ b/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.html @@ -0,0 +1,21 @@ +<div role="alert" class="rounded border-s-4 border-red-500 bg-red-50 p-4"> + <div class="flex items-center gap-2 text-red-800"> + <svg + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 24 24" + fill="currentColor" + class="h-5 w-5" + > + <path + fill-rule="evenodd" + d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" + clip-rule="evenodd" + /> + </svg> + + <strong class="block font-medium"> Erreur </strong> + </div> + + <p class="mt-2 text-sm text-red-700" #errorText> + </p> +</div> diff --git a/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.spec.ts b/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..4cb082ec802620fe0481a6f81a7f1b4f67f420ea --- /dev/null +++ b/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ErrorloginComponent } from './errorlogin.component'; + +describe('ErrorloginComponent', () => { + let component: ErrorloginComponent; + let fixture: ComponentFixture<ErrorloginComponent>; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ErrorloginComponent] + }); + fixture = TestBed.createComponent(ErrorloginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.ts b/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..e68b80db22e7ae0e19c9ad03946df7f2180e745d --- /dev/null +++ b/Frontend/quizz-game/src/app/login/errorlogin/errorlogin.component.ts @@ -0,0 +1,36 @@ +import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core'; +import {ErrorLogin, LoginService} from "../login.service"; + +@Component({ + selector: 'app-errorlogin', + templateUrl: './errorlogin.component.html', + styleUrls: ['./errorlogin.component.css'] +}) +export class ErrorloginComponent implements OnInit, AfterViewInit{ + @ViewChild('errorText', { static: true }) errorText!: ElementRef; + actualError!: ErrorLogin; + + constructor(private loginService: LoginService) { + } + + + ngOnInit() { + this.actualError=this.loginService.actualError; + } + + ngAfterViewInit() { + if(this.actualError === ErrorLogin.PassConfirm){ + this.errorText.nativeElement.textContent="Les mots de passes doivent être identiques" + } + if(this.actualError === ErrorLogin.UserPassword){ + this.errorText.nativeElement.textContent="Le mot de passe que vous avez saisi est incorrect, veuillez réessayer" + } + if(this.actualError === ErrorLogin.UserNotExist){ + this.errorText.nativeElement.textContent="Le nom d'utilisateur que vous avez saisi n'existe pas" + } + if(this.actualError === ErrorLogin.UserNameExist){ + this.errorText.nativeElement.textContent="Le nom d'utilisateur que vous avez saisi existe déjà, veuillez en choisir un autre" + } + } + +} diff --git a/Frontend/quizz-game/src/app/login/password.service.spec.ts b/Frontend/quizz-game/src/app/login/login.service.spec.ts similarity index 63% rename from Frontend/quizz-game/src/app/login/password.service.spec.ts rename to Frontend/quizz-game/src/app/login/login.service.spec.ts index c5c88d43a09788a8a372b0122f2672aa4776832c..3d87f029f6c1c2adb2dc217b92e7a72df8b400a6 100644 --- a/Frontend/quizz-game/src/app/login/password.service.spec.ts +++ b/Frontend/quizz-game/src/app/login/login.service.spec.ts @@ -1,13 +1,13 @@ import { TestBed } from '@angular/core/testing'; -import { PasswordService } from './password.service'; +import { LoginService } from './login.service'; describe('PasswordService', () => { - let service: PasswordService; + let service: LoginService; beforeEach(() => { TestBed.configureTestingModule({}); - service = TestBed.inject(PasswordService); + service = TestBed.inject(LoginService); }); it('should be created', () => { diff --git a/Frontend/quizz-game/src/app/login/login.service.ts b/Frontend/quizz-game/src/app/login/login.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..06bf2a25c9e3f6aa4bcf9e4b17e52a9b11e2b7c7 --- /dev/null +++ b/Frontend/quizz-game/src/app/login/login.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@angular/core'; +import * as CryptoJS from 'crypto-js'; + +export enum ErrorLogin { + PassConfirm , + UserNameExist, + UserNotExist , + UserPassword +} +@Injectable({ + providedIn: 'root' +}) +export class LoginService { + private _actualError!: ErrorLogin; + + + get actualError():ErrorLogin{ + return this._actualError + } + + + set actualError(value: ErrorLogin){ + this._actualError=value; + } + constructor() { } + + hashPassword(password: string): string { + const hash = CryptoJS.SHA256(password); + return hash.toString(CryptoJS.enc.Base64); + } +} diff --git a/Frontend/quizz-game/src/app/login/password.service.ts b/Frontend/quizz-game/src/app/login/password.service.ts deleted file mode 100644 index 82ad8c5b6a07707b15e9b909ffc7934fe0382ad0..0000000000000000000000000000000000000000 --- a/Frontend/quizz-game/src/app/login/password.service.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Injectable } from '@angular/core'; -import * as CryptoJS from 'crypto-js'; - -@Injectable({ - providedIn: 'root' -}) -export class PasswordService { - - constructor() { } - - hashPassword(password: string): string { - const hash = CryptoJS.SHA256(password); - return hash.toString(CryptoJS.enc.Base64); - } -} diff --git a/Frontend/quizz-game/src/app/login/sign-in/sign-in.component.html b/Frontend/quizz-game/src/app/login/sign-in/sign-in.component.html index 26a285b53caff33a545179fb83ad651967ea26cf..3f9cea94933979fb12ab78ed0ddc66881f87dc27 100644 --- a/Frontend/quizz-game/src/app/login/sign-in/sign-in.component.html +++ b/Frontend/quizz-game/src/app/login/sign-in/sign-in.component.html @@ -1,3 +1,6 @@ +<app-errorlogin *ngIf="errorOccured"></app-errorlogin> + + <form [formGroup]="formData" enctype="multipart/form-data" (submit)="submitForm($event)" diff --git a/Frontend/quizz-game/src/app/login/sign-in/sign-in.component.ts b/Frontend/quizz-game/src/app/login/sign-in/sign-in.component.ts index dd5d2f1092ea70dc8cf6d0672848c185d4ee7f0c..269933259e17675eb1fb7a83800f9d48205af288 100644 --- a/Frontend/quizz-game/src/app/login/sign-in/sign-in.component.ts +++ b/Frontend/quizz-game/src/app/login/sign-in/sign-in.component.ts @@ -1,7 +1,8 @@ import {Component, OnInit} from '@angular/core'; -import {ActivatedRoute} from "@angular/router"; +import {Router} from "@angular/router"; import {FormControl, FormGroup, Validators} from "@angular/forms"; import {HttpClient} from "@angular/common/http"; +import {ErrorLogin, LoginService} from "../login.service"; @Component({ selector: 'app-sign-in', @@ -10,10 +11,14 @@ import {HttpClient} from "@angular/common/http"; }) export class SignInComponent implements OnInit{ formData!: FormGroup; + errorOccured!: boolean; - constructor(private httpClient: HttpClient) { } + constructor(private httpClient: HttpClient, private loginService: LoginService, private router: Router) { + + } ngOnInit() { + this.errorOccured=false; this.formData = new FormGroup({ username: new FormControl(null, { updateOn: 'change', @@ -28,17 +33,30 @@ export class SignInComponent implements OnInit{ submitForm(event: Event) { event.preventDefault(); + this.errorOccured=false; let passwordPost= { - password: this.formData.value.password + password: this.loginService.hashPassword(this.formData.value.password) } - this.httpClient.post<any>('http://localhost:30992/api/v1/guest/'+this.formData.value.username, passwordPost).subscribe( + let username:string=this.formData.value.username; + this.httpClient.post<any>('http://localhost:30992/api/v1/guest/'+username, passwordPost).subscribe( response => { - console.log(response); // Affiche la réponse du serveur dans la console - // Effectuer une action en fonction de la réponse du serveur ici + if(response.message === "USER_ALLOWED"){ + this.router.navigate(['/'+username+'/manage']); + } + if(response.message === "ADMIN_ALLOWED"){ + this.router.navigate(['/' + username + '/manage']) + } + console.log(response.message); + }, error => { - console.error(error); // Affiche l'erreur dans la console - // Effectuer une action en cas d'erreur ici + this.errorOccured=true; + if(error.error.message === "USER_PASSWORD_FALSE"){ + this.loginService.actualError=ErrorLogin.UserPassword; + } + if(error.error.message === "USER_NOT_FOUND"){ + this.loginService.actualError=ErrorLogin.UserNotExist; + } } ); } diff --git a/Frontend/quizz-game/src/app/login/sign-up/sign-up.component.html b/Frontend/quizz-game/src/app/login/sign-up/sign-up.component.html index d81596c23cd58fec91519eb5f1e138889acd937c..e48ff4e70e27a637dfd43d20dd9dce4d3c771cb0 100644 --- a/Frontend/quizz-game/src/app/login/sign-up/sign-up.component.html +++ b/Frontend/quizz-game/src/app/login/sign-up/sign-up.component.html @@ -1,3 +1,5 @@ +<app-errorlogin *ngIf="errorOccured"></app-errorlogin> + <form [formGroup]="formData" enctype="multipart/form-data" (submit)="submitForm($event)" diff --git a/Frontend/quizz-game/src/app/login/sign-up/sign-up.component.ts b/Frontend/quizz-game/src/app/login/sign-up/sign-up.component.ts index 2e75923155e90a673c5c32bc262ab7792015be6a..8a6a3feb8160c382541fe36a87d8fcd7482eeb46 100644 --- a/Frontend/quizz-game/src/app/login/sign-up/sign-up.component.ts +++ b/Frontend/quizz-game/src/app/login/sign-up/sign-up.component.ts @@ -1,6 +1,7 @@ import {Component, ElementRef, OnInit, ViewChild} from '@angular/core'; import {FormControl, FormGroup, Validators} from "@angular/forms"; import {HttpClient} from "@angular/common/http"; +import {ErrorLogin, LoginService} from "../login.service"; @Component({ selector: 'app-sign-up', @@ -10,10 +11,11 @@ import {HttpClient} from "@angular/common/http"; export class SignUpComponent{ formData!: FormGroup; @ViewChild('passwordConfirmation') passwordConfirmation!: ElementRef - - constructor(private httpClient: HttpClient) { } + errorOccured!: boolean; + constructor(private httpClient: HttpClient, private loginService: LoginService) { } ngOnInit() { + this.errorOccured=false; this.formData = new FormGroup({ username: new FormControl(null, { updateOn: 'change', @@ -39,20 +41,28 @@ export class SignUpComponent{ }); } + + submitForm(event: Event) { event.preventDefault(); + this.errorOccured=false; if(this.formData.value.password !== this.passwordConfirmation.nativeElement.value){ + this.errorOccured=true; + this.loginService.actualError=ErrorLogin.PassConfirm; console.log("mot de passe non identique"); return; } + this.formData.value.password = this.loginService.hashPassword(this.formData.value.password); this.httpClient.post<any>('http://localhost:30992/api/v1/guest/create-account', this.formData.value).subscribe( response => { console.log(response); // Affiche la réponse du serveur dans la console // Effectuer une action en fonction de la réponse du serveur ici }, error => { - console.error(error); // Affiche l'erreur dans la console - // Effectuer une action en cas d'erreur ici + this.errorOccured=true; + if(error.error.message === "USER_EXIST"){ + this.loginService.actualError=ErrorLogin.UserNameExist; + } } ); } diff --git a/Frontend/quizz-game/src/app/manage/manage.component.css b/Frontend/quizz-game/src/app/manage/manage.component.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Frontend/quizz-game/src/app/manage/manage.component.html b/Frontend/quizz-game/src/app/manage/manage.component.html new file mode 100644 index 0000000000000000000000000000000000000000..f923a4f806b9d61181650e949b58b9c8c6418be1 --- /dev/null +++ b/Frontend/quizz-game/src/app/manage/manage.component.html @@ -0,0 +1,292 @@ +<div class="w-1/4 flex h-screen flex-col justify-between border-e bg-white"> + <div class="px-4 py-6"> + <span + class="grid h-10 w-32 place-content-center rounded-lg bg-gray-100 text-xs text-gray-600" + > + Logo + </span> + + <nav aria-label="Main Nav" class="mt-6 flex flex-col space-y-1"> + + <details class="group [&_summary::-webkit-details-marker]:hidden"> + <summary + class="flex cursor-pointer items-center justify-between rounded-lg px-4 py-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700" + > + <div class="flex items-center gap-2"> + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-5 w-5 opacity-75" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + stroke-width="2" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" + /> + </svg> + + <span class="text-sm font-medium"> Gestion d'utilisateurs </span> + </div> + + <span class="shrink-0 transition duration-300 group-open:-rotate-180"> + <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="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> + </span> + </summary> + + <nav aria-label="Users Manage Nav" class="mt-2 flex flex-col px-4"> + <a + href="#" + class="flex items-center gap-2 rounded-lg px-4 py-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700" + > + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-5 w-5 opacity-75" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + stroke-width="2" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" + /> + </svg> + + <span class="text-sm font-medium"> Liste des utilisateurs </span> + </a> + + <a + href="#" + class="flex items-center gap-2 rounded-lg px-4 py-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700" + > + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-5 w-5 opacity-75" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + stroke-width="2" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" + /> + </svg> + + <span class="text-sm font-medium"> Créer un utilisateur </span> + </a> + </nav> + </details> + + <details class="group [&_summary::-webkit-details-marker]:hidden"> + <summary + class="flex cursor-pointer items-center justify-between rounded-lg px-4 py-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700" + > + <div class="flex items-center gap-2"> + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-5 w-5 opacity-75" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + stroke-width="2" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" + /> + </svg> + + <span class="text-sm font-medium"> Gestion des questions </span> + </div> + + <span class="shrink-0 transition duration-300 group-open:-rotate-180"> + <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="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> + </span> + </summary> + + <nav aria-label="Users Manage Nav" class="mt-2 flex flex-col px-4"> + <a + href="#" + class="flex items-center gap-2 rounded-lg px-4 py-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700" + > + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-5 w-5 opacity-75" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + stroke-width="2" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" + /> + </svg> + + <span class="text-sm font-medium"> Liste des questions </span> + </a> + + <a + href="#" + class="flex items-center gap-2 rounded-lg px-4 py-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700" + > + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-5 w-5 opacity-75" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + stroke-width="2" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" + /> + </svg> + + <span class="text-sm font-medium"> Créer une question </span> + </a> + </nav> + </details> + + + <details class="group [&_summary::-webkit-details-marker]:hidden"> + <summary + class="flex cursor-pointer items-center justify-between rounded-lg px-4 py-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700" + > + <div class="flex items-center gap-2"> + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-5 w-5 opacity-75" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + stroke-width="2" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" + /> + </svg> + + <span class="text-sm font-medium"> Account </span> + </div> + + <span class="shrink-0 transition duration-300 group-open:-rotate-180"> + <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="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> + </span> + </summary> + + <nav aria-label="Account Nav" class="mt-2 flex flex-col px-4"> + <a + href="#" + class="flex items-center gap-2 rounded-lg px-4 py-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700" + > + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-5 w-5 opacity-75" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + stroke-width="2" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M10 6H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V8a2 2 0 00-2-2h-5m-4 0V5a2 2 0 114 0v1m-4 0a2 2 0 104 0m-5 8a2 2 0 100-4 2 2 0 000 4zm0 0c1.306 0 2.417.835 2.83 2M9 14a3.001 3.001 0 00-2.83 2M15 11h3m-3 4h2" + /> + </svg> + + <span class="text-sm font-medium"> Details </span> + </a> + + <form action="/logout"> + <button + type="submit" + class="flex w-full items-center gap-2 rounded-lg px-4 py-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700" + > + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-5 w-5 opacity-75" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + stroke-width="2" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" + /> + </svg> + + <span class="text-sm font-medium"> Logout </span> + </button> + </form> + </nav> + </details> + </nav> + </div> + + <div class="sticky inset-x-0 bottom-0 border-t border-gray-100"> + <a href="#" class="flex items-center gap-2 bg-white p-4 hover:bg-gray-50"> + <img + alt="Man" + src="https://images.unsplash.com/photo-1600486913747-55e5470d6f40?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1770&q=80" + class="h-10 w-10 rounded-full object-cover" + /> + + <div> + <p class="text-xs"> + <strong class="block font-medium">Eric Frusciante</strong> + + <span> eric@frusciante.com </span> + </p> + </div> + </a> + </div> +</div> + diff --git a/Frontend/quizz-game/src/app/manage/manage.component.spec.ts b/Frontend/quizz-game/src/app/manage/manage.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..6b6955b648fa16895b0f25e9fe11d614ce89820f --- /dev/null +++ b/Frontend/quizz-game/src/app/manage/manage.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ManageComponent } from './manage.component'; + +describe('ManageComponent', () => { + let component: ManageComponent; + let fixture: ComponentFixture<ManageComponent>; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ManageComponent] + }); + fixture = TestBed.createComponent(ManageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/Frontend/quizz-game/src/app/manage/manage.component.ts b/Frontend/quizz-game/src/app/manage/manage.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..70ae13a0b37b4b600a1e48e6561a272b15bbda5a --- /dev/null +++ b/Frontend/quizz-game/src/app/manage/manage.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-manage', + templateUrl: './manage.component.html', + styleUrls: ['./manage.component.css'] +}) +export class ManageComponent { + +}