Merge pull request 'develop' (#7) from develop into master
Reviewed-on: https://git.gitpushf.uk/SchoolTask/angular-covid/pulls/7
This commit is contained in:
commit
3714e70e1e
60 changed files with 858 additions and 135 deletions
7
package-lock.json
generated
7
package-lock.json
generated
|
|
@ -17,6 +17,7 @@
|
||||||
"@angular/router": "^19.2.0",
|
"@angular/router": "^19.2.0",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
"bootstrap-icons": "^1.11.3",
|
"bootstrap-icons": "^1.11.3",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"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"
|
||||||
|
|
@ -7737,6 +7738,12 @@
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/file-saver": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
"@angular/router": "^19.2.0",
|
"@angular/router": "^19.2.0",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
"bootstrap-icons": "^1.11.3",
|
"bootstrap-icons": "^1.11.3",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"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"
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
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 { ContactComponent } from './contact/contact.component';
|
import { HomeComponent } from './component/home/home.component';
|
||||||
import { SymptomeComponent } from './symptome/symptome.component';
|
import { SymptomsComponent } from './component/symptoms/symptoms.component';
|
||||||
import { BlogComponent } from './blog/blog.component';
|
import { BlogsComponent } from './component/blogs/blogs.component';
|
||||||
|
import { ContactComponent } from './component/contact/contact.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', component: HomeComponent },
|
{ path: '', component: HomeComponent },
|
||||||
{ path: 'home', component: HomeComponent },
|
{ path: 'home', component: HomeComponent },
|
||||||
{ path: 'contacts', component: ContactComponent },
|
{ path: 'symptoms', component: SymptomsComponent },
|
||||||
{ path: 'symptômes', component: SymptomeComponent },
|
{ path: 'blogs', component: BlogsComponent },
|
||||||
{ path: 'blog', component: BlogComponent },
|
{ path: 'contact', component: ContactComponent },
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
||||||
|
|
@ -4,29 +4,52 @@ import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { NavBarComponent } from './nav-bar/nav-bar.component';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import { HomeComponent } from './home/home.component';
|
|
||||||
import { FooterComponent } from './footer/footer.component';
|
/* Essential */
|
||||||
import { SymptomeComponent } from './symptome/symptome.component';
|
import { NavBarComponent } from './component/essential/nav-bar/nav-bar.component';
|
||||||
import { ContactComponent } from './contact/contact.component';
|
import { FooterComponent } from './component/essential/footer/footer.component';
|
||||||
import { BlogComponent } from './blog/blog.component';
|
|
||||||
|
/* Home */
|
||||||
|
import { HomeComponent } from './component/home/home.component';
|
||||||
|
import { HomeActuComponent } from './component/home/all/home-actu/home-actu.component';
|
||||||
|
import { HomeAccueilComponent } from './component/home/all/home-accueil/home-accueil.component';
|
||||||
|
import { HomeSymptomsComponent } from './component/home/all/home-symptoms/home-symptoms.component';
|
||||||
|
|
||||||
|
/* Symptoms */
|
||||||
|
import { SymptomsComponent } from './component/symptoms/symptoms.component';
|
||||||
|
|
||||||
|
/* Blogs */
|
||||||
|
import { BlogsComponent } from './component/blogs/blogs.component';
|
||||||
|
|
||||||
|
/* Contact */
|
||||||
|
import { ContactComponent } from './component/contact/contact.component';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
/* Essential */
|
||||||
NavBarComponent,
|
NavBarComponent,
|
||||||
HomeComponent,
|
|
||||||
FooterComponent,
|
FooterComponent,
|
||||||
SymptomeComponent,
|
/* Home */
|
||||||
ContactComponent,
|
HomeComponent,
|
||||||
BlogComponent
|
HomeActuComponent,
|
||||||
|
HomeAccueilComponent,
|
||||||
|
HomeSymptomsComponent,
|
||||||
|
/* Symptoms */
|
||||||
|
SymptomsComponent,
|
||||||
|
/* Blogs */
|
||||||
|
BlogsComponent,
|
||||||
|
/* Contact */
|
||||||
|
ContactComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule
|
ReactiveFormsModule,
|
||||||
|
HttpClientModule
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
<p>blog works!</p>
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-blog',
|
|
||||||
standalone: false,
|
|
||||||
templateUrl: './blog.component.html',
|
|
||||||
styleUrl: './blog.component.css'
|
|
||||||
})
|
|
||||||
export class BlogComponent {
|
|
||||||
|
|
||||||
}
|
|
||||||
58
src/app/component/blogs/blogs.component.css
Normal file
58
src/app/component/blogs/blogs.component.css
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
/* Card Image */
|
||||||
|
.card-img-top {
|
||||||
|
height: 200px;
|
||||||
|
object-fit: cover;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assurer une taille uniforme pour les cards */
|
||||||
|
.card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Body de la card pour avoir une hauteur fixe et uniforme */
|
||||||
|
.card-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1.25rem;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Titre de la card (limiter la taille du texte si trop long) */
|
||||||
|
.card-title {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
max-height: 2.5em; /* Limite la hauteur du titre */
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Description de la card (maximiser l'espace disponible pour la description) */
|
||||||
|
.card-text {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #6c757d;
|
||||||
|
flex-grow: 1; /* Permet à la description de prendre l'espace restant */
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
margin-bottom: 1.5rem; /* Espacement entre la description et le bouton */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bouton */
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #007bff;
|
||||||
|
border-color: #007bff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
border-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
16
src/app/component/blogs/blogs.component.html
Normal file
16
src/app/component/blogs/blogs.component.html
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<div class="row row-cols-1 row-cols-md-3 g-4 mb-4">
|
||||||
|
<div *ngFor="let article of articles" class="col">
|
||||||
|
<div class="card h-100">
|
||||||
|
<img [src]="article.urlToImage || 'assets/default.jpg'" class="card-img-top" alt="Article image" loading="lazy">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">{{ article.title }}</h5>
|
||||||
|
<p class="card-text">{{ article.description }}</p>
|
||||||
|
<a [href]="article.url" target="_blank" class="btn btn-primary">Lire l'article</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="articles.length === 0" class="alert alert-warning" role="alert">
|
||||||
|
Aucune actualité disponible pour le moment.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { BlogComponent } from './blog.component';
|
import { BlogsComponent } from './blogs.component';
|
||||||
|
|
||||||
describe('BlogComponent', () => {
|
describe('BlogsComponent', () => {
|
||||||
let component: BlogComponent;
|
let component: BlogsComponent;
|
||||||
let fixture: ComponentFixture<BlogComponent>;
|
let fixture: ComponentFixture<BlogsComponent>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [BlogComponent]
|
declarations: [BlogsComponent]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(BlogComponent);
|
fixture = TestBed.createComponent(BlogsComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
22
src/app/component/blogs/blogs.component.ts
Normal file
22
src/app/component/blogs/blogs.component.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
import { DataService } from '@services/data.service';
|
||||||
|
import { Article } from '@interface/news';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-blogs',
|
||||||
|
standalone: false,
|
||||||
|
templateUrl: './blogs.component.html',
|
||||||
|
styleUrl: './blogs.component.css'
|
||||||
|
})
|
||||||
|
export class BlogsComponent implements OnInit {
|
||||||
|
articles: Article[] = [];
|
||||||
|
|
||||||
|
constructor(private dataService: DataService) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.dataService.getNews().subscribe((response) => {
|
||||||
|
this.articles = response.articles;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/app/component/contact/contact.component.css
Normal file
32
src/app/component/contact/contact.component.css
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
/* Amélioration du formulaire */
|
||||||
|
.custom-input {
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px;
|
||||||
|
transition: border-color 0.3s ease-in-out, box-shadow 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-input:focus {
|
||||||
|
border-color: #007bff;
|
||||||
|
box-shadow: 0 0 5px rgba(0, 123, 255, 0.2);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bouton amélioré */
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #007bff;
|
||||||
|
border: none;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: background 0.3s ease, transform 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Liste des centres */
|
||||||
|
.contact-card {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
70
src/app/component/contact/contact.component.html
Normal file
70
src/app/component/contact/contact.component.html
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
<div class="container mt-5">
|
||||||
|
<div class="text-center mb-5">
|
||||||
|
<h2 class="fw-bold text-primary">Contactez-nous</h2>
|
||||||
|
<p class="text-muted">Vous avez une question ? Contactez-nous via le formulaire ou rendez-vous dans l'un de nos centres.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row g-4 mb-3">
|
||||||
|
<!-- Liste des centres -->
|
||||||
|
<div class="col-lg-6 mb-3">
|
||||||
|
<div class="card contact-card shadow-lg border-0 rounded-4">
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="card-title text-primary mb-4">Nos Centres</h4>
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
<li class="list-group-item py-3 d-flex align-items-start" *ngFor="let address of addresses">
|
||||||
|
<i class="bi bi-geo-alt-fill text-primary me-3 fs-4"></i>
|
||||||
|
<div>
|
||||||
|
<h5 class="mb-1">{{ address.title }}</h5>
|
||||||
|
<p class="text-muted mb-1"><strong>Type :</strong> {{ address.type }}</p>
|
||||||
|
<p class="text-muted mb-0"><strong>Adresse :</strong> {{ address.address }}</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Formulaire de contact -->
|
||||||
|
<div class="col-lg-6 mb-3">
|
||||||
|
<div class="card contact-form shadow-lg border-0 rounded-4">
|
||||||
|
<div class="card-body p-4">
|
||||||
|
<h4 class="card-title text-primary mb-4">Laissez-nous un message</h4>
|
||||||
|
<form>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="name" class="form-label">Nom</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-text bg-light"><i class="bi bi-person-fill"></i></span>
|
||||||
|
<input type="text" class="form-control custom-input" id="name" placeholder="Votre nom">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="email" class="form-label">Email</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-text bg-light"><i class="bi bi-envelope-fill"></i></span>
|
||||||
|
<input type="email" class="form-control custom-input" id="email" placeholder="Votre email">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="subject" class="form-label">Sujet</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-text bg-light"><i class="bi bi-chat-left-text-fill"></i></span>
|
||||||
|
<input type="text" class="form-control custom-input" id="subject" placeholder="Sujet de votre message">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="message" class="form-label">Message</label>
|
||||||
|
<textarea class="form-control custom-input" id="message" rows="4" placeholder="Votre message"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary w-100 py-2 rounded-pill custom-btn">
|
||||||
|
<i class="bi bi-send-fill"></i> Envoyer
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
import { DataService } from '@services/data.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-contact',
|
selector: 'app-contact',
|
||||||
standalone: false,
|
standalone: false,
|
||||||
|
|
@ -7,5 +9,9 @@ import { Component } from '@angular/core';
|
||||||
styleUrl: './contact.component.css'
|
styleUrl: './contact.component.css'
|
||||||
})
|
})
|
||||||
export class ContactComponent {
|
export class ContactComponent {
|
||||||
|
constructor(private dataService: DataService) {}
|
||||||
|
|
||||||
|
get addresses() {
|
||||||
|
return this.dataService.getAddresses();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -19,8 +19,8 @@
|
||||||
<a href="#" class="text-white me-3 SpaceMargin-02">Mentions légales</a>
|
<a href="#" class="text-white me-3 SpaceMargin-02">Mentions légales</a>
|
||||||
<a href="#" class="text-white me-3">Cookies</a>
|
<a href="#" class="text-white me-3">Cookies</a>
|
||||||
<a href="#" class="text-white me-3">Accessibilité</a>
|
<a href="#" class="text-white me-3">Accessibilité</a>
|
||||||
<a routerLink="/contacts" class="text-white me-3">Nous contacter</a>
|
<a routerLink="/contact" class="text-white me-3">Nous contacter</a>
|
||||||
<a href="#" class="text-white me-3">Presse</a>
|
<a routerLink="/blogs" class="text-white me-3">Presse</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
@ -15,16 +15,15 @@
|
||||||
[class.active-link]="isHomeActive()">
|
[class.active-link]="isHomeActive()">
|
||||||
Accueil
|
Accueil
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" routerLink="/symptômes" routerLinkActive="active-link">Symptômes</a>
|
<a class="nav-link" routerLink="/symptoms" routerLinkActive="active-link">Symptômes</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" routerLink="/blog" routerLinkActive="active-link">Blog</a>
|
<a class="nav-link" routerLink="/blogs" routerLinkActive="active-link">Blog</a>
|
||||||
</li>
|
</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="/contact" routerLinkActive="active-link">Contact</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<div class="row align-items-center mb-4">
|
||||||
|
<div class="col-md-6 text-center text-md-start">
|
||||||
|
<h2 class="text-primary">Ensemble. Luttons.</h2>
|
||||||
|
<p>Lorem, ipsum dolor, sit amet consectetur adipisicing elit...</p>
|
||||||
|
<button routerLink="/symptoms" class="btn btn-primary">Comment se protéger</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 text-center">
|
||||||
|
<img src="/assets/illustration.png" alt="Illustration Covid" class="img-fluid">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HomeAccueilComponent } from './home-accueil.component';
|
||||||
|
|
||||||
|
describe('HomeAccueilComponent', () => {
|
||||||
|
let component: HomeAccueilComponent;
|
||||||
|
let fixture: ComponentFixture<HomeAccueilComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [HomeAccueilComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(HomeAccueilComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-home-accueil',
|
||||||
|
standalone: false,
|
||||||
|
templateUrl: './home-accueil.component.html',
|
||||||
|
styleUrl: './home-accueil.component.css'
|
||||||
|
})
|
||||||
|
export class HomeAccueilComponent {
|
||||||
|
|
||||||
|
}
|
||||||
54
src/app/component/home/all/home-actu/home-actu.component.css
Normal file
54
src/app/component/home/all/home-actu/home-actu.component.css
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
#newsCarousel {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-item img {
|
||||||
|
width: 100%;
|
||||||
|
height: 350px; /* Ajuste la hauteur de l'image pour avoir une vue cohérente */
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-caption {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
background-color: rgba(13, 110, 253, 0.7); /* Légère transparence pour le fond */
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-caption h5 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-caption p {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-caption .btn {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-control-prev,
|
||||||
|
.carousel-control-next {
|
||||||
|
background-color: transparent; /* Pas de fond sombre */
|
||||||
|
border-radius: 50%; /* Forme ronde */
|
||||||
|
border: none; /* Retirer la bordure */
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-control-prev:hover,
|
||||||
|
.carousel-control-next:hover {
|
||||||
|
background-color: transparent; /* Pas de changement de fond au survol */
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-control-next-icon-new svg {
|
||||||
|
transform: rotate(180deg); /* Rotation de 180° */
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-control-prev-icon-new svg,
|
||||||
|
.carousel-control-next-icon-new svg {
|
||||||
|
fill: #0d95fd; /* Couleur de l'icône */
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
<div *ngIf="articles.length > 0" id="newsCarousel" class="carousel slide mb-4" data-bs-ride="carousel">
|
||||||
|
<div class="carousel-indicators">
|
||||||
|
<button *ngFor="let article of articles; let i = index"
|
||||||
|
type="button" data-bs-target="#newsCarousel"
|
||||||
|
[attr.data-bs-slide-to]="i"
|
||||||
|
[class.active]="i === 0"
|
||||||
|
[attr.aria-current]="i === 0 ? 'true' : null"
|
||||||
|
[attr.aria-label]="'Slide ' + (i + 1)">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="carousel-inner">
|
||||||
|
<div *ngFor="let article of articles; let i = index" class="carousel-item" [class.active]="i === 0">
|
||||||
|
<img [src]="article.urlToImage || 'assets/default.jpg'" loading="lazy" class="d-block w-100" [alt]="article.title">
|
||||||
|
<div class="carousel-caption d-none d-md-block text-start">
|
||||||
|
<h5 style="color: black;">{{ article.title }}</h5>
|
||||||
|
<p>{{ article.description }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="carousel-control-prev" type="button" data-bs-target="#newsCarousel" data-bs-slide="prev">
|
||||||
|
<span class="carousel-control-prev-icon-new" aria-hidden="true">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 16 16">
|
||||||
|
<path d="M11.854 1.146a.5.5 0 0 1 0 .708L5.707 8l6.147 6.146a.5.5 0 1 1-.708.708l-6.5-6.5a.5.5 0 0 1 0-.708l6.5-6.5a.5.5 0 0 1 .708 0z"/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span class="visually-hidden">Précédent</span>
|
||||||
|
</button>
|
||||||
|
<button class="carousel-control-next" type="button" data-bs-target="#newsCarousel" data-bs-slide="next">
|
||||||
|
<span class="carousel-control-next-icon-new" aria-hidden="true">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 16 16">
|
||||||
|
<path d="M11.854 1.146a.5.5 0 0 1 0 .708L5.707 8l6.147 6.146a.5.5 0 1 1-.708.708l-6.5-6.5a.5.5 0 0 1 0-.708l6.5-6.5a.5.5 0 0 1 .708 0z"/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span class="visually-hidden">Suivant</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="articles.length === 0" class="alert alert-warning mb-4" role="alert">
|
||||||
|
Aucune actualité disponible pour le moment.
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HomeActuComponent } from './home-actu.component';
|
||||||
|
|
||||||
|
describe('HomeActuComponent', () => {
|
||||||
|
let component: HomeActuComponent;
|
||||||
|
let fixture: ComponentFixture<HomeActuComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [HomeActuComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(HomeActuComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
22
src/app/component/home/all/home-actu/home-actu.component.ts
Normal file
22
src/app/component/home/all/home-actu/home-actu.component.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
import { DataService } from '@services/data.service';
|
||||||
|
import { Article } from '@interface/news';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-home-actu',
|
||||||
|
standalone: false,
|
||||||
|
templateUrl: './home-actu.component.html',
|
||||||
|
styleUrls: ['./home-actu.component.css'] // Correction ici : styleUrls (pluriel)
|
||||||
|
})
|
||||||
|
export class HomeActuComponent implements OnInit {
|
||||||
|
articles: Article[] = [];
|
||||||
|
|
||||||
|
constructor(private dataService: DataService) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.dataService.getNews().subscribe((response) => {
|
||||||
|
this.articles = response.articles.slice(0, 5);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<div class="text-center mb-4">
|
||||||
|
<h2 class="text-primary">Symptôme du Coronavirus</h2>
|
||||||
|
<p>Lorem, ipsum dolor sit amet consectetur...</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div *ngFor="let symptom of symptoms | slice:0:4" class="col-md-6 mb-3">
|
||||||
|
<div class="card p-3">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<img [src]="symptom.imageName" [alt]="symptom.title" class="me-3" style="width: 100px;">
|
||||||
|
<div>
|
||||||
|
<h5 class="text-primary">{{ symptom.title }}</h5>
|
||||||
|
<p>{{ symptom.description }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HomeSymptomsComponent } from './home-symptoms.component';
|
||||||
|
|
||||||
|
describe('HomeSymptomsComponent', () => {
|
||||||
|
let component: HomeSymptomsComponent;
|
||||||
|
let fixture: ComponentFixture<HomeSymptomsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [HomeSymptomsComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(HomeSymptomsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
import { DataService } from '@services/data.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-home-symptoms',
|
||||||
|
standalone: false,
|
||||||
|
templateUrl: './home-symptoms.component.html',
|
||||||
|
styleUrl: './home-symptoms.component.css'
|
||||||
|
})
|
||||||
|
export class HomeSymptomsComponent {
|
||||||
|
constructor(private dataService: DataService) {}
|
||||||
|
|
||||||
|
get symptoms() {
|
||||||
|
return this.dataService.getSymptoms();
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/app/component/home/home.component.html
Normal file
5
src/app/component/home/home.component.html
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<div class="container py-5">
|
||||||
|
<app-home-actu></app-home-actu>
|
||||||
|
<app-home-accueil></app-home-accueil>
|
||||||
|
<app-home-symptoms></app-home-symptoms>
|
||||||
|
</div>
|
||||||
18
src/app/component/symptoms/symptoms.component.html
Normal file
18
src/app/component/symptoms/symptoms.component.html
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<div class="text-center mb-4">
|
||||||
|
<h2 class="text-primary">Symptôme du Coronavirus</h2>
|
||||||
|
<p>Lorem, ipsum dolor sit amet consectetur...</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div *ngFor="let symptom of symptoms" class="col-md-6 mb-3">
|
||||||
|
<div class="card p-3">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<img [src]="symptom.imageName" [alt]="symptom.title" class="me-3" style="width: 100px;">
|
||||||
|
<div>
|
||||||
|
<h5 class="text-primary">{{ symptom.title }}</h5>
|
||||||
|
<p>{{ symptom.description }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { SymptomeComponent } from './symptome.component';
|
import { SymptomsComponent } from './symptoms.component';
|
||||||
|
|
||||||
describe('SymptomeComponent', () => {
|
describe('SymptomsComponent', () => {
|
||||||
let component: SymptomeComponent;
|
let component: SymptomsComponent;
|
||||||
let fixture: ComponentFixture<SymptomeComponent>;
|
let fixture: ComponentFixture<SymptomsComponent>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [SymptomeComponent]
|
declarations: [SymptomsComponent]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(SymptomeComponent);
|
fixture = TestBed.createComponent(SymptomsComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
17
src/app/component/symptoms/symptoms.component.ts
Normal file
17
src/app/component/symptoms/symptoms.component.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
import { DataService } from '@services/data.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-symptoms',
|
||||||
|
standalone: false,
|
||||||
|
templateUrl: './symptoms.component.html',
|
||||||
|
styleUrl: './symptoms.component.css'
|
||||||
|
})
|
||||||
|
export class SymptomsComponent {
|
||||||
|
constructor(private dataService: DataService) {}
|
||||||
|
|
||||||
|
get symptoms() {
|
||||||
|
return this.dataService.getSymptoms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
<p>contact works!</p>
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
<div class="container py-5">
|
|
||||||
<div class="row align-items-center mb-4">
|
|
||||||
<div class="col-md-6 text-center text-md-start">
|
|
||||||
<h2 class="text-primary">Ensemble. Luttons.</h2>
|
|
||||||
<p>Lorem, ipsum dolor, sit amet consectetur adipisicing elit...</p>
|
|
||||||
<button routerLink="/symptômes" class="btn btn-primary">Comment se protéger</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 text-center">
|
|
||||||
<img src="/assets/illustration.png" alt="Illustration Covid" class="img-fluid">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center mb-4">
|
|
||||||
<h2 class="text-primary">Symptôme du Coronavirus</h2>
|
|
||||||
<p>Lorem, ipsum dolor sit amet consectetur...</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<div class="card p-3">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<img src="/assets/fievre.png" alt="Forte fièvre" class="me-3">
|
|
||||||
<div>
|
|
||||||
<h5 class="text-primary">Forte fièvre</h5>
|
|
||||||
<p>Lorem ipsum dolor sit amet...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<div class="card p-3">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<img src="/assets/toux.png" alt="Toux" class="me-3">
|
|
||||||
<div>
|
|
||||||
<h5 class="text-primary">Toux</h5>
|
|
||||||
<p>Lorem ipsum dolor sit amet...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<div class="card p-3">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<img src="/assets/gorge.png" alt="Gorge irritée" class="me-3">
|
|
||||||
<div>
|
|
||||||
<h5 class="text-primary">Gorge irritée</h5>
|
|
||||||
<p>Lorem ipsum dolor sit amet...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<div class="card p-3">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<img src="/assets/migraine.png" alt="Migraine" class="me-3">
|
|
||||||
<div>
|
|
||||||
<h5 class="text-primary">Migraine</h5>
|
|
||||||
<p>Lorem ipsum dolor sit amet...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
21
src/app/interface/news.ts
Normal file
21
src/app/interface/news.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
export interface Source {
|
||||||
|
id: string | null;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Article {
|
||||||
|
source: Source;
|
||||||
|
author: string;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
url: string;
|
||||||
|
urlToImage: string;
|
||||||
|
publishedAt: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NewsResponse {
|
||||||
|
status: string;
|
||||||
|
totalResults: number;
|
||||||
|
articles: Article[];
|
||||||
|
}
|
||||||
16
src/app/service/all/address/address.service.spec.ts
Normal file
16
src/app/service/all/address/address.service.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AddressService } from './address.service';
|
||||||
|
|
||||||
|
describe('AddressService', () => {
|
||||||
|
let service: AddressService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(AddressService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
19
src/app/service/all/address/address.service.ts
Normal file
19
src/app/service/all/address/address.service.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AddressService {
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
private addresses = [
|
||||||
|
{ title: "Centre de Dépistage - Laboratoire Biomédical", type: "Dépistage", address: "15 Rue de la Colombette, 31000 Toulouse" },
|
||||||
|
{ title: "Centre de Vaccination Municipal Toulouse La Daurade", type: "Vaccination", address: "17 Place de la Daurade, 31000 Toulouse" },
|
||||||
|
{ title: "Pharmacie des Pyrénées", type: "Dépistage", address: "77 Boulevard de Strasbourg, 31000 Toulouse" },
|
||||||
|
{ title: "Centre de Vaccination - CHU Toulouse Purpan", type: "Dépistage & Vaccination", address: "1 Place du Docteur Joseph Baylac, 31300 Toulouse" }
|
||||||
|
];
|
||||||
|
|
||||||
|
getAddresses() {
|
||||||
|
return this.addresses;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/app/service/all/blog/blog.service.spec.ts
Normal file
16
src/app/service/all/blog/blog.service.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { BlogService } from './blog.service';
|
||||||
|
|
||||||
|
describe('BlogService', () => {
|
||||||
|
let service: BlogService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(BlogService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
35
src/app/service/all/blog/blog.service.ts
Normal file
35
src/app/service/all/blog/blog.service.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class BlogService {
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
private blogs = [
|
||||||
|
{
|
||||||
|
title: "Déclaration de la pandémie par l'OMS",
|
||||||
|
date: "2020-03-11",
|
||||||
|
text: "L'Organisation mondiale de la santé (OMS) a déclaré le COVID-19 comme une pandémie mondiale, soulignant la gravité et la rapidité de la propagation du virus."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Premier confinement en France",
|
||||||
|
date: "2020-03-17",
|
||||||
|
text: "La France a instauré un confinement national strict pour limiter la propagation du virus, entraînant la fermeture des écoles, des commerces non essentiels et des restrictions de déplacement."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Début de la campagne de vaccination en France",
|
||||||
|
date: "2020-12-27",
|
||||||
|
text: "La France a lancé sa campagne de vaccination contre le COVID-19, en commençant par les populations les plus vulnérables."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Levée progressive des restrictions sanitaires",
|
||||||
|
date: "2021-06-09",
|
||||||
|
text: "La France a entamé une levée progressive des restrictions, avec la réouverture des restaurants, des lieux culturels et l'assouplissement du couvre-feu."
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
getBlogs() {
|
||||||
|
return this.blogs;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/app/service/all/news/news.service.spec.ts
Normal file
16
src/app/service/all/news/news.service.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { NewsService } from './news.service';
|
||||||
|
|
||||||
|
describe('NewsService', () => {
|
||||||
|
let service: NewsService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(NewsService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
44
src/app/service/all/news/news.service.ts
Normal file
44
src/app/service/all/news/news.service.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { NewsResponse } from '@interface/news'; // Assure-toi que le chemin est correct
|
||||||
|
import { tap } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class NewsService {
|
||||||
|
private apiKey: string = 'e9bb2770d3374edea421bcadbecdca5c';
|
||||||
|
private apiUrl: string = `https://newsapi.org/v2/everything?q=covid&language=fr&apiKey=${this.apiKey}`;
|
||||||
|
private storageKey: string = 'newsData'; // Clé utilisée pour le localStorage
|
||||||
|
private lastUpdateKey: string = 'lastUpdate'; // Clé pour stocker la date de la dernière mise à jour
|
||||||
|
private cacheDuration: number = 60 * 60 * 1000; // Durée en millisecondes (par exemple, 1 heure)
|
||||||
|
|
||||||
|
constructor(private http: HttpClient) {}
|
||||||
|
|
||||||
|
// Méthode pour récupérer les articles de l'API ou du localStorage
|
||||||
|
getNews(): Observable<NewsResponse> {
|
||||||
|
const storedData = localStorage.getItem(this.storageKey);
|
||||||
|
const lastUpdate = localStorage.getItem(this.lastUpdateKey);
|
||||||
|
|
||||||
|
// Vérifie si les données existent et si elles sont encore valides
|
||||||
|
const currentTime = new Date().getTime();
|
||||||
|
|
||||||
|
if (storedData && lastUpdate && (currentTime - Number(lastUpdate)) < this.cacheDuration) {
|
||||||
|
// Si les données sont présentes et récentes (moins de 1 heure par exemple), on les retourne
|
||||||
|
return new Observable(observer => {
|
||||||
|
observer.next(JSON.parse(storedData)); // On envoie les données stockées
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Sinon, on effectue la requête à l'API
|
||||||
|
return this.http.get<NewsResponse>(this.apiUrl).pipe(
|
||||||
|
tap(response => {
|
||||||
|
// On stocke la réponse dans le localStorage et la date de mise à jour
|
||||||
|
localStorage.setItem(this.storageKey, JSON.stringify(response));
|
||||||
|
localStorage.setItem(this.lastUpdateKey, currentTime.toString()); // On enregistre l'heure de la mise à jour
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/app/service/all/symptom/symptom.service.spec.ts
Normal file
16
src/app/service/all/symptom/symptom.service.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SymptomService } from './symptom.service';
|
||||||
|
|
||||||
|
describe('SymptomService', () => {
|
||||||
|
let service: SymptomService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(SymptomService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
55
src/app/service/all/symptom/symptom.service.ts
Normal file
55
src/app/service/all/symptom/symptom.service.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class SymptomService {
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
private symptoms = [
|
||||||
|
{
|
||||||
|
title: "Toux",
|
||||||
|
imageName: "/assets/toux.png",
|
||||||
|
description: "Une toux sèche et persistante est l'un des premiers symptômes du COVID-19. Elle peut être accompagnée de difficultés respiratoires."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Fièvre",
|
||||||
|
imageName: "/assets/fievre.png",
|
||||||
|
description: "Une fièvre supérieure à 38°C est un symptôme courant du COVID-19, indiquant que le corps combat une infection."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Fatigue",
|
||||||
|
imageName: "/assets/what.avif",
|
||||||
|
description: "Un état de fatigue intense, même sans activité physique, est fréquemment observé chez les personnes atteintes du virus."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Perte du goût et de l'odorat",
|
||||||
|
imageName: "/assets/what.avif",
|
||||||
|
description: "L'anosmie (perte de l'odorat) et l'agueusie (perte du goût) sont des symptômes spécifiques souvent signalés par les patients atteints du COVID-19."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Difficultés respiratoires",
|
||||||
|
imageName: "/assets/what.avif",
|
||||||
|
description: "Une sensation d'essoufflement ou une difficulté à respirer peut indiquer une forme plus grave de l'infection nécessitant une prise en charge médicale."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Maux de gorge",
|
||||||
|
imageName: "/assets/gorge.png",
|
||||||
|
description: "Un mal de gorge accompagné d'une sensation de brûlure ou de picotements peut être un signe d'infection par le virus."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Maux de tête",
|
||||||
|
imageName: "/assets/migraine.png",
|
||||||
|
description: "Des céphalées intenses et persistantes sont rapportées par de nombreux patients atteints du COVID-19."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Douleurs musculaires",
|
||||||
|
imageName: "/assets/what.avif",
|
||||||
|
description: "Des douleurs musculaires généralisées peuvent accompagner l'infection, similaires à celles observées lors d'une grippe."
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
getSymptoms() {
|
||||||
|
return this.symptoms;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/app/service/data.service.spec.ts
Normal file
16
src/app/service/data.service.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DataService } from './data.service';
|
||||||
|
|
||||||
|
describe('DataService', () => {
|
||||||
|
let service: DataService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(DataService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
35
src/app/service/data.service.ts
Normal file
35
src/app/service/data.service.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { SymptomService } from './all/symptom/symptom.service';
|
||||||
|
import { BlogService } from './all/blog/blog.service';
|
||||||
|
import { AddressService } from './all/address/address.service';
|
||||||
|
import { NewsService } from './all/news/news.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class DataService {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private symptomService: SymptomService,
|
||||||
|
private blogService: BlogService,
|
||||||
|
private addressService: AddressService,
|
||||||
|
private newsService: NewsService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
getSymptoms() {
|
||||||
|
return this.symptomService.getSymptoms();
|
||||||
|
}
|
||||||
|
|
||||||
|
getBlogs() {
|
||||||
|
return this.blogService.getBlogs();
|
||||||
|
}
|
||||||
|
|
||||||
|
getAddresses() {
|
||||||
|
return this.addressService.getAddresses();
|
||||||
|
}
|
||||||
|
|
||||||
|
getNews() {
|
||||||
|
return this.newsService.getNews();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
<p>symptome works!</p>
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-symptome',
|
|
||||||
standalone: false,
|
|
||||||
templateUrl: './symptome.component.html',
|
|
||||||
styleUrl: './symptome.component.css'
|
|
||||||
})
|
|
||||||
export class SymptomeComponent {
|
|
||||||
|
|
||||||
}
|
|
||||||
BIN
src/assets/what.avif
Normal file
BIN
src/assets/what.avif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -2,7 +2,7 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Angular</title>
|
<title>Angular Covid</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="/assets/logo.ico">
|
<link rel="icon" type="image/x-icon" href="/assets/logo.ico">
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,12 @@
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"module": "ES2022"
|
"module": "ES2022",
|
||||||
|
"baseUrl": "./src",
|
||||||
|
"paths": {
|
||||||
|
"@services/*": ["app/service/*"],
|
||||||
|
"@interface/*": ["app/interface/*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"angularCompilerOptions": {
|
"angularCompilerOptions": {
|
||||||
"enableI18nLegacyMessageIdFormat": false,
|
"enableI18nLegacyMessageIdFormat": false,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue