diff --git a/angular.json b/angular.json
index 6ca135b..7d2c67e 100644
--- a/angular.json
+++ b/angular.json
@@ -37,9 +37,13 @@
}
],
"styles": [
- "src/styles.css"
+ "src/styles.css",
+ "node_modules/bootstrap/dist/css/bootstrap.min.css",
+ "https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css"
],
- "scripts": []
+ "scripts": [
+ "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
+ ]
},
"configurations": {
"production": {
diff --git a/package-lock.json b/package-lock.json
index 4b8f8c4..2b55f48 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,6 +15,7 @@
"@angular/platform-browser": "^19.2.0",
"@angular/platform-browser-dynamic": "^19.2.0",
"@angular/router": "^19.2.0",
+ "bootstrap": "^5.3.5",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.15.0"
@@ -4258,6 +4259,16 @@
"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==",
+ "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",
@@ -5534,6 +5545,24 @@
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"dev": true
},
+ "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"
+ }
+ ],
+ "peerDependencies": {
+ "@popperjs/core": "^2.11.8"
+ }
+ },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
diff --git a/package.json b/package.json
index f4e2c43..2fbda07 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
"@angular/platform-browser": "^19.2.0",
"@angular/platform-browser-dynamic": "^19.2.0",
"@angular/router": "^19.2.0",
+ "bootstrap": "^5.3.5",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.15.0"
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 0297262..10937c9 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -1,7 +1,15 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
-const routes: Routes = [];
+import { CarListComponent } from './components/cars/car-list/car-list.component';
+import { CarFormComponent } from './components/cars/car-form/car-form.component';
+
+const routes: Routes = [
+ { path: '', redirectTo: 'list', pathMatch: 'full' },
+ { path: 'list', component: CarListComponent },
+ { path: 'add', component: CarFormComponent },
+ { path: 'edit/:id', component: CarFormComponent },
+];
@NgModule({
imports: [RouterModule.forRoot(routes)],
diff --git a/src/app/app.component.css b/src/app/app.component.css
index e69de29..1bd1c52 100644
--- a/src/app/app.component.css
+++ b/src/app/app.component.css
@@ -0,0 +1,45 @@
+/* You can add global styles to this file, and also import other style files */
+.background-all {
+ background: linear-gradient(90deg, #E3F2FD, #FFFFFF);
+ background-size: 400% 400%;
+ animation: gradientAnimation 6s infinite alternate ease-in-out;
+}
+
+@keyframes gradientAnimation {
+ 0% {
+ background-position: 0% 50%;
+ }
+ 100% {
+ background-position: 100% 50%;
+ }
+}
+
+.active-link {
+ color: #ffc107 !important; /* Jaune Bootstrap */
+ font-weight: bold;
+ border-bottom: 2px solid #ffc107;
+}
+
+.fs-40 {
+ padding-top: 2px !important;
+ padding-bottom: 2px !important;
+}
+
+.fs-20 {
+ width: 5vw;
+}
+
+.breakWord {
+ word-break: break-word;
+ word-wrap: break-word;
+}
+
+.SpaceMargin-02 {
+ margin-left: 10px;
+ margin-top: 2px;
+}
+
+.SpaceMargin-05 {
+ margin-left: 10px;
+ margin-top: 10px;
+}
\ No newline at end of file
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 36093e1..2726287 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,336 +1,3 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
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/src/app/app.module.ts b/src/app/app.module.ts
index b1c6c96..592d076 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -3,14 +3,34 @@ import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
+import { FormsModule } from '@angular/forms';
+
+/* Essentials */
+import { HeaderComponent } from './components/essentials/header/header.component';
+import { FooterComponent } from './components/essentials/footer/footer.component';
+
+/* Car */
+import { CarListComponent } from './components/cars/car-list/car-list.component';
+import { CarDetailComponent } from './components/cars/car-detail/car-detail.component';
+import { CarFormComponent } from './components/cars/car-form/car-form.component';
+import { CarItemComponent } from './components/cars/car-item/car-item.component';
+
+/* Modules */
@NgModule({
declarations: [
- AppComponent
+ AppComponent,
+ HeaderComponent,
+ FooterComponent,
+ CarListComponent,
+ CarDetailComponent,
+ CarFormComponent,
+ CarItemComponent
],
imports: [
BrowserModule,
- AppRoutingModule
+ AppRoutingModule,
+ FormsModule
],
providers: [],
bootstrap: [AppComponent]
diff --git a/src/app/components/cars/car-detail/car-detail.component.css b/src/app/components/cars/car-detail/car-detail.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/cars/car-detail/car-detail.component.html b/src/app/components/cars/car-detail/car-detail.component.html
new file mode 100644
index 0000000..12a9d17
--- /dev/null
+++ b/src/app/components/cars/car-detail/car-detail.component.html
@@ -0,0 +1 @@
+
car-detail works!
diff --git a/src/app/components/cars/car-detail/car-detail.component.spec.ts b/src/app/components/cars/car-detail/car-detail.component.spec.ts
new file mode 100644
index 0000000..8d4bcce
--- /dev/null
+++ b/src/app/components/cars/car-detail/car-detail.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CarDetailComponent } from './car-detail.component';
+
+describe('CarDetailComponent', () => {
+ let component: CarDetailComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [CarDetailComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(CarDetailComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/cars/car-detail/car-detail.component.ts b/src/app/components/cars/car-detail/car-detail.component.ts
new file mode 100644
index 0000000..60f0c1c
--- /dev/null
+++ b/src/app/components/cars/car-detail/car-detail.component.ts
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-car-detail',
+ standalone: false,
+ templateUrl: './car-detail.component.html',
+ styleUrl: './car-detail.component.css'
+})
+export class CarDetailComponent {
+
+}
diff --git a/src/app/components/cars/car-form/car-form.component.css b/src/app/components/cars/car-form/car-form.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/cars/car-form/car-form.component.html b/src/app/components/cars/car-form/car-form.component.html
new file mode 100644
index 0000000..8d7e47f
--- /dev/null
+++ b/src/app/components/cars/car-form/car-form.component.html
@@ -0,0 +1,7 @@
+{{ editMode ? 'Modifier' : 'Ajouter' }} une Voiture
+
\ No newline at end of file
diff --git a/src/app/components/cars/car-form/car-form.component.spec.ts b/src/app/components/cars/car-form/car-form.component.spec.ts
new file mode 100644
index 0000000..8c6b94f
--- /dev/null
+++ b/src/app/components/cars/car-form/car-form.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CarFormComponent } from './car-form.component';
+
+describe('CarFormComponent', () => {
+ let component: CarFormComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [CarFormComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(CarFormComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/cars/car-form/car-form.component.ts b/src/app/components/cars/car-form/car-form.component.ts
new file mode 100644
index 0000000..6f9a0e4
--- /dev/null
+++ b/src/app/components/cars/car-form/car-form.component.ts
@@ -0,0 +1,40 @@
+import { Component } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+
+import { CarService } from '../../../services/car.service';
+import { Car } from '../../../interfaces/car';
+
+@Component({
+ selector: 'app-car-form',
+ standalone: false,
+ templateUrl: './car-form.component.html',
+ styleUrl: './car-form.component.css'
+})
+export class CarFormComponent {
+ car: Car = { id: 0, marque: '', modele: '', couleur: '' };
+ editMode = false;
+
+ constructor(
+ private carService: CarService,
+ private route: ActivatedRoute,
+ private router: Router
+ ) {
+ const id = this.route.snapshot.params['id'];
+ if (id) {
+ const existingCar = this.carService.getCarById(+id);
+ if (existingCar) {
+ this.car = { ...existingCar };
+ this.editMode = true;
+ }
+ }
+ }
+
+ saveCar() {
+ if (this.editMode) {
+ this.carService.updateCar(this.car);
+ } else {
+ this.carService.addCar(this.car);
+ }
+ this.router.navigate(['/list']);
+ }
+}
diff --git a/src/app/components/cars/car-item/car-item.component.css b/src/app/components/cars/car-item/car-item.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/cars/car-item/car-item.component.html b/src/app/components/cars/car-item/car-item.component.html
new file mode 100644
index 0000000..78e316d
--- /dev/null
+++ b/src/app/components/cars/car-item/car-item.component.html
@@ -0,0 +1 @@
+car-item works!
diff --git a/src/app/components/cars/car-item/car-item.component.spec.ts b/src/app/components/cars/car-item/car-item.component.spec.ts
new file mode 100644
index 0000000..c7499ee
--- /dev/null
+++ b/src/app/components/cars/car-item/car-item.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CarItemComponent } from './car-item.component';
+
+describe('CarItemComponent', () => {
+ let component: CarItemComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [CarItemComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(CarItemComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/cars/car-item/car-item.component.ts b/src/app/components/cars/car-item/car-item.component.ts
new file mode 100644
index 0000000..2499270
--- /dev/null
+++ b/src/app/components/cars/car-item/car-item.component.ts
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-car-item',
+ standalone: false,
+ templateUrl: './car-item.component.html',
+ styleUrl: './car-item.component.css'
+})
+export class CarItemComponent {
+
+}
diff --git a/src/app/components/cars/car-list/car-list.component.css b/src/app/components/cars/car-list/car-list.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/cars/car-list/car-list.component.html b/src/app/components/cars/car-list/car-list.component.html
new file mode 100644
index 0000000..a33becf
--- /dev/null
+++ b/src/app/components/cars/car-list/car-list.component.html
@@ -0,0 +1,6 @@
+Liste des Voitures
+
+
{{ car.marque }} - {{ car.modele }} - {{ car.couleur }}
+
+
+
\ No newline at end of file
diff --git a/src/app/components/cars/car-list/car-list.component.spec.ts b/src/app/components/cars/car-list/car-list.component.spec.ts
new file mode 100644
index 0000000..91f78af
--- /dev/null
+++ b/src/app/components/cars/car-list/car-list.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CarListComponent } from './car-list.component';
+
+describe('CarListComponent', () => {
+ let component: CarListComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [CarListComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(CarListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/cars/car-list/car-list.component.ts b/src/app/components/cars/car-list/car-list.component.ts
new file mode 100644
index 0000000..c8765dd
--- /dev/null
+++ b/src/app/components/cars/car-list/car-list.component.ts
@@ -0,0 +1,28 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+
+import { CarService } from '../../../services/car.service';
+import { Car } from '../../../interfaces/car';
+
+@Component({
+ selector: 'app-car-list',
+ standalone: false,
+ templateUrl: './car-list.component.html',
+ styleUrl: './car-list.component.css'
+})
+export class CarListComponent {
+ cars: Car[] = [];
+
+ constructor(private carService: CarService, private router: Router) {
+ this.cars = this.carService.getCars();
+ }
+
+ deleteCar(id: number) {
+ this.carService.deleteCar(id);
+ this.cars = this.carService.getCars();
+ }
+
+ editCar(id: number) {
+ this.router.navigate(['/edit', id]);
+ }
+}
diff --git a/src/app/components/essentials/footer/footer.component.css b/src/app/components/essentials/footer/footer.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/essentials/footer/footer.component.html b/src/app/components/essentials/footer/footer.component.html
new file mode 100644
index 0000000..1eb5912
--- /dev/null
+++ b/src/app/components/essentials/footer/footer.component.html
@@ -0,0 +1,13 @@
+
diff --git a/src/app/components/essentials/footer/footer.component.spec.ts b/src/app/components/essentials/footer/footer.component.spec.ts
new file mode 100644
index 0000000..aa27d1c
--- /dev/null
+++ b/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/src/app/components/essentials/footer/footer.component.ts b/src/app/components/essentials/footer/footer.component.ts
new file mode 100644
index 0000000..d8f2f2c
--- /dev/null
+++ b/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/src/app/components/essentials/header/header.component.css b/src/app/components/essentials/header/header.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/essentials/header/header.component.html b/src/app/components/essentials/header/header.component.html
new file mode 100644
index 0000000..239147e
--- /dev/null
+++ b/src/app/components/essentials/header/header.component.html
@@ -0,0 +1,25 @@
+
+
\ No newline at end of file
diff --git a/src/app/components/essentials/header/header.component.spec.ts b/src/app/components/essentials/header/header.component.spec.ts
new file mode 100644
index 0000000..63f2a45
--- /dev/null
+++ b/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/src/app/components/essentials/header/header.component.ts b/src/app/components/essentials/header/header.component.ts
new file mode 100644
index 0000000..4875b91
--- /dev/null
+++ b/src/app/components/essentials/header/header.component.ts
@@ -0,0 +1,24 @@
+import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'app-header',
+ standalone: false,
+ templateUrl: './header.component.html',
+ styleUrl: './header.component.css'
+})
+export class HeaderComponent {
+ constructor(private router: Router) {}
+
+ isHomeActive(): boolean {
+ return this.router.url === '/' || this.router.url === '/list';
+ }
+
+ isHomeActiveBool(): boolean {
+ if (this.router.url != '/list') {
+ return true
+ } else {
+ return false
+ }
+ }
+}
diff --git a/src/app/interfaces/car.ts b/src/app/interfaces/car.ts
new file mode 100644
index 0000000..c48f495
--- /dev/null
+++ b/src/app/interfaces/car.ts
@@ -0,0 +1,6 @@
+export interface Car {
+ id: number;
+ marque: string;
+ modele: string;
+ couleur: string;
+}
diff --git a/src/app/services/car.service.spec.ts b/src/app/services/car.service.spec.ts
new file mode 100644
index 0000000..4bc2d26
--- /dev/null
+++ b/src/app/services/car.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { CarService } from './car.service';
+
+describe('CarService', () => {
+ let service: CarService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(CarService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/app/services/car.service.ts b/src/app/services/car.service.ts
new file mode 100644
index 0000000..f95846f
--- /dev/null
+++ b/src/app/services/car.service.ts
@@ -0,0 +1,40 @@
+import { Injectable } from '@angular/core';
+
+import { Car } from '../interfaces/car';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class CarService {
+ private cars: Car[] = [
+ { id: 1, marque: 'Toyota', modele: 'Yaris', couleur: 'Rouge' },
+ { id: 2, marque: 'Peugeot', modele: '307', couleur: 'Blanche' },
+ { id: 3, marque: 'Renault', modele: 'Clio', couleur: 'Blanche' },
+ ];
+
+ getCars(): Car[] {
+ return this.cars;
+ }
+
+ getCarById(id: number): Car | undefined {
+ return this.cars.find(c => c.id === id);
+ }
+
+ addCar(car: Car) {
+ car.id = Date.now();
+ this.cars.push(car);
+ }
+
+ updateCar(updatedCar: Car) {
+ const index = this.cars.findIndex(c => c.id === updatedCar.id);
+ if (index !== -1) {
+ this.cars[index] = updatedCar;
+ }
+ }
+
+ deleteCar(id: number) {
+ this.cars = this.cars.filter(c => c.id !== id);
+ }
+
+ constructor() { }
+}