Correction demander pour le brief + ajout des infos rating + bouton reset

This commit is contained in:
Julian Tomczyk 2022-03-01 11:55:28 +01:00
parent f6601fcd9c
commit 1f1c069bdd
51 changed files with 6740 additions and 6523 deletions

View file

@ -4,13 +4,15 @@ This project was generated with [Angular CLI](https://github.com/angular/angular
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change
any of the source files.
Run `npm run api` for the api server. Reach to `http://localhost:3000/`
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
Run `ng generate component component-name` to generate a new component. You can also
use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build
@ -22,8 +24,10 @@ Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a
package that implements end-to-end testing capabilities.
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
To get more help on the Angular CLI use `ng help` or go check out
the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

View file

@ -1,5 +1,5 @@
{
"list_products" : [
"list_products": [
{
"product_id": "952438",
"product_name": "Anthurium, pot D12cm",
@ -6049,6 +6049,6 @@
"product_web_only": "oui"
}
],
"users" : []
"users": []
}

View file

@ -28,8 +28,8 @@ module.exports = function (config) {
dir: require('path').join(__dirname, './coverage/la-belle-plante'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
{type: 'html'},
{type: 'text-summary'}
]
},
reporters: ['progress', 'kjhtml'],

2
package-lock.json generated
View file

@ -7185,7 +7185,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
@ -7485,7 +7484,6 @@
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
"node_modules/json-server": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/json-server/-/json-server-0.17.0.tgz",

View file

@ -1,26 +1,27 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CardPlanteComponent } from './components/card-plante/card-plante.component';
import { PageAccueilComponent } from './pages/page-accueil/page-accueil.component';
import { PageDetailsComponent } from './pages/page-details/page-details.component';
import { PageNotFoundComponent } from './pages/page-not-found/page-not-found.component';
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {PageAccueilComponent} from './pages/page-accueil/page-accueil.component';
import {PageDetailsComponent} from './pages/page-details/page-details.component';
import {PageNotFoundComponent} from './pages/page-not-found/page-not-found.component';
const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{path: '', redirectTo: 'home', pathMatch: 'full'},
{
path: 'home', component: PageAccueilComponent },
{ path: 'details/:productId', component: PageDetailsComponent},
{path : 'account',
loadChildren : () => import('./modules/account/account.module')
path: 'home', component: PageAccueilComponent
},
{path: 'details/:productId', component: PageDetailsComponent},
{
path: 'account',
loadChildren: () => import('./modules/account/account.module')
.then(m => m.AccountModule)
},
{ path: '**', component: PageNotFoundComponent }
{path: '**', component: PageNotFoundComponent}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
export class AppRoutingModule {
}

View file

@ -1,6 +1,6 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import {TestBed} from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {AppComponent} from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {

View file

@ -1,4 +1,4 @@
import { Component } from '@angular/core';
import {Component} from '@angular/core';
@Component({
selector: 'app-root',

View file

@ -1,17 +1,17 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NavBarComponent } from './components/nav-bar/nav-bar.component';
import { PageAccueilComponent } from './pages/page-accueil/page-accueil.component';
import { PageDetailsComponent } from './pages/page-details/page-details.component';
import { PageNotFoundComponent } from './pages/page-not-found/page-not-found.component';
import { FilterSideBarComponent } from './components/filter-side-bar/filter-side-bar.component';
import { CardPlanteComponent } from './components/card-plante/card-plante.component';
import { HttpClientModule } from '@angular/common/http';
import { IconComponent } from './components/icon/icon.component';
import { AvisBarComponent } from './components/avis-bar/avis-bar.component';
import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {NavBarComponent} from './components/nav-bar/nav-bar.component';
import {PageAccueilComponent} from './pages/page-accueil/page-accueil.component';
import {PageDetailsComponent} from './pages/page-details/page-details.component';
import {PageNotFoundComponent} from './pages/page-not-found/page-not-found.component';
import {FilterSideBarComponent} from './components/filter-side-bar/filter-side-bar.component';
import {CardPlanteComponent} from './components/card-plante/card-plante.component';
import {HttpClientModule} from '@angular/common/http';
import {IconComponent} from './components/icon/icon.component';
import {AvisBarComponent} from './components/avis-bar/avis-bar.component';
@NgModule({
declarations: [
@ -35,4 +35,5 @@ import { AvisBarComponent } from './components/avis-bar/avis-bar.component';
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
export class AppModule {
}

View file

@ -1,4 +1,11 @@
<div (mouseleave)="onMouseLeave()">
<div (mouseover)="isOver = true" *ngIf="isOver === false">
<app-icon *ngFor="let star of starStates; let starIndex = index"
[iconName]="star.stateRatingProduct ? 'star-fill' : 'star'"
[iconSize]="1.2"
[iconColor]="'#ffbf00'"
></app-icon>
</div>
<div (mouseleave)="onMouseLeave()" *ngIf="isOver">
<app-icon *ngFor="let star of starStates; let starIndex = index"
[iconName]="star.stateHoverUser ? 'star-fill' : 'star'"
[iconSize]="1.2"

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { AvisBarComponent } from './avis-bar.component';
import {AvisBarComponent} from './avis-bar.component';
describe('AvisBarComponent', () => {
let component: AvisBarComponent;
@ -8,7 +8,7 @@ describe('AvisBarComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AvisBarComponent ]
declarations: [AvisBarComponent]
})
.compileComponents();
});

View file

@ -1,4 +1,4 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
@Component({
selector: 'app-avis-bar',
@ -6,30 +6,42 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core';
styleUrls: ['./avis-bar.component.scss']
})
export class AvisBarComponent implements OnInit {
starStates: {stateSelectedUser : boolean, stateHoverUser : boolean}[];
starStates: { stateSelectedUser: boolean, stateHoverUser: boolean, stateRatingProduct: boolean }[];
@Output() stateNumber = new EventEmitter
starStateNumber: number = 0;
@Input() ratingIndex: number = 0;
isOver: boolean;
constructor() {
this.starStates = [];
this.isOver = false;
for (let index = 0; index < 5; index++) {
this.starStates.push(
{
stateSelectedUser : false,
stateHoverUser : false
stateSelectedUser: false,
stateHoverUser: false,
stateRatingProduct: false
}
);
}
}
ngOnInit(): void {
for (let i = 0; i < 5; i++) {
if (i < this.ratingIndex) {
this.starStates[i].stateRatingProduct = true;
} else {
this.starStates[i].stateRatingProduct = false;
}
}
}
onMouseOver(index: number) {
console.log("star over", index);
for (let i = 0; i < this.starStates.length ; i++) {
if(i <= index) {
this.isOver = true;
for (let i = 0; i < this.starStates.length; i++) {
if (i <= index) {
this.starStates[i].stateHoverUser = true;
} else {
this.starStates[i].stateHoverUser = false;
@ -39,12 +51,14 @@ export class AvisBarComponent implements OnInit {
onMouseLeave() {
// this.starState = ['star', 'star', 'star', 'star', 'star'];
this.isOver = false;
const tempTab = [];
for (let index = 0; index < this.starStates.length; index++) {
tempTab.push(
{
stateSelectedUser : this.starStates[index].stateSelectedUser,
stateHoverUser : this.starStates[index].stateSelectedUser
stateSelectedUser: this.starStates[index].stateSelectedUser,
stateHoverUser: this.starStates[index].stateSelectedUser,
stateRatingProduct: this.starStates[index].stateRatingProduct
}
);
}
@ -53,16 +67,17 @@ export class AvisBarComponent implements OnInit {
onClickStar(starIndex: number) {
this.starStateNumber = 0;
for (let i = 0; i < this.starStates.length ; i++) {
if(i <= starIndex) {
for (let i = 0; i < this.starStates.length; i++) {
if (i <= starIndex) {
this.starStates[i].stateSelectedUser = true;
this.starStates[i].stateRatingProduct = true;
this.starStateNumber++;
} else {
this.starStates[i].stateSelectedUser = false;
this.starStates[i].stateRatingProduct = false;
}
}
//console.log(`Rating : ${this.starStateNumber}`);
this.stateNumber.emit(this.starStateNumber);
}
}

View file

@ -3,11 +3,12 @@
[iconName]="'heart'"
[iconColor]="'#e35d6a'"
(click)="onClickLike()"></app-icon>
<img src="{{plant.product_url_picture}}" class="card-img-top" alt="Image de {{ plant.product_name }}" (click) = "onGetId(plant.product_id)">
<img src="{{plant.product_url_picture}}" class="card-img-top" alt="Image de {{ plant.product_name }}"
(click)="onGetId(plant.product_id)">
<div class="card-body">
<h6 class="card-title" (click) = "onGetId(plant.product_id)">{{ plant.product_name }}</h6>
<h6 class="card-title" (click)="onGetId(plant.product_id)">{{ plant.product_name }}</h6>
<div class="card-content">
<app-avis-bar></app-avis-bar>
<app-avis-bar [ratingIndex]="plant.product_rating"></app-avis-bar>
</div>
<div class="d-flex flex-row align-items-end justify-content-between">

View file

@ -1,5 +1,6 @@
.plant {
min-height: 22rem;
.card-body {
display: flex;
flex-direction: column;

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { CardPlanteComponent } from './card-plante.component';
import {CardPlanteComponent} from './card-plante.component';
describe('CardPlanteComponent', () => {
let component: CardPlanteComponent;
@ -8,7 +8,7 @@ describe('CardPlanteComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ CardPlanteComponent ]
declarations: [CardPlanteComponent]
})
.compileComponents();
});

View file

@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Router } from '@angular/router';
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {Router} from '@angular/router';
@Component({
@ -12,17 +12,20 @@ export class CardPlanteComponent implements OnInit {
@Output() clickLike = new EventEmitter();
@Output() clickCardId = new EventEmitter();
constructor(private router : Router) {}
constructor(private router: Router) {
}
ngOnInit(): void {
}
onClickLike() {
console.log('click');
this.clickLike.emit();
}
onGetId(id : string){
onGetId(id: string) {
this.clickCardId.emit(id);
this.router.navigateByUrl('/details/'+ id);
this.router.navigateByUrl('/details/' + id);
}
}

View file

@ -7,7 +7,8 @@
<p class="mb-1 fs-5 fw-semibold">Catégories</p>
<div *ngFor="let category of listCategories; let indexCat = index" class="form-check">
<input class="form-check-input" type="checkbox" value="testcategory" id="checkBoxCategory{{indexCat}}" (click)="onCheckCategory(category,$event)">
<input class="form-check-input" type="checkbox" value="testcategory" id="checkBoxCategory{{indexCat}}"
(click)="onCheckCategory(category,$event)">
<label class="form-check-label" for="checkBoxCategory{{indexCat}}">
{{ category }}
@ -41,4 +42,11 @@
</div>
</div>
</ul>
<ul class="list-unstyled ps-0 border-top">
<div class="p-3">
<div class="flex-column justify-content-start">
<button class="btn btn-success me-2" (click)="onReset()">Réinitialiser</button>
</div>
</div>
</ul>
</div>

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { FilterSideBarComponent } from './filter-side-bar.component';
import {FilterSideBarComponent} from './filter-side-bar.component';
describe('FilterSideBarComponent', () => {
let component: FilterSideBarComponent;
@ -8,7 +8,7 @@ describe('FilterSideBarComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ FilterSideBarComponent ]
declarations: [FilterSideBarComponent]
})
.compileComponents();
});

View file

@ -1,4 +1,4 @@
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
@Component({
selector: 'app-filter-side-bar',
@ -10,10 +10,10 @@ export class FilterSideBarComponent implements OnInit {
@Output() checkCategory = new EventEmitter();
@Output() stateNumber = new EventEmitter();
@Output() rangeNumber = new EventEmitter();
@Output() reset = new EventEmitter();
filterStateNumber: number = 0;
public selectedCategory: string[];
constructor() {
this.listCategories = [];
this.selectedCategory = [];
@ -45,13 +45,23 @@ export class FilterSideBarComponent implements OnInit {
this.filterStateNumber = stateNumber;
}
onSendRating():void {
onSendRating(): void {
this.stateNumber.emit(this.filterStateNumber);
}
onSendValues(minNum: any, maxNum: any): void {
if (minNum.value == '') {
minNum.value = 0;
}
if (maxNum.value == '') {
maxNum.value = 1000;
}
let rangeArray: number[] = [parseFloat(minNum.value), parseFloat(maxNum.value)];
console.log(typeof(rangeArray[0]));
this.rangeNumber.emit(rangeArray);
}
onReset(): void {
this.reset.emit();
}
}

View file

@ -1,2 +1,2 @@
<i class="bi-{{iconName}}"
[ngStyle]="{'font-size.rem': iconSize, 'color': iconColor}"></i>
[ngStyle]="{'font-size.rem': iconSize, 'color': iconColor}"></i>

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { IconComponent } from './icon.component';
import {IconComponent} from './icon.component';
describe('IconComponent', () => {
let component: IconComponent;
@ -8,7 +8,7 @@ describe('IconComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ IconComponent ]
declarations: [IconComponent]
})
.compileComponents();
});

View file

@ -1,4 +1,4 @@
import { Component, Input, OnInit } from '@angular/core';
import {Component, Input, OnInit} from '@angular/core';
@Component({
selector: 'app-icon',
@ -9,7 +9,9 @@ export class IconComponent implements OnInit {
@Input() iconName!: string;
@Input() iconSize!: number;
@Input() iconColor!: string;
constructor() { }
constructor() {
}
ngOnInit(): void {
}

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { NavBarComponent } from './nav-bar.component';
import {NavBarComponent} from './nav-bar.component';
describe('NavBarComponent', () => {
let component: NavBarComponent;
@ -8,7 +8,7 @@ describe('NavBarComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ NavBarComponent ]
declarations: [NavBarComponent]
})
.compileComponents();
});

View file

@ -1,6 +1,6 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { PlantouneService } from 'src/app/services/plantoune.service';
import {Component, OnDestroy, OnInit} from '@angular/core';
import {Subscription} from 'rxjs';
import {PlantouneService} from 'src/app/services/plantoune.service';
@Component({
selector: 'app-nav-bar',
@ -19,7 +19,7 @@ export class NavBarComponent implements OnInit, OnDestroy {
this.subPlantLiked = this.plantouneService.plantLiked$.subscribe(
() => {
console.log('Get new event from Subject');
this.likeCounter ++;
this.likeCounter++;
}
)
}

View file

@ -1,16 +1,16 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { PageForgotPasswordComponent } from './pages/page-forgot-password/page-forgot-password.component';
import { PageResetPasswordComponent } from './pages/page-reset-password/page-reset-password.component';
import { PageSigninComponent } from './pages/page-signin/page-signin.component';
import { PageSignupComponent } from './pages/page-signup/page-signup.component';
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {PageForgotPasswordComponent} from './pages/page-forgot-password/page-forgot-password.component';
import {PageResetPasswordComponent} from './pages/page-reset-password/page-reset-password.component';
import {PageSigninComponent} from './pages/page-signin/page-signin.component';
import {PageSignupComponent} from './pages/page-signup/page-signup.component';
const routes: Routes = [
{path : '', redirectTo:'signin', pathMatch: 'full'},
{path : "signin", component : PageSigninComponent},
{path : "signup", component : PageSignupComponent},
{path : "forgot-password", component : PageForgotPasswordComponent},
{path : "reset-password", component : PageResetPasswordComponent}
{path: '', redirectTo: 'signin', pathMatch: 'full'},
{path: "signin", component: PageSigninComponent},
{path: "signup", component: PageSignupComponent},
{path: "forgot-password", component: PageForgotPasswordComponent},
{path: "reset-password", component: PageResetPasswordComponent}
];
@ -18,4 +18,5 @@ const routes: Routes = [
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AccountRoutingModule { }
export class AccountRoutingModule {
}

View file

@ -1,11 +1,11 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import { AccountRoutingModule } from './account-routing.module';
import { PageSignupComponent } from './pages/page-signup/page-signup.component';
import { PageSigninComponent } from './pages/page-signin/page-signin.component';
import { PageForgotPasswordComponent } from './pages/page-forgot-password/page-forgot-password.component';
import { PageResetPasswordComponent } from './pages/page-reset-password/page-reset-password.component';
import {AccountRoutingModule} from './account-routing.module';
import {PageSignupComponent} from './pages/page-signup/page-signup.component';
import {PageSigninComponent} from './pages/page-signin/page-signin.component';
import {PageForgotPasswordComponent} from './pages/page-forgot-password/page-forgot-password.component';
import {PageResetPasswordComponent} from './pages/page-reset-password/page-reset-password.component';
@NgModule({
@ -20,4 +20,5 @@ import { PageResetPasswordComponent } from './pages/page-reset-password/page-res
AccountRoutingModule
]
})
export class AccountModule { }
export class AccountModule {
}

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { PageForgotPasswordComponent } from './page-forgot-password.component';
import {PageForgotPasswordComponent} from './page-forgot-password.component';
describe('PageForgotPasswordComponent', () => {
let component: PageForgotPasswordComponent;
@ -8,7 +8,7 @@ describe('PageForgotPasswordComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageForgotPasswordComponent ]
declarations: [PageForgotPasswordComponent]
})
.compileComponents();
});

View file

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-page-forgot-password',
@ -7,7 +7,8 @@ import { Component, OnInit } from '@angular/core';
})
export class PageForgotPasswordComponent implements OnInit {
constructor() { }
constructor() {
}
ngOnInit(): void {
}

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { PageResetPasswordComponent } from './page-reset-password.component';
import {PageResetPasswordComponent} from './page-reset-password.component';
describe('PageResetPasswordComponent', () => {
let component: PageResetPasswordComponent;
@ -8,7 +8,7 @@ describe('PageResetPasswordComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageResetPasswordComponent ]
declarations: [PageResetPasswordComponent]
})
.compileComponents();
});

View file

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-page-reset-password',
@ -7,7 +7,8 @@ import { Component, OnInit } from '@angular/core';
})
export class PageResetPasswordComponent implements OnInit {
constructor() { }
constructor() {
}
ngOnInit(): void {
}

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { PageSigninComponent } from './page-signin.component';
import {PageSigninComponent} from './page-signin.component';
describe('PageSigninComponent', () => {
let component: PageSigninComponent;
@ -8,7 +8,7 @@ describe('PageSigninComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageSigninComponent ]
declarations: [PageSigninComponent]
})
.compileComponents();
});

View file

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-page-signin',
@ -7,7 +7,8 @@ import { Component, OnInit } from '@angular/core';
})
export class PageSigninComponent implements OnInit {
constructor() { }
constructor() {
}
ngOnInit(): void {
}

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { PageSignupComponent } from './page-signup.component';
import {PageSignupComponent} from './page-signup.component';
describe('PageSignupComponent', () => {
let component: PageSignupComponent;
@ -8,7 +8,7 @@ describe('PageSignupComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageSignupComponent ]
declarations: [PageSignupComponent]
})
.compileComponents();
});

View file

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-page-signup',
@ -7,7 +7,8 @@ import { Component, OnInit } from '@angular/core';
})
export class PageSignupComponent implements OnInit {
constructor() { }
constructor() {
}
ngOnInit(): void {
}

View file

@ -1,5 +1,7 @@
<div class="d-flex align-items-stretch">
<app-filter-side-bar [listCategories]="listCategoriesFilter" (stateNumber)="onRatingFilter($event)" (rangeNumber)="onPriceFilter($event)" (checkCategory)="onListCategory($event)"></app-filter-side-bar>
<app-filter-side-bar [listCategories]="listCategoriesFilter" (stateNumber)="onRatingFilter($event)"
(rangeNumber)="onPriceFilter($event)" (checkCategory)="onListCategory($event)"
(reset)="onResetFilter()"></app-filter-side-bar>
<div class="custom-main container p-3">
<input class="form-control"
type="text"

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { PageAccueilComponent } from './page-accueil.component';
import {PageAccueilComponent} from './page-accueil.component';
describe('PageAccueilComponent', () => {
let component: PageAccueilComponent;
@ -8,7 +8,7 @@ describe('PageAccueilComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageAccueilComponent ]
declarations: [PageAccueilComponent]
})
.compileComponents();
});

View file

@ -1,9 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { PlantouneService } from 'src/app/services/plantoune.service';
import {Component, OnInit} from '@angular/core';
import {PlantouneService} from 'src/app/services/plantoune.service';
import * as _ from 'underscore';
import { contains, includes } from 'underscore';
@Component({
@ -13,19 +10,21 @@ import { contains, includes } from 'underscore';
})
export class PageAccueilComponent implements OnInit {
public listData: any[];
public listPricePlant : any[];
public clickCounter : any;
public listDataGlobal : any[];
public listPricePlant: any[];
public clickCounter: any;
public listDataGlobal: any[];
public listDataFilter: any[];
public listCategoriesFilter: string[];
public dataFilterCategory : any;
public category: string[];
public choix: string;
public rangeNumber: number[];
public stateNumber: number;
public isCategoryFilterActive: boolean;
public isPricingFilterActive: boolean;
public isRatingFilterActive: boolean;
public isSearchFilterActive: boolean;
constructor(private plantouneService: PlantouneService) {
this.listData = [];
@ -35,11 +34,15 @@ export class PageAccueilComponent implements OnInit {
this.clickCounter = 0;
this.listDataFilter = [];
this.category = [];
this.choix = '';
this.rangeNumber = [];
this.stateNumber = 0;
this.isCategoryFilterActive = false;
this.isPricingFilterActive = false;
this.isRatingFilterActive = false;
this.isSearchFilterActive = false;
this.clickCounter = 0;
}
@ -72,7 +75,6 @@ export class PageAccueilComponent implements OnInit {
// console.log(listUniqCategories);
/**
* Technique native JS pour recupérer les catégories uniques de nos plantes
*/
@ -94,51 +96,74 @@ export class PageAccueilComponent implements OnInit {
this.plantouneService.plantLiked$.next('');
}
onRecherchePlante(choix: any) {
// onRecherchePlante(choix: any) {
//
// this.clickCounter ++
// console.log(this.clickCounter)
// this.listData = [...this.listDataGlobal];
// if (this.clickCounter %2) {
// this.listData.sort((a, b) => parseFloat(a.product_price) - parseFloat(b.product_price));
// }else{
// this.listData.sort((a, b) => parseFloat(b.product_price) - parseFloat(a.product_price));
// }
// const search = choix.target.value
// if (search == '') {
// this.listData = [...this.listDataGlobal];
// }
// console.log(search);
// this.listData = this.listData.filter((plant) => {
// if(plant.product_name.toLowerCase().includes(search.toLowerCase())){
// return plant;
// }
// });
// //Equivaut à la ligne ci-dessous (version abrégée)
// //this.listData = this.listDataGlobal.filter((plant) => plant.product_name.toLowerCase().includes(search.toLowerCase()))
// console.log(this.listData);
// if (this.listData.length >= 9) {this.listData.length=9}
// }
this.clickCounter ++
console.log(this.clickCounter)
if (this.clickCounter %2) {
this.listData.sort((a, b) => parseFloat(a.product_price) - parseFloat(b.product_price));
}else{
this.listData.sort((a, b) => parseFloat(b.product_price) - parseFloat(a.product_price));
}
const search = choix.target.value
console.log(search);
this.listData = this.listDataGlobal.filter((plant) => {
if(plant.product_name.toLowerCase().includes(search.toLowerCase())){
return plant;
}
});
//Equivaut à la ligne ci-dessous (version abrégée)
//this.listData = this.listDataGlobal.filter((plant) => plant.product_name.toLowerCase().includes(search.toLowerCase()))
console.log(this.listData);
if (this.listData.length >= 9) {this.listData.length=9}
}
// onListCategory(categoryArray: string[]) {
// // this.listData=listData;
// //console.log(typeof(valueText));
//
// if (categoryArray.length == 0) {
// this.listData = [...this.listDataGlobal];
//
// } else if (categoryArray.length > 0) {
// let listProductsByCategory: string[] = [];
// this.listDataGlobal.forEach(product => {
//
// categoryArray.forEach(categorySelected => {
// if (product.product_breadcrumb_label == categorySelected) {
// listProductsByCategory.push(product);
// }
// });
// });
// this.listData = [...listProductsByCategory];
// }
//
// if (this.listData.length >= 9) {
// this.listData.length = 9;
// }
// }
onListCategory(categoryArray: string[]) {
// this.listData=listData;
//console.log(typeof(valueText));
if(categoryArray.length == 0) {
if (categoryArray.length == 0) {
this.listData = [...this.listDataGlobal];
} else if(categoryArray.length > 0) {
let listProductsByCategory:string[] = [];
this.listDataGlobal.forEach(product => {
categoryArray.forEach(categorySelected => {
if (product.product_breadcrumb_label == categorySelected){
listProductsByCategory.push(product);
}
});
});
this.listData= [...listProductsByCategory];
this.isCategoryFilterActive = false;
} else {
this.category = [...categoryArray];
this.isCategoryFilterActive = true;
}
if(this.listData.length>=9){
this.listData.length=9;
this.onApplyFilters();
}
onRecherchePlante(choix: any) {
this.choix = choix.target.value;
this.isSearchFilterActive = true;
this.onApplyFilters();
}
onRatingFilter(stateNumber: number): void {
@ -158,71 +183,203 @@ console.log(this.clickCounter)
onApplyFilters(): void {
this.clickCounter = 0;
if(this.isPricingFilterActive) {
if (this.isCategoryFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
if(parseFloat(product.product_unitprice_ati) >= this.rangeNumber[0] && parseFloat(product.product_unitprice_ati) <= this.rangeNumber[1]) {
this.category.forEach(categorySelected => {
if (product.product_breadcrumb_label == categorySelected) {
listDataFinal.push(product);
}
});
});
this.listData = [...listDataFinal];
}
if (this.isSearchFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
if (product.product_name.toLowerCase().includes(this.choix.toLowerCase())) {
listDataFinal.push(product);
}
});
this.listData = [...listDataFinal];
}
if(this.isRatingFilterActive) {
if (this.isPricingFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
if(product.product_rating >= this.stateNumber) {
if (parseFloat(product.product_unitprice_ati) >= this.rangeNumber[0]
&& parseFloat(product.product_unitprice_ati) <= this.rangeNumber[1]) {
listDataFinal.push(product);
}
});
this.listData = [...listDataFinal];
}
if(this.isPricingFilterActive && this.isRatingFilterActive) {
if (this.isRatingFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
if(parseFloat(product.product_unitprice_ati) >= this.rangeNumber[0]
if (product.product_rating >= this.stateNumber) {
listDataFinal.push(product);
}
});
this.listData = [...listDataFinal];
}
if (this.isSearchFilterActive && this.isCategoryFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
this.category.forEach(categorySelected => {
if (product.product_breadcrumb_label == categorySelected
&& product.product_name.toLowerCase().includes(this.choix.toLowerCase())) {
listDataFinal.push(product);
}
});
});
this.listData = [...listDataFinal];
}
if (this.isPricingFilterActive && this.isCategoryFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
this.category.forEach(categorySelected => {
if (product.product_breadcrumb_label == categorySelected
&& parseFloat(product.product_unitprice_ati) >= this.rangeNumber[0]
&& parseFloat(product.product_unitprice_ati) <= this.rangeNumber[1]) {
listDataFinal.push(product);
}
});
});
this.listData = [...listDataFinal];
}
if (this.isRatingFilterActive && this.isCategoryFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
this.category.forEach(categorySelected => {
if (product.product_breadcrumb_label == categorySelected
&& product.product_rating >= this.stateNumber) {
listDataFinal.push(product);
}
});
});
this.listData = [...listDataFinal];
}
if (this.isSearchFilterActive && this.isPricingFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
if (parseFloat(product.product_unitprice_ati) >= this.rangeNumber[0]
&& parseFloat(product.product_unitprice_ati) <= this.rangeNumber[1]
&& product.product_name.toLowerCase().includes(this.choix.toLowerCase())) {
listDataFinal.push(product);
}
});
this.listData = [...listDataFinal];
}
if (this.isSearchFilterActive && this.isRatingFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
if (product.product_rating >= this.stateNumber
&& product.product_name.toLowerCase().includes(this.choix.toLowerCase())) {
listDataFinal.push(product);
}
});
this.listData = [...listDataFinal];
}
if (this.isPricingFilterActive && this.isRatingFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
if (parseFloat(product.product_unitprice_ati) >= this.rangeNumber[0]
&& parseFloat(product.product_unitprice_ati) <= this.rangeNumber[1]
&& product.product_rating >= this.stateNumber) {
listDataFinal.push(product);
}
});
this.listData = [...listDataFinal];
console.log(this.listData);
}
if(this.listData.length >= 9) this.listData.length = 9;
if (this.isSearchFilterActive && this.isPricingFilterActive && this.isRatingFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
if (product.product_rating >= this.stateNumber && parseFloat(product.product_unitprice_ati) >= this.rangeNumber[0]
&& parseFloat(product.product_unitprice_ati) <= this.rangeNumber[1]
&& product.product_name.toLowerCase().includes(this.choix.toLowerCase())) {
listDataFinal.push(product);
}
});
this.listData = [...listDataFinal];
}
if (this.isCategoryFilterActive && this.isSearchFilterActive && this.isPricingFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
this.category.forEach(categorySelected => {
if (product.product_breadcrumb_label == categorySelected
&& parseFloat(product.product_unitprice_ati) >= this.rangeNumber[0]
&& parseFloat(product.product_unitprice_ati) <= this.rangeNumber[1]
&& product.product_name.toLowerCase().includes(this.choix.toLowerCase())) {
listDataFinal.push(product);
}
});
});
this.listData = [...listDataFinal];
}
if (this.isRatingFilterActive && this.isCategoryFilterActive && this.isSearchFilterActive && this.isPricingFilterActive) {
let listDataFinal: any = [];
this.listDataGlobal.forEach(product => {
this.category.forEach(categorySelected => {
if (product.product_breadcrumb_label == categorySelected
&& product.product_rating >= this.stateNumber
&& parseFloat(product.product_unitprice_ati) >= this.rangeNumber[0]
&& parseFloat(product.product_unitprice_ati) <= this.rangeNumber[1]
&& product.product_name.toLowerCase().includes(this.choix.toLowerCase())) {
listDataFinal.push(product);
}
});
});
this.listData = [...listDataFinal];
}
if (this.listData.length >= 9) this.listData.length = 9;
}
onResetFilter(): void {
window.location.reload();
}
//Tri des prix des plantes par ordre croissant ou décroissant
onPriceTri() : void {
onPriceTri(): void {
this.clickCounter ++
this.clickCounter++
console.log(this.clickCounter)
if (this.clickCounter %2) {
if (this.clickCounter % 2) {
this.listData.sort((a, b) => parseFloat(a.product_price) - parseFloat(b.product_price));
}else{
} else {
this.listData.sort((a, b) => parseFloat(b.product_price) - parseFloat(a.product_price));
}
}
//Tri des noms des plantes par ordre alphanumérique
onAlphaTri() : void {
onAlphaTri(): void {
this.clickCounter ++
if (this.clickCounter %2) {
this.clickCounter++
if (this.clickCounter % 2) {
this.listData.sort((a, b) => (a.product_name > b.product_name) ? 1 : -1)
}else{
} else {
this.listData.sort((a, b) => (b.product_name > a.product_name) ? 1 : -1)
}
}
//Tri des avis des plantes par ordre croissant ou décroissant
onRatingTri() : void{
this.clickCounter ++
if (this.clickCounter %2) {
onRatingTri(): void {
this.clickCounter++
if (this.clickCounter % 2) {
this.listData.sort((a, b) => (a.product_rating > b.product_rating) ? 1 : -1)
}else{
} else {
this.listData.sort((a, b) => (b.product_rating > a.product_rating) ? 1 : -1)
}
}

View file

@ -3,7 +3,7 @@
<img src="{{detailsPlant.product_url_picture}}" class="col-sm-5" style="width: 30rem;"
alt="Image de {{ detailsPlant.product_name }}">
<div class="card-content">
<app-avis-bar></app-avis-bar>
<app-avis-bar [ratingIndex]="detailsPlant.product_rating"></app-avis-bar>
</div>
</div>
<div class="d-flex align-items-start flex-column mt-4 ">
@ -14,7 +14,8 @@
<div class="card-content">
</div>
<div style="border-style: solid; border-color: green; margin: auto; text-align: left; margin-right: 20%;padding: 2%;">
<div
style="border-style: solid; border-color: green; margin: auto; text-align: left; margin-right: 20%;padding: 2%;">
<p>
Plante appréciant la chaleur et un bon réseau wifi,
interconnectée avec son propriétaire et détestant les chats.
@ -22,10 +23,11 @@
mois de juin.
</p>
</div>
<a href="#" class="card-content" class="btn btn-success">Je l'ajoute à mon panier : {{ detailsPlant.product_unitprice_ati }} €</a>
<a href="#" class="card-content" class="btn btn-success">Je l'ajoute à mon panier
: {{ detailsPlant.product_unitprice_ati }} €</a>
<div>Quantité restante : {{detailsPlant.product_qty}}</div>
<a href="#" class="btn btn-success" style="margin-left: 75%" >Voir mon panier</a>
<a href="#" class="btn btn-success" style="margin-left: 75%">Voir mon panier</a>
</div>
</div>

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { PageDetailsComponent } from './page-details.component';
import {PageDetailsComponent} from './page-details.component';
describe('PageDetailsComponent', () => {
let component: PageDetailsComponent;
@ -8,7 +8,7 @@ describe('PageDetailsComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageDetailsComponent ]
declarations: [PageDetailsComponent]
})
.compileComponents();
});

View file

@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { PlantouneService } from 'src/app/services/plantoune.service';
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {PlantouneService} from 'src/app/services/plantoune.service';
@Component({

View file

@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import { PageNotFoundComponent } from './page-not-found.component';
import {PageNotFoundComponent} from './page-not-found.component';
describe('PageNotFoundComponent', () => {
let component: PageNotFoundComponent;
@ -8,7 +8,7 @@ describe('PageNotFoundComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageNotFoundComponent ]
declarations: [PageNotFoundComponent]
})
.compileComponents();
});

View file

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-page-not-found',
@ -7,7 +7,8 @@ import { Component, OnInit } from '@angular/core';
})
export class PageNotFoundComponent implements OnInit {
constructor() { }
constructor() {
}
ngOnInit(): void {
}

View file

@ -1,6 +1,6 @@
import { TestBed } from '@angular/core/testing';
import {TestBed} from '@angular/core/testing';
import { PlantouneService } from './plantoune.service';
import {PlantouneService} from './plantoune.service';
describe('PlantouneService', () => {
let service: PlantouneService;

View file

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Observable, Subject} from 'rxjs';
import {HttpClient} from '@angular/common/http';
@Injectable({
providedIn: 'root'
@ -8,14 +8,15 @@ import { HttpClient } from '@angular/common/http';
export class PlantouneService {
plantLiked$ = new Subject<any>();
constructor(private httpClient: HttpClient) { }
constructor(private httpClient: HttpClient) {
}
getData(): Observable<any[]> {
return this.httpClient.get<any[]>('http://localhost:3000/list_products');
}
getPlantById(id : any): Observable<any[]> {
getPlantById(id: any): Observable<any[]> {
return this.httpClient.get<any[]>('http://localhost:3000/list_products?product_id=' + id);
}
}

View file

@ -9,6 +9,6 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
</head>
<body>
<app-root></app-root>
<app-root></app-root>
</body>
</html>

View file

@ -1,8 +1,8 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import {enableProdMode} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import {AppModule} from './app/app.module';
import {environment} from './environments/environment';
if (environment.production) {
enableProdMode();

View file

@ -1,11 +1,8 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
import {getTestBed} from '@angular/core/testing';
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing';
declare const require: {
context(path: string, deep?: boolean, filter?: RegExp): {