From 292ed397ab6a275237cba3366bac35e861297645 Mon Sep 17 00:00:00 2001 From: elyes Date: Thu, 27 Nov 2025 13:07:05 +0100 Subject: [PATCH] feat: Implement multi-step order flow with product configuration, user data input, and order summary page. --- src/app/app.routes.ts | 4 + src/app/models/order.interface.ts | 7 +- .../ordersummarypage/ordersummarypage.html | 30 ++++- .../ordersummarypage/ordersummarypage.scss | 13 ++ src/app/ordersummarypage/ordersummarypage.ts | 30 ++++- .../productconfigpage/productconfigpage.ts | 2 + src/app/services/order.service.ts | 4 +- src/app/userdatapage/userdatapage.html | 118 ++++++++++++------ src/app/userdatapage/userdatapage.scss | 6 + src/app/userdatapage/userdatapage.ts | 52 +++++++- 10 files changed, 223 insertions(+), 43 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index ec07458..90aa47e 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,8 +1,12 @@ import { Routes } from '@angular/router'; import { Productspage } from './productspage/productspage'; import { Productconfigpage } from './productconfigpage/productconfigpage'; +import { Userdatapage } from './userdatapage/userdatapage'; +import { Ordersummarypage } from './ordersummarypage/ordersummarypage'; export const routes: Routes = [ { path: '', component: Productspage }, { path: 'products/:id', component: Productconfigpage }, + { path: 'user-data', component: Userdatapage }, + { path: 'order-success', component: Ordersummarypage }, ]; diff --git a/src/app/models/order.interface.ts b/src/app/models/order.interface.ts index 720e4f1..bd43a6b 100644 --- a/src/app/models/order.interface.ts +++ b/src/app/models/order.interface.ts @@ -28,10 +28,13 @@ export interface IProductConfig { } export interface IUserData { - fullName: string; + firstName: string; + lastName: string; + email: string; + phone: string; + city: string; address: string; zipCode: string; - city: string; } export interface IPaymentMethod { diff --git a/src/app/ordersummarypage/ordersummarypage.html b/src/app/ordersummarypage/ordersummarypage.html index a2250fb..13303b3 100644 --- a/src/app/ordersummarypage/ordersummarypage.html +++ b/src/app/ordersummarypage/ordersummarypage.html @@ -1 +1,29 @@ -

ordersummarypage works!

+
+ + Your order has been confirmed. + Shipping number: {{ order.shippingNumber }} + + + + {{ order.product?.name }} +
+ Gesamtpreis: {{ totalPrice }} CHF +
Added ingredients
+ @if(order.config?.extraBacon){ + + Extra Bacon + + } + @else { + + Extra Bacon + + } + +

Salad amount: {{ order.config?.saladAmount || 'normal' }}

+

Shipping Number:

+

{{ order.shippingNumber }}

+
+
\ No newline at end of file diff --git a/src/app/ordersummarypage/ordersummarypage.scss b/src/app/ordersummarypage/ordersummarypage.scss index e69de29..07fb525 100644 --- a/src/app/ordersummarypage/ordersummarypage.scss +++ b/src/app/ordersummarypage/ordersummarypage.scss @@ -0,0 +1,13 @@ +.summary { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 1rem; + height: 100vh; + +} + +.summary sdx-card { + width: 50%; +} \ No newline at end of file diff --git a/src/app/ordersummarypage/ordersummarypage.ts b/src/app/ordersummarypage/ordersummarypage.ts index e7c6b80..3fcc991 100644 --- a/src/app/ordersummarypage/ordersummarypage.ts +++ b/src/app/ordersummarypage/ordersummarypage.ts @@ -1,11 +1,39 @@ -import { Component } from '@angular/core'; +import { Component , inject, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { OrderService } from '../services/order.service'; @Component({ selector: 'app-ordersummarypage', imports: [], + schemas: [CUSTOM_ELEMENTS_SCHEMA], templateUrl: './ordersummarypage.html', styleUrl: './ordersummarypage.scss', }) export class Ordersummarypage { + orderService = inject(OrderService); + + get totalPrice() { + const order = this.orderService.getOrder(); + return (order.product?.basePrice ?? 0) + (order.config?.priceDelta ?? 0); + } + + get saladAmount(): number { + const order = this.orderService.getOrder(); + switch (order.config?.saladAmount) { + case 'less': + return 1; + case 'normal': + return 2; + case 'much': + return 3; + } + return 2; + } + + get order() { + const order = this.orderService.getOrder(); + + const basePrice = order.product?.basePrice ?? 0; + return order; + } } diff --git a/src/app/productconfigpage/productconfigpage.ts b/src/app/productconfigpage/productconfigpage.ts index accc1fd..d4cdfaa 100644 --- a/src/app/productconfigpage/productconfigpage.ts +++ b/src/app/productconfigpage/productconfigpage.ts @@ -76,5 +76,7 @@ export class Productconfigpage { }, totalPrice: this.totalPrice, }); + + window.location.href = '/user-data'; } } diff --git a/src/app/services/order.service.ts b/src/app/services/order.service.ts index 2db6649..6e59ba3 100644 --- a/src/app/services/order.service.ts +++ b/src/app/services/order.service.ts @@ -16,7 +16,7 @@ export class OrderService { this.currentOrder = { ...this.currentOrder, ...partialOrder }; } - public placeOrder(): string { + public placeOrder(): IOrder { // Logic to send order const finalOrder = this.getOrder(); @@ -26,6 +26,6 @@ export class OrderService { console.log('Order placed:', this.getOrder()); - return shippingID; + return this.getOrder(); } } diff --git a/src/app/userdatapage/userdatapage.html b/src/app/userdatapage/userdatapage.html index 0051067..337ffb9 100644 --- a/src/app/userdatapage/userdatapage.html +++ b/src/app/userdatapage/userdatapage.html @@ -1,38 +1,84 @@ - - - - - +
+ + + Change quantity, add or remove ingredients + + + + - -

We will be happy to put you through to one of our employees now.

- -

- - -

+ +
+
+ + Misses + Mister + +
+
- - - - - - - -
- \ No newline at end of file +
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ + + + +
+
+ + + + + + + + + + + +
+
\ No newline at end of file diff --git a/src/app/userdatapage/userdatapage.scss b/src/app/userdatapage/userdatapage.scss index e69de29..5e97b23 100644 --- a/src/app/userdatapage/userdatapage.scss +++ b/src/app/userdatapage/userdatapage.scss @@ -0,0 +1,6 @@ +.userdatapage { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; +} \ No newline at end of file diff --git a/src/app/userdatapage/userdatapage.ts b/src/app/userdatapage/userdatapage.ts index 7f76501..38ac29d 100644 --- a/src/app/userdatapage/userdatapage.ts +++ b/src/app/userdatapage/userdatapage.ts @@ -1,5 +1,8 @@ -import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { Component, CUSTOM_ELEMENTS_SCHEMA, inject } from '@angular/core'; import { FormsModule } from '@angular/forms'; +import { Router } from '@angular/router'; +import { IPaymentMethod, IProduct, IUserData } from '../models/order.interface'; +import { OrderService } from '../services/order.service'; @Component({ selector: 'app-userdatapage', @@ -10,4 +13,51 @@ import { FormsModule } from '@angular/forms'; }) export class Userdatapage { + orderService = inject(OrderService); + router = inject(Router); + paymentMethod: 'twint' | 'visa' | 'mastercard' = 'twint'; + + get productName() { + const product: IProduct = JSON.parse(localStorage.getItem('cart') || '{}').product; + return product?.name; + } + + get productId() { + const product: IProduct = JSON.parse(localStorage.getItem('cart') || '{}').product; + return product?.id; + } + + + public saveData() { + const contactData: IUserData = { + firstName: (document.getElementById('firstName') as HTMLInputElement)?.value, + lastName: (document.getElementById('lastName') as HTMLInputElement)?.value, + email: (document.getElementById('email') as HTMLInputElement)?.value, + phone: (document.getElementById('phone') as HTMLInputElement)?.value, + city: (document.getElementById('city') as HTMLInputElement)?.value, + address: (document.getElementById('address') as HTMLInputElement)?.value, + zipCode: (document.getElementById('zipCode') as HTMLInputElement)?.value, + }; + + const cart = JSON.parse(localStorage.getItem('cart') || '{}'); + + this.orderService.updateOrder({ + userData: contactData, + paymentMethod: { type: this.paymentMethod }, + product: cart.product, + config: cart.config + }); + console.log(contactData, this.paymentMethod); + } + + public finishOrder() { + this.orderService.placeOrder(); + this.router.navigate(['/order-success']); + } + + public setPaymentMethod(values: any) { + if (Array.isArray(values) && values.length > 0) { + this.paymentMethod = values[0] as 'twint' | 'visa' | 'mastercard'; + } + } }