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/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..4af8eab 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..8679213 100644
--- a/itenium-socks/src/app/socks/sock.component.ts
+++ b/itenium-socks/src/app/socks/sock.component.ts
@@ -3,17 +3,21 @@ 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',
standalone: true,
imports: [NgIf, AsyncPipe, TitleCasePipe],
- templateUrl: './sock.component.html'
+ templateUrl: './sock.component.html',
+ styleUrl: './sock.component.css'
})
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!!
@@ -21,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 4e09105..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": 9
+ "inventory": 6
},
{
"id": 10,