Merge branch 'dev' into Vincent

ok
This commit is contained in:
Vincent Ramiere 2022-02-16 15:09:49 +01:00
commit b774a93da7
44 changed files with 940 additions and 54 deletions

14
package-lock.json generated
View File

@ -17,6 +17,7 @@
"@angular/platform-browser-dynamic": "~13.0.0", "@angular/platform-browser-dynamic": "~13.0.0",
"@angular/router": "~13.0.0", "@angular/router": "~13.0.0",
"bootstrap": "^5.1.3", "bootstrap": "^5.1.3",
"bootstrap-icons": "^1.7.2",
"rxjs": "~7.4.0", "rxjs": "~7.4.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"zone.js": "~0.11.4" "zone.js": "~0.11.4"
@ -3401,6 +3402,14 @@
"@popperjs/core": "^2.10.2" "@popperjs/core": "^2.10.2"
} }
}, },
"node_modules/bootstrap-icons": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.7.2.tgz",
"integrity": "sha512-NiR2PqC73AQOPdVSu6GJfnk+hN2z6powcistXk1JgPnKuoV2FSdSl26w931Oz9HYbKCcKUSB6ncZTYJAYJl3QQ==",
"engines": {
"node": ">=10"
}
},
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -15041,6 +15050,11 @@
"integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==", "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==",
"requires": {} "requires": {}
}, },
"bootstrap-icons": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.7.2.tgz",
"integrity": "sha512-NiR2PqC73AQOPdVSu6GJfnk+hN2z6powcistXk1JgPnKuoV2FSdSl26w931Oz9HYbKCcKUSB6ncZTYJAYJl3QQ=="
},
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",

View File

@ -20,6 +20,7 @@
"@angular/platform-browser-dynamic": "~13.0.0", "@angular/platform-browser-dynamic": "~13.0.0",
"@angular/router": "~13.0.0", "@angular/router": "~13.0.0",
"bootstrap": "^5.1.3", "bootstrap": "^5.1.3",
"bootstrap-icons": "^1.7.2",
"rxjs": "~7.4.0", "rxjs": "~7.4.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"zone.js": "~0.11.4" "zone.js": "~0.11.4"

View File

@ -5,6 +5,7 @@ import { HomePageComponent } from './pages/home-page/home-page.component';
import { ListCategoriesComponent } from './pages/list-categories/list-categories.component'; import { ListCategoriesComponent } from './pages/list-categories/list-categories.component';
import { RestoPageComponent } from './pages/resto-page/resto-page.component'; import { RestoPageComponent } from './pages/resto-page/resto-page.component';
import { PageNotFoundComponent } from './pages/page-not-found/page-not-found.component'; import { PageNotFoundComponent } from './pages/page-not-found/page-not-found.component';
import { FiltersPageComponent } from './pages/filters-page/filters-page.component';
import { SigninComponent } from './pages/signin/signin.component'; import { SigninComponent } from './pages/signin/signin.component';
const routes: Routes = [ const routes: Routes = [
@ -12,6 +13,7 @@ const routes: Routes = [
{ path: 'home', component: HomePageComponent }, { path: 'home', component: HomePageComponent },
{ path: 'categories', component: ListCategoriesComponent }, { path: 'categories', component: ListCategoriesComponent },
{ path: 'favoris', component: FavorisUserComponent }, { path: 'favoris', component: FavorisUserComponent },
{ path: 'filtres', component: FiltersPageComponent },
{ path: 'Deconnexion', redirectTo: 'home'}, { path: 'Deconnexion', redirectTo: 'home'},
{path: 'restaurants',component: RestoPageComponent}, {path: 'restaurants',component: RestoPageComponent},
{path: 'page-not-found',component: PageNotFoundComponent}, {path: 'page-not-found',component: PageNotFoundComponent},

View File

@ -14,6 +14,10 @@ import { ListCategoriesComponent } from './pages/list-categories/list-categories
import { SigninComponent } from './pages/signin/signin.component'; import { SigninComponent } from './pages/signin/signin.component';
import { RestoPageComponent } from './pages/resto-page/resto-page.component'; import { RestoPageComponent } from './pages/resto-page/resto-page.component';
import { PageNotFoundComponent } from './pages/page-not-found/page-not-found.component'; import { PageNotFoundComponent } from './pages/page-not-found/page-not-found.component';
import { FiltersPageComponent } from './pages/filters-page/filters-page.component';
import { AvisBarComponent } from './filters/avis-bar/avis-bar.component';
import { IconComponent } from './filters/icon/icon.component';
import { TemplatePageComponent } from './components/template-page/template-page.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -27,7 +31,11 @@ import { PageNotFoundComponent } from './pages/page-not-found/page-not-found.com
ListCategoriesComponent, ListCategoriesComponent,
RestoPageComponent, RestoPageComponent,
PageNotFoundComponent, PageNotFoundComponent,
SigninComponent FiltersPageComponent,
AvisBarComponent,
IconComponent,
SigninComponent,
TemplatePageComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View File

@ -4,7 +4,7 @@
<div class="card-body rounded-bottom"> <div class="card-body rounded-bottom">
<a routerLink="../restaurants" class="btn">{{ categoryData.libelle }}</a> <a routerLink="../restaurants" class="btn" (click)="onClickCateg(categoryData.id)">{{ categoryData.libelle }}</a>
</div> </div>
</div> </div>

View File

@ -1,4 +1,6 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ApiBackService } from '../services/api-back.service';
@Component({ @Component({
selector: 'app-card-category', selector: 'app-card-category',
@ -9,9 +11,18 @@ export class CardCategoryComponent implements OnInit {
@Input() categoryData : any; @Input() categoryData : any;
constructor() { } constructor(private apiBackService : ApiBackService, private route : Router, private activatedRoute : ActivatedRoute) { }
ngOnInit(): void { ngOnInit(): void {
} }
onClickCateg(id : number){
this.apiBackService.getRestaurantsByCateg(id , this.activatedRoute.snapshot.routeConfig?.path);
// on fait passer en second parametre le path de la route c'est a dire "home"(pour l'instant)
this.route.navigate(['restaurants']);
}
} }

View File

@ -1 +1,92 @@
<p>card-resto works!</p> <div class="container position-relative shadow p-0 mb-5 bg-body rounded rounded m-5 rounded-top "
style="width: 21rem;">
<img class="card-img-top " src="assets/ImagesRestos/photo.jpg" alt="Card image cap">
<div class="rond position-absolute">
<app-icon class="heart"
[iconName]="isLiked ? 'heart-fill' : 'heart'"
[iconColor]="'#e35d6a'"
(click)="onClickLike()"></app-icon></div>
<div class="card-body rounded-bottom">
<h3 class="titre-resto d-flex justify-content-center d-flex align-items-center" style="font-size: 24px;">
{{restaurant.nom }}</h3>
<div class="accordion " id="accordionExample">
<h2 class="accordion-header pt-1" id="headingOne">
<button class="btn accordion-button collapsed ps-5 pe-5 " type="button" data-bs-toggle="collapse"
[attr.data-bs-target]="'#restaurant'+ restaurant.id" aria-expanded="true" aria-controls="collapseOne">
PLUS D'INFOS</button>
</h2>
<div id="restaurant{{restaurant.id}}" class="accordion-collapse collapse" aria-labelledby="headingOne"
data-bs-parent="#accordionExample">
<div class=" body accordion-body">
<strong>This is the first item's accordion body.</strong>
<div class="star-icon d-flex justify-content-flex-start d-flex align-items-center pt-2 ">
<ul class="avis-star d-flex flex-row ps-1 pt-3 pe-0 pb-0 mb-0 ">
<li class="star pe-2"><i class="bi bi-star-fill"></i></li>
<li class="star pe-2"><i class="bi bi-star-fill"></i></li>
<li class="star pe-2"><i class="bi bi-star-fill"></i></li>
<li class="star pe-2"><i class="bi bi-star-fill"></i></li>
<li class="star"><i class="bi bi-star-fill"></i></li>
</ul>
<span class="ps-3 mt-3 " style="font-size: 1.1em; color:#545454">5/5</span>
</div>
<div class="infos ps-1 pt-2" style="color:#545454">
<div>
<span class="categorie pe-4" style="font-style: italic;" *ngFor="let categorie of restaurant.typerestaus">{{ categorie.libelle }}</span>
</div>
<div>
<i class="fas fa-walking ps-2 pe-1" style="color:#a8a8a8"></i>
<span class="categorie pe-4" style="font-weight: bold;">{{distance}} mètres</span>
</div>
<div>
<i class="fas fa-euro-sign ps-2 pe-1" style="color:#a8a8a8"></i>
<span class="prix" style="font-weight: bold;">5-10€</span>
</div>
</div>
<div class="trait-rouge pt-3"></div>
<div *ngIf="restaurant.website; else noWebsite">
<p class="description pt-3 ps-1 pe-1 text-justify d-block" style="font-size:0.9em; color:#545454">
<a href="{{restaurant.website}}" class="description pe-1" style="font-style: italic;font-weight: bold;">Site Web</a>
</p>
</div>
<!-- le else de notre *ngIf plus haut-->
<ng-template #noWebsite class="description pe-1" style="font-style: italic;font-weight: bold;">
<div>
<p class="description pt-3 ps-1 pe-1 text-justify d-block" style="font-size:0.9em; color:#545454"> Pas de site Web </p>
</div>
</ng-template>
<!-- ------------------------------------ -->
<div class="trait-rouge pt-2 pb-0"></div>
<div class="critere ps-1 pt-3">
<span class="sur-place pe-3" style="color:#545454">Sur place :</span>
<app-icon
[iconName]="restaurant.surPlace ? 'bi bi-check-square-fill' : 'bi bi-x-square-fill ps-2 pt-1 '"
[iconColor]="restaurant.surPlace ? '#4ECB71' : '#ED2F2F'"
></app-icon>
<span class="a-emporter pe-2 ps-4 " style="color:#545454">A emporter :</span>
<app-icon
[iconName]="restaurant.emporter ? 'bi bi-check-square-fill' : 'bi bi-x-square-fill ps-2 pt-1'"
[iconColor]="restaurant.emporter ? '#4ECB71' : '#ED2F2F'"
></app-icon>
</div>
<div class="trait-rouge pt-3"></div>
<div class="critere d-flex justify-content-center ps-1 pt-3 pb-3">
<span class="acces-pmr pe-1" style="color:#545454">Accès PMR :</span>
<app-icon
[iconName]="restaurant.accesPMR ? 'bi bi-check-square-fill' : 'bi bi-x-square-fill ps-1 pt-1'"
[iconColor]="restaurant.accesPMR ? '#4ECB71' : '#ED2F2F'"
></app-icon>
</div>
<div class="reserver pt-2">
<button type="button" class="button">Réserver</button>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,90 @@
.rond{
padding: 1em;
background-color: rgb(255, 255, 255);
top: 1em;
right: 1em;
border-radius: 50%;
width: 50px;
height: 50px;
}
.heart{
position: absolute;
top: 7px;
left: 13px;
font-size: 1.5em;
transform: rotate(5deg);
}
.titre-resto{
margin-bottom: 0.9rem;
}
.btn{
position: absolute;
background-color: #CE0000;
color: #fff;
width: 100%;
right: 0;
border-radius: 0 0 0.25rem 0.25rem;
padding: 1.375rem 0.75rem;
}
.accordion-button.collapsed {
background: #CE0000;
}
.accordion-button.collapsed::after {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}
.ps-5 {
padding-left: 6.4rem !important;
}
.pe-5 {
padding-right: 6rem !important;
}
.accordion .btn:focus{
box-shadow: none;
}
.star{
list-style-type: none;
font-size: 1.5em;
color:#ffd900;
}
.trait-rouge{
border-bottom: 1px solid #CE0000;
opacity: 50%;
}
.button{
display: block;
padding: 0.5em 2em 0.5em ;
width: 100%;
border-radius: 5px;
border: none;
background-color: #545454;
color: #ffffff;
text-transform: uppercase;
font-weight: bold;
}

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core'; import { Component,EventEmitter, Input, Output, OnInit } from '@angular/core';
@Component({ @Component({
selector: 'app-card-resto', selector: 'app-card-resto',
@ -7,9 +7,56 @@ import { Component, OnInit } from '@angular/core';
}) })
export class CardRestoComponent implements OnInit { export class CardRestoComponent implements OnInit {
constructor() { } @Input() restaurant : any ;
distance : number;
@Input() likeResto: any;
@Output() clickLike = new EventEmitter<boolean>();
isLiked : boolean = false;
constructor() {
this.distance = 0 ;
}
ngOnInit(): void { ngOnInit(): void {
console.log(this.restaurant);
this.distance = Math.round(
this.getDistanceFromLatLonInKm(
48.86201110271593 , //latitude Simplon
2.4361804827725417, //longitude Simplon
this.restaurant.latitude,
this.restaurant.longitude)
);
console.log(this.distance);
}
onClickLike() {
console.log('click');
this.isLiked = !this.isLiked;
this.clickLike.emit(this.isLiked);
} }
getDistanceFromLatLonInKm(lat1 : number , lon1 : number, lat2 : number, lon2 : number) {
let R = 6371; // Radius of the earth in km
let dLat = this.deg2rad(lat2-lat1); // deg2rad below
let dLon = this.deg2rad(lon2-lon1);
let a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(this.deg2rad(lat1)) * Math.cos(this.deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
let d = R * c * 1000; // Distance in meters
return d;
}
deg2rad(deg : number) {
return deg * (Math.PI/180)
}
} }

View File

@ -0,0 +1,6 @@
<h2 class="titre ">{{title}}</h2>
<div class="separation"></div>
<div class="parent d-flex justify-content-center align-items-start flex-wrap flex-row ">
<ng-content></ng-content>
</div>

View File

@ -0,0 +1,15 @@
.separation{
display: flex;
justify-content: flex-start;
border-bottom: 2px solid #CE0000;
max-width: 83%;
}
.titre{
display: flex;
justify-content: flex-start;
margin: 2.5em 0 0.5em 8.2em;
color: #CE0000;
}

View File

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

View File

@ -0,0 +1,16 @@
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-template-page',
templateUrl: './template-page.component.html',
styleUrls: ['./template-page.component.scss']
})
export class TemplatePageComponent implements OnInit {
@Input() title!: string;
constructor() { }
ngOnInit(): void {
}
}

View File

@ -0,0 +1,10 @@
<div (mouseleave)="onMouseLeave()">
<app-icon *ngFor="let star of starStates; let starIndex = index"
[iconName]="star.stateHoverUser ? 'bi-star-fill' : 'bi-star'"
[iconSize]="2.5"
[iconColor]="'#ffbf00'"
style="padding: 6px;"
(mouseover)="onMouseOver(starIndex)"
(click)="onClickStar(starIndex)"
></app-icon>
</div>

View File

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

View File

@ -0,0 +1,70 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
@Component({
selector: 'app-avis-bar',
templateUrl: './avis-bar.component.html',
styleUrls: ['./avis-bar.component.scss']
})
export class AvisBarComponent implements OnInit {
starStates: {stateSelectedUser : boolean, stateHoverUser : boolean}[];
@Output() stateNumber = new EventEmitter();
starStateNumber: number = 0;
constructor() {
this.starStates = [];
for (let index = 0; index < 5; index++) {
this.starStates.push(
{
stateSelectedUser : false,
stateHoverUser : false
}
);
}
}
ngOnInit(): void {
}
onMouseOver(index: number) {
for (let i = 0; i < this.starStates.length ; i++) {
if(i <= index) {
this.starStates[i].stateHoverUser = true;
} else {
this.starStates[i].stateHoverUser = false;
}
}
}
onMouseLeave() {
const tempTab = [];
for (let index = 0; index < this.starStates.length; index++) {
tempTab.push(
{
stateSelectedUser : this.starStates[index].stateSelectedUser,
stateHoverUser : this.starStates[index].stateSelectedUser
}
);
}
this.starStates = [...tempTab];
}
onClickStar(starIndex: number) {
this.starStateNumber = 0;
for (let i = 0; i < this.starStates.length ; i++) {
if(i <= starIndex) {
this.starStates[i].stateSelectedUser = true;
this.starStateNumber++;
} else {
this.starStates[i].stateSelectedUser = false;
}
}
//console.log(`Rating : ${this.starStateNumber}`);
this.stateNumber.emit(this.starStateNumber);
}
}

View File

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

View File

View File

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

View File

@ -0,0 +1,22 @@
import { Component, OnInit } from '@angular/core';
import { Input } from '@angular/core';
@Component({
selector: 'app-icon',
templateUrl: './icon.component.html',
styleUrls: ['./icon.component.scss']
})
export class IconComponent implements OnInit {
@Input() iconName!: string;
@Input() iconSize!: number;
@Input() iconColor!: string;
constructor() { }
ngOnInit(): void {
}
}

View File

@ -1,6 +1,6 @@
<footer class="d-flex"> <footer class="d-flex">
<div class = "logo d-inline-flex align-items-center"> <div class = "logo d-inline-flex align-items-center p-4">
<img src="../../assets/Logo_footer.png"> <img src="../../assets/Logo_footer.png">
</div> </div>

View File

@ -2,6 +2,7 @@ footer {
width: 100%; width: 100%;
height: 113px; height: 113px;
background-color: #CE0000; background-color: #CE0000;
margin-top: 4em;
} }
.liens{ .liens{
@ -9,6 +10,7 @@ footer {
} }
h5{ h5{
padding-right: 50px; padding-right: 4em;
color: white; color: white;
font-weight: lighter;
} }

View File

@ -11,18 +11,20 @@
</button> </button>
<div class="collapse navbar-collapse justify-content-end" id="nav"> <div class="collapse navbar-collapse justify-content-end" id="nav">
<div class="navbar-nav "> <div class="navbar-nav ">
<a routerLink="home" routerLinkActive="active-custom" class="nav-link p-5 " style="font-size: 25px;">Accueil</a> <a routerLink="home" routerLinkActive="active-custom" class="nav-link p-4 pe-5 " style="font-size: 21px;">Accueil</a>
<a routerLink="categories" routerLinkActive="active-custom" class="nav-link p-5" style="font-size: 25px;">Categories</a> <a routerLink="categories" routerLinkActive="active-custom" class="nav-link p-4 pe-5" style="font-size: 21px;">Categories</a>
<a routerLink="filtres" routerLinkActive="active-custom" class="nav-link p-5" style="font-size: 25px;">Filtres</a> <a routerLink="filtres" routerLinkActive="active-custom" class="nav-link p-4 pe-5" style="font-size: 21px;">Filtres</a>
<a routerLink="favoris" routerLinkActive="active-custom" class="nav-link p-5" style="font-size: 25px;">Mes favoris</a> <a routerLink="favoris" routerLinkActive="active-custom" class="nav-link p-4 pe-5" style="font-size: 21px;">Mes favoris</a>
<a routerLink="deconnexion" routerLinkActive="active-custom" class="nav-link p-5" style="font-size: 25px;">Deconnexion</a> <a routerLink="deconnexion" routerLinkActive="active-custom" class="nav-link p-4 pe-5" style="font-size: 21px;">Deconnexion</a>
</div> </div>
</div> </div>
<div id="image-header"> </div>
<div id="image-header">
<img src="assets/images-header/fond.png" alt="fond_header"> <img src="assets/images-header/fond.png" alt="fond_header">
</div> </div>
</div>
</nav> </nav>

View File

@ -1,14 +1,25 @@
#image-header{ #image-header{
display: flex; display: flex;
justify-content: center; justify-content: center;
padding-bottom: 3%;
filter: drop-shadow(0 0 0.30rem black);
width: auto;
} }
img{
width: 100%;
display: block;
margin: 0 auto;
padding: 0;
margin: 0.5em 0 0 0;
// filter: drop-shadow(0 0 0.30rem rgb(165, 165, 165));
}
.active-custom { .active-custom {
color: red !important; color:#CE0000 !important;
font-weight: bold;
} }

View File

@ -1,11 +1,13 @@
<nav class="navbar navbar-light"> <nav class="navbar navbar-light p-0">
<div class="container-fluid"> <div class="container-fluid d-flex align-items-center pt-3">
<img src="assets/images-header/logo.png" alt="logo"> <div class="logo ps-4">
<form style="width: 20%;" class="d-flex"> <img src="assets/images-header/LOGO2.png" alt="logo">
<input class="form-control me-2" type="search" placeholder="Trouver votre SIMPL'EAT..." aria-label="Search">
</form>
<div class="trait">
<p>LE BON PLAN POUR MANGER</p>
</div>
</div> </div>
<form style="width: 30%;" class="d-flex align-items-center pe-2 pt-2">
<input class="form-control me-5 position-relative" type="search" placeholder="Trouver votre SIMPL'EAT..." aria-label="Search">
</form>
<div class="trait">
<p>LE BON PLAN POUR MANGER</p>
</div>
</div>
</nav> </nav>

View File

@ -14,27 +14,23 @@
width: 100%; width: 100%;
height: 30px; height: 30px;
border-bottom: 2px solid red; border-bottom: 2px solid #CE0000;
position: relative; position: relative;
} }
img{
padding-left: 2%;
}
p{ p{
background-color: white; background-color: white;
position: absolute; position: absolute;
top: 15px; top: 15px;
left: 130px; left: 68px;
padding : 0 10px 0 10px; padding : 0 10px 0 10px;
font-weight: bolder;
color: grey; color: grey;
} }
// .form-control{
// }
input[type="search"], textarea{
background-color: #edf5f1;
}

View File

@ -0,0 +1,136 @@
<h2 class="titre ">Filtres :</h2>
<div class="separation"></div>
<div class="accordion">
<!-------------------------------------------------------------------------- Accordéon Distance -------------------------------------------------------------------------->
<div class="accordion-item">
<h2 class="accordion-header" id="panelsStayOpen-headingOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#panelsStayOpen-collapseOne">
<p style="font-family:'Roboto';font-size: 20px;">Distance</p>
</button>
</h2>
<div id="panelsStayOpen-collapseOne" class="accordion-collapse collapse"
aria-labelledby="panelsStayOpen-headingOne">
<div class="accordion-body">
<div class="distance p-3">
<span>Veuillez sélectionner la distance souhaitée</span>
</div>
<input type="range" class="form-range" min="{{minDistance}}" max="{{maxDistance}}"
(change)="OnChangeValueDistance($event)">
<div class="valuesDistance d-flex d-flex justify-content-between">
<span>0 KM</span>
<span>2 KM</span>
<span>4 KM</span>
</div>
</div>
</div>
</div>
<!-------------------------------------------------------------------------- Accordéon Prix -------------------------------------------------------------------------->
<div class="accordion-item">
<h2 class="accordion-header" id="panelsStayOpen-headingTwo">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#panelsStayOpen-collapseTwo">
<p style="font-family:'Roboto'; font-size: 20px;">Prix</p>
</button>
</h2>
<div id="panelsStayOpen-collapseTwo" class="accordion-collapse collapse"
aria-labelledby="panelsStayOpen-headingTwo">
<div class="accordion-body">
<div class="minMax p-3">
<span>Veuillez sélectionner le prix souhaité</span>
</div>
<input type="range" class="form-range" ng-model="valuePrix" min="{{minPrice}}" max="{{maxPrice}}"
(change)="OnChangeValuePrice($event)">
<div class="valuesPrix d-flex d-flex justify-content-between">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
</div>
</div>
</div>
</div>
<!-------------------------------------------------------------------------- Accordéon Place/Emporter -------------------------------------------------------------------------->
<div class="accordion-item">
<h2 class="accordion-header" id="panelsStayOpen-headingThree">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#panelsStayOpen-collapseThree">
<p style="font-family:'Roboto'; font-size: 20px;">Sur Place / A Emporter</p>
</button>
</h2>
<div id="panelsStayOpen-collapseThree" class="accordion-collapse collapse"
aria-labelledby="panelsStayOpen-headingThree">
<div class="accordion-body">
<div class="Titles m-3 d-flex justify-content-around">
<span>Sur Place</span>
<span>A Emporter</span>
</div>
<div class="PlaceEmporterCheck m-3 d-flex justify-content-around">
<input class="surPlace-check-input" type="checkbox" value="surPlaceOption"
style="width: 25px; height: 25px; border-radius: 300px;" (change)="OnChangeValueSurPlace($event)">
<input class="Emporter-check-input" type="checkbox" value="aEmporterOption" style="width: 25px; height: 25px;"
(change)="OnChangeValueEmporter($event)">
</div>
</div>
</div>
</div>
<!-------------------------------------------------------------------------- Accordéon AccesPMR -------------------------------------------------------------------------->
<div class="accordion-item">
<h2 class="accordion-header" id="panelsStayOpen-headingFour">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#panelsStayOpen-collapseFour">
<p style="font-family:'Roboto'; font-size: 20px;">Accès PMR</p>
</button>
</h2>
<div id="panelsStayOpen-collapseFour" class="accordion-collapse collapse"
aria-labelledby="panelsStayOpen-headingFour">
<div class="accordion-body">
<div class="titrePmr m-3 d-flex justify-content-around">
<span>Accès PMR</span>
</div>
<div class="pmr-check d-flex justify-content-center p-2">
<input class="pmr-check-input mx-auto" type="checkbox" value="AccesPMR" style="width: 25px; height: 25px;"
(change)="OnChangeValuePMR($event)">
</div>
</div>
</div>
</div>
<!-------------------------------------------------------------------------- Accordéon Avis -------------------------------------------------------------------------->
<div class="accordion-item">
<h2 class="accordion-header" id="panelsStayOpen-headingFive">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#panelsStayOpen-collapseFive">
<p style="font-family:'Roboto'; font-size: 20px;">Avis</p>
</button>
</h2>
<div id="panelsStayOpen-collapseFive" class="accordion-collapse collapse"
aria-labelledby="panelsStayOpen-headingFive">
<div class="accordion-body">
<div class="titreAvis m-3 d-flex justify-content-around">
<span>Choisissez parmi les avis déjà donnés</span>
</div>
<app-avis-bar (stateNumber)="onStateNumberChange($event)"></app-avis-bar>
</div>
</div>
</div>
</div>
<button class="btn-search btn-primary" type="button" (click)="onSendFilters()" (click)="onSendRating()">LANCER LA
RECHERCHE</button>

View File

@ -0,0 +1,63 @@
.separation{
display: flex;
justify-content: flex-start;
border-bottom: 2px solid #CE0000;
max-width: 83%;
}
.titre{
display: flex;
justify-content: flex-start;
margin: 2.5em 0 0.5em 8.2em;
color: #CE0000;
}
.accordion{
padding-top: 100px;
max-width: 30%;
margin : 0 auto;
margin-bottom: 100px;
}
.accordion-body{
background-color: #F5F3F3;
text-align: center;
}
.accordion-item{
margin-bottom: 60px;
}
.accordion-button{
background-color: #CE0000;
color: white;
font-family: cursive;
filter: drop-shadow(0 0 0.2rem grey);
}
.btn-search{
background-color: #CE0000;
text-align: center;
margin: 100px auto;
border-radius: 10px;
display: block;
height: 62px;
width: 272px;
font-size: 20px;
border: none;
}
span{
font-weight: 500 ;
}

View File

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

View File

@ -0,0 +1,109 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ApiBackService } from 'src/app/services/api-back.service';
@Component({
selector: 'app-filters-page',
templateUrl: './filters-page.component.html',
styleUrls: ['./filters-page.component.scss']
})
export class FiltersPageComponent implements OnInit {
public minDistance : any;
public maxDistance : any;
public minPrice : any;
public maxPrice: any;
public selectPrice : number;
public selectDistance : any;
public selectPmr :any;
public selectSurPlace : any;
public selectEmporter : any;
@Output() stateNumber = new EventEmitter();
@Output() rangeNumber = new EventEmitter();
public selectRating: number;
public listRestau: any[];
constructor(private apiBackService : ApiBackService, private route : Router, private activatedRoute : ActivatedRoute) {
this.minDistance = 0;
this.maxDistance = 4;
this.selectDistance = null;
this.minPrice = 1;
this.maxPrice = 4;
this.selectPrice = 0;
this.selectPmr = false;
this.selectEmporter = false;
this.selectSurPlace = false;
this.selectRating = 0;
this.listRestau = [];
}
ngOnInit(): void {
this.apiBackService.getRestaurants().subscribe((restaurants: any[]) => {
this.listRestau = restaurants;
});
console.log(this.listRestau);
}
OnChangeValueDistance(valueDistance: any){
this.selectDistance = valueDistance.target.value;
}
OnChangeValuePrice(valuePrice: any){
this.selectPrice = valuePrice.target.value;
}
OnChangeValuePMR(valuePmr : any){
this.selectPmr = (valuePmr.target.checked);
}
OnChangeValueSurPlace(valuePlace : any){
this.selectSurPlace = valuePlace.target.checked;
}
OnChangeValueEmporter(valueEmporter : any){
this.selectEmporter = valueEmporter.target.checked;
}
onStateNumberChange(stateNumber: number): void {
this.selectRating = stateNumber;
}
onSendRating() {
this.stateNumber.emit(this.selectRating);
}
onSendFilters() : void{
let restaus = this.listRestau;
restaus = restaus.filter((restau)=>
this.selectPrice == restau.prix
),
console.log( this.activatedRoute.snapshot.routeConfig?.path);
this.apiBackService.setListRestau(restaus, this.activatedRoute.snapshot.routeConfig?.path);
// on fait passer en second parametre le path de la route c'est a dire "filtres"
this.route.navigate(['restaurants']);
}
}

View File

@ -5,3 +5,4 @@
<app-card-category [categoryData]="category"></app-card-category> <app-card-category [categoryData]="category"></app-card-category>
</div> </div>
</div> </div>

View File

@ -14,7 +14,7 @@
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
margin: 0 0 0.5em 8.2em; margin: 2.5em 0 0.5em 8.2em;
color: #CE0000; color: #CE0000;
} }

View File

@ -16,16 +16,15 @@ export class HomePageComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.apiBackService.getCategories().subscribe((listCategories: any[]) => { this.apiBackService.getCategories().subscribe((listCategories: any[]) => {
console.log(listCategories); // console.log(listCategories);
// const listCategoriesLibelle = listCategories.map(
// (category) => category.libelle
// );
this.listCategories = listCategories; this.listCategories = listCategories;
}); });
} }
onEventLike(isLiked : boolean) {
this.apiBackService.restoLiked$.next(isLiked);
}
} }

View File

@ -1,3 +1,10 @@
<h2 class="titre ">Catégories :</h2> <app-template-page [title]="'Résultats :'">
<div class="separation"></div> <div *ngFor="let restaurantData of listRestaurants">
<app-card-resto [restaurant]= "restaurantData"></app-card-resto>
</div>
</app-template-page>

View File

@ -1,3 +1,5 @@
.separation{ .separation{
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
@ -9,7 +11,8 @@
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
margin: 0 0 0.5em 8.2em; margin: 2.5em 0 0.5em 8.2em;
color: #CE0000; color: #CE0000;
} }

View File

@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ApiBackService } from 'src/app/services/api-back.service';
@Component({ @Component({
selector: 'app-resto-page', selector: 'app-resto-page',
@ -7,9 +8,32 @@ import { Component, OnInit } from '@angular/core';
}) })
export class RestoPageComponent implements OnInit { export class RestoPageComponent implements OnInit {
constructor() { } public listRestaurants : any[];
constructor(private apiBackService : ApiBackService) {
this.listRestaurants = [];
}
ngOnInit(): void { ngOnInit(): void {
// arrivée sur la restau-page depuis filtres ou home(catégories) : appel a une méthode différente du service
if(this.apiBackService.routeParam === "filtres"){
this.listRestaurants = this.apiBackService.restoFilter;
}else if(this.apiBackService.routeParam === "home"){
this.apiBackService.restoByCat.subscribe((restaurants: any[]) => {
this.listRestaurants = restaurants;
});
}else{ // si on arrive sur l'url /restaurants directement = tous les restau affichés
this.apiBackService.getRestaurants().subscribe((restaurants: any[]) => {
this.listRestaurants = restaurants;
})
}
} }
} }

View File

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs'; import { Observable, of, Subject } from 'rxjs';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
@ -8,16 +8,34 @@ import { environment } from 'src/environments/environment';
}) })
export class ApiBackService { export class ApiBackService {
constructor(private httpClient: HttpClient) { } public restoByCat : Observable<any[]> = of([]);
restoLiked$ = new Subject<any>();
public restoFilter : any[];
public routeParam ?: string;
constructor(private httpClient: HttpClient) {
this.restoFilter = [];
this.routeParam = "";
}
getRestaurants(): Observable<any[]> { getRestaurants(): Observable<any[]> {
return this.httpClient.get<any[]>(`${environment.apiUrl}/restaurants`); return this.httpClient.get<any[]>(`${environment.apiUrl}/restaurants`);
} }
getRestaurantsByCateg(id : number, routeParam ?: string ): void {
this.restoByCat = this.httpClient.get<any[]>(`${environment.apiUrl}/restaurantbytype/${id}`);
this.routeParam = routeParam;
}
getCategories(): Observable<any[]>{ getCategories(): Observable<any[]>{
return this.httpClient.get<any[]>(`${environment.apiUrl}/types`); return this.httpClient.get<any[]>(`${environment.apiUrl}/types`);
} }
setListRestau(listRestau : any[], routeParam ?: string ) : void{
this.restoFilter = listRestau;
this.routeParam = routeParam;
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 647 KiB

After

Width:  |  Height:  |  Size: 455 KiB

4
src/assets/pieton.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="8" cy="8" r="7.5" stroke="#545454"/>
<path d="M8.33333 3C8.10417 3 7.90799 3.09415 7.74479 3.28245C7.5816 3.47075 7.5 3.69712 7.5 3.96154C7.5 4.22596 7.5816 4.45232 7.74479 4.64062C7.90799 4.82893 8.10417 4.92308 8.33333 4.92308C8.5625 4.92308 8.75868 4.82893 8.92188 4.64062C9.08507 4.45232 9.16667 4.22596 9.16667 3.96154C9.16667 3.69712 9.08507 3.47075 8.92188 3.28245C8.75868 3.09415 8.5625 3 8.33333 3ZM6.43229 12.7115L7.3125 11.0469C7.40972 10.8626 7.48264 10.6783 7.53125 10.494L7.83333 9.34014L8.74479 10.4399L9.54167 12.6454C9.57986 12.7536 9.63976 12.8397 9.72135 12.9038C9.80295 12.9679 9.89583 13 10 13C10.1389 13 10.2569 12.9439 10.3542 12.8317C10.4514 12.7196 10.5 12.5833 10.5 12.4231C10.5 12.355 10.4878 12.2829 10.4635 12.2067L9.73438 10.1334C9.68924 10.0012 9.65365 9.91206 9.6276 9.86599C9.60156 9.81991 9.5434 9.74079 9.45312 9.62861L8.42708 8.35457L8.73958 6.65986L9.03125 7.3149C9.08681 7.45112 9.16319 7.54928 9.26042 7.60938C9.28125 7.62139 9.64062 7.83173 10.3385 8.24038C10.5052 8.33654 10.6146 8.38462 10.6667 8.38462C10.7639 8.38462 10.8438 8.34856 10.9062 8.27644C10.9688 8.20433 11 8.11218 11 8C11 7.83574 10.934 7.71354 10.8021 7.63341L9.60938 6.90024L9.14062 5.66226C9.05382 5.44191 8.93924 5.32171 8.79688 5.30168L7.60417 5.14543C7.49306 5.13341 7.34375 5.17147 7.15625 5.25962L5.89583 5.83654C5.82639 5.86859 5.75868 5.92268 5.69271 5.9988C5.62674 6.07492 5.58333 6.15304 5.5625 6.23317C5.28819 7.05048 5.10764 7.59535 5.02083 7.86779C5.00694 7.90385 5 7.94792 5 8C5 8.10417 5.03299 8.19431 5.09896 8.27043C5.16493 8.34655 5.24306 8.38462 5.33333 8.38462C5.40278 8.38462 5.47309 8.36558 5.54427 8.32752C5.61545 8.28946 5.66146 8.24038 5.68229 8.18029L6.21354 6.56971L7.30729 6.09495L6.54167 10.2236L5.5625 12.1466C5.52083 12.2388 5.5 12.3309 5.5 12.4231C5.5 12.5833 5.54861 12.7196 5.64583 12.8317C5.74306 12.9439 5.86111 13 6 13C6.1875 13 6.3316 12.9038 6.43229 12.7115Z" fill="#545454"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -6,6 +6,8 @@
<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="favicon.ico"> <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
</head> </head>
<body> <body>
<app-root></app-root> <app-root></app-root>