From e8125f7e195cc01f3073e5c49a612fe882194bc2 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 31 May 2024 15:52:09 +0200 Subject: [PATCH 1/2] Hide buy now button and show sold out badges --- itenium-socks/src/app/socks/shop.component.css | 7 +++++++ itenium-socks/src/app/socks/shop.component.html | 3 +++ itenium-socks/src/app/socks/shop.component.ts | 3 ++- itenium-socks/src/app/socks/sock.component.css | 6 ++++++ itenium-socks/src/app/socks/sock.component.html | 8 +++++++- itenium-socks/src/app/socks/sock.component.ts | 3 ++- socks-backend/db/socks.json | 2 +- 7 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 itenium-socks/src/app/socks/shop.component.css create mode 100644 itenium-socks/src/app/socks/sock.component.css diff --git a/itenium-socks/src/app/socks/shop.component.css b/itenium-socks/src/app/socks/shop.component.css new file mode 100644 index 0000000..7700378 --- /dev/null +++ b/itenium-socks/src/app/socks/shop.component.css @@ -0,0 +1,7 @@ +.soldOutItem { + position: absolute; + top: 0; + right: 0; + background-color: red; + padding: 0.5em; +} \ No newline at end of file diff --git a/itenium-socks/src/app/socks/shop.component.html b/itenium-socks/src/app/socks/shop.component.html index a0139e2..870f72a 100644 --- a/itenium-socks/src/app/socks/shop.component.html +++ b/itenium-socks/src/app/socks/shop.component.html @@ -15,6 +15,9 @@

{{ sock.name }}
{{ sock.price }}
+ @if (sock.inventory == 0) { +
SOLD OUT
+ }
diff --git a/itenium-socks/src/app/socks/shop.component.ts b/itenium-socks/src/app/socks/shop.component.ts index 33c897b..a62d2e2 100644 --- a/itenium-socks/src/app/socks/shop.component.ts +++ b/itenium-socks/src/app/socks/shop.component.ts @@ -8,7 +8,8 @@ import { AsyncPipe, NgFor } from '@angular/common'; selector: 'app-shop', standalone: true, imports: [NgFor, AsyncPipe], - templateUrl: './shop.component.html' + templateUrl: './shop.component.html', + styleUrls: ['./shop.component.css'], }) export class ShopComponent { socks$!: Observable; diff --git a/itenium-socks/src/app/socks/sock.component.css b/itenium-socks/src/app/socks/sock.component.css new file mode 100644 index 0000000..53f509a --- /dev/null +++ b/itenium-socks/src/app/socks/sock.component.css @@ -0,0 +1,6 @@ +.soldOutBadge { + background-color: red; + color: white; + padding: 0.2em; + margin: 0.2em; +} \ No newline at end of file diff --git a/itenium-socks/src/app/socks/sock.component.html b/itenium-socks/src/app/socks/sock.component.html index b40f9d2..6536406 100644 --- a/itenium-socks/src/app/socks/sock.component.html +++ b/itenium-socks/src/app/socks/sock.component.html @@ -32,14 +32,20 @@
{{ sock.price }}

{{ sock.name }}

+ @if (sock.inventory == 0) { + SOLD OUT!! 😭 + } + @else { {{ sock.inventory }} in stock. FREE Shipping! + } +
Color: {{ sock.variant | titlecase }}

-
diff --git a/itenium-socks/src/app/socks/sock.component.ts b/itenium-socks/src/app/socks/sock.component.ts index 1618e41..b5439e8 100644 --- a/itenium-socks/src/app/socks/sock.component.ts +++ b/itenium-socks/src/app/socks/sock.component.ts @@ -8,7 +8,8 @@ import { AsyncPipe, NgIf, TitleCasePipe } from '@angular/common'; selector: 'app-sock', standalone: true, imports: [NgIf, AsyncPipe, TitleCasePipe], - templateUrl: './sock.component.html' + templateUrl: './sock.component.html', + styleUrl: './sock.component.css' }) export class SockComponent { sock$!: Observable; diff --git a/socks-backend/db/socks.json b/socks-backend/db/socks.json index 4e09105..9037dce 100644 --- a/socks-backend/db/socks.json +++ b/socks-backend/db/socks.json @@ -79,7 +79,7 @@ "variant": "Saffron", "color": "#f6c93a", "price": 12.5, - "inventory": 9 + "inventory": 7 }, { "id": 10, From 7a06400d89862467735dc4cc5f004ec69c7526cc Mon Sep 17 00:00:00 2001 From: David Date: Fri, 31 May 2024 16:32:06 +0200 Subject: [PATCH 2/2] Add a popup message on socks bought --- itenium-socks/package-lock.json | 14 ++++++++++++ itenium-socks/package.json | 1 + itenium-socks/src/app/app.component.html | 1 + itenium-socks/src/app/app.component.ts | 6 ++++- itenium-socks/src/app/app.config.ts | 2 ++ .../src/app/socks/sock.component.html | 2 +- itenium-socks/src/app/socks/sock.component.ts | 22 +++++++++++++++++-- socks-backend/db/socks.json | 6 ++--- 8 files changed, 47 insertions(+), 7 deletions(-) diff --git a/itenium-socks/package-lock.json b/itenium-socks/package-lock.json index 295c374..81e06e4 100644 --- a/itenium-socks/package-lock.json +++ b/itenium-socks/package-lock.json @@ -18,6 +18,7 @@ "@angular/router": "^18.0.0", "@fortawesome/angular-fontawesome": "^0.15.0", "@fortawesome/fontawesome-free": "^6.5.2", + "ng-angular-popup": "^0.6.1", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.14.3" @@ -9054,6 +9055,19 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/ng-angular-popup": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/ng-angular-popup/-/ng-angular-popup-0.6.1.tgz", + "integrity": "sha512-wne+45HEwxiRJozXS14qTxZerQ+z75ZrZdJIuEroRIqxh89x7jlGB0pZCXpxL+5mm2EruVLFbbqjc+ZvcDVi4w==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": ">=12.0.0-0", + "@angular/core": ">=12.0.0-0", + "@angular/platform-browser": ">=12.0.0-0" + } + }, "node_modules/nice-napi": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", diff --git a/itenium-socks/package.json b/itenium-socks/package.json index 6b3a9d6..c415056 100644 --- a/itenium-socks/package.json +++ b/itenium-socks/package.json @@ -20,6 +20,7 @@ "@angular/router": "^18.0.0", "@fortawesome/angular-fontawesome": "^0.15.0", "@fortawesome/fontawesome-free": "^6.5.2", + "ng-angular-popup": "^0.6.1", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.14.3" diff --git a/itenium-socks/src/app/app.component.html b/itenium-socks/src/app/app.component.html index 67e7bd4..55bc974 100644 --- a/itenium-socks/src/app/app.component.html +++ b/itenium-socks/src/app/app.component.html @@ -1 +1,2 @@ + \ No newline at end of file diff --git a/itenium-socks/src/app/app.component.ts b/itenium-socks/src/app/app.component.ts index 8ad7283..d5b402d 100644 --- a/itenium-socks/src/app/app.component.ts +++ b/itenium-socks/src/app/app.component.ts @@ -1,12 +1,16 @@ import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; +import {NgToastModule, ToasterPosition} from 'ng-angular-popup'; @Component({ selector: 'app-root', standalone: true, imports: [ + NgToastModule, RouterOutlet, ], templateUrl: './app.component.html', }) -export class AppComponent {} +export class AppComponent { + ToasterPosition = ToasterPosition; +} diff --git a/itenium-socks/src/app/app.config.ts b/itenium-socks/src/app/app.config.ts index 3450030..9c99b77 100644 --- a/itenium-socks/src/app/app.config.ts +++ b/itenium-socks/src/app/app.config.ts @@ -3,11 +3,13 @@ import { provideRouter } from '@angular/router'; import { provideHttpClient, withFetch } from '@angular/common/http'; import { routes } from './app.routes'; +import { provideAnimations } from '@angular/platform-browser/animations'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideHttpClient(withFetch()), + provideAnimations() ] }; diff --git a/itenium-socks/src/app/socks/sock.component.html b/itenium-socks/src/app/socks/sock.component.html index 6536406..4af8eab 100644 --- a/itenium-socks/src/app/socks/sock.component.html +++ b/itenium-socks/src/app/socks/sock.component.html @@ -45,7 +45,7 @@

{{ sock.name }}



- diff --git a/itenium-socks/src/app/socks/sock.component.ts b/itenium-socks/src/app/socks/sock.component.ts index b5439e8..8679213 100644 --- a/itenium-socks/src/app/socks/sock.component.ts +++ b/itenium-socks/src/app/socks/sock.component.ts @@ -3,6 +3,7 @@ import { Observable } from 'rxjs'; import { Sock } from './sock.model'; import { SocksService } from './socks.service'; import { AsyncPipe, NgIf, TitleCasePipe } from '@angular/common'; +import { NgToastService } from 'ng-angular-popup'; @Component({ selector: 'app-sock', @@ -14,7 +15,9 @@ import { AsyncPipe, NgIf, TitleCasePipe } from '@angular/common'; export class SockComponent { sock$!: Observable; - constructor(private socksService: SocksService) {} + constructor(private socksService: SocksService, + private ngToastService: NgToastService + ) {} ngOnInit(): void { // HACK: This is not the way to get the sockId!! @@ -22,9 +25,24 @@ export class SockComponent { this.sock$ = this.socksService.getById(sockId); } + buy(): void { const sockId = +window.location.pathname.split('/')[2]; - this.socksService.buySocks(sockId).subscribe(); + const btn = document.getElementById("buyBtn"); + btn.disabled = true; + let observer = { + next: (value:any) => { + btn.disabled = false; + console.log("Bought!"); + this.ngToastService.success("Bought a pair of socks!", "Congrats!", 5000); + }, + error: (err:any) => { + btn.disabled = false; + console.log("Uh oh!"); + this.ngToastService.danger("Whoops, something went wrong...", "Uh oh!", 5000); + }, + }; + this.socksService.buySocks(sockId).subscribe( observer ); } addReview(): void { diff --git a/socks-backend/db/socks.json b/socks-backend/db/socks.json index 9037dce..d1f6895 100644 --- a/socks-backend/db/socks.json +++ b/socks-backend/db/socks.json @@ -16,7 +16,7 @@ "variant": "blue", "color": "#23A3AC", "price": 20, - "inventory": 3 + "inventory": 1 }, { "id": 3, @@ -25,7 +25,7 @@ "variant": "blue", "color": "#27384F", "price": 30, - "inventory": 9 + "inventory": 6 }, { "id": 4, @@ -79,7 +79,7 @@ "variant": "Saffron", "color": "#f6c93a", "price": 12.5, - "inventory": 7 + "inventory": 6 }, { "id": 10,