account ajout

This commit is contained in:
ExostFlash 2025-03-04 14:37:54 +01:00
parent d3f3a2bd48
commit 11949da58e
26 changed files with 411 additions and 28 deletions

View file

@ -37,7 +37,8 @@
} }
], ],
"styles": [ "styles": [
"src/styles.css" "src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
], ],
"scripts": [] "scripts": []
}, },
@ -66,6 +67,9 @@
"defaultConfiguration": "production" "defaultConfiguration": "production"
}, },
"serve": { "serve": {
"options": {
"port": 80
},
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular-devkit/build-angular:dev-server",
"configurations": { "configurations": {
"production": { "production": {

View file

@ -16,6 +16,7 @@
"@angular/platform-browser": "^19.1.0", "@angular/platform-browser": "^19.1.0",
"@angular/platform-browser-dynamic": "^19.1.0", "@angular/platform-browser-dynamic": "^19.1.0",
"@angular/router": "^19.1.0", "@angular/router": "^19.1.0",
"bootstrap": "^5.3.3",
"rxjs": "~7.8.0", "rxjs": "~7.8.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"zone.js": "~0.15.0" "zone.js": "~0.15.0"
@ -4923,6 +4924,17 @@
"node": ">=14" "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": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.34.8", "version": "4.34.8",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
@ -6314,6 +6326,25 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/bootstrap": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
"integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
"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/brace-expansion": { "node_modules/brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",

View file

@ -18,6 +18,7 @@
"@angular/platform-browser": "^19.1.0", "@angular/platform-browser": "^19.1.0",
"@angular/platform-browser-dynamic": "^19.1.0", "@angular/platform-browser-dynamic": "^19.1.0",
"@angular/router": "^19.1.0", "@angular/router": "^19.1.0",
"bootstrap": "^5.3.3",
"rxjs": "~7.8.0", "rxjs": "~7.8.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"zone.js": "~0.15.0" "zone.js": "~0.15.0"

View file

@ -1,27 +1,37 @@
<ul> <div class="container d-flex flex-column align-items-center mt-4">
<li>{{info.name}}</li> <!-- Liste des informations avec un style amélioré -->
<li>{{info.email}}</li> <ul class="list-group w-50 shadow-sm mb-4">
<li>{{info.phone}}</li> <li class="list-group-item active text-center">Informations</li>
</ul> <li class="list-group-item">{{info.name}}</li>
<li class="list-group-item">{{info.email}}</li>
<div> <li class="list-group-item">{{info.phone}}</li>
<input type="text" [(ngModel)]="comment.message">
<button (click)="addComment()" disabled="newComment">
Add comment
</button>
<div *ngIf="comments.length > 0; else noComment">
<h3>Liste des commentaires</h3>
<ul>
<li *ngFor="let comment of comments">
{{comment.message}} : {{comment.date}}
</li>
</ul> </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> </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> <ng-template #noComment>
<p>Aucun commentaire pour le moment</p> <p class="text-muted text-center mt-3">Aucun commentaire pour le moment</p>
</ng-template> </ng-template>
</div> </div>

View file

@ -6,6 +6,7 @@ import { Component, OnInit } from '@angular/core';
templateUrl: './about.component.html', templateUrl: './about.component.html',
styleUrl: './about.component.css' styleUrl: './about.component.css'
}) })
export class AboutComponent implements OnInit { export class AboutComponent implements OnInit {
info: Info = new Info(); info: Info = new Info();
@ -13,7 +14,7 @@ export class AboutComponent implements OnInit {
comment: Comment = new Comment(); comment: Comment = new Comment();
newComment: boolean = false; newComment: boolean = false;
constructor() { } constructor() {}
ngOnInit(): void {} ngOnInit(): void {}

View file

@ -0,0 +1,67 @@
<div class="container d-flex flex-column align-items-center mt-5">
<!-- Formulaire d'entrée -->
<div class="w-50">
<div class="card shadow-sm">
<div class="card-body">
<h4 class="card-title text-center mb-4">Ajouter vos informations</h4>
<div class="input-group mb-3">
<div class="input-group">
<div class="input-group-text">
<input class="form-check-input mt-0" type="radio" value="Mr." aria-label="Mr." [(ngModel)]="info.gender" name="gender" (change)="updateGender()">
</div>
<input type="text" class="form-control" aria-label="Mr." placeholder="Mr." disabled>
<div class="input-group-text">
<input class="form-check-input mt-0" type="radio" value="Ms." aria-label="Ms." [(ngModel)]="info.gender" name="gender" (change)="updateGender()">
</div>
<input type="text" class="form-control" aria-label="Ms." placeholder="Ms." disabled>
<div class="input-group-text">
<input class="form-check-input mt-0" type="radio" value="Other." aria-label="Othef=r." [(ngModel)]="info.gender" name="gender" (change)="updateGender()">
</div>
<input type="text" class="form-control" aria-label="Other." placeholder="Other." disabled>
</div>
</div>
<div class="input-group mb-3">
<input type="text" [(ngModel)]="info.nameLast" class="form-control" placeholder="Last name" aria-label="Last name">
<span class="input-group-text">&#64;</span>
<input type="text" [(ngModel)]="info.nameFirst" class="form-control" placeholder="First name" aria-label="First name">
</div>
<div class="input-group mb-3">
<input type="text" [(ngModel)]="info.email" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="basic-addon2">
<span class="input-group-text" id="basic-addon2">&#64;edu.igensia.com</span>
</div>
<div class="input-group mb-3">
<span class="input-group-text">Adresse</span>
<textarea class="form-control" [(ngModel)]="info.address" aria-label="Adresse"></textarea>
</div>
<button type="submit" class="btn btn-primary w-100" (click)="addInfo()">Ajouter</button>
</div>
</div>
</div>
<!-- Liste des commentaires -->
<div *ngIf="infos.length > 0; else noComment" class="d-flex flex-column align-items-center w-50">
<h3 class="text-center text-primary">Liste des commentaires</h3>
<ul class="list-group shadow-sm">
<li class="list-group-item d-flex justify-content-between align-items-start" *ngFor="let info of infos">
<div class="ms-2 me-auto">
<div class="fw-bold breakWord">{{ info.nameLast }} {{ info.nameFirst }}</div>
<div class="fw-bold breakWord"><a href="mailto:{{ info.email }}">{{ info.email }}</a></div>
<div class="fw-bold breakWord">{{ info.address }}</div>
</div>
<div class="ms-2 me-auto d-flex flex-column">
<span class="badge text-bg-primary rounded-pill mb-1">{{ info.gender }}</span>
<span class="badge text-bg-success rounded-pill">{{ info.date | date:'dd/MM/yyyy' }}</span>
</div>
</li>
</ul>
</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,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AccountComponent } from './account.component';
describe('AccountComponent', () => {
let component: AccountComponent;
let fixture: ComponentFixture<AccountComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [AccountComponent]
})
.compileComponents();
fixture = TestBed.createComponent(AccountComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,51 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-account',
standalone: false,
templateUrl: './account.component.html',
styleUrl: './account.component.css'
})
export class AccountComponent {
info: Info = new Info();
infos: Array<Info> = [];
newInfo: boolean = false;
constructor() {}
ngOnInit(): void {}
addInfo() {
if (this.info.gender && this.info.nameFirst && this.info.nameLast && this.info.email && this.info.address) {
this.info.date = new Date();
this.info.nameFirst = this.info.nameFirst.charAt(0).toUpperCase() + this.info.nameFirst.slice(1).toLowerCase()
this.infos.push({
gender: this.info.gender,
nameFirst: this.info.nameFirst,
nameLast: this.info.nameLast.toUpperCase(),
email: this.info.email.toLowerCase() + '@edu.igensia.com',
address: this.info.address,
date: this.info.date
})
this.info.nameFirst = '';
this.info.nameLast = '';
this.info.email = '';
this.info.address = '';
this.info.gender = '';
}
}
updateGender() {
// console.log("Le genre sélectionné est :", this.info.gender);
}
}
export class Info {
gender: string = '';
nameFirst: string = '';
nameLast: string = '';
email: string = '';
address: string= '';
date: Date | null = null;
}

View file

@ -1,7 +1,15 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { ContactsComponent } from './contacts/contacts.component';
const routes: Routes = []; const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contacts', component: ContactsComponent },
];
@NgModule({ @NgModule({
imports: [RouterModule.forRoot(routes)], imports: [RouterModule.forRoot(routes)],

View file

@ -1 +1,4 @@
<app-about></app-about> <app-nav-bar></app-nav-bar>
<div class="container mt-4">
<router-outlet></router-outlet>
</div>

View file

@ -7,5 +7,5 @@ import { Component } from '@angular/core';
styleUrl: './app.component.css' styleUrl: './app.component.css'
}) })
export class AppComponent { export class AppComponent {
title = 'angular'; title = 'AngularJS';
} }

View file

@ -5,11 +5,19 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component'; import { AboutComponent } from './about/about.component';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { ContactsComponent } from './contacts/contacts.component';
import { HomeComponent } from './home/home.component';
import { NavBarComponent } from './nav-bar/nav-bar.component';
import { AccountComponent } from './account/account.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
AppComponent, AppComponent,
AboutComponent AboutComponent,
ContactsComponent,
HomeComponent,
NavBarComponent,
AccountComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View file

@ -0,0 +1 @@
<p>contacts works!</p>

View file

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

View file

@ -0,0 +1,11 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-contacts',
standalone: false,
templateUrl: './contacts.component.html',
styleUrl: './contacts.component.css'
})
export class ContactsComponent {
}

View file

View file

@ -0,0 +1,11 @@
<!-- Contenu principal -->
<div class="container text-center mt-4">
<h1 class="text-primary">Bienvenue à la formation AngularJS</h1>
<div class="mt-3">
<a class="btn btn-outline-primary me-2" routerLink="/about">About</a>
<a class="btn btn-outline-primary" routerLink="/contacts">Contacts</a>
</div>
</div>
<app-account></app-account>

View file

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

View file

@ -0,0 +1,11 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-home',
standalone: false,
templateUrl: './home.component.html',
styleUrl: './home.component.css'
})
export class HomeComponent {
}

View file

@ -0,0 +1,29 @@
<!-- Navbar Bootstrap -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" routerLink="/">AngularJS</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link"
routerLink="/"
routerLinkActive="active-link"
[routerLinkActiveOptions]="{ exact: isHomeActiveBool() }"
[class.active-link]="isHomeActive()">
Home
</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/about" routerLinkActive="active-link">About</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/contacts" routerLinkActive="active-link">Contacts</a>
</li>
</ul>
</div>
</div>
</nav>

View file

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

View file

@ -0,0 +1,24 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-nav-bar',
standalone: false,
templateUrl: './nav-bar.component.html',
styleUrl: './nav-bar.component.css'
})
export class NavBarComponent {
constructor(private router: Router) {}
isHomeActive(): boolean {
return this.router.url === '/' || this.router.url === '/home';
}
isHomeActiveBool(): boolean {
if (this.router.url != '/home') {
return true
} else {
return false
}
}
}

View file

@ -1 +1,21 @@
/* You can add global styles to this file, and also import other style files */ /* You can add global styles to this file, and also import other style files */
.active-link {
color: #ffc107 !important; /* Jaune Bootstrap */
font-weight: bold;
border-bottom: 2px solid #ffc107;
}
.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;
}