Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
|
4fcb9dc607 | 12 months ago |
|
b985dd6fd1 | 12 months ago |
|
007772da75 | 12 months ago |
|
aa1f297106 | 12 months ago |
|
62dfca2838 | 1 year ago |
|
5b8b6f33ee | 1 year ago |
|
aaaa3a3a53 | 1 year ago |
|
2295d02452 | 1 year ago |
|
5cedd5a720 | 1 year ago |
@ -1,16 +1,20 @@
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a routerLink="/" routerLinkActive="active" ariaCurrentWhenActive="page">{{ 'title' | transloco }}</a></li>
|
||||
<li><a routerLink="/recipe/add" routerLinkActive="active" ariaCurrentWhenActive="page">{{ 'recipe.add.link' |
|
||||
transloco }}</a></li>
|
||||
<li><a routerLink="/cart" routerLinkActive="active" ariaCurrentWhenActive="page">{{ 'cart'}}</a></li>
|
||||
<li *ngIf="isLogged; else elseBlock"><a routerLink="/logout" routerLinkActive="active" ariaCurrentWhenActive="page">{{ 'logout' | transloco }}</a></li>
|
||||
<ng-template #elseBlock>
|
||||
<li><a routerLink="/login" routerLinkActive="active" ariaCurrentWhenActive="page">{{ 'login' | transloco }}</a></li>
|
||||
</ng-template>
|
||||
|
||||
<select (change)="changeLanguage($event)">
|
||||
<option value="en">🇬🇧 English</option>
|
||||
<option value="fr">🇫🇷 Français</option>
|
||||
<option value="ru">🇷🇺 Русский</option>
|
||||
<option value="en">🇬🇧</option>
|
||||
<option value="fr">🇫🇷</option>
|
||||
<option value="ru">🇷🇺</option>
|
||||
</select>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,29 @@
|
||||
import { inject } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
export const AuthGuard = () => {
|
||||
const router = inject(Router);
|
||||
const rawCookie = decodeURIComponent(document.cookie);
|
||||
const array = rawCookie.split(";");
|
||||
const name = "isAdmin=";
|
||||
let res:String = "";
|
||||
|
||||
for(let cookie of array)
|
||||
{
|
||||
while (cookie.charAt(0) === ' ') {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(name) === 0) {
|
||||
res = cookie.substring(name.length, cookie.length);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(res);
|
||||
|
||||
// Check cookie
|
||||
if(res !== "true") {
|
||||
router.navigateByUrl('/login')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
<p>ingredient-list works!</p>
|
||||
<ng-container *ngIf="ingredients">
|
||||
<div *ngFor="let ingre of ingredients">
|
||||
<p>-----------</p>
|
||||
<p><a>{{ ingre.name}}</a></p>
|
||||
<p>Description: {{ ingre.description}}</p>
|
||||
<p><button (click)="edit(ingre)">Modifier</button></p>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<div class="general-form-add">
|
||||
<h2>Ajouter un ingrédient</h2>
|
||||
<div class="form-group">
|
||||
<label for="newName">Nom:</label>
|
||||
<input id="newName" [(ngModel)]="newIngredient.name" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="newDescription">Description:</label>
|
||||
<textarea id="newDescription" [(ngModel)]="newIngredient.description" required></textarea>
|
||||
</div>
|
||||
<button class="button-form" (click)="addIngredient()">Ajouter</button>
|
||||
</div>
|
||||
|
||||
<div *ngIf="editIngredient" class="general-form-edit">
|
||||
<h2>Modifier l'ingrédient</h2>
|
||||
<div class="form-group">
|
||||
<label for="editName">Nom:</label>
|
||||
<input id="editName" [(ngModel)]="editIngredient.name">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="editDescription">Description:</label>
|
||||
<textarea id="editDescription" [(ngModel)]="editIngredient.description"></textarea>
|
||||
</div>
|
||||
<button class="button-form" (click)="updateIngredient()">Enregistrer</button>
|
||||
<button class="button-form" (click)="cancelEdit()">Annuler</button>
|
||||
</div>
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { IngredientListComponent } from './ingredient-list.component';
|
||||
|
||||
describe('IngredientListComponent', () => {
|
||||
let component: IngredientListComponent;
|
||||
let fixture: ComponentFixture<IngredientListComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [IngredientListComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(IngredientListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,54 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Ingredient } from '../../model/ingredient.model';
|
||||
import { IngredientService } from '../../services/ingredient.service';
|
||||
import { OnInit } from '@angular/core';
|
||||
import { NgFor, NgIf } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'app-ingredient-list',
|
||||
standalone: true,
|
||||
imports: [NgIf, NgFor, FormsModule],
|
||||
providers: [],
|
||||
templateUrl: './ingredient-list.component.html',
|
||||
styleUrl: './ingredient-list.component.css'
|
||||
})
|
||||
export class IngredientListComponent {
|
||||
public ingredients! : Ingredient[];
|
||||
newIngredient: Ingredient = { id: 0, name: '', description: '', qty: 0 };
|
||||
editIngredient: Ingredient | null = null;
|
||||
|
||||
constructor(private serviceIngredient : IngredientService){}
|
||||
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.serviceIngredient.getIngredient().subscribe(ingredients => {
|
||||
this.ingredients = ingredients;
|
||||
});
|
||||
}
|
||||
|
||||
edit(ingre: Ingredient){
|
||||
this.editIngredient = ingre;
|
||||
}
|
||||
|
||||
addIngredient() {
|
||||
this.serviceIngredient.add(this.newIngredient).subscribe(ingredient => {
|
||||
this.ingredients.push(ingredient);
|
||||
this.newIngredient = { id: 0, name: '', description: '', qty: 0}
|
||||
});
|
||||
}
|
||||
|
||||
updateIngredient() {
|
||||
if (this.editIngredient) {
|
||||
this.serviceIngredient.update(this.editIngredient).subscribe(updatedIngredient => {
|
||||
const index = this.ingredients.findIndex(i => i.id === updatedIngredient.id);
|
||||
this.ingredients[index] = updatedIngredient;
|
||||
this.editIngredient = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
cancelEdit() {
|
||||
this.editIngredient = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
.ingredient-mini {
|
||||
min-width: 130px;
|
||||
background-color: #d3d3d3;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
|
||||
.ingredient-mini-title {
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<div class="ingredient-mini">
|
||||
<span class="ingredient-mini-title">{{ ingredient.name }}</span>
|
||||
<span>{{ ingredient.qty }}g</span>
|
||||
</div>
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { IngredientMiniComponent } from './ingredient-mini.component';
|
||||
|
||||
describe('IngredientMiniComponent', () => {
|
||||
let component: IngredientMiniComponent;
|
||||
let fixture: ComponentFixture<IngredientMiniComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [IngredientMiniComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(IngredientMiniComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,14 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Ingredient } from '../../model/ingredient.model'
|
||||
import { Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-ingredient-mini',
|
||||
standalone: true,
|
||||
imports: [],
|
||||
templateUrl: './ingredient-mini.component.html',
|
||||
styleUrl: './ingredient-mini.component.css'
|
||||
})
|
||||
export class IngredientMiniComponent {
|
||||
@Input() ingredient!: Ingredient;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<p>login works!</p>
|
||||
<button (click)="setCookie()"> Log Me ! </button>
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoginComponent } from './login.component';
|
||||
|
||||
describe('LoginComponent', () => {
|
||||
let component: LoginComponent;
|
||||
let fixture: ComponentFixture<LoginComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [LoginComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(LoginComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,21 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Router } from "@angular/router";
|
||||
import { Inject } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
standalone: true,
|
||||
imports: [],
|
||||
templateUrl: './login.component.html',
|
||||
styleUrl: './login.component.css'
|
||||
})
|
||||
export class LoginComponent {
|
||||
|
||||
constructor(@Inject(Router) private router: Router) {}
|
||||
|
||||
|
||||
setCookie():void{
|
||||
document.cookie = "isAdmin=true";
|
||||
this.router.navigateByUrl('/ingredients');
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
<p>logout works!</p>
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LogoutComponent } from './logout.component';
|
||||
|
||||
describe('LogoutComponent', () => {
|
||||
let component: LogoutComponent;
|
||||
let fixture: ComponentFixture<LogoutComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [LogoutComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(LogoutComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,20 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Inject } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-logout',
|
||||
standalone: true,
|
||||
imports: [],
|
||||
templateUrl: './logout.component.html',
|
||||
styleUrl: './logout.component.css'
|
||||
})
|
||||
export class LogoutComponent {
|
||||
constructor(@Inject(Router) private router: Router) {}
|
||||
|
||||
|
||||
ngOnInit(){
|
||||
document.cookie = "isAdmin=false";
|
||||
this.router.navigateByUrl('/');
|
||||
}
|
||||
}
|
@ -1,4 +1,11 @@
|
||||
img {
|
||||
max-height: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
#recipe-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
}
|
@ -1,5 +1,11 @@
|
||||
<h1>{{ 'recipe.list' | transloco }}</h1>
|
||||
|
||||
<div id="recipe-list">
|
||||
<app-recipe-mini *ngFor="let recipe of recipes" [recipe]="recipe"></app-recipe-mini>
|
||||
</div>
|
||||
<app-recipe-mini *ngFor="let recipe of paginatedRecipes" [recipe]="recipe"></app-recipe-mini>
|
||||
</div>
|
||||
|
||||
<a routerLink="/recipe/add" class="plus-button">+</a>
|
||||
|
||||
<mat-paginator class="pagination" (page)="handlePageEvent($event)" [length]="length" [pageSize]="pageSize"
|
||||
[pageIndex]="pageIndex">
|
||||
</mat-paginator>
|
||||
|
@ -0,0 +1,21 @@
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
font-size: 16px;
|
||||
color: white;
|
||||
background-color: #007BFF;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.button:active {
|
||||
background-color: #004085;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<div *ngIf="commandes">
|
||||
<app-recipe-mini *ngFor="let recipe of commandes" [recipe]="recipe"></app-recipe-mini>
|
||||
<a class="button" (click)="deleteCart()">Clear recipes</a>
|
||||
</div>
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SavedRecipeComponent } from './saved-recipe.component';
|
||||
|
||||
describe('SavedRecipeComponent', () => {
|
||||
let component: SavedRecipeComponent;
|
||||
let fixture: ComponentFixture<SavedRecipeComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SavedRecipeComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SavedRecipeComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,29 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { CommandeService } from '../../services/commandes.service';
|
||||
import { OnInit } from '@angular/core';
|
||||
import { Recipe } from '../../model/recipe.model';
|
||||
import { NgFor, NgIf } from '@angular/common';
|
||||
import { RecipeMiniComponent } from '../recipe-mini/recipe-mini.component';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-saved-recipe',
|
||||
standalone: true,
|
||||
imports: [NgIf, NgFor, RecipeMiniComponent],
|
||||
templateUrl: './saved-recipe.component.html',
|
||||
styleUrl: './saved-recipe.component.css'
|
||||
})
|
||||
export class SavedRecipeComponent {
|
||||
public commandes?: Recipe[];
|
||||
|
||||
constructor(private serviceCommande : CommandeService){}
|
||||
|
||||
ngOnInit(){
|
||||
this.commandes = this.serviceCommande.getRecipe();
|
||||
}
|
||||
|
||||
deleteCart(){
|
||||
this.commandes = [];
|
||||
this.serviceCommande.clearRecipes();
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Recipe } from "../model/recipe.model";
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class CommandeService {
|
||||
private commande: Recipe[] = [];
|
||||
private localStorageKey = 'commande';
|
||||
|
||||
constructor(){
|
||||
console.log(this.commande);
|
||||
}
|
||||
|
||||
getRecipeById(id: number) {
|
||||
return this.commande.find(e => e.id === id);
|
||||
}
|
||||
|
||||
// Get recipes from local storage
|
||||
getRecipe(): Recipe[] {
|
||||
const recipesJson = localStorage.getItem(this.localStorageKey) || "[]";
|
||||
this.commande = JSON.parse(recipesJson) || [];
|
||||
return this.commande;
|
||||
}
|
||||
|
||||
// Add a new recipe
|
||||
addRecipe(recipe: Recipe): number {
|
||||
this.getRecipe();
|
||||
recipe.id = this.commande.length
|
||||
let newId = this.commande.push(recipe);
|
||||
localStorage.setItem(this.localStorageKey, JSON.stringify(this.commande));
|
||||
return newId;
|
||||
}
|
||||
|
||||
// Clear all recipes (for example, if needed)
|
||||
clearRecipes(): void {
|
||||
localStorage.removeItem(this.localStorageKey);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Ingredient } from "../model/ingredient.model";
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class IngredientService {
|
||||
private path:string = "https://664ba07f35bbda10987d9f99.mockapi.io/api/ingredients";
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
getIngredient() : Observable<Ingredient[]>{
|
||||
return this.http.get<Ingredient[]>(this.path);
|
||||
}
|
||||
|
||||
add(ingredient: Ingredient): Observable<Ingredient> {
|
||||
return this.http.post<Ingredient>(this.path, ingredient);
|
||||
}
|
||||
|
||||
update(ingredient: Ingredient): Observable<Ingredient> {
|
||||
return this.http.put<Ingredient>(`${this.path}/${ingredient.id}`, ingredient);
|
||||
}
|
||||
}
|
@ -1,8 +1,3 @@
|
||||
:root {
|
||||
font-family: "Helvetica";
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
Loading…
Reference in new issue