Compare commits

..

5 commits

55 changed files with 358 additions and 155 deletions

View file

Binary file not shown.

View file

@ -0,0 +1,59 @@
# Angular
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 19.1.6.
## Development server
To start a local development server, run:
```bash
ng serve
```
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
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
```bash
ng generate component component-name
```
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
```bash
ng generate --help
```
## Building
To build the project run:
```bash
ng build
```
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
## Running unit tests
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
```bash
ng test
```
## Running end-to-end tests
For end-to-end (e2e) testing, run:
```bash
ng e2e
```
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
## Additional Resources
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.

View file

@ -40,7 +40,9 @@
"src/styles.css", "src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css" "node_modules/bootstrap/dist/css/bootstrap.min.css"
], ],
"scripts": [] "scripts": [
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
]
}, },
"configurations": { "configurations": {
"production": { "production": {

View file

@ -1,59 +0,0 @@
# Angular
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 19.1.6.
## Development server
To start a local development server, run:
```bash
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.
## Code scaffolding
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
```bash
ng generate component component-name
```
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
```bash
ng generate --help
```
## Building
To build the project run:
```bash
ng build
```
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
## Running unit tests
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
```bash
ng test
```
## Running end-to-end tests
For end-to-end (e2e) testing, run:
```bash
ng e2e
```
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
## Additional Resources
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.

View file

@ -1,37 +0,0 @@
<div class="container d-flex flex-column align-items-center mt-4">
<!-- Liste des informations avec un style amélioré -->
<ul class="list-group w-50 shadow-sm mb-4">
<li class="list-group-item active text-center">Informations</li>
<li class="list-group-item">{{info.name}}</li>
<li class="list-group-item">{{info.email}}</li>
<li class="list-group-item">{{info.phone}}</li>
</ul>
<!-- Champ d'entrée réduit et centré -->
<div class="w-50">
<div class="input-group mb-3 shadow-sm">
<span class="input-group-text">Message</span>
<input type="text" [(ngModel)]="comment.message" (keydown.enter)="addComment()" class="form-control">
<button type="submit" (click)="addComment()" class="btn btn-primary">Add</button>
</div>
</div>
<!-- Liste des commentaires -->
<div *ngIf="comments.length > 0; else noComment" class="d-flex flex-column align-items-center w-50">
<h3 class="text-center text-primary">Liste des commentaires</h3>
<ol class="list-group list-group-numbered shadow-sm">
<li class="list-group-item d-flex justify-content-between align-items-start" *ngFor="let comment of comments">
<div class="ms-2 me-auto">
<div class="fw-bold breakWord">{{ comment.message }}</div>
</div>
<!-- <span>&nbsp;&nbsp;</span> -->
<span class="badge text-bg-primary rounded-pill SpaceMargin-02">{{ comment.date | date:'dd/MM/yyyy' }}</span>
</li>
</ol>
</div>
<!-- Message si aucun commentaire -->
<ng-template #noComment>
<p class="text-muted text-center mt-3">Aucun commentaire pour le moment</p>
</ng-template>
</div>

View file

@ -1,42 +0,0 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-about',
standalone: false,
templateUrl: './about.component.html',
styleUrl: './about.component.css'
})
export class AboutComponent implements OnInit {
info: Info = new Info();
comments: Array<Comment> = [];
comment: Comment = new Comment();
newComment: boolean = false;
constructor() {}
ngOnInit(): void {}
addComment() {
if (this.comment.message) {
this.comment.date = new Date();
this.comments.push({
message: this.comment.message,
date: this.comment.date
});
this.comment.message = '';
}
}
}
export class Info {
name: string = "Test";
email: string = "test@mail.com";
phone: string= "000000000";
}
export class Comment {
message: string = '';
date: Date | null = null;
}

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -0,0 +1,68 @@
<div class="container d-flex flex-column align-items-center mt-4">
<!-- Liste des informations avec un style amélioré -->
<ul class="list-group w-50 shadow-sm mb-4">
<li class="list-group-item active text-center">Informations</li>
<li class="list-group-item">{{info.gender}}{{info.nameLast}} {{info.nameFirst}}</li>
<li class="list-group-item">{{info.email}}</li>
<li class="list-group-item">{{info.address}}, {{info.codePostal}}</li>
</ul>
<!-- Champ d'entrée réduit et centré -->
<div class="w-50">
<form [formGroup]="messageForm" (ngSubmit)="addComment()">
<div class="input-group mb-3 shadow-sm">
<span class="input-group-text" id="message-addon">Message</span>
<input
type="text"
formControlName="message"
class="form-control"
aria-describedby="message-addon"
placeholder="Entrez votre message">
<button
type="submit"
class="btn btn-primary"
[disabled]="messageForm.invalid">
Add
</button>
</div>
</form>
</div>
<!-- Liste des commentaires -->
<div *ngIf="comments.length > 0; else noComment" class="d-flex flex-column align-items-center w-50">
<h3 class="text-center text-primary">Liste des commentaires</h3>
<div class="list-group shadow-sm w-100">
<div
*ngFor="let msg of comments.slice().reverse()"
class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold breakWord">{{ msg.user }}</div>
<div class="breakWord">{{ msg.message }}</div>
</div>
<span class="badge text-bg-primary rounded-pill SpaceMargin-02">
{{ msg.date | date:'dd/MM/yyyy' }}
</span>
</div>
</div>
</div>
<div *ngIf="commentsAll.length > 0;" class="d-flex flex-column align-items-center w-50">
<div class="list-group shadow-sm w-100">
<div
*ngFor="let msg of commentsAll"
class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold breakWord">{{ msg.user }}</div>
<div class="breakWord">{{ msg.message }}</div>
</div>
<span class="badge text-bg-primary rounded-pill SpaceMargin-02">
{{ msg.date | date:'dd/MM/yyyy' }}
</span>
</div>
</div>
</div>
<!-- Message si aucun commentaire -->
<ng-template #noComment>
<p class="text-muted text-center mt-3">Aucun commentaire pour le moment</p>
</ng-template>
</div>

View file

@ -0,0 +1,72 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { InfoService } from '../services/info.service';
import { MessageService } from '../services/message.service';
@Component({
selector: 'app-about',
standalone: false,
templateUrl: './about.component.html',
styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {
messageForm: FormGroup;
infos: Info[] = [];
info: Info = new Info();
commentsAll: Comment[] = [];
comments: Comment[] = [];
comment: Comment = new Comment();
newComment: boolean = false;
constructor(private fb: FormBuilder, private infoService: InfoService, private messageService: MessageService) {
this.messageForm = this.fb.group({
message: ['', [Validators.required, Validators.minLength(3)]],
});
}
ngOnInit() {
this.infos = this.infoService.getInfos();
this.info = this.infos.length > 0 ? this.infos[this.infos.length - 1] : new Info();
this.commentsAll = this.messageService.getMessage().slice().reverse();
this.comment = this.commentsAll.length > 0 ? this.commentsAll[0] : new Comment();
}
addComment() {
if (this.messageForm.valid) {
const formData = this.messageForm.value;
const user = this.info.gender + this.info.nameLast + ' ' + this.info.nameFirst;
const newComment = {
...formData,
user: user,
date: new Date()
};
this.comments.push(newComment);
this.messageService.addMessage(newComment);
this.messageForm.reset();
}
}
}
export class Info {
gender: string = 'Mister.';
nameLast: string = 'Inconnu';
nameFirst: string = 'PASLA';
email: string = 'inconnu.pasla@edu.igensia.com';
address: string = '0 rue d\'inconnu';
codePostal: number = 1234;
}
export class Comment {
user: string = '';
message: string = '';
date: Date | null = null;
}

View file

@ -77,12 +77,17 @@
<div class="alert alert-danger fs-40" role="alert" *ngIf="infoForm.get('address')?.hasError('minlength') && infoForm.get('address')?.touched"> <div class="alert alert-danger fs-40" role="alert" *ngIf="infoForm.get('address')?.hasError('minlength') && infoForm.get('address')?.touched">
L'adresse doit comporter au moins 10 caractères. L'adresse doit comporter au moins 10 caractères.
</div> </div>
<div class="alert alert-dark fs-40" role="alert"></div> <div class="d-flex justify-content-center align-items-center alert alert-dark fs-40" role="alert"></div>
<div class="alert alert-danger fs-40" role="alert" *ngIf="infoForm.get('codePostal')?.hasError('required') && infoForm.get('codePostal')?.touched"> <div *ngIf="infoForm.get('codePostal')?.invalid">
Le code postal est requis. <div class="alert alert-danger fs-40" role="alert" *ngIf="infoForm.get('codePostal')?.hasError('required')">
</div> Le code postal est requis.
<div class="alert alert-danger fs-40" role="alert" *ngIf="infoForm.get('codePostal')?.hasError('minlength') && infoForm.get('codePostal')?.touched"> </div>
Le code postal doit comporter au moins 4 chiffres. <div class="alert alert-danger fs-40" role="alert" *ngIf="infoForm.get('codePostal')?.hasError('minlength')">
Le code postal doit comporter au moins 4 chiffres.
</div>
<div class="alert alert-danger fs-40" role="alert" *ngIf="infoForm.get('codePostal')?.hasError('pattern')">
Le code postal doit comporter uniquement des chiffres.
</div>
</div> </div>
</div> </div>

View file

@ -1,5 +1,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { InfoService } from '../services/info.service';
@Component({ @Component({
selector: 'app-account', selector: 'app-account',
@ -12,22 +13,21 @@ export class AccountComponent {
infoForm: FormGroup; infoForm: FormGroup;
infos: any[] = []; infos: any[] = [];
constructor(private fb: FormBuilder) { constructor(private fb: FormBuilder, private infoService: InfoService) {
this.infoForm = this.fb.group({ this.infoForm = this.fb.group({
gender: ['', Validators.required], gender: ['', Validators.required],
nameLast: ['', [Validators.required, Validators.minLength(3)]], nameLast: ['', [Validators.required, Validators.minLength(3)]],
nameFirst: ['', [Validators.required, Validators.minLength(3)]], nameFirst: ['', [Validators.required, Validators.minLength(3)]],
email: ['', [Validators.required, Validators.pattern(/^[a-zA-Z0-9._%+-]+$/)]], email: ['', [Validators.required, Validators.pattern(/^[a-zA-Z0-9._%+-]+$/)]],
address: ['', [Validators.required, Validators.minLength(10)]], address: ['', [Validators.required, Validators.minLength(10)]],
codePostal: ['', [Validators.required, Validators.minLength(4), Validators.pattern(/^\d{4,}$/)]], codePostal: ['', [Validators.required, Validators.minLength(4), Validators.pattern(/^\d+$/)]],
}); });
} }
addInfo() { addInfo() {
if (this.infoForm.valid) { if (this.infoForm.valid) {
const formData = this.infoForm.value; const formData = this.infoForm.value;
// Ajouter @edu.igensia.com automatiquement
const email = formData.email.toLowerCase(); const email = formData.email.toLowerCase();
const fullEmail = `${email}@edu.igensia.com`; const fullEmail = `${email}@edu.igensia.com`;
const nameLast = formData.nameLast.toUpperCase(); const nameLast = formData.nameLast.toUpperCase();
@ -35,14 +35,15 @@ export class AccountComponent {
const newInfo = { const newInfo = {
...formData, ...formData,
nameLast: nameLast, // Mettre l'email complet nameLast: nameLast,
nameFirst: nameFirst, // Mettre l'email complet nameFirst: nameFirst,
email: fullEmail, // Mettre l'email complet email: fullEmail,
date: new Date() // Ajoute la date actuelle date: new Date()
}; };
this.infos.push(newInfo); this.infos.push(newInfo);
this.infoForm.reset(); // Réinitialise le formulaire après l'ajout this.infoService.addInfo(newInfo);
this.infoForm.reset();
} }
} }
} }

View file

@ -2,12 +2,14 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component'; import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component'; import { AboutComponent } from './about/about.component';
import { InfoComponent } from './info/info.component';
import { ContactsComponent } from './contacts/contacts.component'; import { ContactsComponent } from './contacts/contacts.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: HomeComponent }, { path: '', component: HomeComponent },
{ path: 'home', component: HomeComponent }, { path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent }, { path: 'about', component: AboutComponent },
{ path: 'info', component: InfoComponent },
{ path: 'contacts', component: ContactsComponent }, { path: 'contacts', component: ContactsComponent },
]; ];

View file

@ -9,6 +9,7 @@ import { ContactsComponent } from './contacts/contacts.component';
import { HomeComponent } from './home/home.component'; import { HomeComponent } from './home/home.component';
import { NavBarComponent } from './nav-bar/nav-bar.component'; import { NavBarComponent } from './nav-bar/nav-bar.component';
import { AccountComponent } from './account/account.component'; import { AccountComponent } from './account/account.component';
import { InfoComponent } from './info/info.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -17,7 +18,8 @@ import { AccountComponent } from './account/account.component';
ContactsComponent, ContactsComponent,
HomeComponent, HomeComponent,
NavBarComponent, NavBarComponent,
AccountComponent AccountComponent,
InfoComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View file

@ -0,0 +1,14 @@
<div class="container d-flex flex-column align-items-center mt-4">
<ul class="list-group w-50 shadow-sm mb-4" *ngFor="let info of infos">
<li class="list-group-item active text-center">
<div class="ms-2 me-auto">
Informations de {{ info.gender }}{{ info.nameLast }}
<span class="badge text-bg-success rounded-pill">{{ info.date | date:'dd/MM/yyyy' }}</span>
</div>
</li>
<li class="list-group-item">{{ info.gender }}{{ info.nameLast }} {{info.nameFirst}}</li>
<li class="list-group-item">{{ info.email }}</li>
<li class="list-group-item">{{ info.address }}, {{ info.codePostal }}</li>
</ul>
</div>

View file

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

View file

@ -0,0 +1,18 @@
import { Component } from '@angular/core';
import { InfoService } from '../services/info.service';
@Component({
selector: 'app-info',
standalone: false,
templateUrl: './info.component.html',
styleUrl: './info.component.css'
})
export class InfoComponent {
infos: any[] = [];
constructor(private infoService: InfoService) {}
ngOnInit() {
this.infos = this.infoService.getInfos().slice().reverse();
}
}

View file

View file

@ -20,6 +20,9 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" routerLink="/about" routerLinkActive="active-link">About</a> <a class="nav-link" routerLink="/about" routerLinkActive="active-link">About</a>
</li> </li>
<li class="nav-item">
<a class="nav-link" routerLink="/info" routerLinkActive="active-link">Infos</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" routerLink="/contacts" routerLinkActive="active-link">Contacts</a> <a class="nav-link" routerLink="/contacts" routerLinkActive="active-link">Contacts</a>
</li> </li>

View file

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { InfoService } from './info.service';
describe('InfoService', () => {
let service: InfoService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(InfoService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View file

@ -0,0 +1,20 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class InfoService {
private infos: any[] = [];
constructor() { }
// Ajouter une info
addInfo(info: any) {
this.infos.push(info);
}
// Récupérer toutes les infos
getInfos() {
return this.infos;
}
}

View file

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { MessageService } from './message.service';
describe('MessageService', () => {
let service: MessageService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(MessageService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View file

@ -0,0 +1,20 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MessageService {
private messages: any[] = [];
constructor() { }
// Ajouter une info
addMessage(message: any) {
this.messages.push(message);
}
// Récupérer toutes les infos
getMessage() {
return this.messages;
}
}