diff --git a/FencerJudgeFront/README.md b/FencerJudgeFront/README.md
index c5c9b8d..cf8675c 100644
--- a/FencerJudgeFront/README.md
+++ b/FencerJudgeFront/README.md
@@ -10,7 +10,7 @@ To start a local development server, run:
ng serve
```
-Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
+Once the server is running, open your browser and navigate to `http://localhost/`. The application will automatically reload whenever you modify any of the source files.
## Code scaffolding
diff --git a/FencerJudgeFront/angular.json b/FencerJudgeFront/angular.json
index f49bfa8..3f97b8b 100644
--- a/FencerJudgeFront/angular.json
+++ b/FencerJudgeFront/angular.json
@@ -34,10 +34,13 @@
{
"glob": "**/*",
"input": "public"
- }
+ },
+ "src/assets/"
],
"styles": [
- "src/styles.css"
+ "src/styles.css",
+ "node_modules/bootstrap/dist/css/bootstrap.min.css",
+ "node_modules/bootstrap-icons/font/bootstrap-icons.css"
],
"scripts": []
},
@@ -66,6 +69,9 @@
"defaultConfiguration": "production"
},
"serve": {
+ "options": {
+ "port": 80
+ },
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
@@ -102,5 +108,8 @@
}
}
}
+ },
+ "cli": {
+ "analytics": false
}
}
diff --git a/FencerJudgeFront/package-lock.json b/FencerJudgeFront/package-lock.json
index 9da01e2..00f2a33 100644
--- a/FencerJudgeFront/package-lock.json
+++ b/FencerJudgeFront/package-lock.json
@@ -16,6 +16,9 @@
"@angular/platform-browser": "^19.1.0",
"@angular/platform-browser-dynamic": "^19.1.0",
"@angular/router": "^19.1.0",
+ "boostrap": "^2.0.0",
+ "bootstrap": "^5.3.5",
+ "bootstrap-icons": "^1.11.3",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.15.0"
@@ -4530,6 +4533,17 @@
"node": ">=14"
}
},
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "license": "MIT",
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
@@ -5921,6 +5935,48 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/boostrap": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/boostrap/-/boostrap-2.0.0.tgz",
+ "integrity": "sha512-JEeFMOweKeGXEM9rt95eaVISOkluG9aKcl0jQCETOVH9jynCZxuBZe2oWgcWJpj5wqYWZl625SnW7OgHT2Ineg==",
+ "deprecated": "Package no longer supported. Contact support@npmjs.com for more info.",
+ "license": "ISC"
+ },
+ "node_modules/bootstrap": {
+ "version": "5.3.5",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.5.tgz",
+ "integrity": "sha512-ct1CHKtiobRimyGzmsSldEtM03E8fcEX4Tb3dGXz1V8faRwM50+vfHwTzOxB3IlKO7m+9vTH3s/3C6T2EAPeTA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ }
+ ],
+ "license": "MIT",
+ "peerDependencies": {
+ "@popperjs/core": "^2.11.8"
+ }
+ },
+ "node_modules/bootstrap-icons": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz",
+ "integrity": "sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
diff --git a/FencerJudgeFront/package.json b/FencerJudgeFront/package.json
index 757656f..aecac98 100644
--- a/FencerJudgeFront/package.json
+++ b/FencerJudgeFront/package.json
@@ -18,6 +18,9 @@
"@angular/platform-browser": "^19.1.0",
"@angular/platform-browser-dynamic": "^19.1.0",
"@angular/router": "^19.1.0",
+ "boostrap": "^2.0.0",
+ "bootstrap": "^5.3.5",
+ "bootstrap-icons": "^1.11.3",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.15.0"
diff --git a/FencerJudgeFront/public/favicon.ico b/FencerJudgeFront/public/favicon.ico
index 57614f9..7684fbd 100644
Binary files a/FencerJudgeFront/public/favicon.ico and b/FencerJudgeFront/public/favicon.ico differ
diff --git a/FencerJudgeFront/src/app/app-routing.module.ts b/FencerJudgeFront/src/app/app-routing.module.ts
index 0297262..b958478 100644
--- a/FencerJudgeFront/src/app/app-routing.module.ts
+++ b/FencerJudgeFront/src/app/app-routing.module.ts
@@ -1,10 +1,29 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
-const routes: Routes = [];
+import { authGuard } from '@guards/auth.guard';
+
+import { LoginComponent } from './components/essentials/login/login.component';
+import { LogoutComponent } from './components/essentials/logout/logout.component';
+
+import { HomeComponent } from './components/home/home.component';
+
+import { MatchesComponent } from './components/match/matches/matches.component';
+import { MatchesIdComponent } from './components/match/matches-id/matches-id.component';
+
+const routes: Routes = [
+ { path: 'login', component: LoginComponent },
+ { path: 'logout', component: LogoutComponent },
+
+ { path: '', component: HomeComponent },
+ { path: 'home', component: HomeComponent },
+
+ { path: 'matches', component: MatchesComponent },
+ { path: 'matches/:id', component: MatchesIdComponent },
+];
@NgModule({
imports: [RouterModule.forRoot(routes)],
- exports: [RouterModule]
+ exports: [RouterModule],
})
-export class AppRoutingModule { }
+export class AppRoutingModule {}
diff --git a/FencerJudgeFront/src/app/app.component.html b/FencerJudgeFront/src/app/app.component.html
index 36093e1..a37d5f5 100644
--- a/FencerJudgeFront/src/app/app.component.html
+++ b/FencerJudgeFront/src/app/app.component.html
@@ -1,336 +1,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Hello, {{ title }}
-
Congratulations! Your app is running. 🎉
-
-
-
-
- @for (item of [
- { title: 'Explore the Docs', link: 'https://angular.dev' },
- { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' },
- { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' },
- { title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' },
- { title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' },
- ]; track item.title) {
-
- {{ item.title }}
-
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/FencerJudgeFront/src/app/app.component.ts b/FencerJudgeFront/src/app/app.component.ts
index edbb159..c713d57 100644
--- a/FencerJudgeFront/src/app/app.component.ts
+++ b/FencerJudgeFront/src/app/app.component.ts
@@ -4,7 +4,7 @@ import { Component } from '@angular/core';
selector: 'app-root',
templateUrl: './app.component.html',
standalone: false,
- styleUrl: './app.component.css'
+ styleUrl: './app.component.css',
})
export class AppComponent {
title = 'FencerJudgeFront';
diff --git a/FencerJudgeFront/src/app/app.module.ts b/FencerJudgeFront/src/app/app.module.ts
index b1c6c96..e17ffe8 100644
--- a/FencerJudgeFront/src/app/app.module.ts
+++ b/FencerJudgeFront/src/app/app.module.ts
@@ -1,18 +1,30 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
+import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
+import { HeaderComponent } from './components/essentials/header/header.component';
+import { FooterComponent } from './components/essentials/footer/footer.component';
+import { HomeComponent } from './components/home/home.component';
+import { LoginComponent } from './components/essentials/login/login.component';
+import { LogoutComponent } from './components/essentials/logout/logout.component';
+import { MatchesComponent } from './components/match/matches/matches.component';
+import { MatchesIdComponent } from './components/match/matches-id/matches-id.component';
@NgModule({
declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- AppRoutingModule
+ AppComponent,
+ HeaderComponent,
+ FooterComponent,
+ HomeComponent,
+ LoginComponent,
+ LogoutComponent,
+ MatchesComponent,
+ MatchesIdComponent,
],
+ imports: [BrowserModule, AppRoutingModule, FormsModule],
providers: [],
- bootstrap: [AppComponent]
+ bootstrap: [AppComponent],
})
-export class AppModule { }
+export class AppModule {}
diff --git a/FencerJudgeFront/src/app/components/essentials/footer/footer.component.css b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.css
new file mode 100644
index 0000000..a76370e
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.css
@@ -0,0 +1,21 @@
+
+.footer-gris {
+ background-color: #2c2c2c; /* Gris foncé personnalisé */
+}
+
+.flag-bar {
+ height: 6px; /* épaisseur du trait */
+ width: 100%; /* toute la largeur */
+ background: linear-gradient(
+ to right,
+ #0055a4 0%, /* bleu */
+ #0055a4 33.33%, /* 1/3 */
+ #fff 33.33%, /* blanc */
+ #fff 66.66%, /* 2/3 */
+ #ef4135 66.66%, /* rouge */
+ #ef4135 100%
+ );
+ margin-bottom: 8px;
+ border-radius: 3px; /* optionnel, pour arrondir les bords */
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+}
\ No newline at end of file
diff --git a/FencerJudgeFront/src/app/components/essentials/footer/footer.component.html b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.html
new file mode 100644
index 0000000..01eca56
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.html
@@ -0,0 +1,59 @@
+
diff --git a/FencerJudgeFront/src/app/components/essentials/footer/footer.component.spec.ts b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.spec.ts
new file mode 100644
index 0000000..aa27d1c
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { FooterComponent } from './footer.component';
+
+describe('FooterComponent', () => {
+ let component: FooterComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [FooterComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(FooterComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/components/essentials/footer/footer.component.ts b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.ts
new file mode 100644
index 0000000..d8f2f2c
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/footer/footer.component.ts
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-footer',
+ standalone: false,
+ templateUrl: './footer.component.html',
+ styleUrl: './footer.component.css'
+})
+export class FooterComponent {
+
+}
diff --git a/FencerJudgeFront/src/app/components/essentials/header/header.component.css b/FencerJudgeFront/src/app/components/essentials/header/header.component.css
new file mode 100644
index 0000000..9df8f3d
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/header/header.component.css
@@ -0,0 +1,25 @@
+.navbar {
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+}
+
+.navbar-brand {
+ font-weight: 700;
+ font-size: 1.4rem;
+ display: flex;
+ align-items: center;
+}
+
+.navbar-brand img {
+ height: 30px;
+ margin-right: 0.5rem;
+}
+
+.nav-link {
+ transition: color 0.3s ease;
+}
+
+.nav-link:hover,
+.active-link {
+ color: #ffcc00 !important;
+ font-weight: 600;
+}
diff --git a/FencerJudgeFront/src/app/components/essentials/header/header.component.html b/FencerJudgeFront/src/app/components/essentials/header/header.component.html
new file mode 100644
index 0000000..d0e7a6f
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/header/header.component.html
@@ -0,0 +1,43 @@
+
+
diff --git a/FencerJudgeFront/src/app/components/essentials/header/header.component.spec.ts b/FencerJudgeFront/src/app/components/essentials/header/header.component.spec.ts
new file mode 100644
index 0000000..63f2a45
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/header/header.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HeaderComponent } from './header.component';
+
+describe('HeaderComponent', () => {
+ let component: HeaderComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [HeaderComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(HeaderComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/components/essentials/header/header.component.ts b/FencerJudgeFront/src/app/components/essentials/header/header.component.ts
new file mode 100644
index 0000000..6b0a735
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/header/header.component.ts
@@ -0,0 +1,25 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+import { AuthService } from '@services/auth/auth.service';
+
+@Component({
+ selector: 'app-header',
+ standalone: false,
+ templateUrl: './header.component.html',
+ styleUrl: './header.component.css',
+})
+export class HeaderComponent {
+ constructor(private router: Router, public authService: AuthService) {}
+
+ isHomeActive(): boolean {
+ return this.router.url === '/' || this.router.url === '/home';
+ }
+
+ isHomeActiveBool(): boolean {
+ if (this.router.url != '/home') {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/FencerJudgeFront/src/app/components/essentials/login/login.component.css b/FencerJudgeFront/src/app/components/essentials/login/login.component.css
new file mode 100644
index 0000000..2a0292b
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/login/login.component.css
@@ -0,0 +1,124 @@
+.login-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 25vh;
+ padding: 2rem;
+}
+
+.login-card {
+ background-color: #fff;
+ border-radius: 12px;
+ overflow: hidden;
+ width: 500px;
+ box-shadow: 0 12px 24px rgba(0, 0, 0, 0.25);
+ color: #333;
+}
+
+.login-header-img {
+ position: absolute;
+ height: inherit;
+ width: 100%;
+ background-color: rgba(0, 0, 0, 0.25);
+ top: 0;
+ left: 0;
+}
+
+.login-header {
+ background: url("https://www.lejdd.fr/lmnr/var/jdd/public/media/image/2022/07/19/12/escrime-comment-les-francais-apprivoisent-leurs-armes.jpg?VersionId=Mw31AogdDUwVLuCaVdxMozm9kito7TTP")
+ no-repeat center/cover;
+ position: relative;
+ padding: 4rem 1rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 300px;
+ color: white;
+}
+
+.login-header::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.3); /* voile sombre */
+ backdrop-filter: blur(2px); /* effet de flou */
+ z-index: 1;
+ border-radius: 0.5rem;
+}
+
+.login-header h1 {
+ position: relative;
+ z-index: 2;
+ padding: 2rem;
+}
+
+.login-header h2 {
+ margin-bottom: 0.5rem;
+}
+
+.login-header p {
+ font-size: 0.85rem;
+ line-height: 1.4;
+}
+
+.login-form {
+ padding: 1.5rem;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.login-form h3 {
+ text-align: center;
+ color: #235d4f;
+ margin-bottom: 1rem;
+}
+
+.input-group {
+ display: flex;
+ align-items: center;
+ background-color: #235d4f;
+ border-radius: 30px;
+ padding: 0.5rem 1rem;
+}
+
+.input-group .icon {
+ color: white;
+ margin-right: 0.5rem;
+}
+
+.input-group input {
+ border: none;
+ background: none;
+ color: white;
+ width: 100%;
+ font-size: 1rem;
+ outline: none;
+}
+
+.options {
+ display: flex;
+ justify-content: space-between;
+ font-size: 0.85rem;
+ color: #555;
+}
+
+.options a {
+ color: #235d4f;
+ text-decoration: none;
+}
+
+.login-btn {
+ background-color: #235d4f;
+ color: white;
+ padding: 0.6rem;
+ border: none;
+ border-radius: 6px;
+ font-size: 1rem;
+ cursor: pointer;
+ transition: background-color 0.3s;
+}
+
+.login-btn:hover {
+ background-color: #1b4b3d;
+}
diff --git a/FencerJudgeFront/src/app/components/essentials/login/login.component.html b/FencerJudgeFront/src/app/components/essentials/login/login.component.html
new file mode 100644
index 0000000..980a230
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/login/login.component.html
@@ -0,0 +1,32 @@
+
diff --git a/FencerJudgeFront/src/app/components/essentials/login/login.component.spec.ts b/FencerJudgeFront/src/app/components/essentials/login/login.component.spec.ts
new file mode 100644
index 0000000..4adbc3d
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/login/login.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LoginComponent } from './login.component';
+
+describe('LoginComponent', () => {
+ let component: LoginComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [LoginComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(LoginComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/components/essentials/login/login.component.ts b/FencerJudgeFront/src/app/components/essentials/login/login.component.ts
new file mode 100644
index 0000000..f7b137a
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/login/login.component.ts
@@ -0,0 +1,25 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+import { AuthService } from '@services/auth/auth.service';
+
+@Component({
+ selector: 'app-login',
+ standalone: false,
+ templateUrl: './login.component.html',
+ styleUrl: './login.component.css',
+})
+export class LoginComponent {
+ email = '';
+ password = '';
+ errorMessage = '';
+
+ constructor(private authService: AuthService, private router: Router) {}
+
+ onSubmit() {
+ if (this.authService.login(this.email, this.password)) {
+ this.router.navigate(['/']);
+ } else {
+ this.errorMessage = 'Identifiants incorrects';
+ }
+ }
+}
diff --git a/FencerJudgeFront/src/app/components/essentials/logout/logout.component.css b/FencerJudgeFront/src/app/components/essentials/logout/logout.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/FencerJudgeFront/src/app/components/essentials/logout/logout.component.html b/FencerJudgeFront/src/app/components/essentials/logout/logout.component.html
new file mode 100644
index 0000000..c6ae40e
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/logout/logout.component.html
@@ -0,0 +1 @@
+logout works!
diff --git a/FencerJudgeFront/src/app/components/essentials/logout/logout.component.spec.ts b/FencerJudgeFront/src/app/components/essentials/logout/logout.component.spec.ts
new file mode 100644
index 0000000..074294b
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/logout/logout.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LogoutComponent } from './logout.component';
+
+describe('LogoutComponent', () => {
+ let component: LogoutComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [LogoutComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(LogoutComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/components/essentials/logout/logout.component.ts b/FencerJudgeFront/src/app/components/essentials/logout/logout.component.ts
new file mode 100644
index 0000000..7945a95
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/essentials/logout/logout.component.ts
@@ -0,0 +1,16 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+import { AuthService } from '@services/auth/auth.service';
+
+@Component({
+ selector: 'app-logout',
+ standalone: false,
+ templateUrl: './logout.component.html',
+ styleUrl: './logout.component.css',
+})
+export class LogoutComponent {
+ constructor(private authService: AuthService, private router: Router) {
+ this.authService.logout();
+ this.router.navigate(['/']); // Redirection après déconnexion
+ }
+}
diff --git a/FencerJudgeFront/src/app/components/home/home.component.css b/FencerJudgeFront/src/app/components/home/home.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/FencerJudgeFront/src/app/components/home/home.component.html b/FencerJudgeFront/src/app/components/home/home.component.html
new file mode 100644
index 0000000..a1ac75f
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/home/home.component.html
@@ -0,0 +1 @@
+HELLO !
diff --git a/FencerJudgeFront/src/app/components/home/home.component.spec.ts b/FencerJudgeFront/src/app/components/home/home.component.spec.ts
new file mode 100644
index 0000000..545a43d
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/home/home.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HomeComponent } from './home.component';
+
+describe('HomeComponent', () => {
+ let component: HomeComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [HomeComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(HomeComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/components/home/home.component.ts b/FencerJudgeFront/src/app/components/home/home.component.ts
new file mode 100644
index 0000000..67af68d
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/home/home.component.ts
@@ -0,0 +1,9 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-home',
+ standalone: false,
+ templateUrl: './home.component.html',
+ styleUrl: './home.component.css',
+})
+export class HomeComponent {}
diff --git a/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.css b/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.css
new file mode 100644
index 0000000..f517d5c
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.css
@@ -0,0 +1,3 @@
+.card {
+ border-left-width: 0.5rem !important;
+}
diff --git a/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.html b/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.html
new file mode 100644
index 0000000..3e82262
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.html
@@ -0,0 +1,94 @@
+
+
Détail du Match
+
+
+
+
+
+ {{ match.city }}, {{ match.country }}
+
+ {{ match.date | date : "fullDate" }} -
+ {{ match.date | date : "shortTime" }}
+
+ {{ match.weapon }}
+
+
+
+
+ {{ player1.firstName }} {{ player1.name }}
+ {{ player1.club }}
+
+
+
+
+
+ {{ match.score1 }}
+
+ vs
+
+ {{ match.score2 }}
+
+
+
+
+ {{ match.score1 }}
+ vs
+ {{ match.score2 }}
+
+
+
+
+ {{ player2.firstName }} {{ player2.name }}
+ {{ player2.club }}
+
+
+
+
+
+ {{ getMatchStateLabel(match.state) }}
+
+
+
+
+
Arbitre
+
+
+ {{ referee.firstName }} {{ referee.name }}
+
+
+ Niveau : {{ getRefereeLevelLabel(referee.level) }}
+
+
+
+
+
+
+
+
+
+
diff --git a/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.spec.ts b/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.spec.ts
new file mode 100644
index 0000000..b09ff2d
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MatchesIdComponent } from './matches-id.component';
+
+describe('MatchesIdComponent', () => {
+ let component: MatchesIdComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [MatchesIdComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(MatchesIdComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.ts b/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.ts
new file mode 100644
index 0000000..65d932b
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/match/matches-id/matches-id.component.ts
@@ -0,0 +1,141 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
+import { AuthService } from '@services/auth/auth.service';
+
+import { MatchesService } from '@services/matches/matches.service';
+import { MatchState, Matches } from '@interfaces/matches';
+import { PlayerService } from '@services/player/player.service';
+import { Player } from '@interfaces/player';
+import { RefereeService } from '@services/referee/referee.service';
+import { Referee, RefereeLevel } from '@interfaces/referee';
+
+@Component({
+ selector: 'app-matches-id',
+ standalone: false,
+ templateUrl: './matches-id.component.html',
+ styleUrl: './matches-id.component.css',
+})
+export class MatchesIdComponent implements OnInit {
+ match: Matches | undefined;
+ player1: Player | undefined;
+ player2: Player | undefined;
+ referee: Referee | undefined;
+
+ constructor(
+ private route: ActivatedRoute,
+ private matchService: MatchesService,
+ private playerService: PlayerService,
+ private refereeService: RefereeService,
+ public authService: AuthService
+ ) {}
+
+ ngOnInit(): void {
+ const id = Number(this.route.snapshot.paramMap.get('id'));
+ this.matchService.getMatchById(id).subscribe((match) => {
+ if (match) {
+ this.match = match;
+
+ this.playerService
+ .getPlayerById(match.player1ID)
+ .subscribe((p1) => (this.player1 = p1!));
+ this.playerService
+ .getPlayerById(match.player2ID)
+ .subscribe((p2) => (this.player2 = p2!));
+
+ this.refereeService
+ .getRefereeById(match.refereeID)
+ .subscribe((ref) => (this.referee = ref!));
+ }
+ });
+ }
+
+ saveScores(): void {
+ if (this.match) {
+ this.matchService.updateMatch(this.match.id, {
+ score1: this.match.score1,
+ score2: this.match.score2,
+ });
+ }
+ }
+
+ getMatchStateLabel(state: MatchState): string {
+ switch (state) {
+ case MatchState.NOT_STARTED:
+ return 'Ă€ venir';
+ case MatchState.ONGOING:
+ return 'En cours';
+ case MatchState.OVER:
+ return 'Terminé';
+ default:
+ return 'Inconnu';
+ }
+ }
+
+ getMatchStateColor(state: MatchState): string {
+ switch (state) {
+ case MatchState.NOT_STARTED:
+ return 'secondary';
+ case MatchState.ONGOING:
+ return 'warning';
+ case MatchState.OVER:
+ return 'success';
+ default:
+ return 'light';
+ }
+ }
+
+ getRefereeLevelLabel(level: RefereeLevel): string {
+ switch (level) {
+ case RefereeLevel.NATIONAL:
+ return 'National';
+ case RefereeLevel.REGIONAL:
+ return 'Régional';
+ case RefereeLevel.DEPARTMENTAL:
+ return 'Départemental';
+ default:
+ return 'Inconnu';
+ }
+ }
+
+ updateScores(): void {
+ if (this.match) {
+ this.matchService.updateMatch(this.match.id, {
+ score1: this.match.score1,
+ score2: this.match.score2,
+ });
+ }
+ }
+
+ incrementScore(player: 1 | 2): void {
+ if (!this.match) return;
+
+ // Incrémente le score du joueur
+ if (player === 1) {
+ this.match.score1 += 1;
+ } else {
+ this.match.score2 += 1;
+ }
+
+ // Change l'état en fonction des scores
+ if (
+ this.match.score1 === 1 &&
+ this.match.score2 === 0 &&
+ this.match.state === MatchState.NOT_STARTED
+ ) {
+ this.match.state = MatchState.ONGOING; // passage à l'état 1 (en cours)
+ } else if (
+ this.match.score2 === 1 &&
+ this.match.score1 === 0 &&
+ this.match.state === MatchState.NOT_STARTED
+ ) {
+ this.match.state = MatchState.ONGOING;
+ }
+
+ // Si l'un des scores arrive à 15, on considère le match terminé
+ if (this.match.score1 >= 15 || this.match.score2 >= 15) {
+ this.match.state = MatchState.OVER; // passage à l'état 2 (terminé)
+ }
+
+ this.updateScores();
+ }
+}
diff --git a/FencerJudgeFront/src/app/components/match/matches/matches.component.css b/FencerJudgeFront/src/app/components/match/matches/matches.component.css
new file mode 100644
index 0000000..2fa4ff6
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/match/matches/matches.component.css
@@ -0,0 +1,8 @@
+.border-start-5 {
+ border-left: 5px solid #ccc;
+}
+
+.card:hover {
+ transform: translateY(-2px);
+ transition: 0.2s ease-in-out;
+}
diff --git a/FencerJudgeFront/src/app/components/match/matches/matches.component.html b/FencerJudgeFront/src/app/components/match/matches/matches.component.html
new file mode 100644
index 0000000..e7036ad
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/match/matches/matches.component.html
@@ -0,0 +1,53 @@
+
+
Liste des Matchs
+
+
+
+
+
+
+
+ {{ match.city }} —
+ {{
+ match.date | date : "longDate"
+ }}
+
+ {{ match.weapon }}
+
+
+
+
+ {{ getPlayerName(match.player1ID) }}
+ {{ match.score1 }}
+
+
+
vs
+
+
+ {{ getPlayerName(match.player2ID) }}
+ {{ match.score2 }}
+
+
+
+
+
+ {{ getMatchStatusLabel(match.state) }}
+
+
+
+
+
+
+
diff --git a/FencerJudgeFront/src/app/components/match/matches/matches.component.spec.ts b/FencerJudgeFront/src/app/components/match/matches/matches.component.spec.ts
new file mode 100644
index 0000000..7f7c3e1
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/match/matches/matches.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MatchesComponent } from './matches.component';
+
+describe('MatchesComponent', () => {
+ let component: MatchesComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [MatchesComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(MatchesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/components/match/matches/matches.component.ts b/FencerJudgeFront/src/app/components/match/matches/matches.component.ts
new file mode 100644
index 0000000..a1cf3dc
--- /dev/null
+++ b/FencerJudgeFront/src/app/components/match/matches/matches.component.ts
@@ -0,0 +1,72 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { MatchesService } from '@services/matches/matches.service';
+import { Matches, MatchState } from '@interfaces/matches';
+
+import { PlayerService } from '@services/player/player.service';
+import { Player } from '@interfaces/player';
+
+@Component({
+ selector: 'app-matches',
+ standalone: false,
+ templateUrl: './matches.component.html',
+ styleUrl: './matches.component.css',
+})
+export class MatchesComponent {
+ matches: Matches[] = [];
+ playersMap: Map = new Map();
+ MatchState = MatchState;
+
+ constructor(
+ private matchesService: MatchesService,
+ private playerService: PlayerService,
+ private router: Router
+ ) {}
+
+ ngOnInit(): void {
+ this.playerService.getPlayers().subscribe((players) => {
+ // construire la map ID -> joueur
+ players.forEach((player) => this.playersMap.set(player.id, player));
+ });
+
+ this.matchesService.getMatches().subscribe((data) => {
+ this.matches = data;
+ });
+ }
+
+ getPlayerName(id: number): string {
+ const player = this.playersMap.get(id);
+ return player ? `${player.firstName} ${player.name}` : 'Joueur inconnu';
+ }
+
+ getMatchBorderColor(state: MatchState): string {
+ switch (state) {
+ case MatchState.NOT_STARTED:
+ return 'border-secondary';
+ case MatchState.ONGOING:
+ return 'border-warning';
+ case MatchState.OVER:
+ return 'border-success';
+ default:
+ return 'border-light';
+ }
+ }
+
+ getMatchStatusLabel(state: MatchState): string {
+ switch (state) {
+ case MatchState.NOT_STARTED:
+ return 'Ă€ venir';
+ case MatchState.ONGOING:
+ return 'En cours';
+ case MatchState.OVER:
+ return 'Terminé';
+ default:
+ return 'Inconnu';
+ }
+ }
+
+ goToMatchDetail(matchId: number): void {
+ this.router.navigate(['/matches', matchId]);
+ }
+}
diff --git a/FencerJudgeFront/src/app/guards/auth.guard.spec.ts b/FencerJudgeFront/src/app/guards/auth.guard.spec.ts
new file mode 100644
index 0000000..4ae275e
--- /dev/null
+++ b/FencerJudgeFront/src/app/guards/auth.guard.spec.ts
@@ -0,0 +1,17 @@
+import { TestBed } from '@angular/core/testing';
+import { CanActivateFn } from '@angular/router';
+
+import { authGuard } from './auth.guard';
+
+describe('authGuard', () => {
+ const executeGuard: CanActivateFn = (...guardParameters) =>
+ TestBed.runInInjectionContext(() => authGuard(...guardParameters));
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ });
+
+ it('should be created', () => {
+ expect(executeGuard).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/guards/auth.guard.ts b/FencerJudgeFront/src/app/guards/auth.guard.ts
new file mode 100644
index 0000000..2da4546
--- /dev/null
+++ b/FencerJudgeFront/src/app/guards/auth.guard.ts
@@ -0,0 +1,15 @@
+import { inject } from '@angular/core';
+import { CanActivateFn, Router } from '@angular/router';
+import { AuthService } from '@services/auth/auth.service';
+
+export const authGuard: CanActivateFn = (route, state) => {
+ const authService = inject(AuthService);
+ const router = inject(Router);
+
+ if (!authService.isAuthenticated()) {
+ router.navigate(['/login']);
+ return false;
+ }
+
+ return true;
+};
diff --git a/FencerJudgeFront/src/app/interfaces/matches.ts b/FencerJudgeFront/src/app/interfaces/matches.ts
new file mode 100644
index 0000000..26c6767
--- /dev/null
+++ b/FencerJudgeFront/src/app/interfaces/matches.ts
@@ -0,0 +1,19 @@
+export enum MatchState {
+ ONGOING = 1,
+ OVER = 2,
+ NOT_STARTED = 3,
+}
+
+export interface Matches {
+ id: number;
+ refereeID: number;
+ player1ID: number;
+ score1: number;
+ player2ID: number;
+ score2: number;
+ country: String;
+ city: String;
+ weapon: String;
+ date: Date;
+ state: MatchState;
+}
diff --git a/FencerJudgeFront/src/app/interfaces/models/user.model.ts b/FencerJudgeFront/src/app/interfaces/models/user.model.ts
new file mode 100644
index 0000000..954ae9a
--- /dev/null
+++ b/FencerJudgeFront/src/app/interfaces/models/user.model.ts
@@ -0,0 +1,5 @@
+export interface UserModel {
+ id: number;
+ name: string;
+ firstName: string;
+}
diff --git a/FencerJudgeFront/src/app/interfaces/player.ts b/FencerJudgeFront/src/app/interfaces/player.ts
new file mode 100644
index 0000000..6f39558
--- /dev/null
+++ b/FencerJudgeFront/src/app/interfaces/player.ts
@@ -0,0 +1,5 @@
+import { UserModel } from './models/user.model';
+
+export interface Player extends UserModel {
+ club: string;
+}
diff --git a/FencerJudgeFront/src/app/interfaces/referee.ts b/FencerJudgeFront/src/app/interfaces/referee.ts
new file mode 100644
index 0000000..3b4f0c1
--- /dev/null
+++ b/FencerJudgeFront/src/app/interfaces/referee.ts
@@ -0,0 +1,12 @@
+import { UserModel } from './models/user.model';
+
+export enum RefereeLevel {
+ DEPARTMENTAL = 0,
+ REGIONAL = 1,
+ NATIONAL = 2,
+ INTERNATIONAL = 3,
+}
+
+export interface Referee extends UserModel {
+ level: RefereeLevel;
+}
diff --git a/FencerJudgeFront/src/app/services/auth/auth.service.spec.ts b/FencerJudgeFront/src/app/services/auth/auth.service.spec.ts
new file mode 100644
index 0000000..f1251ca
--- /dev/null
+++ b/FencerJudgeFront/src/app/services/auth/auth.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { AuthService } from './auth.service';
+
+describe('AuthService', () => {
+ let service: AuthService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(AuthService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/services/auth/auth.service.ts b/FencerJudgeFront/src/app/services/auth/auth.service.ts
new file mode 100644
index 0000000..522d786
--- /dev/null
+++ b/FencerJudgeFront/src/app/services/auth/auth.service.ts
@@ -0,0 +1,35 @@
+import { Injectable } from '@angular/core';
+import { Router } from '@angular/router';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class AuthService {
+ private isLoggedIn = false;
+ private readonly hardcodedUser = {
+ email: 'user@test.com',
+ password: 'password123',
+ };
+
+ constructor(private router: Router) {}
+
+ login(email: string, password: string): boolean {
+ if (
+ email === this.hardcodedUser.email &&
+ password === this.hardcodedUser.password
+ ) {
+ this.isLoggedIn = true;
+ return true;
+ }
+ return false;
+ }
+
+ logout(): void {
+ this.isLoggedIn = false;
+ this.router.navigate(['/login']);
+ }
+
+ isAuthenticated(): boolean {
+ return this.isLoggedIn;
+ }
+}
diff --git a/FencerJudgeFront/src/app/services/matches/matches.service.spec.ts b/FencerJudgeFront/src/app/services/matches/matches.service.spec.ts
new file mode 100644
index 0000000..0e9bf15
--- /dev/null
+++ b/FencerJudgeFront/src/app/services/matches/matches.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { MatchesService } from './matches.service';
+
+describe('MatchesService', () => {
+ let service: MatchesService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(MatchesService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/services/matches/matches.service.ts b/FencerJudgeFront/src/app/services/matches/matches.service.ts
new file mode 100644
index 0000000..fef45dd
--- /dev/null
+++ b/FencerJudgeFront/src/app/services/matches/matches.service.ts
@@ -0,0 +1,81 @@
+import { Injectable } from '@angular/core';
+import { Observable, of } from 'rxjs';
+import { Matches, MatchState } from '@interfaces/matches';
+
+@Injectable({ providedIn: 'root' })
+export class MatchesService {
+ private matches: Matches[] = [
+ {
+ id: 1,
+ refereeID: 10,
+ player1ID: 1,
+ score1: 15,
+ player2ID: 2,
+ score2: 13,
+ country: 'France',
+ city: 'Paris',
+ weapon: 'Fleuret',
+ date: new Date('2025-06-10T14:00:00'),
+ state: MatchState.OVER,
+ },
+ {
+ id: 2,
+ refereeID: 11,
+ player1ID: 3,
+ score1: 5,
+ player2ID: 4,
+ score2: 7,
+ country: 'France',
+ city: 'Lyon',
+ weapon: 'Épée',
+ date: new Date('2025-06-15T10:00:00'),
+ state: MatchState.ONGOING,
+ },
+ {
+ id: 3,
+ refereeID: 12,
+ player1ID: 5,
+ score1: 0,
+ player2ID: 6,
+ score2: 0,
+ country: 'Belgique',
+ city: 'Bruxelles',
+ weapon: 'Sabre',
+ date: new Date('2025-06-20T16:30:00'),
+ state: MatchState.NOT_STARTED,
+ },
+ ];
+
+ constructor() {
+ console.log('[MatchesService] Initial matches loaded:', this.matches);
+ }
+
+ getMatches(): Observable {
+ console.log('[MatchesService] Fetching all matches');
+ return of(this.matches);
+ }
+
+ getMatchById(id: number): Observable {
+ const match = this.matches.find((m) => m.id === id);
+ console.log(`[MatchesService] Fetching match ID: ${id}`, match);
+ return of(match);
+ }
+
+ // Préparation future pour WebSocket
+ connectToMatchUpdatesWebSocket(): void {
+ console.log(
+ '[MatchesService] WebSocket connection placeholder initialized'
+ );
+ // ici tu pourrais plus tard faire : this.socket = new WebSocket('ws://...') etc.
+ }
+
+ updateMatch(id: number, updatedData: Partial): void {
+ const match = this.matches.find((m) => m.id === id);
+ if (match) {
+ Object.assign(match, updatedData);
+ console.log(`[MatchesService] Match ${id} mis Ă jour :`, match);
+ } else {
+ console.warn(`[MatchesService] Match ${id} introuvable`);
+ }
+ }
+}
diff --git a/FencerJudgeFront/src/app/services/player/player.service.spec.ts b/FencerJudgeFront/src/app/services/player/player.service.spec.ts
new file mode 100644
index 0000000..5355445
--- /dev/null
+++ b/FencerJudgeFront/src/app/services/player/player.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { PlayerService } from './player.service';
+
+describe('PlayerService', () => {
+ let service: PlayerService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(PlayerService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/services/player/player.service.ts b/FencerJudgeFront/src/app/services/player/player.service.ts
new file mode 100644
index 0000000..53d4350
--- /dev/null
+++ b/FencerJudgeFront/src/app/services/player/player.service.ts
@@ -0,0 +1,30 @@
+import { Injectable } from '@angular/core';
+import { Observable, of } from 'rxjs';
+import { Player } from '@interfaces/player';
+
+@Injectable({ providedIn: 'root' })
+export class PlayerService {
+ private players: Player[] = [
+ { id: 1, name: 'Martin', firstName: 'Alex', club: 'Lille Escrime' },
+ { id: 2, name: 'Nguyen', firstName: 'Sophie', club: 'Paris Epée' },
+ { id: 3, name: 'Klein', firstName: 'Thomas', club: 'Strasbourg Sabre' },
+ { id: 4, name: 'Leclerc', firstName: 'Lucie', club: 'Nice Fleuret' },
+ { id: 5, name: 'Dubois', firstName: 'Hugo', club: 'Lyon Epée' },
+ { id: 6, name: 'Girard', firstName: 'Manon', club: 'Marseille Club' },
+ ];
+
+ constructor() {
+ console.log('[PlayerService] Initial players loaded:', this.players);
+ }
+
+ getPlayers(): Observable {
+ console.log('[PlayerService] Fetching all players');
+ return of(this.players);
+ }
+
+ getPlayerById(id: number): Observable {
+ const player = this.players.find((p) => p.id === id);
+ console.log(`[PlayerService] Fetching player ID: ${id}`, player);
+ return of(player);
+ }
+}
diff --git a/FencerJudgeFront/src/app/services/referee/referee.service.spec.ts b/FencerJudgeFront/src/app/services/referee/referee.service.spec.ts
new file mode 100644
index 0000000..b0f470c
--- /dev/null
+++ b/FencerJudgeFront/src/app/services/referee/referee.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { RefereeService } from './referee.service';
+
+describe('RefereeService', () => {
+ let service: RefereeService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(RefereeService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/FencerJudgeFront/src/app/services/referee/referee.service.ts b/FencerJudgeFront/src/app/services/referee/referee.service.ts
new file mode 100644
index 0000000..6963230
--- /dev/null
+++ b/FencerJudgeFront/src/app/services/referee/referee.service.ts
@@ -0,0 +1,42 @@
+import { Injectable } from '@angular/core';
+import { Observable, of } from 'rxjs';
+import { Referee, RefereeLevel } from '@interfaces/referee';
+
+@Injectable({ providedIn: 'root' })
+export class RefereeService {
+ private referees: Referee[] = [
+ {
+ id: 10,
+ name: 'Durand',
+ firstName: 'Pierre',
+ level: RefereeLevel.NATIONAL,
+ },
+ {
+ id: 11,
+ name: 'Lemoine',
+ firstName: 'Anna',
+ level: RefereeLevel.REGIONAL,
+ },
+ {
+ id: 12,
+ name: 'Morel',
+ firstName: 'Lucas',
+ level: RefereeLevel.DEPARTMENTAL,
+ },
+ ];
+
+ constructor() {
+ console.log('[RefereeService] Initial referees loaded:', this.referees);
+ }
+
+ getReferees(): Observable {
+ console.log('[RefereeService] Fetching all referees');
+ return of(this.referees);
+ }
+
+ getRefereeById(id: number): Observable {
+ const ref = this.referees.find((r) => r.id === id);
+ console.log(`[RefereeService] Fetching referee ID: ${id}`, ref);
+ return of(ref);
+ }
+}
diff --git a/FencerJudgeFront/src/assets/Logo/favicon.ico b/FencerJudgeFront/src/assets/Logo/favicon.ico
new file mode 100644
index 0000000..7684fbd
Binary files /dev/null and b/FencerJudgeFront/src/assets/Logo/favicon.ico differ
diff --git a/FencerJudgeFront/src/assets/Logo/favicon.png b/FencerJudgeFront/src/assets/Logo/favicon.png
new file mode 100644
index 0000000..a3376ab
Binary files /dev/null and b/FencerJudgeFront/src/assets/Logo/favicon.png differ
diff --git a/FencerJudgeFront/src/index.html b/FencerJudgeFront/src/index.html
index 381bbb3..27faadb 100644
--- a/FencerJudgeFront/src/index.html
+++ b/FencerJudgeFront/src/index.html
@@ -2,7 +2,7 @@
- FencerJudgeFront
+ FencerJudge
diff --git a/FencerJudgeFront/src/styles.css b/FencerJudgeFront/src/styles.css
index 90d4ee0..c44aac6 100644
--- a/FencerJudgeFront/src/styles.css
+++ b/FencerJudgeFront/src/styles.css
@@ -1 +1,4 @@
/* You can add global styles to this file, and also import other style files */
+.bg-primary-custom {
+ background-color: #414141;
+}
diff --git a/FencerJudgeFront/tsconfig.json b/FencerJudgeFront/tsconfig.json
index 5525117..fca3db7 100644
--- a/FencerJudgeFront/tsconfig.json
+++ b/FencerJudgeFront/tsconfig.json
@@ -16,7 +16,14 @@
"moduleResolution": "bundler",
"importHelpers": true,
"target": "ES2022",
- "module": "ES2022"
+ "module": "ES2022",
+ "baseUrl": "./src",
+ "paths": {
+ "@interfaces/*": ["app/interfaces/*"],
+ "@services/*": ["app/services/*"],
+ "@guards/*": ["app/guards/*"],
+ "@utils/*": ["app/utils/*"]
+ }
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..966ef08
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6 @@
+{
+ "name": "jpe-controle",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {}
+}