Skip to content
Snippets Groups Projects
Commit a14d938d authored by Hugo BAYOUD's avatar Hugo BAYOUD
Browse files

create loadMenu effect and change routing to use it

parent 0dcf2333
No related branches found
No related tags found
1 merge request!3Resolve "[FRONT] Créer le composant drinks et la card pour une maquette"
Showing
with 140 additions and 38 deletions
......@@ -25,9 +25,10 @@ import { reducersMap } from './share/store';
import { AuthEffects } from './share/store/effects/auth.effects';
import { BarEffects } from './share/store/effects/bar.effects';
import { DrinksComponent } from './components/drinks/drinks.component';
import { ToDegreePipe } from './share/pipes/to-degree.pipe';
@NgModule({
declarations: [AppComponent],
declarations: [AppComponent, ToDegreePipe],
imports: [
BrowserModule,
BrowserAnimationsModule,
......
......@@ -12,7 +12,7 @@ export const APP_ROUTING: Route[] = [
{ path: 'photos', canActivate: [AuthGuard], loadChildren: () => import('./photos/photos.module').then(m => m.PhotosModule) },
{ path: 'profile', canActivate: [AuthGuard], loadChildren: () => import('./profile/profile.module').then(m => m.ProfileModule) },
{ path: 'bars', canActivate: [AuthGuard], component: BarsComponent },
{ path: 'drinks', canActivate: [AuthGuard], component: DrinksComponent },
{ path: 'menu/:id', canActivate: [AuthGuard], component: DrinksComponent },
{ path: 'signup', canActivate: [AlreadyLoggedInGuard], component: SignupComponent },
{ path: 'signin', canActivate: [AlreadyLoggedInGuard], component: SigninComponent },
{ path: '', redirectTo: '', pathMatch: 'full' },
......
......@@ -3,7 +3,7 @@
<p>Choisis ton lieu de beuverie.
Tu pourras ensuite accéder à la carte des boissons.</p>
</div>
<!-- <section>
<section>
<div *ngFor="let bar of (bars$ | async)" class=" card row-container center">
<div class="card-header">
<img class="logo-img" src="https://fakeimg.pl/300/" alt="fake-img">
......@@ -13,21 +13,7 @@
<div>{{ bar.address }}</div>
</div>
<div class="card-action">
<button mat-raised-button routerLink="/drinks" color='accent'>choisir</button>
</div>
</div>
</section> -->
<section>
<div class=" card row-container center">
<div class="card-header">
<img class="logo-img" src="https://fakeimg.pl/300/" alt="fake-img">
</div>
<div class="card-content">
<p>Déliriuem Café clermont-ferrand</p>
<div>Delidelideli</div>
</div>
<div class="card-action">
<button mat-raised-button routerLink="/drinks" color='accent'>choisir</button>
<button mat-raised-button routerLink="/menu/{{bar._id}}" color='accent'>choisir</button>
</div>
</div>
</section>
</section>
\ No newline at end of file
<div class="band">
<div *ngFor="let nb of tests" class="drink-card">
<h3 class="title">Délirium Tremens</h3>
<div *ngFor="let drink of (menu$ | async).drinks" class="drink-card">
<h3 class="title">{{ drink.shortname }}</h3>
<div class="thumb" style="background-image: url(https://fakeimg.pl/250x250/);"></div>
<hr>
<article>
<p>degrée : <strong>7,5°</strong> / Prix : <strong>7.5€</strong></p>
<p>degrée : <strong>{{ drink.abv }}°</strong> / Prix : <strong>7.5€</strong></p>
<span class="xp-number">1200</span><span class="xp">xp</span>
<p class="description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Ut officiis ea minus nostrum vel fuga.</p>
<p class="description">{{ drink.description }}</p>
</article>
<button mat-raised-button routerLink="/drinks" color='accent'>commander</button>
<button mat-raised-button routerLink="/menu" color='accent'>commander</button>
</div>
</div>
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { currentMenuSelector } from '../../share/store/selectors/bar.selectors';
import { FetchBarMenu } from '../../share/store/actions/bar.actions';
import { Menu } from '../../share/models/menu.model';
import { State } from '../../share/store';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-drinks',
......@@ -6,11 +14,22 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./drinks.component.css']
})
export class DrinksComponent implements OnInit {
public menu$: Observable<Menu> = this.store.select(currentMenuSelector);
public tests: number[] = [0, 1, 2, 3, 4];
constructor() { }
constructor(
private activatedRoute: ActivatedRoute,
private store: Store<State>,
) {}
ngOnInit(): void {
}
this.activatedRoute.params.subscribe(params => {
const barId = params['id'];
if (barId) {
this.store.dispatch(new FetchBarMenu(barId));
}
});
}
}
......@@ -3,9 +3,9 @@
<!-- <span *ngIf="!(isLoggedIn$ | async)" fxLayoutGap="15px" fxLayout="row" fxLayoutAlign="center center">
<mat-icon class="link" routerLink="/signin">login</mat-icon>
<mat-icon class="link" routerLink="/signup">launch</mat-icon>
</span>
</span> -->
<span *ngIf="isLoggedIn$ | async" fxLayoutGap="15px" fxLayout="row" fxLayoutAlign="center center">
<mat-icon class="link" routerLink="/profile">account_circle</mat-icon>
<!-- <mat-icon class="link" routerLink="/profile">account_circle</mat-icon> -->
<mat-icon class="link" routerLink="/" (click)="onLogout()">power_settings_new</mat-icon>
</span> -->
</span>
</mat-toolbar>
\ No newline at end of file
export interface Bar {
_id: string;
shortname: string;
longname: string;
description: string;
......
export interface Drink {
id: number,
shortname: string,
longname: string,
description: string,
idFamilyDrink: number,
abv: string,
img: string,
sizes: number[],
}
\ No newline at end of file
import { Bar } from "./bar.model";
import { Drink } from "./drink.model";
export interface Menu {
bar: Bar;
drinks: Drink[];
}
\ No newline at end of file
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'toDegree'
})
export class ToDegreePipe implements PipeTransform {
transform(value: string, ...args: unknown[]): number {
return (+value) * 100;
}
}
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Menu } from '../models/menu.model';
import { Bar } from '../models/bar.model';
@Injectable({
......@@ -13,5 +15,9 @@ export class BarService {
// authInterceptor add the token in the HTTP request
public getAll(): Observable<Bar[]> {
return this.http.get<Bar[]>('/api/v1/bars');
}
}
public getMenu(barId: string): Observable<Menu> {
return this.http.get<Menu>(`/api/v1/menu/${barId}`)
}
}
import { Action } from "@ngrx/store";
import { Bar } from "../../models/bar.model";
import { Menu } from "../../models/menu.model";
export enum BarActionsTypes {
FETCH_BARS = '[bars/api] fetch all bars',
FETCH_BARS_SUCCESS = '[bars/api] fetch bars success',
FETCH_BARS_FAILED = '[bars/api] fetch bars failed'
FETCH_BARS_FAILED = '[bars/api] fetch bars failed',
FETCH_BAR_MENU = '[bars/menu/api] fetch bar menu',
FETCH_BAR_MENU_SUCCESS = '[bar/menu/api] fetch bar menu success',
FETCH_BAR_MENU_FAILED = '[bars/menu/api] fetch bar menu failed',
}
export class FetchBars implements Action {
......@@ -21,4 +25,24 @@ export class FetchBarsFailed implements Action {
constructor(public payload: string) {}
}
export type BarsActions = FetchBars | FetchBarsSuccess | FetchBarsFailed;
\ No newline at end of file
export class FetchBarMenu implements Action {
readonly type = BarActionsTypes.FETCH_BAR_MENU;
constructor(public payload: string) {}
}
export class FetchBarMenuSuccess implements Action {
readonly type = BarActionsTypes.FETCH_BAR_MENU_SUCCESS;
constructor(public payload: Menu) {}
}
export class FetchBarMenuFailed implements Action {
readonly type = BarActionsTypes.FETCH_BAR_MENU_FAILED;
constructor(public payload: string) {}
}
export type BarsActions = FetchBars |
FetchBarsSuccess |
FetchBarsFailed |
FetchBarMenu |
FetchBarMenuSuccess |
FetchBarMenuFailed;
\ No newline at end of file
import { Actions, createEffect, ofType } from "@ngrx/effects";
import { Injectable } from "@angular/core";
import { catchError, map, mergeMap } from "rxjs/operators";
import { catchError, map, mergeMap, withLatestFrom } from "rxjs/operators";
import { EMPTY, of } from "rxjs";
import { BarActionsTypes, FetchBarsFailed, FetchBarsSuccess } from "../actions/bar.actions";
import { BarActionsTypes, FetchBarMenuFailed, FetchBarMenuSuccess, FetchBarsFailed, FetchBarsSuccess } from "../actions/bar.actions";
import { BarService } from "../../services/bar.service";
import { Bar } from "../../models/bar.model";
import { Menu } from "../../models/menu.model";
import { Store } from "@ngrx/store";
import { State } from "..";
import { currentBarIdSelector } from "../selectors/bar.selectors";
@Injectable()
export class BarEffects {
constructor(
private actions$: Actions,
private barService: BarService
private barService: BarService,
private store: Store<State>
) {}
loadBars$ = createEffect(() => this.actions$.pipe(
......@@ -22,4 +27,14 @@ export class BarEffects {
catchError(() => of(new FetchBarsFailed('failed fetching all bars')))
))
));
loadMenu$ = createEffect(() => this.actions$.pipe(
ofType(BarActionsTypes.FETCH_BAR_MENU),
withLatestFrom(this.store.select(currentBarIdSelector)),
mergeMap(([_, barId]) => this.barService.getMenu(barId)
.pipe(
map((menu: Menu) => (new FetchBarMenuSuccess(menu))),
catchError(() => of(new FetchBarMenuFailed(`failed fetch bar's menu`)))
))
));
}
\ No newline at end of file
import { Bar } from "../../models/bar.model";
import { Menu } from "../../models/menu.model";
import { BarsActions, BarActionsTypes } from "../actions/bar.actions";
export interface BarState {
bars: Bar[];
currentBar: Bar;
currentMenu: Menu;
currentBarId: string;
error: string;
}
const defaultBarState = {
bars: [],
currentBar: null,
currentMenu: null,
currentBarId: '',
error: '',
}
export function barReducer(state: BarState = defaultBarState, action: BarsActions): BarState {
switch (action.type) {
case BarActionsTypes.FETCH_BAR_MENU: {
return {
...state,
currentBarId: action.payload
};
}
case BarActionsTypes.FETCH_BARS_SUCCESS: {
return {
...state,
......@@ -23,6 +33,14 @@ export function barReducer(state: BarState = defaultBarState, action: BarsAction
};
}
case BarActionsTypes.FETCH_BAR_MENU_SUCCESS: {
return {
...state,
currentMenu: action.payload
};
}
case BarActionsTypes.FETCH_BAR_MENU_FAILED:
case BarActionsTypes.FETCH_BARS_FAILED: {
return {
...state,
......
......@@ -5,4 +5,6 @@ export const baseSelector = createFeatureSelector('bars');
export const allBarsSelector = createSelector(baseSelector, (barState: BarState) => barState?.bars);
export const currentBarSelector = createSelector(baseSelector, (barState: BarState) => barState?.currentBar);
\ No newline at end of file
export const currentMenuSelector = createSelector(baseSelector, (barState: BarState) => barState?.currentMenu);
export const currentBarIdSelector = createSelector(baseSelector, (barState: BarState) => barState?.currentBarId);
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment